diff options
| author | Khaled Hosny <khaledhosny@eglug.org> | 2009-12-31 16:32:37 +0200 | 
|---|---|---|
| committer | Khaled Hosny <khaledhosny@eglug.org> | 2009-12-31 16:32:37 +0200 | 
| commit | 21f69a1cb547fc10a4927171de7dddaec5c09b35 (patch) | |
| tree | 827694fa5be47bd9ba09e48d47915fe4b39de9fc | |
| parent | 0823f27801c9f0d84a67c27a9b629949d1296f8b (diff) | |
| download | luaotfload-21f69a1cb547fc10a4927171de7dddaec5c09b35.tar.gz | |
Updating to latest ConTeXt beta (2009.12.30)
| -rw-r--r-- | otfl-font-def.lua | 2 | ||||
| -rw-r--r-- | otfl-font-otb.lua | 82 | ||||
| -rw-r--r-- | otfl-font-otf.lua | 212 | ||||
| -rw-r--r-- | otfl-font-tfm.lua | 110 | 
4 files changed, 303 insertions, 103 deletions
| diff --git a/otfl-font-def.lua b/otfl-font-def.lua index 9a007b9..02369cc 100644 --- a/otfl-font-def.lua +++ b/otfl-font-def.lua @@ -314,7 +314,7 @@ function tfm.read(specification)                  local reader = sequence[s]                  if readers[reader] then -- not really needed                      if trace_defining then -                        logs.report("define font","trying (sequence driven) type %s for %s with file %s",reader,specification.name,specification.filename or "unknown") +                        logs.report("define font","trying (reader sequence driven) type %s for %s with file %s",reader,specification.name,specification.filename or "unknown")                      end                      tfmtable = readers[reader](specification)                      if tfmtable then diff --git a/otfl-font-otb.lua b/otfl-font-otb.lua index 675c124..a684580 100644 --- a/otfl-font-otb.lua +++ b/otfl-font-otb.lua @@ -279,6 +279,47 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod      end  end +--~ local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all +--~     if value then +--~         local otfdata = tfmdata.shared.otfdata +--~         local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language) +--~         if validlookups then +--~             local unicodes = tfmdata.unicodes -- names to unicodes +--~             local indices = tfmdata.indices +--~             local characters = tfmdata.characters +--~             local descriptions = tfmdata.descriptions +--~             for u, chr in next, characters do +--~                 local d = descriptions[u] +--~                 if d then +--~                     local dk = d.mykerns +--~                     if dk then +--~                         local t, done = chr.kerns or { }, false +--~                         for l=1,#lookuplist do +--~                             local lookup = lookuplist[l] +--~                             local kerns = dk[lookup] +--~                             if kerns then +--~                                 for k, v in next, kerns do +--~                                     if v ~= 0 and not t[k] then -- maybe no 0 test here +--~                                         t[k], done = v, true +--~                                         if trace_baseinit and trace_kerns then +--~                                             logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v) +--~                                         end +--~                                     end +--~                                 end +--~                             end +--~                         end +--~                         if done then +--~                             chr.kerns = t -- no empty assignments +--~                         end +--~                 --  elseif d.kerns then +--~                 --      logs.report("define otf","%s: invalid mykerns for %s",cref(kind),gref(descriptions,u)) +--~                     end +--~                 end +--~             end +--~         end +--~     end +--~ end +  local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all      if value then          local otfdata = tfmdata.shared.otfdata @@ -288,31 +329,40 @@ local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns              local indices = tfmdata.indices              local characters = tfmdata.characters              local descriptions = tfmdata.descriptions +            local sharedkerns = { }              for u, chr in next, characters do                  local d = descriptions[u]                  if d then -                    local dk = d.mykerns +                    local dk = d.mykerns -- shared                      if dk then -                        local t, done = chr.kerns or { }, false -                        for l=1,#lookuplist do -                            local lookup = lookuplist[l] -                            local kerns = dk[lookup] -                            if kerns then -                                for k, v in next, kerns do -                                    if v ~= 0 and not t[k] then -- maybe no 0 test here -                                        t[k], done = v, true -                                        if trace_baseinit and trace_kerns then -                                            logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v) +                        local s = sharedkerns[dk] +                        if s == false then +                            -- skip +                        elseif s then +                            chr.kerns = s +                        else +                            local t, done = chr.kerns or { }, false +                            for l=1,#lookuplist do +                                local lookup = lookuplist[l] +                                local kerns = dk[lookup] +                                if kerns then +                                    for k, v in next, kerns do +                                        if v ~= 0 and not t[k] then -- maybe no 0 test here +                                            t[k], done = v, true +                                            if trace_baseinit and trace_kerns then +                                                logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v) +                                            end                                          end                                      end                                  end                              end +                            if done then +                                sharedkerns[dk] = t +                                chr.kerns = t -- no empty assignments +                            else +                                sharedkerns[dk] = false +                            end                          end -                        if done then -                            chr.kerns = t -- no empty assignments -                        end -                --  elseif d.kerns then -                --      logs.report("define otf","%s: invalid mykerns for %s",cref(kind),gref(descriptions,u))                      end                  end              end diff --git a/otfl-font-otf.lua b/otfl-font-otf.lua index bf5acad..1cf5148 100644 --- a/otfl-font-otf.lua +++ b/otfl-font-otf.lua @@ -193,7 +193,7 @@ function otf.enhance(name,data,filename,verbose)      local enhancer = otf.enhancers[name]      if enhancer then          if (verbose ~= nil and verbose) or trace_loading then -            logs.report("load otf","enhance: %s",name) +            logs.report("load otf","enhance: %s (%s)",name,filename)          end          enhancer(data,filename)      end @@ -258,6 +258,7 @@ function otf.load(filename,format,sub,featurefile)                  logs.report("load otf","enhancing ...")                  for e=1,#enhancers do                      otf.enhance(enhancers[e],data,filename) +                    io.flush() -- we want instant messages                  end                  if otf.pack and not fonts.verbose then                      otf.enhance("pack",data,filename) @@ -993,6 +994,129 @@ end  -- kern: ttf has a table with kerns +--~ otf.enhancers["reorganize kerns"] = function(data,filename) +--~     local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes +--~     local mkdone = false +--~     for index, glyph in next, data.glyphs do +--~         if glyph.kerns then +--~             local mykerns = { } +--~             for k,v in next, glyph.kerns do +--~                 local vc, vo, vl = v.char, v.off, v.lookup +--~                 if vc and vo and vl then -- brrr, wrong! we miss the non unicode ones +--~                     local uvc = unicodes[vc] +--~                     if not uvc then +--~                         if trace_loading then +--~                             logs.report("load otf","problems with unicode %s of kern %s at glyph %s",vc,k,index) +--~                         end +--~                     else +--~                         if type(vl) ~= "table" then +--~                             vl = { vl } +--~                         end +--~                         for l=1,#vl do +--~                             local vll = vl[l] +--~                             local mkl = mykerns[vll] +--~                             if not mkl then +--~                                 mkl = { } +--~                                 mykerns[vll] = mkl +--~                             end +--~                             if type(uvc) == "table" then +--~                                 for u=1,#uvc do +--~                                     mkl[uvc[u]] = vo +--~                                 end +--~                             else +--~                                 mkl[uvc] = vo +--~                             end +--~                         end +--~                     end +--~                 end +--~             end +--~             glyph.mykerns = mykerns +--~             glyph.kerns = nil -- saves space and time +--~             mkdone = true +--~         end +--~     end +--~     if trace_loading and mkdone then +--~         logs.report("load otf", "replacing 'kerns' tables by 'mykerns' tables") +--~     end +--~     if data.kerns then +--~         if trace_loading then +--~             logs.report("load otf", "removing global 'kern' table") +--~         end +--~         data.kerns = nil +--~     end +--~     local dgpos = data.gpos +--~     if dgpos then +--~         for gp=1,#dgpos do +--~             local gpos = dgpos[gp] +--~             local subtables = gpos.subtables +--~             if subtables then +--~                 for s=1,#subtables do +--~                     local subtable = subtables[s] +--~                     local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes +--~                     if kernclass then -- the next one is quite slow +--~                         for k=1,#kernclass do +--~                             local kcl = kernclass[k] +--~                             local firsts, seconds, offsets, lookups = kcl.firsts, kcl.seconds, kcl.offsets, kcl.lookup -- singular +--~                             if type(lookups) ~= "table" then +--~                                 lookups = { lookups } +--~                             end +--~                             for l=1,#lookups do +--~                                 local lookup = lookups[l] +--~                                 -- weird, as maxfirst and maxseconds can have holes +--~                                 local maxfirsts, maxseconds = getn(firsts), getn(seconds) +--~                                 if trace_loading then +--~                                     logs.report("load otf", "adding kernclass %s with %s times %s pairs",lookup, maxfirsts, maxseconds) +--~                                 end +--~                                 for fk, fv in next, firsts do +--~                                     for first in gmatch(fv,"[^ ]+") do +--~                                         local first_unicode = unicodes[first] +--~                                         if type(first_unicode) == "number" then +--~                                             first_unicode = { first_unicode } +--~                                         end +--~                                         for f=1,#first_unicode do +--~                                             local glyph = glyphs[mapmap[first_unicode[f]]] +--~                                             if glyph then +--~                                                 local mykerns = glyph.mykerns +--~                                                 if not mykerns then +--~                                                     mykerns = { } -- unicode indexed ! +--~                                                     glyph.mykerns = mykerns +--~                                                 end +--~                                                 local lookupkerns = mykerns[lookup] +--~                                                 if not lookupkerns then +--~                                                     lookupkerns = { } +--~                                                     mykerns[lookup] = lookupkerns +--~                                                 end +--~                                                 for sk, sv in next, seconds do +--~                                                     local offset = offsets[(fk-1) * maxseconds + sk] +--~                                                     --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk] +--~                                                     for second in gmatch(sv,"[^ ]+") do +--~                                                         local second_unicode = unicodes[second] +--~                                                         if type(second_unicode) == "number" then +--~                                                             lookupkerns[second_unicode] = offset +--~                                                         else +--~                                                             for s=1,#second_unicode do +--~                                                                 lookupkerns[second_unicode[s]] = offset +--~                                                             end +--~                                                         end +--~                                                     end +--~                                                 end +--~                                             elseif trace_loading then +--~                                                 logs.report("load otf", "no glyph data for U+%04X", first_unicode[f]) +--~                                             end +--~                                         end +--~                                     end +--~                                 end +--~                             end +--~                         end +--~                         subtable.comment = "The kernclass table is merged into mykerns in the indexed glyph tables." +--~                         subtable.kernclass = { } +--~                     end +--~                 end +--~             end +--~         end +--~     end +--~ end +  otf.enhancers["reorganize kerns"] = function(data,filename)      local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes      local mkdone = false @@ -1045,6 +1169,9 @@ otf.enhancers["reorganize kerns"] = function(data,filename)      end      local dgpos = data.gpos      if dgpos then +        local separator = lpeg.P(" ") +        local other = ((1 - separator)^0) / unicodes +        local splitter = lpeg.Ct(other * (separator * other)^0)          for gp=1,#dgpos do              local gpos = dgpos[gp]              local subtables = gpos.subtables @@ -1052,54 +1179,71 @@ otf.enhancers["reorganize kerns"] = function(data,filename)                  for s=1,#subtables do                      local subtable = subtables[s]                      local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes -                    if kernclass then +                    if kernclass then -- the next one is quite slow                          for k=1,#kernclass do                              local kcl = kernclass[k]                              local firsts, seconds, offsets, lookups = kcl.firsts, kcl.seconds, kcl.offsets, kcl.lookup -- singular                              if type(lookups) ~= "table" then                                  lookups = { lookups }                              end +                            local split = { }                              for l=1,#lookups do                                  local lookup = lookups[l] +                                -- weird, as maxfirst and maxseconds can have holes, first seems to be indexed, seconds starts at 2                                  local maxfirsts, maxseconds = getn(firsts), getn(seconds) +                                for _, s in next, firsts do +                                    split[s] = split[s] or lpegmatch(splitter,s) +                                end +                                for _, s in next, seconds do +                                    split[s] = split[s] or lpegmatch(splitter,s) +                                end                                  if trace_loading then                                      logs.report("load otf", "adding kernclass %s with %s times %s pairs",lookup, maxfirsts, maxseconds)                                  end -                                for fk, fv in next, firsts do -                                    for first in gmatch(fv,"[^ ]+") do -                                        local first_unicode = unicodes[first] -                                        if type(first_unicode) == "number" then -                                            first_unicode = { first_unicode } +                                local function do_it(fk,first_unicode) +                                    local glyph = glyphs[mapmap[first_unicode]] +                                    if glyph then +                                        local mykerns = glyph.mykerns +                                        if not mykerns then +                                            mykerns = { } -- unicode indexed ! +                                            glyph.mykerns = mykerns                                          end -                                        for f=1,#first_unicode do -                                            local glyph = glyphs[mapmap[first_unicode[f]]] -                                            if glyph then -                                                local mykerns = glyph.mykerns -                                                if not mykerns then -                                                    mykerns = { } -- unicode indexed ! -                                                    glyph.mykerns = mykerns -                                                end -                                                local lookupkerns = mykerns[lookup] -                                                if not lookupkerns then -                                                    lookupkerns = { } -                                                    mykerns[lookup] = lookupkerns -                                                end -                                                for sk, sv in next, seconds do -                                                    local offset = offsets[(fk-1) * maxseconds + sk] -                                                    --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk] -                                                    for second in gmatch(sv,"[^ ]+") do -                                                        local second_unicode = unicodes[second] -                                                        if type(second_unicode) == "number" then -                                                            lookupkerns[second_unicode] = offset -                                                        else -                                                            for s=1,#second_unicode do -                                                                lookupkerns[second_unicode[s]] = offset -                                                            end -                                                        end +                                        local lookupkerns = mykerns[lookup] +                                        if not lookupkerns then +                                            lookupkerns = { } +                                            mykerns[lookup] = lookupkerns +                                        end +                                        local baseoffset = (fk-1) * maxseconds +                                        for sk=2,maxseconds do +                                            local sv = seconds[sk] +                                            local offset = offsets[baseoffset + sk] +                                            --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk] +                                            local splt = split[sv] +                                            for i=1,#splt do +                                                local second_unicode = splt[i] +                                                if tonumber(second_unicode) then +                                                    lookupkerns[second_unicode] = offset +                                                else +                                                    for s=1,#second_unicode do +                                                        lookupkerns[second_unicode[s]] = offset                                                      end                                                  end -                                            elseif trace_loading then -                                                logs.report("load otf", "no glyph data for U+%04X", first_unicode[f]) +                                            end +                                        end +                                    elseif trace_loading then +                                        logs.report("load otf", "no glyph data for U+%04X", first_unicode) +                                    end +                                end +                                for fk=1,#firsts do +                                    local fv = firsts[fk] +                                    local splt = split[fv] +                                    for i=1,#splt do +                                        local first_unicode = splt[i] +                                        if tonumber(first_unicode) then +                                            do_it(fk,first_unicode) +                                        else +                                            for f=1,#first_unicode do +                                                do_it(fk,first_unicode[f])                                              end                                          end                                      end diff --git a/otfl-font-tfm.lua b/otfl-font-tfm.lua index 2ab28c7..4bb47cf 100644 --- a/otfl-font-tfm.lua +++ b/otfl-font-tfm.lua @@ -186,36 +186,36 @@ fonts.trace_scaling = false  -- basekerns are scaled and will be hashed by table id  -- sharedkerns are unscaled and are be hashed by concatenated indexes -function tfm.check_base_kerns(tfmdata) -    if tfm.share_base_kerns then -        local sharedkerns = tfmdata.sharedkerns -        if sharedkerns then -            local basekerns = { } -            tfmdata.basekerns = basekerns -            return sharedkerns, basekerns -        end -    end -    return nil, nil -end +--~ function tfm.check_base_kerns(tfmdata) +--~     if tfm.share_base_kerns then +--~         local sharedkerns = tfmdata.sharedkerns +--~         if sharedkerns then +--~             local basekerns = { } +--~             tfmdata.basekerns = basekerns +--~             return sharedkerns, basekerns +--~         end +--~     end +--~     return nil, nil +--~ end -function tfm.prepare_base_kerns(tfmdata) -    if tfm.share_base_kerns and not tfmdata.sharedkerns then -        local sharedkerns = { } -        tfmdata.sharedkerns = sharedkerns -        for u, chr in next, tfmdata.characters do -            local kerns = chr.kerns -            if kerns then -                local hash = concat(sortedkeys(kerns), " ") -                local base = sharedkerns[hash] -                if not base then -                    sharedkerns[hash] = kerns -                else -                    chr.kerns = base -                end -            end -        end -    end -end +--~ function tfm.prepare_base_kerns(tfmdata) +--~     if tfm.share_base_kerns and not tfmdata.sharedkerns then +--~         local sharedkerns = { } +--~         tfmdata.sharedkerns = sharedkerns +--~         for u, chr in next, tfmdata.characters do +--~             local kerns = chr.kerns +--~             if kerns then +--~                 local hash = concat(sortedkeys(kerns), " ") +--~                 local base = sharedkerns[hash] +--~                 if not base then +--~                     sharedkerns[hash] = kerns +--~                 else +--~                     chr.kerns = base +--~                 end +--~             end +--~         end +--~     end +--~ end  -- we can have cache scaled characters when we are in node mode and don't have  -- protruding and expansion: hash == fullname @ size @ protruding @ expansion @@ -229,7 +229,7 @@ local charactercache = { }  -- has_italic flag. Some more flags will be added in the future.  function tfm.do_scale(tfmtable, scaledpoints) -    tfm.prepare_base_kerns(tfmtable) -- optimalization + -- tfm.prepare_base_kerns(tfmtable) -- optimalization      if scaledpoints < 0 then          scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp      end @@ -303,7 +303,7 @@ t.colorscheme = tfmtable.colorscheme      local defaultheight = luatex and luatex.defaultheight or 0      local defaultdepth  = luatex and luatex.defaultdepth  or 0      -- experimental, sharing kerns (unscaled and scaled) saves memory -    local sharedkerns, basekerns = tfm.check_base_kerns(tfmtable) +    -- local sharedkerns, basekerns = tfm.check_base_kerns(tfmtable)      -- loop over descriptions (afm and otf have descriptions, tfm not)      -- there is no need (yet) to assign a value to chr.tonunicode      local scaledwidth  = defaultwidth  * hdelta @@ -311,6 +311,7 @@ t.colorscheme = tfmtable.colorscheme      local scaleddepth  = defaultdepth  * vdelta      local stackmath = tfmtable.ignore_stack_math ~= true      local private = fonts.private +    local sharedkerns = { }      for k,v in next, characters do          local chr, description, index          if ischanged then @@ -471,19 +472,26 @@ t.colorscheme = tfmtable.colorscheme          if not nodemode then              local vk = v.kerns              if vk then -                if sharedkerns then -                    local base = basekerns[vk] -- hashed by table id, not content -                    if not base then -                        base = {} -                        for k,v in next, vk do base[k] = v*hdelta end -                        basekerns[vk] = base -                    end -                    chr.kerns = base -                else -                    local tt = {} -                    for k,v in next, vk do tt[k] = v*hdelta end -                    chr.kerns = tt +            --~ if sharedkerns then +            --~     local base = basekerns[vk] -- hashed by table id, not content +            --~     if not base then +            --~         base = {} +            --~         for k,v in next, vk do base[k] = v*hdelta end +            --~         basekerns[vk] = base +            --~     end +            --~     chr.kerns = base +            --~ else +            --~     local tt = {} +            --~     for k,v in next, vk do tt[k] = v*hdelta end +            --~     chr.kerns = tt +            --~ end +                local s = sharedkerns[vk] +                if not s then +                    local s = {} +                    for k,v in next, vk do s[k] = v*hdelta end +                    sharedkerns[vk] = s                  end +                chr.kerns = s              end              local vl = v.ligatures              if vl then @@ -600,21 +608,19 @@ local lastfont = nil  --  -- flushing the kern and ligature tables from memory saves a lot (only  -- base mode) but it complicates vf building where the new characters --- demand this data - ---~ for id, f in pairs(fonts.ids) do -- or font.fonts ---~     local ffi = font.fonts[id] ---~     f.characters = ffi.characters ---~     f.kerns = ffi.kerns ---~     f.ligatures = ffi.ligatures ---~ end +-- demand this data .. solution: functions that access them  function tfm.cleanup_table(tfmdata) -- we need a cleanup callback, now we miss the last one      if tfm.auto_cleanup then  -- ok, we can hook this into everyshipout or so ... todo          if tfmdata.type == 'virtual' or tfmdata.virtualized then              for k, v in next, tfmdata.characters do -                if v.commands then v.commands  = nil end +                if v.commands then v.commands = nil end +            --  if v.kerns    then v.kerns    = nil end              end +        else +        --  for k, v in next, tfmdata.characters do +        --     if v.kerns    then v.kerns    = nil end +        --  end          end      end  end | 
