summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2010-04-02 07:29:34 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2010-04-02 09:34:09 +0200
commite829a47bf78db8f1a9f691dcd7b096eab58040ad (patch)
tree73f1d8e22c17d1dd2861718f25460865fc9a1080
parent6ef791e91eb0c497494cbb12063d9ef72841080e (diff)
downloadluaotfload-e829a47bf78db8f1a9f691dcd7b096eab58040ad.tar.gz
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).
-rw-r--r--otfl-font-nms.lua52
-rw-r--r--tests/opticalsize.tex4
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