Created
April 18, 2020 07:06
-
-
Save jkrumbiegel/8d3fe634cad98abd1208ff767504beeb to your computer and use it in GitHub Desktop.
Unscaled font metrics with Cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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