Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable kerning without external dependency #5191

Closed
josephernest opened this issue Jan 7, 2021 · 2 comments
Closed

Disable kerning without external dependency #5191

josephernest opened this issue Jan 7, 2021 · 2 comments

Comments

@josephernest
Copy link

josephernest commented Jan 7, 2021

Hi! It's rather complex to use "no kerning":

ImageDraw.text(..., features=["-kern"])

when drawing TrueType font text on an image with ImageDraw.text.

Indeed, on Windows, we have to:

Since we're just disabling a feature (kerning), is it really necessary to import libraqm?

@nulano
Copy link
Contributor

nulano commented Jan 7, 2021

As I noted in #4724, when using basic layout (i.e. without Raqm installed or with layout_engine=ImageFont.LAYOUT_BASIC), kerning is currently non-functional anyway, at least since #2576, when Raqm was added. In the code quoted below, the PIXEL macro is dividing all values by 64, but this is then repeated in later functions when reading the result, rounding all values to zero (except for massive font sizes). I meant to open a separate issue for this but forgot... 😕

Pillow/src/_imagingft.c

Lines 578 to 585 in c9745f4

if (kerning && last_index && (*glyph_info)[i].index) {
FT_Vector delta;
if (FT_Get_Kerning(self->face, last_index, (*glyph_info)[i].index,
ft_kerning_default,&delta) == 0) {
(*glyph_info)[i-1].x_advance += PIXEL(delta.x);
(*glyph_info)[i-1].y_advance += PIXEL(delta.y);
}
}

So the answer to "Since we're just disabling a feature (kerning), is it really necessary to import libraqm?" is no 😄.


use unofficial builds of libraqm such as https://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow, and it's not mentioned in the documentation

I agree it's not very user-friendly, and I wouldn't necessarily recommend it, but you are welcome to build Raqm yourself... (I'm not saying you should, but you can if you really want an "official" version.) If you run the scripts for Windows test builds (winbuild directory), you will get a build of libraqm in the winbuild/build/bin subdirectory.

The Windows documentation could be improved, however...

we can find some info here: https://stackoverflow.com/questions/62939101/how-to-install-pre-built-pillow-wheel-with-libraqm-dlls-on-windows

Putting these two .DLL files in C:\Python37\DLLs\ doesn't work (it should! it works for Sqlite3.dll for example), we have to put them in C:\Python37\ along python.exe (which is not really great) or in C:\Windows\System32

I think the expectation is that Raqm should be installed in the system (i.e. in a PATH directory). The DLL is just loaded with the WinAPI LoadLibrary function, which looks in directories as defined in the Microsoft documentation. From that list, I would conclude that putting it in the C:\Python37\ is the preferred option for most people.

I'm not sure how well adding the C:\Python37\DLLs\ directory would work; no other Python version (that I'm aware of) has it. Therefore it could break support for PyPy, Python on MSYS2/MinGW, Cygwin, ..., not to mention anyone who has been putting it next to python.exe.

PS: I'm not sure what you mean by the sqlite3 example, but I already have sqlite3.dll in the DLLs directory and I didn't add it manually.

@josephernest
Copy link
Author

josephernest commented Jan 7, 2021

Thanks a lot for your answer @nulano!

In the meantime I found a solution for what I was looking for. My goal was to draw text with exactly the same output than the Windows user interface. As mentioned by @ned in this post:

Font rendering is a complex and subtle process, and one that has been implemented a number of times. In your case, PIL and Windows look different because they are using completely different font rendering engines. Windows uses its built-in rendering, and PIL is using the Freetype it was compiled with.

... so the solution was simply to use WinAPI, with the method detailed in python: use windows api to render text using a ttf font.

PS: if you're curious about why I wanted to have exactly the same font rendering as the Windows user inteface, here is the reason ;): asweigart/pyautogui#521

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants