khaledhosny / luaotfload

Moved to https://github.com/latex3/luaotfload
23 stars 15 forks source link

Fontspec's [Scale=Match...] feature broken for "ordinary" fonts. #7

Closed wspr closed 14 years ago

wspr commented 14 years ago

E.g.,

\documentclass{article}
\usepackage{fontspec}
\setsansfont[Scale=MatchLowercase]{Verdana}
\begin{document}
\end{document}

because Verdana does not have

fonts.ids[id].shared.otfdata.pfminfo.os2_xheight

set. Any idea how to fix this?

khaledhosny commented 14 years ago

Luatex returns a 0 xheight (an capheight too) for verdana, I'm not sure where is the problem, I've to look further. Any other fonts exhibiting this?

khaledhosny commented 14 years ago

Checking with ttx tool, the font don't have xheight bit set at all, I think we need to revert to calculating xheight manually in such cases, but I think this is to be done in fontspec.

wspr commented 14 years ago

Strange. I wonder how XeTeX is calculating the xheight in this case. Perhaps Jonathan falls back on inspecting one of the glyphs before setting the appropriate \fontdimen.

Would it be possible in luaotfload to fill in the proper values of the \fontdimen 's rather than requiring Lua code to get these values? We want to be able to at least be partially compatible with older TeX documents, right?

khaledhosny commented 14 years ago

I've no idea what XeTeX is doing, better ask Jonathan or check the source (I always get lost inspecting XeTeX's source). Filling fontdimens might be good idea, expect I never managed to get it done, I don't recall the details, but I spent several days on this (for unicode-math) until I gave up.

khaledhosny commented 14 years ago

BTW, \fontdimen5 is a TeX82 fontdimen so it is already there, and for verdana it returns a non-zero value.

wspr commented 14 years ago

Do you mean that \fontdimen5 will always have a value for any font in LuaTeX? If so then why the Lua code? If not, are you suggesting to first check the Lua value, then check the fontdimen value, and then fall back to manual measurements?

khaledhosny commented 14 years ago

I don't know if it always have a value or not, what I meant is that \fontdimen5 is not a xetex extension, so it should be the same in luatex (or any descendant of tex82). The lua code for dimen 5 was either an oversight from me or because I felt this makes the code simple (unlikely).

khaledhosny commented 14 years ago

here an ugly code snippet that makes \fontdimen8 available, it doesn't fix this issue, but makes the hack in fontspec unnecessary. local function def_font(...) local fontdata = fonts.define.read(...) if fontdata then local units = fontdata.units local size = fontdata.size local otfdata = fontdata.shared.otfdata

        local capheight = otfdata.pfminfo.os2_capheight

        fontdata.parameters[8] = capheight/units*size
    end
    return fontdata
end
luatexbase.reset_callback('define_font')
luatexbase.add_to_callback('define_font',
                            def_font,
                           'luaotfload.define_font', 1)

This should be put after loading luaotfload and before defining any font. With this code you can now use \fontdimen5 with luatex, fixing this issue, and also \fontdimen8, which will not work with verdana but the current code is not working either.

You can use this as a temporary measure, until we figure a robust way to calculate capheight and push it to luaotfload.

khaledhosny commented 14 years ago

This code works for verdana too, I just check the height of X glyph, still not robust enough (GFS fonts for example). \input luaotfload.sty \directlua { local function def_font(...) local fontdata = fonts.define.read(...) if fontdata then local units = fontdata.units local size = fontdata.size local otfdata = fontdata.shared.otfdata

        local capheight = otfdata.pfminfo.os2_capheight

        local dimen8 = capheight/units*size

        if capheight <= 0 then
            dimen8 = fontdata.characters[string.byte("X")].height
        end

        fontdata.parameters[8] = dimen8
    end
    return fontdata
end
luatexbase.reset_callback('define_font')
luatexbase.add_to_callback('define_font',
                            def_font,
                           'luaotfload.define_font', 1)
}

\font\test=file:verdana.ttf \test
%\font\test=file:texgyretermes-regular.otf at 25pt \test

abcdABCD\vrule height \fontdimen8\font depth 0pt width 1em X

ABCDabcd\vrule height \fontdimen5\font depth 0pt width 1em x

\bye
wspr commented 14 years ago

Hi Khaled, I've incorporated this into master. Let me know if that was a bad move.

khaledhosny commented 14 years ago

I checked xetex source, the caphieght code is pretty simple; it just checks the height of X, if no X in the font then capheight is set to font ascender. So, we are doing even better by checking the font supplied os2_caphieght first.