From 51ef2e4e9e9cacc517b6b7c2420872d7cf73c369 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 23 Dec 2022 22:19:11 +0100 Subject: [PATCH 1/6] add cache mechanism --- src/findfonts.jl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/findfonts.jl b/src/findfonts.jl index 0b668a5..7ac207e 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, Tuple{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="" ) + (path_ft = get(FONT_CACHE, searchstring, nothing)) !== nothing && return path_ft font_folders = copy(fontpaths()) isempty(additional_fonts) || pushfirst!(font_folders, additional_fonts) @@ -135,6 +138,7 @@ function findfont( searchparts = unique(split(lowercase(searchstring), r"\W+", keepempty=false)) best_score_so_far = (0, 0, false, typemin(Int)) + best_font_path = "" best_font = nothing for folder in font_folders @@ -144,7 +148,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,11 +159,10 @@ 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_path = fpath best_font = face best_score_so_far = score else @@ -168,6 +170,6 @@ function findfont( end end end - - return best_font + best_font === nothing || (FONT_CACHE[searchstring] = (best_font_path, best_font)) + return (best_font_path, best_font) end From af5a949688a8e9e142e2b717ba1414612e9a20e4 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 23 Dec 2022 23:30:37 +0100 Subject: [PATCH 2/6] adapt tests --- test/runtests.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 8ce3bde..0fc6b16 100755 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,7 +13,7 @@ using Test @test FA.ft_init() end -face = FA.findfont("hack") +face = FA.findfont("hack")[2] @testset "basics" begin @test :size in propertynames(face) @@ -261,12 +261,12 @@ end append!(FA.valid_fontpaths, valid_fontpaths) for font in fonts @testset "finding $font" begin - @test findfont(font) !== nothing + @test findfont(font)[2] !== nothing end end @testset "find in additional dir" begin - @test findfont("Hack") === nothing - @test findfont("Hack", additional_fonts = @__DIR__) !== nothing + @test findfont("Hack")[2] === nothing + @test findfont("Hack", additional_fonts = @__DIR__)[2] !== nothing end end From caa0f02b49b7a66c729a37a46230aef953d1672f Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 23 Dec 2022 23:33:58 +0100 Subject: [PATCH 3/6] bump minor version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" From 00b00a6e7b3f0aeb15578159ac25619c22c4f382 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 23 Dec 2022 23:40:51 +0100 Subject: [PATCH 4/6] add `ft_path` field to FTFont --- src/findfonts.jl | 8 +++----- src/types.jl | 8 +++++--- test/runtests.jl | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/findfonts.jl b/src/findfonts.jl index 7ac207e..d6965df 100644 --- a/src/findfonts.jl +++ b/src/findfonts.jl @@ -121,7 +121,7 @@ end fontname(ft::FTFont) = "$(family_name(ft)) $(style_name(ft))" -const FONT_CACHE = Dict{String, Tuple{String,FTFont}}() +const FONT_CACHE = Dict{String, FTFont}() function findfont( searchstring::String; @@ -138,7 +138,6 @@ function findfont( searchparts = unique(split(lowercase(searchstring), r"\W+", keepempty=false)) best_score_so_far = (0, 0, false, typemin(Int)) - best_font_path = "" best_font = nothing for folder in font_folders @@ -162,7 +161,6 @@ function findfont( isnothing(best_font) || finalize(best_font) # new candidate - best_font_path = fpath best_font = face best_score_so_far = score else @@ -170,6 +168,6 @@ function findfont( end end end - best_font === nothing || (FONT_CACHE[searchstring] = (best_font_path, best_font)) - return (best_font_path, best_font) + 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 0fc6b16..8ce3bde 100755 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,7 +13,7 @@ using Test @test FA.ft_init() end -face = FA.findfont("hack")[2] +face = FA.findfont("hack") @testset "basics" begin @test :size in propertynames(face) @@ -261,12 +261,12 @@ end append!(FA.valid_fontpaths, valid_fontpaths) for font in fonts @testset "finding $font" begin - @test findfont(font)[2] !== nothing + @test findfont(font) !== nothing end end @testset "find in additional dir" begin - @test findfont("Hack")[2] === nothing - @test findfont("Hack", additional_fonts = @__DIR__)[2] !== nothing + @test findfont("Hack") === nothing + @test findfont("Hack", additional_fonts = @__DIR__) !== nothing end end From 83706fc7829390cae7af2189fe5464413d54e24a Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 23 Dec 2022 23:47:51 +0100 Subject: [PATCH 5/6] add test --- src/findfonts.jl | 2 +- test/runtests.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/findfonts.jl b/src/findfonts.jl index d6965df..6259cd2 100644 --- a/src/findfonts.jl +++ b/src/findfonts.jl @@ -129,7 +129,7 @@ function findfont( bold::Bool=false, # and this as well additional_fonts::String="" ) - (path_ft = get(FONT_CACHE, searchstring, nothing)) !== nothing && return path_ft + (font = get(FONT_CACHE, searchstring, nothing)) !== nothing && return font font_folders = copy(fontpaths()) isempty(additional_fonts) || pushfirst!(font_folders, additional_fonts) 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 From 0864e78b289b0fb00dbd3805ad181fb8abccb60b Mon Sep 17 00:00:00 2001 From: t-bltg Date: Sat, 24 Dec 2022 00:00:29 +0100 Subject: [PATCH 6/6] empty FONT_CACHE on __init__ --- src/FreeTypeAbstraction.jl | 2 ++ 1 file changed, 2 insertions(+) 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"