rxi / lite

A lightweight text editor written in Lua
MIT License
7.4k stars 352 forks source link

Subpixel font rendering / demo version for preview #145

Closed franko closed 4 years ago

franko commented 4 years ago

I have recently worked on the Lite editor to improve the quality of the font rendering.

To this purpose I have used the AGG library which use, in turns, the Freetype library and I have removed the original implementation based on STB truetype. It was a lot of hark work but I am quite satisfied with the result.

The binaries to preview the results are available there:

https://github.com/franko/lite/releases/tag/1.06-subpixel-rc1

The code is available in my branch:

https://github.com/franko/lite/tree/agg-font-renderer

and it can be compiled using Meson provided the required library are installed.

I would love to have these changes merged in the Lite editor but for the moment I would like to gather some feedback and reactions both from the Lite's developer and from the users.

Kind regards Francesco

dslul commented 4 years ago

@franko my eyes are thanking you! After prolonged coding sessions, I had to switch to other editors. I'm going to use your code for the time being (on ubuntu, I had to fix the meson file to use lua52, newer versions do not work). I think on lower dpi systems like full hd desktop monitors (~100dpi) this is pretty much mandatory, but I highly doubt it is going to be merged, given the project goals. Maybe there could be a chance if using directly the freetype library, if it doesn't add much complexity.

I also tried to improve rendering without changing much, e.g. keeping stb_truetype but using a better packer, oversampling + linear filtering but the results were not as I wanted (I didn't have the time to investigate much, but in the official tests using opengl the difference was quite noticeable).

Screenshot_20200608_092343 no oversampling

Screenshot_20200608_092406 2x2 oversampling

franko commented 4 years ago

Hi Daniele,

I am glad you appreciate what I have done in term of font rendering.

Thank you for the remark about the Lua version, I have modified the Meson build file to check the Lua version. I am also planning a new release where I have fixed, most notably some glitches seen on Windows.

I am also planning to fix a problem with the project file's thread not running properly but this is a problem not related with my code and for the moment I don't have a fix.

As for the inclusion of by branch into the Lite editor I agree with your comments. It seems that the author greatly favor code simplicity over "features" so he may reject my proposition but that's okay, for the moment I just want to gather some feedback.

I agree that to have only C code and calling directly the freetype library would be better but for the moment I cannot do it as it would be a lot of additional work.

For the tests you have done with the stb_truetype library to be honest I don't think the solution is oversampling. My idea about the optimal font rendering is based on this excellent article of Maxim Shemanarev, the author of the AGG library:

https://franko.github.io/antigrain/research/font_rasterization/index.html#FONT_RASTERIZATION

(I have made a mirror of the original antigrain.com site).

Basically Maxim shows that the optimal solution is:

If you look to the high-standard applications they all use subpixel font rendering like for example Google Chrome, Sublime Text, all the Electron based application etc. This is also what Ubuntu brought on the table for the Linux desktop.

Only for really high-dpi display, like in smartphones, one can drop the subpixel rendering and hinting and use just grayscale. I would argue that you should still use gamma correction but on high dpi the difference would be hardly noticeable.

Using stb_truetype

Otherwise it is possible to adapt my implementation to use only stb_truetype. It would be quite straightforward and the only thing we would miss is vertical font hinting because stb_truetype doesn't do hinting but that could be acceptable. If there is an interest I could work in this direction.

In any case thank you for your comments!

franko commented 4 years ago

I have uploaded a new binary package for linux x86, the previous one had a major problem because it was built with the -malign-double.

franko commented 4 years ago

Here some screenshot to compare the subpixel for rendering with the reference implementation.

Dark theme

Reference

lite-dark-original

Subpixel fonts

lite-dark-subpixel

Light Summer theme

Reference

lite-light-original

Subpixel fonts

lite-light-subpixel

franko commented 4 years ago

Hi @rxi,

I have been working on the agg-font-renderer branch and now it is mostly clean.

The file renderer.c is now simple and close to its original version. I have moved all the details about rendering the fonts in a C++ library, "font renderer", located under lib/font_renderer.

The font renderer library has a simple C interface that performs just the functions needed for the Lite editor. Using the interface it is possible to choose, at compile time, grayscale or subpixel font rendering, the gamma value and some options about font's hinting.

From my point of view the code is now good enough to be used in the project if you decide to.

Please could I have your point of view about the possible utilization of this subpixel font rendering implementation into the Lite editor ?

Do you think that it is visually better ? Do you think that the complexity (C++) and additional dependencies (libagg and freetype2 instead of stb_truetype) could be acceptable ?

Personally I would love if this modification could be merged in the Lite editor. I don't mean that you should merge the new branch as it is but we may discuss the details. The most notable thing is that then build.sh script is no longer working and I am using a Meson build but this can be discussed of course.

Thank you in advance for your feedback.

rxi commented 4 years ago

Sorry for the delayed response @franko -- due to the size of the changes I was waiting for an opportunity where I would be able to take the time to give it a proper look over.

Firstly I appreciate the effort that went into this as well as the provided comparison screenshots, the changes do seem to make the font rendering a lot crisper. Unfortunately the changes go against the goals of simplicity in lite, as you pointed out; adding additional library dependencies, build system and a whole other language. Due to this conflict it isn't something I would be willing to introduce into the project.

I hope you can understand the reasoning for this and don't feel your time was wasted.

That being said: text rendering improvements to lite are not out the question, though I'm unsure sub-pixels are the solution due to the work involved (including platform specific code) in properly supporting it.

franko commented 4 years ago

Thank you for your answer, I appreciate.

For the build system, no change is needed, I can provide a build script similar to the original one to build the application without any external build system. I have used Meson only for my convenience.

I am offering you state-of-the-art font rendering for the Lite editor to be on par with all the other editors, please don't dismiss this proposition too quickly.

The AGG library and the Freetype library are already available as simple packages to install in any linux distribution.

Please have a look at the code I wrote: it is quite simple and clean if you look and its C interface used in renderer.c. Yes there is more complexity under the hood but to have subpixel font rendering it is needed and all the complexity is inside the AGG library and inside font_renderer.cpp.

Please look at the binaries I provided, they are small and have much less dependencies on external shared libraries, try to run ldd on them.

So please have another look before giving a final answer, I will wait, I am not in a hurry :-)

