100 lines
4.9 KiB
Plaintext
100 lines
4.9 KiB
Plaintext
|
||
|
||
<p>In a recent entry on <a href="https://protesilaos.com/codelog/2020-07-17-emacs-mixed-fonts-org/">configuring mixed
|
||
fonts</a>,
|
||
I outlined how to specify your typefaces of choice by configuring the
|
||
<code>default</code>, <code>variable-pitch</code>, and <code>fixed-pitch</code> faces. This would allow
|
||
you to benefit from variegated typography, such as having paragraph text
|
||
rendered in a proportionately spaced font, while inline code is
|
||
displayed as monospaced.</p>
|
||
|
||
<p>The overall approach of controlling the three basic faces is fine, but
|
||
the code I shared had the unintended consequence of breaking the
|
||
built-in <code>text-scale-adjust</code> command (by default bound to <code>C-x C-+</code>,
|
||
<code>C-x C--</code>, <code>C-x C-0</code>). Here I issue a corrective to the technique that
|
||
was used before.</p>
|
||
|
||
<h2>The code that breaks ‘text-scale-adjust’</h2>
|
||
|
||
<p>This is the gist of what I was using for several months:</p>
|
||
|
||
<pre><code class="language-elisp">(set-face-attribute 'default nil :font "Hack-16")
|
||
(set-face-attribute 'fixed-pitch nil :font "Hack-16")
|
||
(set-face-attribute 'variable-pitch nil :font "FiraGO-16")
|
||
</code></pre>
|
||
|
||
<p>A variant of the above can be expressed as follows:</p>
|
||
|
||
<pre><code class="language-elisp">(set-face-attribute 'default nil :family "Hack" :height 160)
|
||
(set-face-attribute 'fixed-pitch nil :family "Hack" :height 160)
|
||
(set-face-attribute 'variable-pitch nil :family "FiraGO" :height 160)
|
||
</code></pre>
|
||
|
||
<p>If you set fonts this way and try to use <code>text-scale-adjust</code> in a buffer
|
||
with mixed fonts, you will notice that only the main text, affected by
|
||
the <code>default</code> face, gets scaled. The rest retain their height—not good.</p>
|
||
|
||
<p>This is because of a hard-wired assumption in the <code>text-scale-adjust</code>
|
||
command to only target the <code>default</code> face: <code>variable-pitch</code> and
|
||
<code>fixed-pitch</code> remain in tact, thus breaking our expectations.</p>
|
||
|
||
<p>The problem consists in the fact that we are specifying an absolute size
|
||
for each font family. Whereas we should be benefiting from relative
|
||
sizes that all have a single point of reference, which is easy to do.</p>
|
||
|
||
<h2>The recommended way to set font heights with faces</h2>
|
||
|
||
<p>Let us re-purpose the sample code from the previous section, in order to
|
||
get the behaviour we expect out of <code>text-scale-adjust</code>.</p>
|
||
|
||
<pre><code class="language-elisp">(set-face-attribute 'default nil :font "Hack-16")
|
||
(set-face-attribute 'fixed-pitch nil :family "Hack" :height 1.0)
|
||
(set-face-attribute 'variable-pitch nil :family "FiraGO" :height 1.0)
|
||
</code></pre>
|
||
|
||
<p>A alternative to the above is this:</p>
|
||
|
||
<pre><code class="language-elisp">(set-face-attribute 'default nil :family "Hack" :height 160)
|
||
(set-face-attribute 'fixed-pitch nil :family "Hack")
|
||
(set-face-attribute 'variable-pitch nil :family "FiraGO")
|
||
</code></pre>
|
||
|
||
<p>Notice that we set an absolute point size only for the <code>default</code> face.
|
||
While we instruct Emacs to interpret the height of <code>fixed-pitch</code> and
|
||
<code>variable-pitch</code> as relative to that constant. Therein lies the
|
||
difference between integer and floating point values for the <code>:height</code>
|
||
attribute (remember to consult <code>C-h f set-face-attribute</code>).</p>
|
||
|
||
<p>Strictly speaking, the <code>:height 1.0</code> is not necessary, unless you are
|
||
overriding a prior state. It is what applies when the specification is
|
||
omitted. Rendering it explicit here helps us spot the subtleties in
|
||
notation and be clear about what is at play.</p>
|
||
|
||
<h2>Details are tricky</h2>
|
||
|
||
<p>I was using the old technique for several months, adjusting fonts
|
||
through a bespoke function of mine that altered their absolute sizes.
|
||
What inspired me to investigate and eventually address this issue is a
|
||
particular statement in the doc string of <code>set-face-attribute</code>:</p>
|
||
|
||
<blockquote>
|
||
<p>Note that for the ‘default’ face, you must specify an absolute height
|
||
(since there is nothing for it to be relative to).</p>
|
||
</blockquote>
|
||
|
||
<p>Which implied that if the <code>default</code> was a constant, all other faces
|
||
could simply have a relative height. This is because of the peculiar
|
||
nature of that face to serve as the foundation upon which all others are
|
||
established. As such, a <code>:height</code> with a floating point is a multiple
|
||
of the <code>default</code> font size. Simple and effective!</p>
|
||
|
||
<p>I am now happily using <code>text-scale-adjust</code> in tandem with the tools I
|
||
mentioned in my recent video about <a href="https://protesilaos.com/codelog/2020-07-16-emacs-focused-editing/">“Focused editing” for
|
||
Emacs</a>.</p>
|
||
|
||
<p>This information is also documented in the <a href="https://protesilaos.com/emacs/modus-themes/">official manual of the Modus
|
||
themes</a> because they are designed
|
||
to cope well with mixed font scenaria, such as when the user decides to
|
||
enable the built-in <code>variable-pitch-mode</code>.</p>
|
||
|
||
|