pkulchenko / ZeroBraneStudio

Lightweight Lua-based IDE for Lua with code completion, syntax highlighting, live coding, remote debugger, and code analyzer; supports Lua 5.1, 5.2, 5.3, 5.4, LuaJIT and other Lua interpreters on Windows, macOS, and Linux
http://studio.zerobrane.com/
Other
2.61k stars 519 forks source link

Default editor font when font weight suffix is provided #1082

Closed ghost closed 3 years ago

ghost commented 3 years ago

Setting the following in user.lua works as expected:

editor.fontname = "SF Mono"
editor.fontsize = 10

But changing it to editor.fontname = "SF Mono Medium" results in a fallback to the default editor font. This weight suffix works in other editors, such as emacs, on my system.

Is there a way to select a font weigth variant other than the regular one?

pkulchenko commented 3 years ago

@oddp, the answer is "no" (although I'd expect SetFaceName method to take the weight into account), but it shouldn't be too difficult to fix. I'll have something to test shortly...

pkulchenko commented 3 years ago

@oddp, can you try the following patch:

diff --git a/src/editor/package.lua b/src/editor/package.lua
index 5feb76db..6978ab6c 100644
--- a/src/editor/package.lua
+++ b/src/editor/package.lua
@@ -890,11 +891,33 @@ function ide:CreateTreeCtrl(...)
   return ctrl
 end

+local fontWeights = {
+  thin = wx.wxFONTWEIGHT_THIN or 100,
+  extralight = wx.wxFONTWEIGHT_EXTRALIGHT or 200,
+  light = wx.wxFONTWEIGHT_LIGHT or 300,
+  normal = wx.wxFONTWEIGHT_NORMAL or 400,
+  medium = wx.wxFONTWEIGHT_MEDIUM or 500,
+  semibold = wx.wxFONTWEIGHT_SEMIBOLD or 600,
+  bold = wx.wxFONTWEIGHT_BOLD or 700,
+  extrabold = wx.wxFONTWEIGHT_EXTRABOLD or 800,
+  heavy = wx.wxFONTWEIGHT_HEAVY or 900,
+  extraheavy = wx.wxFONTWEIGHT_EXTRAHEAVY or 1000,
+}
+
 function ide:CreateFont(size, family, style, weight, underline, name, encoding)
   local font = wx.wxFont(size, family, style, weight, underline, "", encoding)
   if name > "" then
     -- assign the face name separately to detect when it fails to load the font
     font:SetFaceName(name)
+    if ide:IsValidProperty(font, "IsOk") and not font:IsOk() then
+      local name, weightName = name:match("(.+)%s+(%w+)$")
+      local weight = weightName and fontWeights[weightName:lower()]
+      if weight and ide:IsValidProperty(font, "SetNumericWeight") then
+        font = wx.wxFont(size, family, style, weight, underline, "", encoding)
+        font:SetFaceName(name)
+        font:SetNumericWeight(weight)
+      end
+    end
     if ide:IsValidProperty(font, "IsOk") and not font:IsOk() then
       -- assign default font from the same family if the exact font is not loaded
       font = wx.wxFont(size, family, style, weight, underline, "", encoding)

If it does work, can you comment out font:SetNumericWeight(weight) call and see if it still works. Thanks!

ghost commented 3 years ago

Regarding weight I'm not seeing much of a difference, but the font no longer reverts to the default fallback font:

Screenshot_2020-10-11_13-05-16 Screenshot_2020-10-11_13-04-50 Screenshot_2020-10-11_13-03-29 Screenshot_2020-10-11_13-04-14

Quick and dirty debug printing:

print("CreateFont:", name, weightName, weight)
font:SetFaceName(name)
font:SetNumericWeight(weight)
==> CreateFont: SF Mono Medium  500
pkulchenko commented 3 years ago

@oddp, indeed. It turned out that Scintilla (the editor component) doesn't take the weight from the font, but requires explicit setting of it for each style. Still working on it, as editor:StyleSetBold(style, true) works, but editor:StyleSetWeight(style, 700) doesn't for some reason (even though it should according to the docs).

pkulchenko commented 3 years ago

@oddp, try adding the following patch to the earlier one:

diff --git a/src/editor/style.lua b/src/editor/style.lua
index 950435f8..7772eafe 100644
--- a/src/editor/style.lua
+++ b/src/editor/style.lua
@@ -368,9 +368,12 @@ function StylesApplyToEditor(styles,editor,font,fontitalic,lexerconvert)
     fontitalic:SetStyle(wx.wxFONTSTYLE_ITALIC)
   end

+  local weight = ide:IsValidProperty(font, "GetNumericWeight") and font:GetNumericWeight()
+
   local function applystyle(style,id)
     editor:StyleSetFont(id, style.i and fontitalic or font)
     editor:StyleSetBold(id, style.b or false)
+    if weight and not style.b then editor:StyleSetWeight(id, weight) end
     editor:StyleSetUnderline(id, style.u or false)
     editor:StyleSetEOLFilled(id, style.fill or false)

This does make a difference for me, but not all fonts seem to support a variety of weights; some show the same result for Bold/ExtraBold/Heavy weights.

ghost commented 3 years ago

Yes, it does make a difference for Light and Bold weight variants, but some, like Medium, still aren't recognized, it seems.

Thanks for taking the time to look into this!

pkulchenko commented 3 years ago

@oddp, do you think it's a feature of the font or do you clearly see the difference with the Medium font in other applications? Keep in mind that the difference in other applications may be related to the actual weight that medium label is associated with. For example, in my (wxwidgets) mapping medium is mapped to 500, but if in some other application it's mapped to 700, then you'll see some visual difference, but it may be the same as bold or semibold.

ghost commented 3 years ago

I've tested multiple fonts in multiple editors, be it TUI or GUI, and all of them are displaying Regular, Medium, Semibold and Bold weight suffixes as one would expect. They are consistently distinct from one another in all other editors, ZeroBrane/wxwidgets is the outlier here.

But feel free to close, since the above patch allows choosing a font weight different from the default regular variant in most cases.

Thanks again!