questor commented 4 years ago

I would love to test the subpixel version and think it's a very good idea to have it, but I can also understand rxi. I tried to compile it, but failed because of missing libs (ubuntu20.x variant, no meson-knowledge). Could amalgamated version of freetype be a solution? (it seems libagg is already included as source module into the repository)

franko commented 4 years ago

Hi Kai,

I understand your concern. It is true that Meson is not widely used and many people don't know this build system.

In case you are interested, Meson is a modern build system originally made for the Mesa3d project and now used by many projects like, among others, the Gnome desktop system. It can be installed as a distribution package or using python's pip installer.

Otherwise I agree that it is nice to be able to build the application without requiring Meson. To this purpose I have just updated the rxi's build.sh script in the agg-renderer-font branch.

Build instructions

Install the following packages (for ubuntu and debian based systems in general):

sudo apt install libfreetype6-dev libagg-dev libsdl2-dev liblua5.2-dev

then you shoud le able to buid Lite with the command:

./build.sh

Comments about the build

Installing all the dev packages above to compile Lite is the standard practice nowadays to build application on Linux. Unfortunately the resulting binary will be linked to a huge number of shared libraries and many of them are not really required for the Lite editor.

If you care about that I may suggest using the Little library helper to compile the application.

Once lhelper is installed, which is very simple, Lite can be built using the commands:

lhelper create lite # create a new build environment for Lite
# now inside the "lite" environment
lhelper install libagg
lhelper install lua 5.2.4
lhelper install freetype2
lhelper install sdl2

then you can proceed to build Lite either using the build.sh script or using Meson, as you prefer.

The advantage of using lhelper is that it will build the libraries you need only with minimal options and for static linking. The result is a more lean executable, more self contained and of small size.

I hope it will works for you but please let me know if you have any problem.

franko commented 4 years ago

Hi @rxi,

I understand you don't want to merge the changes and I respect you choice.

I am going to create a fork of Lite under the name of Lite XL. The new repository already includes the subpixel font rendering and a modification to reduce or stop CPU usage when the editor is idle.

I have also some plans to improve some other aspects of Lite, things that have been reported by users and I have observed myself using Lite. I have prepared there a Wiki with a few things in the To Do list for Lite XL:

https://github.com/franko/lite-xl/wiki/To-Do-for-first-public-release

I am therefore closing this issue.

Kind regards