Skip to content

Instantly share code, notes, and snippets.

@13rac1
Last active June 23, 2024 06:29
Show Gist options
  • Save 13rac1/7e0b5fb32939685ea44e1a713aac081b to your computer and use it in GitHub Desktop.
Save 13rac1/7e0b5fb32939685ea44e1a713aac081b to your computer and use it in GitHub Desktop.
Find the display width in pixels of a string given a font, point size and DPI in Python using Freetype
"Find the display width in pixels of a string given a font, point size and DPI."
import freetype
# Uses Freetype Python bindings:http://freetype-py.readthedocs.io/en/latest/
# Based on the FreeType Tutorial examples:
# https://www.freetype.org/freetype2/docs/tutorial/step2.html
# Note: This code uses bitshift by six to divide/multiply by 64 to convert
# between 26.6 pixel format (i.e., 1/64th of pixels) and points.
THE_STRING = "Hello World!"
FONT_POINTS = 50
# Freetype default is 72 DPI.
DISPLAY_DPI = 96
# Using Open Sans, but any other font will work.
face = freetype.Face("fonts/OpenSans-Regular.ttf")
# Set the point size and DPI.
face.set_char_size(FONT_POINTS << 6, FONT_POINTS << 6, DISPLAY_DPI, DISPLAY_DPI)
pen_x = 0
previous_glyph = 0
for char in THE_STRING:
# Convert character code to glyph index.
glyph_index = face.get_char_index(char)
# Retrieve kerning distance and move pen position.
if face.has_kerning and previous_glyph and glyph_index:
delta = face.get_kerning(previous_glyph, glyph_index)
pen_x += delta.x >> 6
# Load the glyph at glyph_index.
face.load_glyph(glyph_index, freetype.FT_LOAD_FLAGS['FT_LOAD_RENDER'])
# Dividing by 64 and increment pen position.
pen_x += face.glyph.advance.x >> 6
# Record current glyph index
previous_glyph = glyph_index
output = "{}\nDisplayed at {}pts on a {} DPI screen is {}px wide."
print(output.format(THE_STRING, FONT_POINTS, DISPLAY_DPI, pen_x))
# Hello World!
# Displayed at 50pts on a 96 DPI screen is 383px wide.
@randoragon
Copy link

There is a typo in line 39, "glpyh" instead of "glyph".

@13rac1
Copy link
Author

13rac1 commented Jul 6, 2020

Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment