diff --git a/Project.toml b/Project.toml index 62c1f86..35e4767 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "FreeTypeAbstraction" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.0" +version = "0.11.0" [deps] ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" diff --git a/src/FreeTypeAbstraction.jl b/src/FreeTypeAbstraction.jl index a607abd..20714d5 100644 --- a/src/FreeTypeAbstraction.jl +++ b/src/FreeTypeAbstraction.jl @@ -34,6 +34,8 @@ function __init__() push!(paths, path) end append!(valid_fontpaths, paths) + # fonts aren't cacheable by precompilation, so we need to empty it on load! + empty!(FONT_CACHE) end if Base.VERSION >= v"1.4.2" diff --git a/src/findfonts.jl b/src/findfonts.jl index 0b668a5..6259cd2 100644 --- a/src/findfonts.jl +++ b/src/findfonts.jl @@ -121,12 +121,15 @@ end fontname(ft::FTFont) = "$(family_name(ft)) $(style_name(ft))" +const FONT_CACHE = Dict{String, FTFont}() + function findfont( searchstring::String; italic::Bool=false, # this is unused in the new implementation bold::Bool=false, # and this as well additional_fonts::String="" ) + (font = get(FONT_CACHE, searchstring, nothing)) !== nothing && return font font_folders = copy(fontpaths()) isempty(additional_fonts) || pushfirst!(font_folders, additional_fonts) @@ -144,7 +147,6 @@ function findfont( face === nothing && continue score = match_font(face, searchparts) - # we can compare all four tuple elements of the score at once # in order of importance: @@ -156,9 +158,7 @@ function findfont( family_match_score = score[1] if family_match_score > 0 && score > best_score_so_far # finalize previous best font to close the font file - if !isnothing(best_font) - finalize(best_font) - end + isnothing(best_font) || finalize(best_font) # new candidate best_font = face @@ -168,6 +168,6 @@ function findfont( end end end - + best_font === nothing || (FONT_CACHE[searchstring] = best_font) return best_font end diff --git a/src/types.jl b/src/types.jl index 36d094b..fc260bc 100644 --- a/src/types.jl +++ b/src/types.jl @@ -124,12 +124,13 @@ function boundingbox(extent::FontExtent{T}) where T end mutable struct FTFont + ft_path::String ft_ptr::FreeType.FT_Face use_cache::Bool extent_cache::Dict{UInt64, FontExtent{Float32}} - function FTFont(ft_ptr::FreeType.FT_Face, use_cache::Bool=true) + function FTFont(ft_path::String, ft_ptr::FreeType.FT_Face, use_cache::Bool=true) extent_cache = Dict{UInt64, FontExtent{Float32}}() - face = new(ft_ptr, use_cache, extent_cache) + face = new(ft_path, ft_ptr, use_cache, extent_cache) finalizer(safe_free, face) return face end @@ -137,8 +138,9 @@ end use_cache(face::FTFont) = getfield(face, :use_cache) get_cache(face::FTFont) = getfield(face, :extent_cache) +get_path(face::FTFont) = getfield(face, :ft_path) -FTFont(path::String) = FTFont(newface(path)) +FTFont(path::String) = FTFont(path, newface(path)) # C interop Base.cconvert(::Type{FreeType.FT_Face}, font::FTFont) = font diff --git a/test/runtests.jl b/test/runtests.jl index 8ce3bde..013ec9a 100755 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,6 +19,7 @@ face = FA.findfont("hack") @test :size in propertynames(face) @test repr(face) == "FTFont (family = Hack, style = Regular)" @test Broadcast.broadcastable(face)[] == face + @test FA.get_path(face) == joinpath(@__DIR__, "hack_regular.ttf") @test FA.ascender(face) isa Real @test FA.descender(face) isa Real