Skip to content

Commit dbe0d40

Browse files
committed
fix regular + performance
1 parent 805b8cb commit dbe0d40

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

src/findfonts.jl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,16 @@ Then this is how this function would match different search strings:
6868
- "times new roman" => Times New Roman
6969
- "arial" => no match
7070
"""
71-
function match_font(face::FTFont, searchstring)
71+
function match_font(face::FTFont, searchparts)
7272
fname = family_name(face)
7373
sname = style_name(face)
74-
full_name = "$fname $sname"
75-
# \W splits at all groups of non-word characters (like space, -, ., etc)
76-
searchparts = unique(split(lowercase(searchstring), r"\W+", keepempty=false))
74+
# Regular should get selected / full match if we dont specificy any styling!
75+
full_name = if sname == "regular"
76+
"$fname"
77+
else
78+
"$fname $sname"
79+
end
80+
full_name == "" && return 0
7781
# count letters of parts that occurred in the font name positively and those that didn't negatively.
7882
# we assume that the user knows at least parts of the name and doesn't misspell them
7983
# but they might not know the exact name, especially for long font names, or they
@@ -82,7 +86,7 @@ function match_font(face::FTFont, searchstring)
8286
# doesn't match against it, therefore rejecting fonts that mismatch more parts
8387
# than they match. this heuristic should be good enough to provide a hassle-free
8488
# font selection experience where most spellings that are expected to work, work.
85-
match_score = sum(map(part -> sign(occursin(part, full_name)) * length(part), searchparts))
89+
match_score = sum(map(part -> (2 * occursin(part, full_name) - 1) * length(part), searchparts))
8690
# give shorter font names that matched equally well a higher score after the decimal point.
8791
# this should usually pick the "standard" variant of a font as long as it
8892
# doesn't have a special identifier like "regular", "roman", "book", etc.
@@ -105,28 +109,29 @@ function try_load(fpath)
105109
end
106110

107111
function findfont(
108-
name::String;
112+
searchstring::String;
109113
italic::Bool=false, # this is unused in the new implementation
110114
bold::Bool=false, # and this as well
111115
additional_fonts::String=""
112116
)
113117
font_folders = copy(fontpaths())
114118
# normalized_name = family_name(name)
115119
isempty(additional_fonts) || pushfirst!(font_folders, additional_fonts)
116-
120+
# \W splits at all groups of non-word characters (like space, -, ., etc)
121+
searchparts = unique(split(lowercase(searchstring), r"\W+", keepempty=false))
117122
candidates = Pair{FTFont, Float64}[]
118123
for folder in font_folders
119124
for font in readdir(folder)
120125
fpath = joinpath(folder, font)
121126
face = try_load(fpath)
122127
face === nothing && continue
123-
score = match_font(face, name)
124-
128+
score = match_font(face, searchparts)
125129
# only take results with net positive character matches into account
126130
if floor(score) > 0
127131
push!(candidates, face => score)
128132
else
129-
finalize(face) # help gc a bit!
133+
# help gc a bit! Otherwise, this won't end well with the font keeping tons of open files
134+
finalize(face)
130135
end
131136
end
132137
end

0 commit comments

Comments
 (0)