From e829a47bf78db8f1a9f691dcd7b096eab58040ad Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Fri, 2 Apr 2010 07:29:34 +0200 Subject: Fix optical size matching With the previous commit, if we don't found a font with the requested optical size, we return nothing, though we might have a matching font name. Now we store all matching names with no matching optical size and return the first one, then we return the closest match (i.e. if the requested size is 15pt and we have 10pt and 5pt match, we return the 10pt one). --- otfl-font-nms.lua | 52 ++++++++++++++++++++++++++++++++++++--------------- tests/opticalsize.tex | 4 ++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 51db3bd..bb5628c 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -63,6 +63,7 @@ local synonyms = { function names.resolve(specification) local name = sanitize(specification.name) local style = sanitize(specification.style) or "regular" + local size = tonumber(specification.optsize) or specification.size and specification.size / 65536 if not loaded then names.data = names.load() loaded = true @@ -70,17 +71,16 @@ function names.resolve(specification) local data = names.data if type(data) == "table" and data.version == names.version then if data.mappings then - local found + local found = { } for _,face in ipairs(data.mappings) do local family = sanitize(face.names.family) local subfamily = sanitize(face.names.subfamily) local fullname = sanitize(face.names.fullname) local psname = sanitize(face.names.psname) local filename = face.filename - local optsize, rqssize, dsnsize, maxsize, minsize + local optsize, dsnsize, maxsize, minsize if #face.size > 0 then optsize = face.size - rqssize = tonumber(specification.optsize) or specification.size and specification.size / 65536 dsnsize = optsize[1] and optsize[1] / 10 maxsize = optsize[2] and optsize[2] / 10 or dsnsize -- can be nil minsize = optsize[3] and optsize[3] / 10 or dsnsize -- can be nil @@ -88,12 +88,14 @@ function names.resolve(specification) if name == family and subfamily then if subfamily == style then if optsize then - if dsnsize == rqssize or (rqssize > minsize and rqssize <= maxsize) then - found = filename + if dsnsize == size or (size > minsize and size <= maxsize) then + found[1] = face break + else + found[#found+1] = face end else - found = filename + found[1] = face break end else @@ -101,12 +103,14 @@ function names.resolve(specification) for _,v in ipairs(synonyms[style]) do if subfamily == v then if optsize then - if dsnsize == rqssize or (rqssize > minsize and rqssize <= maxsize) then - found = filename + if dsnsize == size or (size > minsize and size <= maxsize) then + found[1] = face break + else + found[#found+1] = face end else - found = filename + found[1] = face break end end @@ -116,20 +120,38 @@ function names.resolve(specification) else if name == family or name == fullname or name == psname then if optsize then - if dsnsize == rqssize or (rqssize > minsize and rqssize <= maxsize) then - found = filename + if dsnsize == size or (size > minsize and size <= maxsize) then + found[1] = face break + else + found[#found+1] = face end else - found = filename + found[1] = face break end end end end - if found then - logs.report("load font", "font family='%s', subfamily='%s' found: %s", name, style, found) - return found, false + if #found == 1 then + logs.report("load font", "font family='%s', subfamily='%s' found: %s", name, style, found[1].filename) + return found[1].filename, false + elseif #found > 1 then + -- we found matching font(s) but not in the requested optical + -- sizes, so we loop through the matches to find the one with + -- least difference from the requested size. + local closest + local least = math.huge -- initial value is infinity + for i,face in ipairs(found) do + local dsnsize = face.size[1]/10 + local difference = math.abs(dsnsize-size) + if difference < least then + closest = face + least = difference + end + end + logs.report("load font", "font family='%s', subfamily='%s' found: %s", name, style, closest.filename) + return closest.filename, false else return name, false -- fallback to filename end diff --git a/tests/opticalsize.tex b/tests/opticalsize.tex index d19bb59..53b1bb8 100644 --- a/tests/opticalsize.tex +++ b/tests/opticalsize.tex @@ -3,7 +3,11 @@ \font\testa={Latin Modern Roman/S=12} at 10pt \font\testb={Latin Modern Roman} at 5pt \font\testc={Latin Modern Roman} at 10pt +\font\testd={Latin Modern Roman/S=15} at 10pt +\font\teste={Latin Modern Roman/S=3} at 10pt \testa abcd ABCD \par \testb abcd ABCD \par \testc abcd ABCD \par +\testd abcd ABCD \par +\teste abcd ABCD \par \bye -- cgit v1.2.3