-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
findfont scans all fonts every time #67
Comments
Thanks for looking into this. DynamicGrids could allow passing in the FTFont directly, but a cache seems like a cleaner solution, and maybe better if we dont all implement that. Can we just move the cache in Makie here? How easy would it be to just copy the code over? @SimonDanisch @jkrumbiegel |
Agreed that centralizing would be better. |
Sounds like a good idea to make |
Yes depending on FontConfig.jl here does look like the best solution. Im happy to review a PR for this. |
If there is an agreement about making this package dependent on FontConfig.jl, then
|
So I tried pretty hard to use FontConfig instead of rolling our own font search, but I couldn't get it to work reliable on all platforms. |
JuliaGraphics/Fontconfig.jl#21 (solved few months after the first |
Seems like there is at least BinaryBuilder now...But: JuliaGraphics/Fontconfig.jl#31 (comment) And I guess someone will need to maintain Fontconfig.jl and update the CIs etc... |
This seems relevant for JuliaLang/julia#47184 (comment). I inserted some debugging code: $ git diff
diff --git a/src/findfonts.jl b/src/findfonts.jl
index 0b668a5..fabdc2e 100644
--- a/src/findfonts.jl
+++ b/src/findfonts.jl
@@ -136,9 +136,12 @@ function findfont(
best_score_so_far = (0, 0, false, typemin(Int))
best_font = nothing
+ @show font_folders
+ nfonts = 0
for folder in font_folders
for font in readdir(folder)
+ nfonts += 1
fpath = joinpath(folder, font)
face = try_load(fpath)
face === nothing && continue
@@ -168,6 +171,7 @@ function findfont(
end
end
end
+ @show nfonts best_font
return best_font
end and got this output: julia> @time using CairoMakie
11.008582 seconds (18.42 M allocations: 1.153 GiB, 5.60% gc time, 0.54% compilation time)
julia> @time @eval scatter(0..1, rand(10), markersize=rand(10) .* 20)
font_folders = ["/home/tim/.julia/packages/Makie/Ggejq/assets/fonts", "/usr/share/fonts", "/usr/share/fonts/X11", "/usr/share/fonts/X11/Type1", "/usr/share/fonts/X11/encodings", "/usr/share/fonts/X11/encodings/large", "/usr/share/fonts/X11/misc", "/usr/share/fonts/X11/util", "/usr/share/fonts/cMap", "/usr/share/fonts/cmap", "/usr/share/fonts/cmap/adobe-cns1", "/usr/share/fonts/cmap/adobe-gb1", "/usr/share/fonts/cmap/adobe-japan1", "/usr/share/fonts/cmap/adobe-japan2", "/usr/share/fonts/cmap/adobe-korea1", "/usr/share/fonts/opentype", "/usr/share/fonts/opentype/urw-base35", "/usr/share/fonts/truetype", "/usr/share/fonts/truetype/ancient-scripts", "/usr/share/fonts/truetype/dejavu", "/usr/share/fonts/truetype/droid", "/usr/share/fonts/truetype/lato", "/usr/share/fonts/truetype/noto", "/usr/share/fonts/truetype/unifont", "/usr/share/fonts/type1", "/usr/share/fonts/type1/gsfonts", "/usr/share/fonts/type1/texlive-fonts-recommended", "/usr/share/fonts/type1/urw-base35", "/home/tim/.local/share/fonts", "/usr/local/share/fonts"]
nfonts = 1730
best_font = FTFont (family = TeX Gyre Heros Makie, style = Regular)
font_folders = ["/home/tim/.julia/packages/Makie/Ggejq/assets/fonts", "/usr/share/fonts", "/usr/share/fonts/X11", "/usr/share/fonts/X11/Type1", "/usr/share/fonts/X11/encodings", "/usr/share/fonts/X11/encodings/large", "/usr/share/fonts/X11/misc", "/usr/share/fonts/X11/util", "/usr/share/fonts/cMap", "/usr/share/fonts/cmap", "/usr/share/fonts/cmap/adobe-cns1", "/usr/share/fonts/cmap/adobe-gb1", "/usr/share/fonts/cmap/adobe-japan1", "/usr/share/fonts/cmap/adobe-japan2", "/usr/share/fonts/cmap/adobe-korea1", "/usr/share/fonts/opentype", "/usr/share/fonts/opentype/urw-base35", "/usr/share/fonts/truetype", "/usr/share/fonts/truetype/ancient-scripts", "/usr/share/fonts/truetype/dejavu", "/usr/share/fonts/truetype/droid", "/usr/share/fonts/truetype/lato", "/usr/share/fonts/truetype/noto", "/usr/share/fonts/truetype/unifont", "/usr/share/fonts/type1", "/usr/share/fonts/type1/gsfonts", "/usr/share/fonts/type1/texlive-fonts-recommended", "/usr/share/fonts/type1/urw-base35", "/home/tim/.local/share/fonts", "/usr/local/share/fonts"]
nfonts = 1730
best_font = FTFont (family = TeX Gyre Heros Makie, style = Bold)
16.750444 seconds (185.45 k allocations: 11.756 MiB, 1.04% compilation time)
FigureAxisPlot() I think you could add a const best_regular = findfonts(...)
const best_bold = findfonts(...) and then the choice would be precompiled. (You wouldn't call it at runtime at all.) |
NVM, fonts are already cached. |
I guess a simple optimization could be just saving the list of font names for all found files in a text file. The font search as it is relies only on family and style name, as I have always found that to be the most reliable way to pick specific font variants. As opposed to trying to make the engine match a font whose name I already know by picking weight values etc. correctly. I used to fight with matplotlib a lot to make it match certain font variants back in the day. I think most users really just want to select specific fonts and do not need a complicated matching engine. So we don't need to open each file just to read family and style name over and over again. The only thing to work out would be when to invalidate the cache. |
I really don't see how we could reuse |
Right, it has to be something durable. Cache the choice, not the result. Reading a single font file will be much faster than reading all of them. |
findfont
works well, but takes several seconds - which may be considered fast, considering - here (openSUSE Leap-15.3),but led to the significant system-dependent overhead found in cesaraustralia/DynamicGrids.jl#194 (comment).
findfont
is always scanning all fonts, opening themto get their name and properties and find the best one.
The issue is that on my system there were over 10_000 fonts installed, most quick to load (median about 7.5 µs),
but some taking much longer (see the diagnosis histogram), so the average is about 270 µs.
diagnosis
There are several solutions on the other side (e.g. removing slow fonts, using
FTFont(font_path)
to load the specific font directly).But it might be nice to have a kind of cache so that
findfont(font_name)
would be even faster on subsequent calls ?The text was updated successfully, but these errors were encountered: