libertinus icon indicating copy to clipboard operation
libertinus copied to clipboard

Reduce side bearings on single quote

Open alerque opened this issue 4 years ago • 5 comments

Closes #323.

This currently a WIP, but when it does land it will be a significant change to metrics, so I will probably delay merging this until after a few small fixes hit and a minor dot release happens first.

test code

\begin[papersize=500pt x 1000pt]{document}
\script[src=packages/rules]
\nofolios
\neverindent
\font[family=Libertinus Sans,size=5pt]
\begin{raggedright}
\begin{script}

local _c = io.open(".fontship/last-commit", "r")
newver = _c:read("*a"):gsub("\n", "")
io.close(_c)

function extant(face, weight, style)
  face = face:gsub(" ", "")
  local fname = string.format("Libertinus%s-%s%s.otf", face, weight, style)
  local f = io.open(fname, "r")
  if f then
    io.close(f)
    return fname
  end
end

function tonum(weight)
  if weight == "Bold" then
    return 800
  elseif weight == "Semibold" then
    return 600
  end
  return 400
end

faces = { "Serif", "Serif Display", "Sans", --[[ "Mono", "Math", --[["SerifInitials", "Keyboard" ]]}
weights = { "", "Bold", "Semibold" }
styles = { "", "Regular", "Italic" }

SILE.registerCommand("sample", function (options, _)
  options.size = "25pt"
  SILE.call("font", options, function ()
    local str = "C'è po'. C'era D'est L'o A'e Saint' Ant's."
    SILE.typesetter:typeset(str)
    --SILE.call("font", { features = "+smcp" }, { "\\f\\ (f) [f] {f}" })
  end)
  SILE.call("skip", { height = "4pt" })
  SILE.call("par")
end)

SILE.registerCommand("label", function (options, content)
  SILE.process(content)
  SILE.call("hfill")
  SILE.call("break")
end)

for _, face in ipairs(faces) do
  for _, weight in ipairs(weights) do
    for _, style in ipairs(styles) do
      local fname = extant(face, weight, style)
      if fname then
        local disp = string.format("Libertinus %s – %s %s v", face, weight, style)
        SILE.call("label", {}, { disp .. "7.000" })
        SILE.call("sample", { family = "Libertinus "..face, weight = tonum(weight), style = style })
        SILE.call("label", {}, { disp .. newver })
        SILE.call("sample", { filename = fname })
        SILE.call("hrule", { width = "100%lw" })
        SILE.call("skip", { height = "4pt" })
      end
    end
  end
end

\end{script}
\end{raggedright}
\end{document}

image

@rriemann What do you think of this? (Besides the preview above you can download artifacts from the Actions tab of this PR to test for yourself.)

alerque avatar Aug 20 '20 23:08 alerque

Do the changes also apply to e.g. the Unicode Character 'RIGHT SINGLE QUOTATION MARK' (U+2019)?

rriemann avatar Aug 25 '20 10:08 rriemann

Nope not yet. And that's egg on my face because that's what the original issue was about!

Here is a slightly more advanced test case that covers U+2019 as well:

SILE test code

\begin[papersize=500pt x 1060pt]{document}
\script[src=packages/rules]
\nofolios
\neverindent
\font[family=Libertinus Sans,size=5pt]
\begin{raggedright}
\begin{script}

local _c = io.open(".fontship/last-commit", "r")
newver = _c:read("*a"):gsub("\n", "")
io.close(_c)

function extant(face, weight, style)
  face = face:gsub(" ", "")
  local fname = string.format("Libertinus%s-%s%s.otf", face, weight, style)
  local f = io.open(fname, "r")
  if f then
    io.close(f)
    return fname
  end
end

function tonum(weight)
  if weight == "Bold" then
    return 800
  elseif weight == "Semibold" then
    return 600
  end
  return 400
end

faces = { "Serif", "Serif Display", "Sans", --[[ "Mono", "Math", --[["SerifInitials", "Keyboard" ]]}
weights = { "", "Bold", "Semibold" }
styles = { "", "Regular", "Italic" }

SILE.registerCommand("sample", function (options, _)
  options.size = "20pt"
  SILE.call("font", options, function ()
    local str = "C'è po'. C'era D'est L'o A'e Saint' Ant's."
    SILE.typesetter:typeset(str)
	SILE.call("break")
	local str2 = str:gsub("'", "’")
    SILE.typesetter:typeset(str2)
	SILE.call("break")
	SILE.call("font", { features = "+smcp" }, { str })
	SILE.call("break")
	SILE.call("font", { features = "+smcp" }, { str2 })
  end)
  SILE.call("skip", { height = "4pt" })
  SILE.call("par")
end)

SILE.registerCommand("label", function (options, content)
  SILE.process(content)
  SILE.call("hfill")
  SILE.call("break")
end)

for _, face in ipairs(faces) do
  for _, weight in ipairs(weights) do
    for _, style in ipairs(styles) do
      local fname = extant(face, weight, style)
      if fname then
        local disp = string.format("Libertinus %s – %s %s v", face, weight, style)
        SILE.call("label", {}, { disp .. "7.000" })
        SILE.call("sample", { family = "Libertinus "..face, weight = tonum(weight), style = style })
        SILE.call("label", {}, { disp .. newver })
        SILE.call("sample", { filename = fname })
        SILE.call("hrule", { width = "100%lw" })
        SILE.call("skip", { height = "4pt" })
      end
    end
  end
end

\end{script}
\end{raggedright}
\end{document}

image

Full test output: quote.pdf

Clearly not addressed yet...

alerque avatar Aug 25 '20 11:08 alerque

Here it is with U+2019 adjusted similarly to U+0027.

image

alerque avatar Aug 25 '20 12:08 alerque

Should this change (or a similar one) also be applied to the italic font? The single quote can also have odd spacing there:

Screen Shot 2020-11-06 at 8 15 58 AM

capnrefsmmat avatar Nov 06 '20 13:11 capnrefsmmat

Yes. Actually all the other weights and styles need adjusting, but I was putting it off since I'm not ready to merge this (which will be a major breaking change). I'll do it eventually and probably keep it along with some other big changes in a devel branch for a while before enough comes together to do a breaking release.

alerque avatar Nov 06 '20 13:11 alerque