Skip to content

Instantly share code, notes, and snippets.

@jkrumbiegel
Created April 18, 2020 07:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkrumbiegel/8d3fe634cad98abd1208ff767504beeb to your computer and use it in GitHub Desktop.
Save jkrumbiegel/8d3fe634cad98abd1208ff767504beeb to your computer and use it in GitHub Desktop.
Unscaled font metrics with Cairo
using FreeType
using FreeTypeAbstraction
using Cairo
function normalized_metrics(font, char)
# load char with NO_SCALE flag to receive font units
# which can be scaled by the units_per_EM
FT_Load_Char(font, char, FT_LOAD_NO_SCALE)
m = font.glyph.metrics
(; map(fieldnames(typeof(m))) do f
f => getfield(m, f) / font.units_per_EM
end...)
end
function set_ft_font(cr, font)
font_face = ccall(
(:cairo_ft_font_face_create_for_ft_face, Cairo.libcairo),
Ptr{Cvoid}, (FreeTypeAbstraction.FT_Face, Cint),
font, 0
)
ccall((:cairo_set_font_face, Cairo.libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), cr.ptr, font_face)
font_face
end
function cairo_font_face_destroy(font_face)
ccall(
(:cairo_font_face_destroy, Cairo.libcairo),
Cvoid, (Ptr{Cvoid},),
font_face
)
end
##
function test(fontstring)
font = FreeTypeAbstraction.findfont(fontstring)
surf = CairoPDFSurface("test.pdf", 500, 500)
c = CairoContext(surf)
rectangle(c, 0, 0, 500, 500)
set_source_rgb(c, 1, 1, 1)
paint(c)
cairofont = set_ft_font(c, font)
set_source_rgb(c, 0, 0, 0)
fontsize = 20
set_font_size(c, fontsize)
pos = (100, 100)
move_to(c, pos...)
rel_line_to(c, 0, -fontsize)
stroke(c)
# test manual placement of glyphs with normalized font metrics
for char in "This is a test string"
move_to(c, pos...)
show_text(c, string(char))
metrics = normalized_metrics(font, char)
adv = metrics.horiAdvance
# the normalized metrics can just be multiplied by font size
pos = pos .+ (fontsize * adv, 0)
end
# check that the result is the same when using the cairo show_text command for the whole string
move_to(c, 100, 100 + fontsize * 1.3)
show_text(c, "This is a test string")
cairo_font_face_destroy(cairofont)
display(surf)
finish(surf)
nothing
end
test("SF Compact Text Light")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment