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

Ligature support #2287

Closed
Graucsh opened this issue Sep 15, 2016 · 44 comments
Closed

Ligature support #2287

Graucsh opened this issue Sep 15, 2016 · 44 comments
Assignees
Labels
accepted feature Feature requests and Feature commits

Comments

@Graucsh
Copy link

Graucsh commented Sep 15, 2016

Description of the Issue

Fonts that support ligatures are not drawn with them

Steps to Reproduce the Issue

  1. Select a font that supports ligatures, such as Fira Code
  2. Select a C-based language
  3. key in "!="

Expected Behavior

a long equals sign with a slash through it

Actual Behavior

discrete characters

Suggestion

Set the Technology property of the Scintilla objects to DirectWrite, which draws with ligatures, or provide an option to turn it on.

default
directwrite

@dail8859
Copy link
Contributor

Duplicate of #1651

I looked into this at one point and just using SC_TECHNOLOGY_DIRECTWRITE is not enough. Notepad++ uses Scintilla v3.5.6 and it seems that a newer version of Scintilla is required to support ligatures. So once Scintilla is updated internally this will most likely be possible.

@Graucsh
Copy link
Author

Graucsh commented Oct 24, 2016

I added the following line to void Notepad_plus::loadBufferIntoView(BufferID id, int whichOne, bool dontClose):
::SendMessage(viewToOpen->getHSelf(), SCI_SETTECHNOLOGY, SC_TECHNOLOGY_DIRECTWRITE, 0);

I realize that's probably not the right place, but I got the following result using the Fira Code font:

npp_ligatures

@dail8859
Copy link
Contributor

That's interesting. I tried the exact same thing before without any success. Though I tried it on Win7 which might be a difference.

@Graucsh
Copy link
Author

Graucsh commented Oct 25, 2016

Maybe it makes a difference where the message is sent?
npp_ligatures_win7

I put the code after:
MainFileManager->addBufferReference(id, viewToOpen);

@dail8859
Copy link
Contributor

This is what I tried:

  • Install the Fira Code font (I think I used the medium)
  • Set the global Notepad++ font to use Fira Code
  • Type something like != and nothing happens. (I can see the font is getting changed, it just doesn't seem to pick up on the character sequences at all.)

Can't remember where I put that call in that function, but I'll try exactly where you said and see if that works for me.

@Graucsh
Copy link
Author

Graucsh commented Oct 25, 2016

I can confirm your results. Only Fira Code and Fira Code Retina draw with ligatures. Light and Medium do not.

@dail8859
Copy link
Contributor

dail8859 commented Oct 25, 2016

Success!

capture

I found I had all the different fonts installed but none of them worked...however I installed them a while ago so I downloaded and installed the latest version of the regular Fira Code font and it worked perfectly.

On a side note I don't think it matters when SCI_SETTECHNOLOGY is set because I manually changed it by my scripting plugin while a file was already opened and it immediately worked. :)

@Graucsh
Copy link
Author

Graucsh commented Oct 25, 2016

Fantastic! Thanks for staying with me on this. I really appreciate it!

@dail8859
Copy link
Contributor

Only Fira Code and Fira Code Retina draw with ligatures. Light and Medium do not.

Is this something you discovered yourself or is it documented somewhere?

@Graucsh
Copy link
Author

Graucsh commented Oct 25, 2016

Discovered with your help. I just put a != in the editor and flipped through the 4 variants. Your mentioning that you tried the medium got me to thinking.

It may be worth noting that Windows Notepad only lists the regular and retina. However, the Windows font previewer seems to like them all.

@mmokross
Copy link

Hmmm... sorry but maybe I'm confused: should this work right now on Windows 10 with Notepad++ v7.1, 32bit, build from Oct 15 2016? Or do I have to wait for an update?

@dail8859
Copy link
Contributor

It won't currently work "out of the box". The text rendering needs tweaked but you can do it with a plugin. Keep in mind support for ligatures is not officially supported so you might run into issues.

This is the easiest way I know (without recompiling) to get ligatures to work in Notepad++:

  1. Install a recent version of Fira Code (use either the normal font or the retina as those are the only ones that seem to work).
  2. Install LuaScript via the Plugin Manager (you can also use PythonScript if you are more comfortable with it or want to use a 10 ton hammer).
  3. Select the font via Settings > Style Configurator > Global Styles > Global Override. Select "Fira Code" for the font style and turn on Enable global font
  4. Edit the LuaScript startup file by doing Plugins > LuaScript > Edit Startup Script and add the following code:
editor1.Technology = SC_TECHNOLOGY_DIRECTWRITE
editor2.Technology = SC_TECHNOLOGY_DIRECTWRITE

Restart and enjoy.

@mmokross
Copy link

Thanks! Worked like a charm!

@limingjie
Copy link

@dail8859 After using the workaround, font Iosevka works, but Iosevka Light not.

@treyharris
Copy link

I don't know how OpenType rendering works on Windows, but from work on Mac and Linux I can say that this (standard weight of Fira Code and Iosevka works, nonstandard weights do not) is the expected (and arguably correct) behavior.

In OpenType you specify weight not through font selection but through OpenType variations. Ligatures, too, are supported not through glyph selection (which would require Notepad++ to be aware that "->" becomes the → ligature, etc.) but through glyph variation.

Once you use a non-base weight directly via font selection rather than through variation, you've signaled that you're not using OpenType features (correctly) anyway, so the font doesn't enable them.

So, the solution if you want Fira Code Bold to be your default is to click the "Bold" checkbox in your Style Settings. (Ligatures are preserved in boldface and bold italic text; if you've done the SC_TECHNOLOGY_DIRECTWRITE workaround above, you can check this for yourself, by checking Bold in your styles with plain Fira Code or Iosevka and not Light/Bold as your base font. Fira Code Retina is also a base font containing ligatures, bold weight and oblique (italic) variants, so it also works.)

There's no "Light" style checkbox, so there's no way to get that unfortunately, but the correct solution there is for Notepad++ to offer weight selection. The problem is that many (most) coding fonts do not have a Light variant, so the checkbox would do nothing in those cases.

I don't know what, if anything, is lost by making use of the SC_TECHNOLOGY_DIRECTWRITE. But if the answer is nothing, it should probably be enabled by default.

@dail8859
Copy link
Contributor

@treyharris The lower level text drawing is handled by Scintilla which is what Notepad++ uses internally. So any technical questions are probably best directed toward that project, especially regarding what SC_TECHNOLOGY_DIRECTWRITE does exactly.

There's no "Light" style checkbox, so there's no way to get that unfortunately, but the correct solution there is for Notepad++ to offer weight selection.

You are correct that Notepad++ does not offer anything to set a "light" version, however the underlying Scintilla control does allow setting a font weight. You can use a scripting plugin (such as LuaScript referenced above) and set the font style to a lighter weight using the call to SCI_STYLESETWEIGHT.

@treyharris
Copy link

treyharris commented Nov 13, 2017

@dail8859 Then should this issue be closed? If using LuaScript is sufficient, then you can get ligatures and you can get weights, so Notepad++ "has ligature support".

But if using LuaScript isn't sufficient to consider the issue closed, then my point stands—UI is needed or, if Light is not to be provided and it causes no other issues, SC_TECHNOLOGY_DIRECTWRITE should be set by default.

@dail8859
Copy link
Contributor

Then should this issue be closed?

There isn't official support for ligatures as it stands so I would say this should still be left open.

SC_TECHNOLOGY_DIRECTWRITE should be set by default

I know in the past there have been issues regarding the quality of the text rendering on certain systems and I'm not sure if changing this would cause any types of problems like that. Scintilla allows different technologies so I would assume there is a good reason why one is better than another in certain cases, but again these technical questions are probably best for the Scintilla project as I don't know how all this works on a detailed level.

@treyharris
Copy link

treyharris commented Nov 13, 2017

@dail8859 — thanks. I appreciate the technical question, so I just did a little research into Scintilla.

I checked the Scintilla bug tracker for references to SC_TECHNOLOGY_DIRECTWRITE, and there were only a few, none of whose responses discouraged use of it and some of which suggested using it.

According to the docs:

The technology property allows choosing between different drawing APIs and options. On most platforms, the only choice is SC_TECHNOLOGY_DEFAULT (0). On Windows Vista or later, SC_TECHNOLOGY_DIRECTWRITE (1), SC_TECHNOLOGY_DIRECTWRITERETAIN (2), or SC_TECHNOLOGY_DIRECTWRITEDC (3) can be chosen to use the Direct2D and DirectWrite APIs for higher quality antialiased drawing. SC_TECHNOLOGY_DIRECTWRITERETAIN differs from SC_TECHNOLOGY_DIRECTWRITE by requesting that the frame is retained after being presented which may prevent drawing failures on some cards and drivers. SC_TECHNOLOGY_DIRECTWRITEDC differs from SC_TECHNOLOGY_DIRECTWRITE by using DirectWrite to draw into a GDI DC. Since Direct2D buffers drawing, Scintilla's buffering can be turned off with SCI_SETBUFFEREDDRAW(0).

So: Scintilla doesn't make it the default because it needed to be unset on non-Windows and on pre-Vista versions of Windows, and it would break downstream clients of the API to make 1 the default now.

That being the case, it sounds like SC_TECHNOLOGY_DIRECTWRITE should always be used by Notepad++ on Windows Vista or later, perhaps with an option to disable.


By the way, on another note in what I wrote earlier: the difference between Fira Code and Fira Code Retina is that the latter simply has slightly increased weight across the entire spectrum. IOW, the Fira Code Retina 400 weight ("Normal", "Regular", or "Book") is closer to the Fira Code 500 weight ("Medium"), the Fire Code 400 weight is closer to Fira Code Retina's 300 ("Light"), and so on. (This is to address the reason many people set a Bold font as their default in the first place: fixed-width text on Retina displays tend to look thinner, particularly for monospaced text mixed with proportional text, like SC_TECHNOLOGY_DIRECTWRITE here.)

@dail8859
Copy link
Contributor

Thanks for the additional info.

@jefflomax
Copy link

This should NOT have been closed. Notepad++ should support ligatures out of the box, not thru hacks or adding plugins users neither need nor want.

@Graucsh
Copy link
Author

Graucsh commented Jun 29, 2018

This wasn't closed. It's still marked as open at the top. It's the referencing articles that have been closed.

@LesterCovax
Copy link

Just an FYI, a recent Windows 10 update (KB-4340917) was supposed to fix OpenType support for Win32 applications, but I tried removing the startup options and it still doesn't work.

@Flaxarn
Copy link

Flaxarn commented Aug 25, 2019

I have a problem in getting Operator Mono Light / light italic ligatures to work.
Ive used kilimans script for making the operator mono font into a ligature font and have it working in sublime3 on macOS and have tested it in windows notepad where it also works.
With above solution to att LuaScript and editing startupscript with
editor1.Technology = SC_TECHNOLOGY_DIRECTWRITE
editor2.Technology = SC_TECHNOLOGY_DIRECTWRITE
i have FiraCode working with ligatures but with the operator font it will not make the ligatures + it will break my italic fonts ive selected for my tags.

@KOLANICH
Copy link
Contributor

https://gitlab.com/KOLANICH/nppDirectWriteEnable

@KOLANICH
Copy link
Contributor

KOLANICH commented Mar 23, 2020

@sigzero, just implement it, rather than complain.

@dodmi
Copy link

dodmi commented May 22, 2020

@KOLANICH Could you please provide a compiled version of you plugin? I'd need it for the x86 architecture.
Implementing it yourself is great - if you're able to...

@xmha97
Copy link

xmha97 commented Jun 8, 2020

It won't currently work "out of the box". The text rendering needs tweaked but you can do it with a plugin. Keep in mind support for ligatures is not officially supported so you might run into issues.

This is the easiest way I know (without recompiling) to get ligatures to work in Notepad++:

  1. Install a recent version of Fira Code (use either the normal font or the retina as those are the only ones that seem to work).
  2. Install LuaScript via the Plugin Manager (you can also use PythonScript if you are more comfortable with it or want to use a 10 ton hammer).
  3. Select the font via Settings > Style Configurator > Global Styles > Global Override. Select "Fira Code" for the font style and turn on Enable global font
  4. Edit the LuaScript startup file by doing Plugins > LuaScript > Edit Startup Script and add the following code:
editor1.Technology = SC_TECHNOLOGY_DIRECTWRITE
editor2.Technology = SC_TECHNOLOGY_DIRECTWRITE

Restart and enjoy.

It won't currently work "out of the box". The text rendering needs tweaked but you can do it with a plugin. Keep in mind support for ligatures is not officially supported so you might run into issues.

This is the easiest way I know (without recompiling) to get ligatures to work in Notepad++:

  1. Install a recent version of Fira Code (use either the normal font or the retina as those are the only ones that seem to work).
  2. Install LuaScript via the Plugin Manager (you can also use PythonScript if you are more comfortable with it or want to use a 10 ton hammer).
  3. Select the font via Settings > Style Configurator > Global Styles > Global Override. Select "Fira Code" for the font style and turn on Enable global font
  4. Edit the LuaScript startup file by doing Plugins > LuaScript > Edit Startup Script and add the following code:
editor1.Technology = SC_TECHNOLOGY_DIRECTWRITE
editor2.Technology = SC_TECHNOLOGY_DIRECTWRITE

Restart and enjoy.

It doesn't work, please help me.

@dail8859
Copy link
Contributor

dail8859 commented Jun 8, 2020

@xmha97 Since you provided absolutely no additional details, there is little-to-no chance someone can help you figure out why it "doesn't work"

@KOLANICH
Copy link
Contributor

KOLANICH commented Jun 9, 2020

@KOLANICH Could you please provide a compiled version of you plugin? I'd need it for the x86 architecture. Implementing it yourself is great - if you're able to...

I can, but I don't think for such a small and trivial plugin it is beneficial. Please, download the source and build it yourself (use MinGW-w64, please, Visual Studio is not trusted after all the "adcidents") if it is feasible for you - you will get better trusted dll (it is a dll, it can contain code, so it can contain malware, so a malicious or hacked CDN or CI can insert malware into the dll you download!) this way. But if you still really want me to build it for you, just say, though don't expect the immediate response or any security or other guarantees.

I'm sorry for this late response, I was offline.

@dodmi
Copy link

dodmi commented Jun 10, 2020

@KOLANICH Actually I tried that in a way, before posting.

For a small plugin

  • I downloaded Visual Studio Community Edition (several gb of code, bearing the same risks as downloading a compiled dll from github, ok the VS installer is digitally signed...)
  • I didn't manage to get the small piece of code compiled and actually couldn't figure out, what was missing. The error messages were about something is wrong with my environment and my preferred search engine was not my friend.
  • I uninstalled Visual Studio again and posted

For people who know, what they're doing and already have a working environment, it's for sure better to compile it from the source.
For the average user, it's way more comfortable to get a dll for their system. And at least for hacking the site or the connection to insert malicious code, the risk is the same. And the dll was built from someone who knows what she/he's doing and which compiler security features to enable and which not to reduce the dlls attack surface.

That said, I'm now using LuaScript plugin, which allows to set the settings in a script at startup as described above. It's working fine, but probably your plugin would need less resources.

For other users, I'd guess, it would probably be a benefit if were providing a compiled version.

@Ekopalypse
Copy link
Contributor

There is a PR #8326 which addresses this.

@KOLANICH
Copy link
Contributor

KOLANICH commented Jun 10, 2020

I downloaded Visual Studio Community Edition

Visual Studio bears more risks. It is malware itself - it contains telemetry and even downloading it without collecting wnd sending telemetry is hard. MinGW-w64 is lot smaller - about 100 MiBs. They have an obsolete 8.1 on SourceForge (the only https-capable official source of mingw-w64), but

  1. it is sufficient for this plugin
  2. Fedora contains some RPM packages, which can be unpacked to get a working MinGW-w64 of version 9. My patch of headers is needed though to make it work with anything complex, mingw-w64 has a bug, original authors are not responding, packages maintainers deny the bug untill I give them a minimal reproducer, but I am not going to spend my time on that, so here is the patch.

In order to build you need git, CMake, mingw-64 and ninja-build. Download portable versions and unpack. Clone the repo with submodules. Open CMake GUI. create a build subdir in the repo. Put into the lower text box build dir path and into the upper one repo dir path. Click "Configure". Select ninja in generator. Select the second option to select the compilers manually and put there paths to gcc g++ and gfortran in mingw-w64 (visual studio compilers can also be used, but I have not tested on it). Then finish the wizard. It will ask you a path to ninja. Provide it too. You will want to add the compiler flags for static glibc and glibc++. Otherwise you will need some dlls from mingw. These are analogues of VS redistributables. For VS they are usually already installed. For MinGW they are usually just shipped with each app because there are different versions of MinGW-w64. Or just static linking is used. For such a small plugin static linking will be better. So google the flags and add them to the variable. You may also want to build Release configuration, so set the variable. Then configure. Then generate. Then open cmd.exe and cd to build dir and type ninja. You will get a dll within that dir. All the software using CMake is built this way.

Look, Notepad++ is an editor for programmers. And programmers must know how to use a C++ compiler. Even if you write in python or javascript only, you sometimes will have to compile native modules, and to do this you must understand how to use the compiler and the build system. There are 4 main build systems: dumb make, autotools, CMake (the most popular one) and Meson. You must know how to build software (as a user, not as a build script writer) using them.

@dodmi
Copy link

dodmi commented Jun 11, 2020

@KOLANICH Thank you for the explanation and the instructions on how to build the dll.

@Ekopalypse Thank you for the hint on the issue.

@KOLANICH
Copy link
Contributor

KOLANICH commented Jul 2, 2020

BTW, this is how (DAMN SLOW (it used to be damn slow even without ligatures), but works, wine team has implemented ligatures) it works in Wine
dwrite_npp.mp4.zip

May be somehow related to

00c0:fixme:d2d:d2d_device_context_Flush iface 000000000<something>, tag1 0000000000000000, tag2 0000000000000000 stub!

@chcg chcg added the feature Feature requests and Feature commits label Aug 1, 2020
alef162 pushed a commit to alef162/notepad-plus-plus that referenced this issue Oct 11, 2020
@rmmaniac
Copy link

rmmaniac commented Dec 7, 2020

Starting from version 7 7.8.8, Officially supports DirectWrite.
from menu->Settings->Preferences->MISC->Use DireteWrite,
Use DireteWrite checkcked and I tested JetBrainsMono-Regular.ttf and FiraCode-Retina.ttf both work fine (no LuaScpipt plugins installed)....

@thomas-ashcraft
Copy link

from menu->Settings->Preferences->MISC->Use DireteWrite,

Note: restart is required to take effect.

@sasumner
Copy link
Contributor

@thomas-ashcraft

from menu->Settings->Preferences->MISC->Use DireteWrite,

Note: restart is required to take effect.

Is that unclear in any way?

image

@u01jmg3
Copy link

u01jmg3 commented Jun 7, 2021

Has anyone else experienced an issue enabling DirectWrite and using the font Operator Mono? The font doesn't appear correctly with this option enabled.

  • Top disabled, bottom enabled.

operator

@u01jmg3
Copy link

u01jmg3 commented Jun 7, 2021

Both screenshots are using "Operator Mono Light". The only difference is DirectWrite has been enabled/disabled.

@mfaizsyahmi
Copy link

Has anyone else experienced an issue enabling DirectWrite and using the font Operator Mono? The font doesn't appear correctly with this option enabled.

* Top disabled, bottom enabled.
operator

I have this exact same problem. When DirectWrite is enabled scintilla just straight up revert to Arial, plus a whole slew of graphical and behaviour glitches.
Considering ligatures are just a "nice to have" and I got Fira Code to work on VSCodium, I'm just gonna cut my losses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted feature Feature requests and Feature commits
Projects
None yet
Development

No branches or pull requests