Skip to content

Instantly share code, notes, and snippets.

@gettalong
Last active June 9, 2021 17:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gettalong/5f13d27a2170e507cd890aa3a4273a43 to your computer and use it in GitHub Desktop.
Save gettalong/5f13d27a2170e507cd890aa3a4273a43 to your computer and use it in GitHub Desktop.
Using a TrueType font with HexaPDF

HexaPDF is now able to use a TrueType font to generate content. There are still some limitations, like the missing support for subsets but most things work quite well already. Complete integration into the Canvas and font selection API is also not done yet.

The attached script generates a PDF showcasing all available glyphs defined in a font as well as a sample text containing characters from the Unicode BMP as well as from other Unicode planes.

Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
require 'hexapdf/document'
require 'hexapdf/font/ttf_wrapper'
doc = HexaPDF::Document.new
doc.config['font.on_missing_glyph'] = ->(n,f) { f.missing_glyph_id }
fontio = File.open('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 'r')
ttf_font = HexaPDF::Font::TTF::Font.new(io: fontio)
wrapper = HexaPDF::Font::TTFWrapper.new(doc, ttf_font)
max_gid = ttf_font[:maxp].num_glyphs
canvas = doc.pages.add_page.canvas
canvas.instance_eval { @font = wrapper }
canvas.font_size = 12
canvas.text("qwertyuiop[]asdfghjkl;'\zxcvbnm,./1234567890-\n~!@# $%^&*()_+}{|\":?><|\n¶öóáßðfïghäåéëöóþü朩µbñ¹²³¤‘\n" \
"🐭 🐮 🐱 🐵 😀", at: [100, 100])
255.times do |page|
break unless page*256 < ttf_font[:maxp].num_glyphs
canvas = doc.pages.add_page.canvas
canvas.instance_eval { @font = wrapper }
canvas.font_size = 15
16.times do |y|
canvas.move_text_cursor(offset: [10, 800 - y*50], absolute: true)
canvas.show_glyphs((0..15).map do |i|
gid = page*256 + y*16 + i
glyph = wrapper.glyph(gid) || wrapper.glyph(0)
gid > max_gid ? [] : [glyph, -(2000 - glyph.width)]
end.flatten!)
end
end
doc.write("ttf.pdf")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment