Did Musk steal his new X logo?

Published: 2023 / 07 / 26

Summary: I show how to use Python to analyze glyphs from SVG and fonts. I compare the new X.com logo to the corresponding glyph in a few different fonts. There are no exact matches, but some features closely match those in the Noto Font.

Contents

1. Overview

A few days ago, Elon Musk changed the name of Twitter to X.com and replaced the iconic little blue bird logo with something that looks like this: ๐•

He was rightfully ridiculed for throwing away a good brand to chase some long-simmering dream of an "everything app" that no one seems to want. More criticism came when he unveiled the logo, with comments like "he just used a Unicode character!".

While the spirit of this criticism was right, some comments confused a few terms. Unicode defines a set of characters and their properties, but does not specify their visual appearance. (Although official code charts do include one representative glyph for each character). So, if he did just "steal" something, it would be a glyph from a font used to represent this character.

The character in question is U+1D54F, whose name is MATHEMATICAL DOUBLE-STRUCK CAPITAL X, and appears in the Mathematical Alphanumeric Symbols block. The official code chart for this block, U1D400.pdf, calls this group of characters Double-struck symbols.

The goal of this post is to investigate the actual shape of the logo and compare to the ๐• glyphs found in some common fonts. As usual, Python (with some third-party packages) makes this pretty easy.

Now, if you go to x.com, it redirects you to twitter.com but does display the new logo. Open Developer Tools and inspect the logo. You can see that it is an SVG element, consisting of a single svg path.

You can use the Python package svg.path to parse the path data into its components.

from svg.path import parse_path

#copied from <path d=___>
d = "M18.244 2.25h3.308l-7.227 8.26 8.502 " \
    "11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 "\
    "2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"

for item in parse_path(d):
    print(item)

#output:        
# Move(to=(18.244+2.25j))
# Line(start=(18.244+2.25j), end=(21.552+2.25j))
# Line(start=(21.552+2.25j), end=(14.325+10.51j))
# ...        
        

Below, we will use matplotlib to draw this shape, so we need to convert this svg.path Path object into a matplotlib Path object. Read the docs for matplotlib Path and do something like this,

from matplotlib.path import Path
from svg.path import Move, Line, Close
               
verts,codes = [],[]
for item in parse_path(d):

    verts.append( (p.end.real, p.end.imag) )
               
    if   type(p) == Move:  codes.append(Path.MOVETO)
    elif type(p) == Line:  codes.append(Path.LINETO)
    elif type(p) == Close: codes.append(Path.CLOSEPOLY)
    else:
        raise NotImplmementedError(repr(p))
               
verts = np.array(verts)
path = Path(verts,codes)
               

3. Find font files

Scanning my macOS system, I found two fonts that have this glyph,

  • /System/Library/Fonts/Supplemental/STIXGeneral.otf

  • /System/Library/Fonts/Supplemental/STIXGeneralBol.otf

Both are STIX fonts; one regular and one bold.

Another place to look for free, widely used fonts is the Noto project from Google. The font with this glyph is called Noto Sans Math, which we can download as a TTF file, NotoSansMath-Regular.ttf.

4. Get glyphs from fonts

I will use fontTools library to get the glyphs from the fonts. After getting the glyph, we again create the vertices and codes arguments we need for matplotlib.path.Path:

from fontTools.ttLib import TTFont
from fontTools.pens.ttGlyphPen import TTGlyphPen
from fontTools.pens.recordingPen import RecordingPen

font_path = "NotoSansMath-Regular.ttf"
               
font = TTFont(file_path)

glyphSet = font.getGlyphSet()
glyph = glyphSet['u1D54F']

pen = RecordingPen()
glyph.draw(pen)

verts,codes = [],[]
for cmd,pts in pen.value:
    
    if cmd == 'moveTo':
        pt, = pts
        codes.append(Path.MOVETO)
        verts.append(pt)
    elif cmd == 'lineTo':
        pt, = pts
        codes.append(Path.LINETO)
        verts.append(pt)
    elif cmd == 'closePath':
        codes.append(Path.CLOSEPOLY)
        verts.append((0,0))
    else:
        raise NotImplmementedError(cmd)

verts = np.array(verts,np.float64)
               

5. Normalize

SVG and TTF files use different coordinate systems and we donโ€™t know how the X.com logo may have been scaled or transformed, so to compare everything, lets scale and shift our vertices to fill the unit square,

def normalize_verts(v,c):
    """
    v,c are the vertices and codes
    arguments to matplotlib.path.Path

    return new vertices with x and y
    scaled and translated to the range [0,1]
    """
    y = v.copy()

    # ignore CLOSEPOLY vertex because its not a real point,
    ii = [i for (i,cc) in enumerate(c) if not cc == Path.CLOSEPOLY]

    xmin,ymin = y[ii,:].min(axis=0)
    y[:,0] -= xmin
    y[:,1] -= ymin

    xmax,ymax = y[ii,:].max(axis=0)
    y[:,0] /= xmax
    y[:,1] /= ymax

    return y
            

6. Plot them together

We plot and save image using matplotlib,

import matplotlib.pyplot as plt
            
dpi = 100
Wp = 1600
Hp = 1600
fig = plt.Figure( (Wp/dpi, Hp/dpi), )

ax = fig.add_axes([0,0,1,1])

linewidth = 3

ax.add_patch(
    patches.PathPatch(
        Path(verts1, codes1),
        facecolor=(1,0,0,0.2), #red,transparent
        edgecolor='red',
        linestyle = '--',
        lw = linewidth,
    ))

ax.add_patch(
    patches.PathPatch(
        Path(verts2, codes2),
        facecolor=(0,0,1,0.2), #blue,transparent
        edgecolor='blue',
        linestyle = ':',
        lw = linewidth,
    ))

ax.set_xbound(-.2, 1.2)
ax.set_ybound(-.2, 1.2)

ax.grid(True)

ax.figure.savefig("fig.png")
            

So, in the following figures,

  • Twitter/X.com logo is in transparent-blue, with blue-dotted border.

  • The font glyph is in transparent-red, with red-dashed border.

NotoSansMath-Regular.ttf:

STIXGeneral.otf:

STIXGeneralBol.otf:

7. More fonts on Linux

A also checked my Ubuntu machine for fonts with this glyph and found 17: the same Noto Sans Math font, five STIX fonts, and 11 variations of DejaVu fonts. Some of the variations have identical glyphs. Hereโ€™s a GIF of all them:

8. Conclusions

For these commonly-used fonts, the logo does not match exactly any of the ๐• glyphs. But, the Noto Sans Math glyph has some pretty strong similarities: The slopes of the lines are nearly identical, some of the lines almost perfectly line-up, and the width of the double-struck line is basically identical (click the above images for higher resolution). Coincidence โ€ฆ?

This, of course, does not answer the question, Did Musk steal his new X logo? - there are countless more fonts out there (although the amount of fonts that support this character is probably relatively small).

It is also possible that Musk didnโ€™t steal it and he actually paid a designer for 10 minutes of work to draw two lines.

Anyways, it was a good excuse to do some glyph analysis in Python.