<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>font &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/font/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Fri, 13 Mar 2026 15:18:22 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>font &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[An odd font rendering bug in Firefox and Safari]]></title>
		<link>https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/</link>
					<comments>https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 13 Mar 2026 12:34:09 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[font]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=68692</guid>

					<description><![CDATA[First up, you should go and watch The Importance of Being Earnest with Ncuti Gatwa. It is a brilliant set of performances and a joy to see.  While perusing the programme on the National Theatre website I stumbled upon a little bug.  The incredible Ronkẹ Adékọluẹ́jọ́ has her name rendered in a most unusual style:    It rendered just fine in Chrome - but both Firefox and Safari misrendered some of t…]]></description>
										<content:encoded><![CDATA[<p>First up, you should go and watch <a href="https://www.youtube.com/watch?v=obX-HGs-PS8">The Importance of Being Earnest</a> with Ncuti Gatwa. It is a brilliant set of performances and a joy to see.</p>

<p>While perusing the <a href="https://www.nationaltheatre.org.uk/productions/the-importance-of-being-earnest/#cast">programme on the National Theatre website</a> I stumbled upon a little bug.  The incredible Ronkẹ Adékọluẹ́jọ́ has her name rendered in a most unusual style:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/ronke.webp" alt="Screenshot of a website. Contains a phone of a black woman next to her name. Any characters with accents in her name are rendered without boldface." width="2953" height="1798" class="aligncenter size-full wp-image-68694">

<p>It rendered just fine in Chrome - but both Firefox and Safari misrendered <em>some</em> of the accented characters.</p>

<p>Here's a minimum viable demo to show what's happening:</p>

<iframe height="300" style="width: 100%;" scrolling="no" title="FF Font Rendering Issue?" src="https://codepen.io/edent/embed/qEaRyrz?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true">
  See the Pen <a href="https://codepen.io/edent/pen/qEaRyrz">
  FF Font Rendering Issue?</a> by Terence Eden (<a href="https://codepen.io/edent">@edent</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<h2 id="fonts-are-hard-ok"><a href="https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/#fonts-are-hard-ok">Fonts are hard, OK?!?!</a></h2>

<p>Broadly speaking<sup id="fnref:complicated"><a href="https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/#fn:complicated" class="footnote-ref" title="It is a lot more complicated than that." role="doc-noteref">0</a></sup>, accented characters can be made in two way.</p>

<ol>
<li>Pre-composed. There is a separate code for the character <code>é</code></li>
<li>Combining. The plain letter <code>e</code> is immediately followed by the <em>combining</em> character <code>◌́</code> and the computer smushes them together.</li>
</ol>

<p>Similarly, a font file can have separate little drawings for each accented character or it can have separate accents.</p>

<p>In this case, the National Theatre is using the font "Helvetica Now Display W04".</p>

<p>The web font contains <code>é</code> (U+00E9) and both <code>◌́</code> (U+0301) &amp; <code>̣◌</code> (U+0323).</p>

<p>But doesn't include <code>ẹ</code> (U+1EB9) or <code>ọ</code> (U+1ECD).</p>

<p>So the ẹ́  and ọ́  have to be made by combining characters in the font.</p>

<p>On Chrome this works. On Firefox and Safari, it seems to break when the CSS is set to <code>font-weight: normal;</code>. This causes the browser to render those characters in the default fallback font - hence the slightly weird look.</p>

<h2 id="next-steps"><a href="https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/#next-steps">Next Steps</a></h2>

<p>I've raised <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=2023126">a bug with Firefox</a> and one with <a href="https://bugs.webkit.org/show_bug.cgi?id=309889">WebKit</a>.</p>

<p>Of course, it might be that they're doing the right thing and Chrome is in the wrong - but I think that's unlikely.</p>

<p>Now, time to fix the font I use on this website to prevent any rendering errors!</p>

<div id="footnotes" role="doc-endnotes">
<hr aria-label="Footnotes">
<ol start="0">

<li id="fn:complicated">
<p>It is a <em>lot</em> more <a href="https://www.youtube.com/watch?v=5NPBIwQyPWE">complicated</a> than that.&nbsp;<a href="https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/#fnref:complicated" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=68692&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/03/an-odd-font-rendering-bug-in-firefox-and-safari/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Use CSS to boost the font size of emoji with no extra markup]]></title>
		<link>https://shkspr.mobi/blog/2024/04/use-css-to-boost-the-font-size-of-emoji-with-no-extra-markup/</link>
					<comments>https://shkspr.mobi/blog/2024/04/use-css-to-boost-the-font-size-of-emoji-with-no-extra-markup/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 14 Apr 2024 11:34:58 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[emoji]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[HTML]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=50168</guid>

					<description><![CDATA[I want to make emoji bigger than the text that surrounds them. At my age and eyesight, it can be difficult to tell the difference between 😃, 😄, and 😊 when they are as small as the text.  Is there a way to use CSS to increase the font size of specific characters without having to wrap them in an extra &#60;span&#62; or similar?  Yes! Although it is a bit of a hack.    This relies on 3 CSS features: src: lo…]]></description>
										<content:encoded><![CDATA[<p>I want to make emoji bigger than the text that surrounds them. At my age and eyesight, it can be difficult to tell the difference between 😃, 😄, and 😊 when they are as small as the text.</p>

<p>Is there a way to use CSS to increase the font size of <em>specific</em> characters without having to wrap them in an extra <code>&lt;span&gt;</code> or similar?</p>

<p>Yes! Although it is a bit of a hack.</p>

<iframe width="100%" height="550" src="//jsfiddle.net/edent/531htvmn/embedded/result,html,css/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>

<p>This relies on 3 CSS features: <code>src: local()</code>, <code>unicode-range</code>,and <code>size-adjust</code>.  Let me walk you through it.</p>

<pre><code class="language-css">@font-face {
    font-family: "emoji";

    src: local('Apple Color Emoji'),
         local('Android Emoji'),
         local('Segoe UI Emoji'),
         local('Noto Color Emoji'),
         local(EmojiSymbols),
         local(Symbola);

    unicode-range: U+231A-231B, U+23E9-23EC, U+23F0, U+23F3, U+25FD-25FE, U+2614-2615, U+2648-2653, U+267F, U+2693, U+26A1, U+26AA-26AB, U+26BD-26BE, U+26C4-26C5, U+26CE, U+26D4, U+26EA, U+26F2-26F3, U+26F5, U+26FA, U+26FD, U+2705, U+270A-270B, U+2728, U+274C, U+274E, U+2753-2755, U+2757, U+2795-2797, U+27B0, U+27BF, U+2B1B-2B1C, U+2B50, U+2B55, U+FE0F, U+1F004, U+1F0CF, U+1F18E, U+1F191-1F19A, U+1F1E6-1F1FF, U+1F201, U+1F21A, U+1F22F, U+1F232-1F236, U+1F238-1F23A, U+1F250-1F251, U+1F300-1F320, U+1F32D-1F335, U+1F337-1F393, U+1F3A0-1F3CA, U+1F3CF-1F3D3, U+1F3E0-1F3F0, U+1F3F4, U+1F3F8-1F43E, U+1F440, U+1F442-1F4FC, U+1F4FF-1F53D, U+1F54B-1F567, U+1F57A, U+1F595-1F596, U+1F5A4, U+1F5FB-1F64F, U+1F680-1F6CC, U+1F6D0-1F6D2, U+1F6D5-1F6D7, U+1F6DC-1F6DF, U+1F6EB-1F6EC, U+1F6F4-1F6FC, U+1F7E0-1F7EB, U+1F7F0, U+1F90C-1F93A, U+1F93C-1F945, U+1F947-1FA7C, U+1FA80-1FAC5, U+1FACE-1FADB, U+1FAE0-1FAE8, U+1FAF0-1FAF8;

    size-adjust: 300%;
}

body {
    font-family: "emoji", sans-serif;
}
</code></pre>

<p>Here's how it works.</p>

<p><code>@font-face</code> this tells the browser that we're defining a new font which will be referenced later.</p>

<p><code>font-family</code> this is the name we're going to be using as a reference.</p>

<p><code>src: local('Apple Color Emoji') ...</code> CSS can reference <em>local</em> fonts. We don't know what device this page is being viewed on, so we've included a number of popular fallback fonts which <em>should</em> work with all major browsers.  You can also reference a webfont if you want - although Emoji fonts tend to have a large filesize.  I've adapted this from <a href="https://gist.github.com/mfornos/9991865">Marc Fornós' CSS</a> and added a few more common default emoji fonts.</p>

<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range"><code>unicode-range</code></a> this tells the browser to use this font <em>only</em> for the specific codepoints mentioned.  This is where the magic happens.</p>

<p>Emoji codepoints are complicated - especially when it comes to combining characters. You can see <a href="https://unicode.org/Public/emoji/15.1/emoji-sequences.txt">a full list of every sequence in Unicode 15.1</a>. There are currently <a href="https://en.wikipedia.org/wiki/List_of_emojis">3,782 different emoji</a>.</p>

<p>There was <a href="https://github.com/w3c/csswg-drafts/issues/7921">some talk of using named ranges</a> but that doesn't seem to have gone anywhere. So, instead, I've extracted all the Emoji codepoints and manually grouped them. It's a pretty long sequence, and I'm sure I've made a few mistakes.</p>

<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/size-adjust"><code>size-adjust</code></a> this is used to increase or decrease the apparent size of a font.</p>

<p>Finally, the <code>body { font-family: "emoji", sans-serif; }</code> tells the browser to use the Emoji font (remember, this will only work on the specified Unicode range) and then fall back to the defaults sans-serif font. Obviously, you can specify whatever fonts you like.</p>

<p><a href="https://jsfiddle.net/edent/531htvmn/">Have a play with it</a></p>

<p>This is a nifty little hack if you want to make Emoji (or any other text) bigger than its surroundings.</p>

<p>I am indebted to <a href="https://mastodon.social/@simevidas/112204970338133463">Šime Vidas</a> who demonstrated this trick to me.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=50168&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/04/use-css-to-boost-the-font-size-of-emoji-with-no-extra-markup/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Shakespeare Serif - an experimental font based on the First Folio]]></title>
		<link>https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/</link>
					<comments>https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 29 Jul 2023 11:34:57 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[shakespeare]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=46355</guid>

					<description><![CDATA[Disclaimer! Work In Progress! See source code.  I recently read this wonderful blog post about using 17th Century Dutch fonts on the web. And, because I&#039;m an idiot, I decided to try and build something similar using Shakespeare&#039;s first folio as a template.  Now, before setting off on a journey, it is worth seeing if anyone else has tried this before. I found David Pustansky&#039;s First Folio Font.…]]></description>
										<content:encoded><![CDATA[<p><mark>Disclaimer! Work In Progress! <a href="https://github.com/edent/Shakespeare-Serif-Font">See source code</a>.</mark></p>

<p>I recently read this <a href="https://www.linyangchen.com/Typography-Fell-Types-font">wonderful blog post about using 17th Century Dutch fonts on the web</a>. And, because I'm an idiot, I decided to try and build something similar using Shakespeare's first folio as a template.</p>

<p>Now, before setting off on a journey, it is worth seeing if anyone else has tried this before. I found <a href="https://www.dafont.com/shakespeare-first-folio-font.font">David Pustansky's First Folio Font</a>. There's not much info about it, other than it's based on the 1623 folio. It's a nice font, but missing brackets and a few other pieces of punctuation. Also, no ligatures. And the <a href="https://en.wikipedia.org/wiki/Long_s">long s</a> is in the wrong place.</p>

<p>So, let's try to build a font!</p>

<p>You can read how it works, or <a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#demo">skip straight to the demo</a>.</p>

<h2 id="get-some-scans"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#get-some-scans">Get some scans</a></h2>

<p>There are <a href="https://shkspr.mobi/blog/2023/02/shakespeares-missing-smile/">various scans of the First Folio</a>. I picked <a href="https://iiif.bodleian.ox.ac.uk/iiif/viewer/?iiif-content=https://iiif.bodleian.ox.ac.uk/iiif/manifest/390fd0e8-9eae-475d-9564-ed916ab9035c.json#?c=0&amp;m=0&amp;s=0&amp;cv=0&amp;r=0&amp;xywh=-5359%2C-401%2C16129%2C8017">The Bodlian's scan</a> as it seemed the highest resolution.</p>

<p>I plucked a couple of pages at random to see what I could find.  Of course, a modern font can't replicate the vagaries of hot metal printing. As you can see here, each letter "y" is substantially different.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/text-sample.jpg" alt="A sample of Shakespearean text from the First Folio. All the letters are subtly different." width="962" height="478" class="aligncenter size-full wp-image-46356"></p>

<p>Within the plays, there are some italic characters - which could be used to make a variant font. You can also see just how poor quality some of the letters are.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/text.jpg" alt="Closely typed Shakespearean text. The letters are indistinct, with bleed-through from the other side of the paper." width="1154" height="574" class="aligncenter size-full wp-image-46367"></p>

<p>There are also plenty of ligatures to choose from:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/ligatures.jpg" alt="Text showing ligatures." width="664" height="374" class="aligncenter size-full wp-image-46368">

<p>Ready? Let's go!</p>

<h2 id="extract-the-characters"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#extract-the-characters">Extract the characters</a></h2>

<p>This Python code reads in an image file. It then extracts every distinct letter, number, and punctuation mark.  It then detects which character it is and saves each glyph to disk with a filename like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/Letters-detected.jpg" alt="Screenshot of a file listing. The letter &quot;e&quot; is sometimes detected as a &quot;c&quot;." width="1024" height="360" class="aligncenter size-full wp-image-46369">

<p>As you can see, the text <em>detection</em> is good, but the letter <em>recognition</em> is poor.</p>

<pre><code class="language-python">import cv2
import pytesseract
from PIL import Image

def preprocess_image(image_path):
    # Load the image using OpenCV
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

    # Thresholding to convert to binary image
    _, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY_INV)

    # Find contours to isolate individual letters
    contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    return image, contours

def extract_and_save_letters(image, contours, output_directory):
    # Create output directory if it doesn't exist
    import os
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    for i, contour in enumerate(contours):
        x, y, w, h = cv2.boundingRect(contour)

        # Crop and save each letter as a separate image
        letter_image = image[y:y + h, x:x + w]

        # (Don't) Perform OCR to extract the text (letter) from the contour
        letter_text = "_"
        #letter_text = pytesseract.image_to_string(letter_image, config='--psm 10')
        #letter_text = letter_text.strip()  # Remove leading/trailing whitespace

        # Create a filename with the detected letter
        letter_filename = f"letter_{letter_text}_{i}.png"

        letter_path = os.path.join(output_directory, letter_filename)
        cv2.imwrite(letter_path, letter_image)

if __name__ == "__main__":
    input_image_path = "letters.jpg"
    output_directory = "/tmp/letters/"

    # Preprocess the image
    image, contours = preprocess_image(input_image_path)

    # Perform OCR and save individual letters
    extract_and_save_letters(image, contours, output_directory)
</code></pre>

<p>Something to note - the <code>CHAIN_APPROX_SIMPLE</code> is looking for <em>contiguous</em> characters. So it loses the dots from <code>i</code>, <code>j</code>, <code>:</code>, and <code>;</code>. But it is <em>quick</em>.</p>

<h2 id="detecting-dots"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#detecting-dots">Detecting Dots</a></h2>

<p>In order to get glyphs which vertically separate, we need to <a href="https://docs.opencv.org/3.4/db/df6/tutorial_erosion_dilatation.html">vertically erode the image</a> so it looks like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/binary_erode.png" alt="Letters stretched vertically." width="776" height="330" class="aligncenter size-full wp-image-46428">

<pre><code class="language-python"># Erode the image vertically
kernel = np.array([[0, 0, 0, 0, 0],
                   [0, 0, 1, 0, 0],
                   [0, 0, 1, 0, 0],
                   [0, 0, 1, 0, 0],
                   [0, 0, 0, 0, 0]], dtype=np.uint8)

erode = cv2.erode(image, kernel,iterations = 6)
</code></pre>

<p>We use this eroded image for contiguous detection - but we do the actual cropping on the original image.</p>

<p>As you can see, it does make some character touch each other - which means you get occasional crops like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/character_8.png" alt="A g above an h." width="41" height="131" class="aligncenter size-full wp-image-46429">

<p>They can either be manually split, or ignored.</p>

<h2 id="put-each-letter-into-a-folder"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#put-each-letter-into-a-folder">Put each letter into a folder</a></h2>

<p>There's no automated way to do this. It's just a lot of tedious dragging and dropping. It's hard to tell the difference between o and O, or commas and apostrophes.</p>

<p>Ideally we want several of each glyph because we're about to...</p>

<h2 id="find-the-average-letterform"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#find-the-average-letterform">Find the average letterform</a></h2>

<p>Here's a selection of letter "e" images which were extracted.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/montage.png" alt="24 different &quot;e&quot; letters. Each one slightly misshapen." width="302" height="262" class="aligncenter size-full wp-image-46370">

<p>I didn't want to make some rather arbitrary decisions on which letters I like best. So I cheated.</p>

<p>I copied all the letter "e"s into a folder. I used Python to create the <em>average</em> letter based on the two-dozen or so that I'd extracted. This code takes all the images in a directory, and spits out a 1bpp average letter - like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/1bpp.png" alt="A black letter &quot;e&quot;." width="220" height="220" class="aligncenter size-full wp-image-46373">

<pre><code class="language-python">import os
import numpy as np
import argparse
import math
from PIL import Image

def get_arguments():
    ap = argparse.ArgumentParser()
    ap.add_argument('-l', '--letter', type=str,
                    help='The letter you want to average')
    arguments = vars(ap.parse_args())

    return arguments

def load_and_resize_images_from_directory(directory, target_size):
    image_files = [f for f in os.listdir(directory) if f.endswith(".png")]

    images = []
    for image_file in image_files:
        image_path = os.path.join(directory, image_file)
        print("Reading " + image_path)
        image = Image.open(image_path).convert("L")  # Convert to grayscale

        # Create a new white background image
        new_size = (target_size[0], target_size[1])
        new_image = Image.new("L", new_size, color=255)  # White background

        old_width, old_height = image.size

        # Center the image
        x1 = int(math.floor((target_size[0] - old_width)  / 2))
        y1 = int(math.floor((target_size[1] - old_height) / 2))

        # Paste the image at the center
        new_image.paste(image, (x1, y1, x1 + old_width, y1 + old_height))

        # Make it larger to see if that improves the curve detection  
        new_image = new_image.resize( (600,600), Image.LANCZOS)
        images.append(new_image)

    return images

def calculate_average_image(images):
    # Convert the list of images to numpy arrays
    images_array = [np.array(img) for img in images]

    # Calculate the average image along the first axis
    average_image = np.mean(images_array, axis=0)

    return average_image

def convert_to_1bpp(average_image, threshold=120):
    # Convert the average image to 1bpp by setting a threshold value
    binary_image = np.where(average_image &gt;= threshold, 255, 0).astype(np.uint8)

    return binary_image

def save_1bpp_image(binary_image, output_path):
    # Convert the numpy array to a binary image
    binary_image = Image.fromarray(binary_image, mode="L")

    # Save the 1bpp monochrome image to the specified output path
    binary_image.save(output_path)

if __name__ == "__main__":
    args = get_arguments()
    letter = args['letter']
    input_directory   = "../letters/" + letter + "/"
    output_png_path = "../letters/" + letter + ".png"
    target_size = (75, 75)  # Set the desired target size for resizing

    # Load, resize, and add border to all images from the directory
    images = load_and_resize_images_from_directory(input_directory, target_size)

    # Calculate the average image
    average_image = calculate_average_image(images)

    # Convert the average image to 1bpp
    binary_image = convert_to_1bpp(average_image)

    # Save the 1bpp monochrome image
    save_1bpp_image(binary_image, output_png_path)
</code></pre>

<h2 id="one-big-image"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#one-big-image">One Big Image</a></h2>

<p>The next step is to create a single image which holds all of the glyphs. Our good friend ImageMagick comes to the rescue here:</p>

<p><code>montage *.png -tile 12x8 -geometry +10+10 all_glyphs.png</code></p>

<p>That takes all of the average symbol .png files and places them on a single image. It looks like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/montage_glyphs.png" alt="Montage of all the letters and punctuation." width="1925" height="1449" class="aligncenter size-full wp-image-46435">

<h2 id="trace-those-glyphs"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#trace-those-glyphs">Trace Those Glyphs</a></h2>

<p>The <a href="https://github.com/jpakkane/glyphtracer">GlyphTracer App</a> will take the image and generates a <a href="https://fontforge.org/docs/techref/sfdformat.html">Spline Font Database</a>. It isn't the most intuitive app to use. But after a bit of clicking around you can work out how to assign each image to a glyph.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/GlyphTracer.png" alt="Screenshot showing the GlyphTracer program. Some of the letters are highlighted. There is an interface at the bottom to select a codepoint." width="1009" height="374" class="aligncenter size-full wp-image-46378">

<p>GlyphTracer uses <a href="https://potrace.sourceforge.net/">potrace</a> which turns those raggedy rasters into smoothly curved paths.</p>

<p>Once done, we're on to the next step.</p>

<h2 id="forge-those-fonts"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#forge-those-fonts">Forge Those Fonts!</a></h2>

<p>The venerable <a href="https://fontforge.org/">FontForge</a> will open the SFD and show us what the proto-font looks like:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/fontforge.png" alt="Collection of letters - each is vertically centred." width="813" height="417" class="aligncenter size-full wp-image-46379">

<p>As you can see, all the letters have been vertically centred. So double tap and edit their position - you can also adjust the curves if you like:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/FontForge-Glyph-editor.png" alt="The letter &quot;a&quot; shown as an outline - with lots of complicated controls to edit it." width="788" height="733" class="aligncenter size-full wp-image-46380">

<p>The final result looks something like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/07/Current-font.png" alt="Screenshot showing all the letters in more-or-less the right place" width="915" height="683" class="aligncenter size-full wp-image-46438">

<p>FontForge's "File" ➡ "Generate Font" will let you save the output as TTF, WOFF2, or anything else you want.</p>

<style>
@font-face { 
  font-family: "Shakespeare Serif";
  src: url(data:font/woff2;base64,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);
}
</style>

<h2 id="demo"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#demo">Demo!</a></h2>

<p>Here's what the font looks like when rendered on the web:<br><br></p>

<p><span style="font-family:'Shakespeare Serif';font-size:4em;line-height:1em;">Two houſeholds, both alike in dignity!</span>
<br>
<span style="font-family:'Shakespeare Serif';font-size:2em;line-height:1em;">Alas poor Yorik; I knew him Horatio.</span>
<br>
<span style="font-family:'Shakespeare Serif';font-size:2em;line-height:1em;">To be? Or not to be? That's the uestion.</span>
<br>
<span style="font-family:'Shakespeare Serif';font-size:2em;line-height:1em;">Bump sickly, vexing wizard! Be sly, fox, and charm the dragon's breath.</span></p>

<h2 id="todo"><a href="https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/#todo">TODO</a></h2>

<ul>
<li>Get more sample images from the 1st Folio.</li>
<li>Extract more letters, numbers, ligatures, and symbols.</li>
<li>Sort symbols into sub-directories.</li>
<li>Generate font with complete alphabet.</li>
<li>Tidy up curves.</li>
<li>Set correct height, ascenders, descenders, etc.</li>
<li>Make the ligatures automatic.</li>
<li>Other font stuff that I haven't even thought of yet!</li>
</ul>

<p>Want to help out?  <a href="https://github.com/edent/Shakespeare-Serif-Font">See the source code on GitHub</a>.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=46355&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/07/shakespeare-serif-a-new-font-based-on-the-first-folio/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Fonts with threatening auras]]></title>
		<link>https://shkspr.mobi/blog/2023/05/fonts-with-threatening-auras/</link>
					<comments>https://shkspr.mobi/blog/2023/05/fonts-with-threatening-auras/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 18 May 2023 11:34:37 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[usability]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=45762</guid>

					<description><![CDATA[I was browsing the web recently when I can across this utter horror show of a font.  Warning, not for the faint of heart.    The thing is, I can&#039;t adequately describe why I - and many others - find it so disturbing.  In all my years of reading English, I&#039;ve never found a font which slants backwards. I&#039;m used to italics so there&#039;s no reason it should seem weird. And yet... it&#039;s like the uncanny…]]></description>
										<content:encoded><![CDATA[<p>I was browsing the web recently when I can across this utter horror show of a font.</p>

<p>Warning, not for the faint of heart.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/05/slant-font.png" alt="Screenshot of text where all the characters lean to the left." width="978" height="454" class="aligncenter size-full wp-image-45778">

<p>The thing is, I can't adequately describe why I - <a href="https://mastodon.social/@Edent/110350836225930781">and many others</a> - find it so disturbing.</p>

<p>In all my years of reading English, I've never found a font which slants backwards. I'm used to <em>italics</em> so there's no reason it should seem weird. And yet... it's like the uncanny valley of fonts. Something in my brain just screams "WRONG".</p>

<p>I examined the page to see if it was some kind of fancy CSS transformation. But, no. It appears to belong to a font family called "recline".</p>

<p>Thanks. I hate it.</p>

<p>What's the most unsettling font you've seen in the wild?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=45762&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/05/fonts-with-threatening-auras/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Should ₹ be part of the Latin font subset?]]></title>
		<link>https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/</link>
					<comments>https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Tue, 01 Dec 2020 12:14:20 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[racism]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[unicode]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=37373</guid>

					<description><![CDATA[Some background reading. Skip if you&#039;re familiar with fonts.  A font file contains a list of characters (usually letters, numbers, and punctuation) and glyphs (the drawn representation of that character). It is, of course, a lot more complicated than that.  Each character has a codepoint which is represented in hexadecimal.  For example, U+0057 is the Latin letter Capital W, U+20AC is the Euro…]]></description>
										<content:encoded><![CDATA[<p>Some background reading. Skip if you're familiar with fonts.</p>

<p>A font file contains a list of characters (usually letters, numbers, and punctuation) and glyphs (the drawn representation of that character). It is, of course, a lot more complicated than that.</p>

<p>Each character has a codepoint which is represented in hexadecimal.  For example, <code>U+0057</code> is the Latin letter Capital W, <code>U+20AC</code> is the Euro Symbol €, and <code>U+1F600</code> is the Emoji Smiling Face 😀.  These codepoints are assigned by the Unicode Consortium.</p>

<p>A font which contains thousands of characters will be multi-megabytes in size. That's annoying when downloading a font file to display text on a website in a particular font.</p>

<p>It is possible to create a "subset" of a font which only contains the characters that you want. This makes the font file smaller, which makes downloading things quicker for the user.</p>

<p>Again - it is all a <em>lot</em> more complicated than that, but it's a good approximation of the truth.</p>

<p>Traditionally, it makes sense to subset fonts by human languages. If you are writing in English, you don't want the Greek set of characters. If you're writing in Vietnamese, you don't want Cyrillic characters.</p>

<p>Once a subset has been created, you can refer to it in CSS like this:</p>

<pre><code class="language-css">@font-face {
  font-family: 'CoolFont';
  src: url(https://example.com/font.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131;
}
</code></pre>

<p>This tells the web browser that the font covers the characters <code>U+0000</code> to <code>U+00FF</code> and, additionally, the character <code>U+0131</code> - "Latin Small Letter Dotless I".</p>

<p><code>U+0000</code> to <code>U+007F</code> are "Basic Latin". They contain the traditional English letters, numbers, and some symbols.</p>

<p><code>U+0080</code> to <code>U+00FF</code> are "Latin-1 Supplement". They contain "European" symbols like Ñ, å, and ÿ.</p>

<p>As Unicode has added more languages, they have scattered characters across the specification.  And that's where the problem lies.</p>

<h2 id="the-problem"><a href="https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/#the-problem">The Problem</a></h2>

<p>A user in India has complained that <a href="https://github.com/google/fonts/issues/2784">Google's font subsetting ignores Indian users</a>.</p>

<p>Here's an example.</p>

<p>Google's Roboto font has the following characters as part of <a href="https://fonts.googleapis.com/css?family=Roboto&amp;subset=latin">its Latin subset</a>:</p>

<ul>
<li><code>U+0000-00FF</code> Basic Latin and Supplement</li>
<li><code>U+0131</code> ı Latin Small Letter Dotless I</li>
<li><code>U+0152-0153</code> Œ and œ Ligature Oe</li>
<li><code>U+02BB-02BC</code> ʻ and ʼ Modified Punctuation</li>
<li><code>U+02C6</code> ˆ Modifier Letter Circumflex Accent</li>
<li><code>U+02DA</code> ˚ Ring Above</li>
<li><code>U+02DC</code> ˜ Small Tilde</li>
<li><code>U+2000-206F</code> - <a href="https://en.wikipedia.org/wiki/General_Punctuation">General Punctuation</a></li>
<li><code>U+2074</code> ⁴ Superscript Four</li>
<li><code>U+20AC</code> € euro sign</li>
<li><code>U+2122</code> ™ Trade Mark Sign</li>
<li><code>U+2191</code> ↑ Upwards Arrow</li>
<li><code>U+2193</code> ↓ Downwards Arrow</li>
<li><code>U+2212</code> − Minus Sign</li>
<li><code>U+2215</code> ∕ Division Slash</li>
</ul>

<p>You can argue how useful or not some of these characters are - but what's interesting is what's <em>missing</em>.</p>

<p>India has <a href="https://en.wikipedia.org/wiki/List_of_countries_by_English-speaking_population">twice the number of English speakers</a> as the United Kingdom.</p>

<p>A website written for an English speaking audience in India is likely to want the Latin subset of a font. But it will also want one local character - ₹ - <code>U+20B9</code>. The Rupee is the currency of India and its character is part of the "<a href="https://en.wikipedia.org/wiki/Currency_Symbols_(Unicode_block)">Currency Symbols</a>" Unicode block.</p>

<p>So should the Rupee be part of the "Latin" subset?</p>

<h2 id="colonialism-in-tech"><a href="https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/#colonialism-in-tech">Colonialism In Tech</a></h2>

<p>The original complainant says:</p>

<blockquote><p>this symbol [₹] is excluded (subsetted out) of many Latin fonts that originally included it due to an American assumption that English is not spoken in India.</p></blockquote>

<p>I don't know whether their assumption about Google is correct. But it seems odd to specifically include € in Google's Latin subset, but not the Rupee.  Latin is not synonymous with "European".</p>

<p>Through a quirk of history, the Dollar symbol - $ - is in Basic Latin. The Yen currency symbol - ¥  - is included in the Latin-1 Supplement, as is the Pound - £.</p>

<p>Roboto's Latin subset contains Old English characters like þ (<a href="https://en.wikipedia.org/wiki/Thorn_(letter)">Thorn</a>) and Ð (<a href="https://en.wikipedia.org/wiki/Eth">Eth</a>).</p>

<p>Are obsolete characters used only in mediaeval text <em>really</em> more important to include than the currency for a billion people?</p>

<p>Google do include the ₹ in their "Latin Extended" subset. So if an Indian user wants to use their currency, they need to download <em>a separate</em> font which includes 1,011 characters they <em>don't</em> need.</p>

<p>This is inefficient.  It increases the download weight and energy usage of billions of people.</p>

<h2 id="some-simple-solutions"><a href="https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/#some-simple-solutions">Some Simple Solutions</a></h2>

<p>There are a few things which can be done here.</p>

<p>I think that Google probably should include a popular currency symbol in their Latin subset font. Yes, there's a risk that the font might grow in size as more useful symbols are added. And, no, Latin doesn't mean English and English doesn't mean Indian - but we're all trying to get along on this crowded planet. So let's be flexible.</p>

<p>Google could create an "en_IN" subset which includes all the popular and useful characters needed by an Indian audience.  It seems like there is sufficient demand for it.</p>

<p>Users should use the <a href="https://developers.google.com/fonts/docs/getting_started#optimizing_your_font_requests">Google Font API</a> to create a subset which has only the specific characters they want.  That way they aren't reliant on the whims of a megacorp to decide what counts for their language.</p>

<p>Finally, as developers, we should understand that what is "logical" and "orderly" isn't always how our users see things. We have a huge range of biases and unexamined assumptions.  Some of the earliest foundations of computer science are based on a very rigid and limited set of assumptions about the world. Let's do our best to be more inclusive.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=37373&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/12/should-%e2%82%b9-be-part-of-the-latin-font-subset/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[WOTAN - the Font of Doctor Who and the War Machines]]></title>
		<link>https://shkspr.mobi/blog/2020/09/wotan-the-font-of-doctor-who-and-the-war-machines/</link>
					<comments>https://shkspr.mobi/blog/2020/09/wotan-the-font-of-doctor-who-and-the-war-machines/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 26 Sep 2020 11:35:34 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Doctor Who]]></category>
		<category><![CDATA[font]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=36681</guid>

					<description><![CDATA[As part of my silly floppy artwork, I wanted to find a retro computer font. Then I remembered that there&#039;s a 1960s Doctor Who serial with this beauty.  The War Machines is a cracking slice of 60s sci-fi. It&#039;s very groovy.    But what font is it?  It isn&#039;t Westminster.  The W is completely wrong. And the letter T is mirrored.  Westminster has a surprising and interesting history.  It isn&#039;t Data…]]></description>
										<content:encoded><![CDATA[<p>As part of my silly floppy artwork, I wanted to find a retro computer font. Then I remembered that there's a 1960s Doctor Who serial with this beauty.</p>

<p><a href="https://tardis.fandom.com/wiki/The_War_Machines_(TV_story)">The War Machines</a> is a cracking slice of 60s sci-fi. It's <em>very</em> groovy.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/09/The-War-Machines-title-card.jpg" alt="The War Machines title card." width="192" height="144" class="aligncenter size-full wp-image-36682">

<p>But what font is it?</p>

<p>It isn't <a href="https://en.wikipedia.org/wiki/Westminster_(typeface)">Westminster</a>.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/09/westminster.png" alt="The text in Westminster." width="550" height="70" class="aligncenter size-full wp-image-36683">
The W is completely wrong. And the letter <code>T</code> is mirrored.</p>

<p>Westminster has a <a href="https://www.mercerdesign.com/true-story-westminster-font/">surprising and interesting history</a>.</p>

<p>It isn't <a href="https://fontsgeek.com/fonts/Data-70-Regular">Data 70</a>.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/09/Screenshot_2020-09-12-Data-70-Regular-Download-For-Free-View-Sample-Text-Rating-And-More-On-Fontsgeek-Com.png" alt="1960S COMPUTER FONT." width="525" height="76" class="aligncenter size-full wp-image-36685"></p>

<p>Which, in any case, was released a few years after the episode. Time travel is complex though.</p>

<p>It isn't a modern font like <a href="https://fontzone.net/font-details/computerfont-regular">Computer Font</a>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/09/Computer-Font.png" alt="A computer style font." width="550" height="70" class="aligncenter size-full wp-image-36684"></p>

<p>As far as I can tell, it is an original font which is <em>heavily</em> inspired by Westminster. The <code>T</code> is a particular giveaway.</p>

<p>There are only a few title screens, so there are only a limited number of characters available.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/09/fontmontage.jpg" alt="A montage of letters." width="319" height="345" class="aligncenter size-full wp-image-36687">

<p>With a bit of jiggery-pokery, we can grab a few more character. A flipped <code>E</code> easily becomes a <code>3</code>, for example.</p>

<hr>

<p>I am indebted to <del>my producer</del> Clayton Hickman for his original investigative work.</p>

<blockquote class="social-embed" id="social-embed-713382099638726656" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"><header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><a href="https://twitter.com/claytonhickman" class="social-embed-user" itemprop="url"><img class="social-embed-avatar social-embed-avatar-circle" src="data:image/webp;base64,UklGRogCAABXRUJQVlA4IHwCAABQDACdASowADAAPrVOnEonJCKhrjgMyOAWiWQAv3FBV9pFvjY5tnB4F1brTO4WWlpLGkx99w9Juwqd465hzxevzgbPWyJcydcxHWlFWSEW9bgy3KRAiHcyYU+7SXrsM6msAUfuwfk7waYwAAD+72VuK60l+LcrypBnB0LbAGVtjKHtLc97PxbIF70OYE6+wytB0jv36RsvT55y/EI2hTOEGeiMOn65XIq+19jChPhwBNFC3k7fgy9BKU1+AznTCUJbPggHi7cnE4Ui/KU/VCzQ/SIQG3UbGMeG4wqeP8AKc1uzK7RLtSnn3fea6rDJOXrtXzzZxgP5geSXyTOwkdq5Vg+GsrfHeViFSCu/wLHYOIIAqrBzgvBRuHPh/YMhu394jFTwm4dudPEzUiITIX+xR7UHvHqmtCLo+tj3gbDNZrFanuWV+mt/6Q2KXiQ6ZYBex/JbVjlELnEhYUPhvqKPb429C2kIvmiMJ/bkxvBbI9kp3UAxPwgSrfFgNQ5XH1dLCJVkkayQWDSdneYAnzfzs5tgb/UiCzFSAmA8JQhdrxIUsKlM/r6M+vtZIGmeRczGSNPOAzDN1FOG6CPkDRPCjjQHiR/VcDXFPAvr1bBdAVKIrvrPWFXyu8bYsH4WHLlM0KK9cZuSzO+iT5gfahEBfVBU1HzZsq+tP+S47mjK/eKzjF3y2FHNANOG7a3059HkpSuo1ZdV9dhGhl1b2T/VfcVcfptJw7BuD6uev9lXqMbEkzNiDzNm1KAJi5U6u89CWDw2V8qvBgj2pzUg2XKbwPblpka2127rx40Zb29CbYRiyYHP4u2Kn4qgd/PfruH7gVusNqZ+RT4AAAA=" alt="" itemprop="image"><div class="social-embed-user-names"><p class="social-embed-user-names-name" itemprop="name">Clayton Hickman</p>@claytonhickman</div></a><img class="social-embed-logo" alt="Twitter" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0Aaria-label%3D%22Twitter%22%20role%3D%22img%22%0AviewBox%3D%220%200%20512%20512%22%3E%3Cpath%0Ad%3D%22m0%200H512V512H0%22%0Afill%3D%22%23fff%22%2F%3E%3Cpath%20fill%3D%22%231d9bf0%22%20d%3D%22m458%20140q-23%2010-45%2012%2025-15%2034-43-24%2014-50%2019a79%2079%200%2000-135%2072q-101-7-163-83a80%2080%200%200024%20106q-17%200-36-10s-3%2062%2064%2079q-19%205-36%201s15%2053%2074%2055q-50%2040-117%2033a224%20224%200%2000346-200q23-16%2040-41%22%2F%3E%3C%2Fsvg%3E"></header><section class="social-embed-text" itemprop="articleBody">Just noticed the War Machines title font isn't one of the regular typefaces I assumed it was. Was it specially made? <a href="https://twitter.com/claytonhickman/status/713382099638726656/photo/1">pic.x.com/jiyfllgl8d</a><div class="social-embed-media-grid"><a href="https://pbs.twimg.com/media/CeZxOtcW8AAergC.jpg" class="social-embed-media-link"><img class="social-embed-media" alt="" src="data:image/webp;base64,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"></a></div></section><hr class="social-embed-hr"><footer class="social-embed-footer"><a href="https://twitter.com/claytonhickman/status/713382099638726656"><span aria-label="19 likes" class="social-embed-meta">❤️ 19</span><span aria-label="12 replies" class="social-embed-meta">💬 12</span><span aria-label="0 reposts" class="social-embed-meta">🔁 0</span><time datetime="2016-03-25T15:08:41.000Z" itemprop="datePublished">15:08 - Fri 25 March 2016</time></a></footer></blockquote>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=36681&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/09/wotan-the-font-of-doctor-who-and-the-war-machines/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Subsetting (Chinese) Fonts]]></title>
		<link>https://shkspr.mobi/blog/2013/05/subsetting-chinese-fonts/</link>
					<comments>https://shkspr.mobi/blog/2013/05/subsetting-chinese-fonts/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 22 May 2013 07:52:11 +0000</pubDate>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[utf-8]]></category>
		<guid isPermaLink="false">http://shkspr.mobi/blog/?p=8294</guid>

					<description><![CDATA[There are loads of really delightful Simplified and Traditional Chinese True Type Fonts available on the web.  There&#039;s only one issue - the file sizes are really large.  In many cases, too large to effectively use as a web-font.  For example, this calligraphy style font is 3.4MB.    The beautiful Paper Cut Font weighs in at 14MB!    That file-size is far to heavy to embed on a web page. …]]></description>
										<content:encoded><![CDATA[<p>There are loads of really delightful <a href="https://web.archive.org/web/20130520092556/http://chinesefont.brushes8.com/tag/simplified-chinese-font">Simplified and Traditional Chinese True Type Fonts</a> available on the web.  There's only one issue - the file sizes are really large.  In many cases, too large to effectively use as a web-font.</p>

<p>For example, this <a href="https://web.archive.org/web/20121219024439/http://chinesefont.brushes8.com/richwin-fonts/richwin-xing-kai-jian-fan-font.html">calligraphy style font</a> is 3.4MB.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/05/Richwin-Xing-kai-jian-Fan-Font-fs8.png" alt="Richwin-Xing-kai-jian-Fan-Font-fs8" width="445" height="79" class="alignnone size-full wp-image-8296">

<p>The beautiful <a href="https://web.archive.org/web/20140608004145/http://chinesefont.brushes8.com/xin-di-paper-cut-font-simplified-chinese.html">Paper Cut Font</a> weighs in at 14MB!</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/05/Paper-Cut-Chinese-Font-fs8.png" alt="Paper Cut Chinese Font-fs8" width="487" height="223" class="alignnone size-full wp-image-8297">

<p>That file-size is far to heavy to embed on a web page.</p>

<h2 id="subsetting"><a href="https://shkspr.mobi/blog/2013/05/subsetting-chinese-fonts/#subsetting">Subsetting</a></h2>

<p>Generally speaking, font files like .ttf contain a representation of every single character. 0-9, a-z, A-z, all the punctuation, non-English characters etc.</p>

<p>That's really useful if the font is installed on your computer and you want to write a document which <em>could</em> contain every character.  It's less helpful if you want to use a fancy font on your website's headers.</p>

<p>Subsetting is the act of creating a subset of a font.  That is, a font file which only contains specific characters.</p>

<p>Let's suppose that we only want a specific phrase rendered in this font.</p>

<pre>我很丢脸。我没有吃Fruity Oaty Bar</pre>

<p>We only need 19 unique characters - we can get rid of any character which doesn't appear in that heading.</p>

<p>There are sevel font manipulation tools available.  I've chosen <a href="https://web.archive.org/web/20130522120140/http://fonts.philip.html5.org/">Font Optimizer</a> which has an excellent live demo page.  The <a href="https://web.archive.org/web/20160322095140/https://bitbucket.org/philip/font-optimizer/overview">source code is on BitBucket</a>.</p>

<p>The command line syntax is really simple</p>

<pre>./subset.pl --chars="我很丢脸。我没有吃Fruity Oaty Bar" input.ttf output.ttf</pre>

<p>The file size reduction is impressive.  My original font was over 14MB.  The optimized one is 32<strong>K</strong>B</p>

<pre>14,066,456 input.ttf
   32,084 output.ttf
</pre>

<p>The process run instantly - fast enough to run as a web service to generate these fonts dynamically, I would think.</p>

<p>One could quite easily create a scrap of JavaScript which read the contents of a block of text and then requested a font which contained only the necessary characters.</p>

<p>Apparently, <a href="https://web.archive.org/web/20130620105955/http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web_fonts_and_RFNs#b4599c52">Monotype have a proprietary and patent-pending solution</a> to this rather trivial application.</p>

<h2 id="uses"><a href="https://shkspr.mobi/blog/2013/05/subsetting-chinese-fonts/#uses">Uses</a></h2>

<p>Being able to subset fonts to reduce file size is incredibly useful.  Supposing you want a different font for body text, headers, and navigation.  Rather than having to load three large font files containing every character in the known universe, you could subset each one for only exactly the relevant characters.</p>

<p>This also has an interesting DRM like effect.  Some people don't want their shiny web fonts to be downloaded and used as a regular font.  With subsetting, the font only contains the specific characters.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=8294&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2013/05/subsetting-chinese-fonts/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Chrome For Android Font Rendering Bug]]></title>
		<link>https://shkspr.mobi/blog/2013/03/chrome-for-android-rendering-bug/</link>
					<comments>https://shkspr.mobi/blog/2013/03/chrome-for-android-rendering-bug/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 01 Mar 2013 12:00:47 +0000</pubDate>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[font]]></category>
		<guid isPermaLink="false">http://shkspr.mobi/blog/?p=7697</guid>

					<description><![CDATA[The latest version of the Chrome Browser for Android has introduced a curious rendering bug.  When scrolling, I notice that the font hinting seems to break down.  This makes the text very &#34;juddery&#34;.  It looks like the fonts shrink and grow and they scroll. This is very disorienting when reading.  In this example I&#039;ve noticed that once I&#039;ve stopped scrolled the page, the fonts are hinted…]]></description>
										<content:encoded><![CDATA[<p>The latest version of the <a href="https://play.google.com/store/apps/details?id=com.android.chrome">Chrome Browser for Android</a> has introduced a curious rendering bug.</p>

<p>When scrolling, I notice that the font hinting seems to break down.  This makes the text very "juddery".  It looks like the fonts shrink and grow and they scroll. This is very disorienting when reading.</p>

<p>In this example I've noticed that once I've stopped scrolled the page, the fonts are hinted differently.</p>

<p><img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/1.png" alt="1" width="132" height="23" class="aligncenter size-full wp-image-7698">
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/2.png" alt="2" width="132" height="22" class="aligncenter size-full wp-image-7700">
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/3.png" alt="3" width="132" height="23" class="aligncenter size-full wp-image-7702"></p>

<p>I've enlarged the examples (without interpolation) so you can see them a bit more clearly.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/1-Big.png" alt="1 Big" width="528" height="92" class="aligncenter size-full wp-image-7699">
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/2-Big.png" alt="2 Big" width="528" height="88" class="aligncenter size-full wp-image-7701">
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/3-Big.png" alt="3 Big" width="528" height="92" class="aligncenter size-full wp-image-7703"></p>

<p>To give you a good idea of what's happening, I've magnified the letter "e" (again, without interpolation).  You can quite clearly see what happens to the font.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2013/02/e.gif" alt="e" width="300" height="340" class="aligncenter size-full wp-image-7704"></p>

<p>I can understand why the font hinting changes as the scrolling occurs - but why does it change even after scrolling has finished?</p>

<p>All screenshots taken on an N7100 running 4.1.2 with the latest version of Chrome for Android.  The Galaxy Note II has a fairly standard resoltion of 1280×720, giving it 267 PPI - that shouldn't cause any problems.</p>

<p><a href="https://code.google.com/p/chromium/issues/detail?id=174699">This issue has been reported to the Chromium team</a>.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=7697&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2013/03/chrome-for-android-rendering-bug/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
