Skip to content

Commit 6895a64

Browse files
committed
2026Q1 retrospective
1 parent f23cff5 commit 6895a64

8 files changed

Lines changed: 418 additions & 12 deletions

File tree

build.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<link rel=\"stylesheet\" href=\"/css/styles.css\">
2828
<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">
2929
<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>
30-
<link href=\"https://fonts.googleapis.com/css2?family=Baskervville:ital,wght@0,400..700;1,400..700&family=Fira+Code:wght@300..700&family=Sen:wght@400..800&display=swap\" rel=\"stylesheet\">
30+
<link href=\"https://fonts.googleapis.com/css2?family=Baskervville:wght@700&family=Fira+Code:wght@300..700&family=Sen:wght@400..800&display=swap\" rel=\"stylesheet\">
3131
"
3232
;; When doing syntax highlighting, output as CSS classes instead of the default
3333
;; inline CSS. The color theme is defined in ./content/css/htmlize-styles.css. To get

content/css/styles.css

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ th {
6363
font-size: 18px;
6464
}
6565
h1, h2, h3, h4, h5, h6 {
66-
font-family: "Baskervville";
66+
font-family: "Baskervville", serif;
6767
}
6868
h1 { font-size: 36px; }
6969
h2 { font-size: 32px; }
@@ -80,14 +80,24 @@ label.org-src-name {
8080
font-size: 14px;
8181
color: #666666;
8282
}
83-
code, pre {
84-
font-family: "Fira Code";
83+
.post-date {
8584
font-size: 14px;
85+
color: #666666;
8686
}
87-
code {
87+
.figure p {
88+
margin: 0 !important;
8889
font-size: 14px;
89-
border: 1px solid #e5e5e5;
90+
color: #666666;
91+
}
92+
div.figure {
93+
margin: 1.5rem 0;
94+
}
95+
code, pre {
96+
font-family: "Fira Code", monospace;
97+
font-size: 14px;
98+
9099
}
100+
code {border: 1px solid #e5e5e5;}
91101
div.org-src-container {
92102
margin: 1rem 0;
93103
}

content/index.org

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,21 @@
33

44
* Recent
55

6+
[[file:post/2026/04/11/fonts-q1.org][Fonts Q1]] @@html:<span class="post-date">2026-04-11</span>@@
7+
68
[[file:post/2026/03/31/function-ptrs.org][Functional Dispatch]] @@html:<span class="post-date">2026-03-31</span>@@
79

810
[[file:post/2026/02/21/lisp-3.org][Building a Lisp Interpreter (with Rust) Part 3]] @@html:<span class="post-date">2026-02-21</span>@@
911

1012
[[file:post/2026/01/25/lisp-2.org][Building a Lisp Interpreter (with Rust) Part 2]] @@html:<span class="post-date">2026-01-25</span>@@
1113

12-
[[file:post/2026/01/14/2025-recap.org][2025 Recap]] @@html:<span class="post-date">2026-01-14</span>@@
13-
1414

1515
* Archive
1616

1717
** General
1818

1919
[[file:post/2026/03/31/function-ptrs.org][Functional Dispatch]] @@html:<span class="post-date">2026-03-31</span>@@
2020

21-
[[file:post/2026/01/14/2025-recap.org][2025 Recap]] @@html:<span class="post-date">2026-01-14</span>@@
22-
2321
[[file:post/2024/12/18/new-years-resolution-evaluation-reading.org][New Years Resolution Evaluation - Reading]] @@html:<span class="post-date">2024-12-18</span>@@
2422

2523
[[file:post/2024/08/22/zigging-out.org][Zigging Out]] @@html:<span class="post-date">2024-08-22</span>@@
@@ -28,6 +26,11 @@
2826

2927
[[file:post/2024/05/13/github-gitlab.org][GitHub or GitLab for Hobby Projects]] @@html:<span class="post-date">2024-05-13</span>@@
3028

29+
** Retrospectives
30+
31+
[[file:post/2026/04/11/fonts-q1.org][Fonts Q1]] @@html:<span class="post-date">2026-04-11</span>@@
32+
33+
[[file:post/2026/01/14/2025-recap.org][2025 Recap]] @@html:<span class="post-date">2026-01-14</span>@@
3134

3235
** Tutorials
3336

content/post/2026/03/31/function-ptrs.org

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Tiny Skia compiles to a ~Context~ to store parameters and a sequence of simple
3434
enums is converted into a sequence of function pointers that run one after
3535
another.
3636

37-
#+CAPTION: Implementation of the ~Transform~ step. It tweaks some registers and moves on to the next stage.
37+
#+CAPTION: Implementation of the Transform step. It tweaks some registers and moves on to the next stage.
3838
#+BEGIN_SRC rust
3939
fn transform(p: &mut Pipeline) {
4040
let ts = &p.ctx.transform;
@@ -658,7 +658,7 @@ if let (
658658

659659
// The combined instruction sits at the LoadLocal(0) slot, so the jump offset
660660
// must be increased by 2 to reach the same target as the original JumpIf.
661-
data.extend_from_slice(&[n.wrapping_add(2) as u8, 0, 0]);
661+
data.extend_from_slice(&[n as u8 + 2, 0, 0]);
662662
i += 3;
663663
continue;
664664
}
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#+title: Fonts Q1
2+
#+date: <2026-04-11 Sat>
3+
#+author: Will S. Medrano
4+
5+
* Introduction
6+
:PROPERTIES:
7+
:ID: 8441fc9d-1865-439c-95de-5de5833e41f0
8+
:END:
9+
10+
I just completed my first full quarter on my new team[fn:startdate], the Google
11+
Fonts team. It went about as I expected; I learned a lot of stuff, but wish I
12+
had learned it all faster.
13+
14+
So what does the Google Fonts team do? Quite a bit of random stuff here and
15+
there, some of it internal to Google, and some of it open source. It's easy to
16+
talk about the more open stuff than the internal.
17+
18+
** Google Fonts
19+
:PROPERTIES:
20+
:ID: eae09021-7a19-4c3f-acd7-c48c0c58f804
21+
:END:
22+
23+
The easiest thing to explain under my team's purview is [[https://fonts.google.com/][fonts.google.com]]. You
24+
have probably used this! Many websites load their fonts from the Google Fonts
25+
catalog. Google Fonts lets you browse a catalog of fonts. Once the fonts have
26+
been selected, the site gives you a link to embed the font files into your
27+
website.
28+
29+
#+BEGIN_SRC html
30+
<link rel="preconnect" href="https://fonts.googleapis.com">
31+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
32+
<link href="https://fonts.googleapis.com/css2?family=Baskervville:wght@700&family=Sen:wght@400..800&display=swap" rel="stylesheet">
33+
#+END_SRC
34+
35+
The neat part about the Google Fonts API is that:
36+
37+
1. Google Fonts provides the font hosting. No need to download and serve the fonts.
38+
2. Efficient (enough) formatting. If you look at the generated CSS, you can see
39+
a few different technologies to better serve fonts.
40+
41+
#+CAPTION: Note the use of =woff2= and =unicode-range= to serve only the required glyphs. This page actually only needs the /latin/ range.
42+
#+BEGIN_SRC css
43+
/* latin-ext */
44+
@font-face {
45+
font-family: 'Baskervville';
46+
font-style: normal;
47+
font-weight: 700;
48+
src: url(https://fonts.gstatic.com/s/baskervville/v20/YA9Br0yU4l_XOrogbkun3kQ6vLFYXmpq8sRsYgfsigq4dC1F.woff2) format('woff2');
49+
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
50+
}
51+
/* latin */
52+
@font-face {
53+
font-family: 'Baskervville';
54+
font-style: normal;
55+
font-weight: 700;
56+
src: url(https://fonts.gstatic.com/s/baskervville/v20/YA9Br0yU4l_XOrogbkun3kQ6vLFYXmpq8sRsYgfsigS4dA.woff2) format('woff2');
57+
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
58+
}
59+
/* latin-ext */
60+
@font-face {
61+
font-family: 'Sen';
62+
font-style: normal;
63+
font-weight: 400 800;
64+
src: url(https://fonts.gstatic.com/s/sen/v12/6xKjdSxYI9_3kvWNEmo.woff2) format('woff2');
65+
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
66+
}
67+
/* latin */
68+
@font-face {
69+
font-family: 'Sen';
70+
font-style: normal;
71+
font-weight: 400 800;
72+
src: url(https://fonts.gstatic.com/s/sen/v12/6xKjdSxYI9_3nPWN.woff2) format('woff2');
73+
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
74+
}
75+
#+END_SRC
76+
77+
** Font Compiler
78+
:PROPERTIES:
79+
:ID: 346f6172-0f28-4b18-b41f-a27789e7c580
80+
:END:
81+
82+
Google maintains and develops [[https://github.com/googlefonts/fontc][fontc]], a Rust-based compiler that takes font sources
83+
and converts them into ttf/otf files. It's a lot quicker than the previous Python
84+
font compiler, [[https://github.com/googlefonts/fontmake][fontmake]], which was also developed and maintained by Google.
85+
86+
** Fontations
87+
:PROPERTIES:
88+
:ID: 412ffb16-9652-4652-bb99-d3abac6383b3
89+
:END:
90+
91+
The Rust [[https://github.com/googlefonts/fontations][Fontations]] libraries provide a foundation to read and write font
92+
data. This library is used in =fontc= as well as Skia, the 2D graphics engine
93+
used by Chrome, Chromium, Firefox, and Android.
94+
95+
* Accomplishments
96+
:PROPERTIES:
97+
:ID: b806dbeb-ba06-497c-8f8d-3d733cff1d16
98+
:END:
99+
100+
I did a few things that are internal to Google, but most of my work has been
101+
open source. Since it's open source, I can actually present some of the stuff
102+
I've done.
103+
104+
** colrv1/RadialGradients
105+
106+
*** Task
107+
108+
My starter project was to fix [[https://github.com/googlefonts/sleipnir][Sleipnir]] rendering of color fonts like
109+
[[https://fonts.google.com/specimen/Nabla?query=nabla&preview.script=Latn][Nabla]]. Sleipnir is a Rust library that can render text and icons into png or
110+
svg.
111+
112+
This one was quite a rabbit hole. The most important skill I picked up was
113+
understanding the font format. Fonts (ttf/otf files) are composed of tables. The
114+
tables define things such as contours, supported unicodes, ligatures, kerning,
115+
and lots of other stuff; it's a fairly extensible format.
116+
117+
To inspect the contents of a font, you can open it with the =ttx= command from
118+
[[https://github.com/fonttools/fonttools][fonttools]]. This produces an =xml= representation of the tables. To help me out,
119+
I even made an Emacs package that adds the ability to open ttf, otf, and
120+
woff2[fn:woff2] font files. Check out [[https://github.com/wmedrano/ttx-mode][=ttx-mode=]] if interested.
121+
122+
*** Detour
123+
124+
It turns out that getting Nabla to work was not too complicated. However, the
125+
underlying 2D graphics library did not have the full expressiveness of Radial
126+
Gradients and was missing Sweep Gradients entirely. I originally was going to
127+
leave it as is, but my manager encouraged me to continue. So I ended up learning
128+
some math and implementing [[https://github.com/linebender/tiny-skia/pull/164][radial gradient]] and [[https://github.com/linebender/tiny-skia/pull/166][sweep gradients]].
129+
130+
What's rewarding about this is that it affects a few other users. Once /typst/
131+
updates their dependencies, they should have better gradients ([[https://github.com/typst/typst/issues/7760][issues]]). I also
132+
[[https://github.com/linebender/resvg/pull/1014][completed]] /resvg/ integration to better render radial gradients. Both of these
133+
are pretty popular open source tools.
134+
135+
** IFT Support for TTX
136+
:PROPERTIES:
137+
:ID: 3642f9d0-72a4-417b-b4b1-8e39420c65f4
138+
:END:
139+
140+
*** Background
141+
:PROPERTIES:
142+
:ID: 5bb31103-5b81-476f-a9d3-079015baac71
143+
:END:
144+
145+
The main project I should be working on at the moment is landing IFT on the
146+
client. I said should since I've spent most of this quarter procrastinating and
147+
failing to comprehend specs. At least I've made a bit of progress.
148+
149+
IFT stands for Incremental Font Transfer. It is a font technology that
150+
theoretically enables more efficient transfer of fonts. One of my coworkers has
151+
been working on the spec and prototype for a while. He's done a great job at
152+
authoring the [[https://www.w3.org/TR/IFT/][W3 Spec]] for it.
153+
154+
IFT requires 2 components:
155+
156+
1. A font must be IFT encoded. This splits the font into a base font and a
157+
collection of patches.
158+
2. Client support. Clients (web browsers) must be able to request and apply the
159+
patches as needed.
160+
161+
#+BEGIN_SRC dot :file ift-encoder.svg :exports results
162+
digraph IFT {
163+
rankdir=LR;
164+
node [fontname="sans-serif"; fontsize=12; shape=record;];
165+
font [label="Font File"];
166+
base [label="Base Font"];
167+
patches [label="Patch 0|Patch 1|⋮|Patch N"];
168+
encoder [label="IFT\nEncoder"];
169+
font -> encoder;
170+
encoder -> base;
171+
encoder -> patches;
172+
}
173+
#+END_SRC
174+
175+
#+CAPTION: The encoder converts a font file into a font and its patches.
176+
#+ATTR_HTML: :style width:50%;
177+
#+RESULTS:
178+
[[file:ift-encoder.svg]]
179+
180+
#+BEGIN_SRC dot :file ift-client.svg :exports results
181+
digraph IFTClient {
182+
rankdir=LR;
183+
node [fontname="sans-serif"; fontsize=12; shape=record;];
184+
185+
webpage [label="Web Page"];
186+
browser [label="Browser"];
187+
188+
subgraph cluster_cdn {
189+
label="CDN";
190+
style="rounded";
191+
color=gray;
192+
fontname="sans-serif";
193+
fontsize=12;
194+
195+
basefont [label="Base Font"];
196+
patches [label="Patches"];
197+
}
198+
199+
webpage -> browser;
200+
basefont -> browser;
201+
patches -> browser;
202+
}
203+
#+END_SRC
204+
205+
#+CAPTION: The client must download and apply the relevant patches at runtime.
206+
#+ATTR_HTML: :style width:33%;
207+
#+RESULTS:
208+
[[file:ift-client.svg]]
209+
210+
So why is it useful to split up a font? This is all to reduce download sizes and
211+
make things load quickly and more consistently. When using a font, a web page
212+
may not need all the glyphs (characters) or styles (italic/bold/underline).
213+
214+
*** Actual Deliverables
215+
:PROPERTIES:
216+
:ID: 0894041b-86cb-4551-818e-95c382fee073
217+
:END:
218+
219+
Well, I've been really procrastinating on this since it's rather
220+
intimidating. I've read some spec, IFT code, and Chromium code, but that's not
221+
really a deliverable[fn:ift-progress].
222+
223+
However, at the end of the quarter I managed to squeeze in =fonttools= support
224+
([[https://github.com/fonttools/fonttools/pull/4072][PR]]). This allows us to inspect the =IFT= table with the very useful =ttx=
225+
tool[fn:ttx]. This is useful for debugging the feature as =IFT= contains all the
226+
metadata for defining the available patches.
227+
228+
*** Next
229+
:PROPERTIES:
230+
:ID: ac6005e1-8823-4c19-be1e-b92839a10764
231+
:END:
232+
233+
My Q2 goal is to have working IFT support in the browser. This means understanding
234+
the Chromium code, implementing the feature, and shipping it behind a flag.
235+
236+
* An Appreciation for Typeface
237+
238+
#+CAPTION: It's not all "fonts", Steve.
239+
#+ATTR_HTML: :style width:50%;margin:auto;
240+
[[./pooh.jpg]]
241+
242+
I've also gained an appreciation for typeface[fn:typeface]. I've liked tweaking
243+
around the monospace font I use after I started programming.
244+
245+
| Purpose | Typeface | Support Link |
246+
|--------------+-----------+----------------------|
247+
| OS Interface | [[https://indestructibletype.com/Jost.html][Jost*]] | [[https://indestructibletype.com/BuyJost.html][indestructible type*]] |
248+
| Body Text | [[https://rsms.me/inter/][Inter]] | [[https://rsms.me/inter/download/][rsms]] |
249+
| Code | Fira Code | 😵‍💫 |
250+
251+
252+
* Footnotes
253+
:PROPERTIES:
254+
:ID: 94bb74e4-b31a-4b91-bc53-55343586c83d
255+
:END:
256+
257+
258+
[fn:startdate] I actually started on the team in late November, but it's a short
259+
quarter between all the holidays, nobody being present, and some unexpected sick
260+
days💩.
261+
262+
[fn:woff2] A woff2 font is just a compressed version of a font.
263+
264+
[fn:ift-progress] At the time this was written, my grasp is a lot better. That's
265+
a relief, but it would be a 2026Q2 update!
266+
267+
[fn:ttx] You know, the thing I talked about earlier. The font file to xml
268+
converter.
269+
270+
[fn:typeface] Typeface is the design, for example, the Helvetica typeface. The
271+
font is the digital representation manifested into bytes.

0 commit comments

Comments
 (0)