diff options
Diffstat (limited to 'tex')
-rw-r--r-- | tex/context/base/cldf-prs.lua | 5 | ||||
-rw-r--r-- | tex/context/base/cont-new.mkii | 2 | ||||
-rw-r--r-- | tex/context/base/cont-new.mkiv | 2 | ||||
-rw-r--r-- | tex/context/base/context-version.pdf | bin | 4133 -> 4138 bytes | |||
-rw-r--r-- | tex/context/base/context-version.png | bin | 40062 -> 40531 bytes | |||
-rw-r--r-- | tex/context/base/context.mkii | 2 | ||||
-rw-r--r-- | tex/context/base/context.mkiv | 2 | ||||
-rw-r--r-- | tex/context/base/data-tmp.lua | 17 | ||||
-rw-r--r-- | tex/context/base/font-ctx.lua | 45 | ||||
-rw-r--r-- | tex/context/base/font-fea.mkvi | 98 | ||||
-rw-r--r-- | tex/context/base/font-otd.lua | 65 | ||||
-rw-r--r-- | tex/context/base/luat-sto.lua | 22 | ||||
-rw-r--r-- | tex/context/base/status-files.pdf | bin | 24747 -> 24822 bytes | |||
-rw-r--r-- | tex/context/base/status-lua.pdf | bin | 210817 -> 210709 bytes | |||
-rw-r--r-- | tex/context/base/util-lua.lua | 6 | ||||
-rw-r--r-- | tex/generic/context/luatex/luatex-fonts-merged.lua | 2 |
16 files changed, 162 insertions, 106 deletions
diff --git a/tex/context/base/cldf-prs.lua b/tex/context/base/cldf-prs.lua index be3f190f7..9fbdba0c8 100644 --- a/tex/context/base/cldf-prs.lua +++ b/tex/context/base/cldf-prs.lua @@ -49,7 +49,6 @@ cpatterns.scripted = scripted cpatterns.nested = nested -- inspect(scripted) - -print(lpegmatch(scripted,"10^-3_x")) -print(lpegmatch(scripted,"10^-a")) +-- print(lpegmatch(scripted,"10^-3_x")) +-- print(lpegmatch(scripted,"10^-a")) diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 24f5b6125..14806b2f7 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.16 01:51} +\newcontextversion{2013.03.16 13:40} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 40af8292c..f5a255157 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.16 01:51} +\newcontextversion{2013.03.16 13:40} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex b6cf0ade4..c7983e4ad 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png Binary files differindex 773e1bda4..9a8b54a89 100644 --- a/tex/context/base/context-version.png +++ b/tex/context/base/context-version.png diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index e66203c0c..800f5ff4e 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.16 01:51} +\edef\contextversion{2013.03.16 13:40} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index b489389a2..aba51903e 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.16 01:51} +\edef\contextversion{2013.03.16 13:40} %D For those who want to use this: diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua index c9180dba6..525698d1e 100644 --- a/tex/context/base/data-tmp.lua +++ b/tex/context/base/data-tmp.lua @@ -24,7 +24,7 @@ luatools with a recache feature.</p> local format, lower, gsub, concat = string.format, string.lower, string.gsub, table.concat local serialize, serializetofile = table.serialize, table.tofile -local mkdirs, isdir = dir.mkdirs, lfs.isdir +local mkdirs, isdir, isfile = dir.mkdirs, lfs.isdir, lfs.isfile local addsuffix, is_writable, is_readable = file.addsuffix, file.is_writable, file.is_readable local formatters = string.formatters @@ -279,12 +279,19 @@ function caches.loaddata(readables,name) for i=1,#readables do local path = readables[i] local tmaname, tmcname = caches.setluanames(path,name) - local loader = loadfile(tmcname) - if not loader then + local loader = false + if isfile(tmcname) then + loader = loadfile(tmcname) + end + if not loader and isfile(tmaname) then -- in case we have a different engine utilities.lua.compile(tmaname,tmcname) - -- - loader = loadfile(tmaname) + if isfile(tmcname) then + loader = loadfile(tmcname) + end + if not loader then + loader = loadfile(tmaname) + end end if loader then loader = loader() diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 51924e70c..44ac032b9 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -83,6 +83,14 @@ storage.register("fonts/numbers", numbers, "fonts.specifiers.contextnumbers") storage.register("fonts/merged", merged, "fonts.specifiers.contextmerged") storage.register("fonts/synonyms", synonyms, "fonts.specifiers.synonyms") +-- todo: put numbers also in setups .. we only need those at runtime anyway + +-- if not environment.initex then +-- for i=1,#numbers do +-- setups[i] = setups[numbers[i]] +-- end +-- end + utilities.strings.formatters.add(string.formatters, "font:name", [["'"..file.basename(%s.properties.name).."'"]] @@ -506,6 +514,9 @@ local function definecontext(name,t) -- can be shared end t.number = number setups[name] = t +-- if not environment.initex then +-- setups[number] = t +-- end return number, t end @@ -660,14 +671,16 @@ local function mergecontextfeatures(currentname,extraname,how,mergedname) -- str end end for k, v in next, extra do - mergedfeatures[k] = not v + -- only boolean features + if v == true then + mergedfeatures[k] = false + end end else -- = for k, v in next, extra do mergedfeatures[k] = v end end - -- local mergedname = currentname .. how .. extraname local number = #numbers + 1 mergedfeatures.number = number numbers[number] = mergedname @@ -747,8 +760,8 @@ end -- end of redefine -local withcache = { } -- concat might be less efficient than nested tables - +-- local withcache = { } -- concat might be less efficient than nested tables +-- -- local function withset(name,what) -- local zero = texattribute[0] -- local hash = zero .. "+" .. name .. "*" .. what @@ -775,8 +788,6 @@ function specifiers.showcontext(name) return setups[name] or setups[numbers[name]] or setups[numbers[tonumber(name)]] or { } end --- todo: support a,b,c - -- we need a copy as we will add (fontclass) goodies to the features and -- that is bad for a shared table @@ -1182,17 +1193,17 @@ local calculatescale = constructors.calculatescale function constructors.calculatescale(tfmdata,scaledpoints,relativeid) local scaledpoints, delta = calculatescale(tfmdata,scaledpoints) ---~ if enable_auto_r_scale and relativeid then -- for the moment this is rather context specific ---~ local relativedata = fontdata[relativeid] ---~ local rfmdata = relativedata and relativedata.unscaled and relativedata.unscaled ---~ local id_x_height = rfmdata and rfmdata.parameters and rfmdata.parameters.x_height ---~ local tf_x_height = tfmdata and tfmdata.parameters and tfmdata.parameters.x_height ---~ if id_x_height and tf_x_height then ---~ local rscale = id_x_height/tf_x_height ---~ delta = rscale * delta ---~ scaledpoints = rscale * scaledpoints ---~ end ---~ end + -- if enable_auto_r_scale and relativeid then -- for the moment this is rather context specific + -- local relativedata = fontdata[relativeid] + -- local rfmdata = relativedata and relativedata.unscaled and relativedata.unscaled + -- local id_x_height = rfmdata and rfmdata.parameters and rfmdata.parameters.x_height + -- local tf_x_height = tfmdata and tfmdata.parameters and tfmdata.parameters.x_height + -- if id_x_height and tf_x_height then + -- local rscale = id_x_height/tf_x_height + -- delta = rscale * delta + -- scaledpoints = rscale * scaledpoints + -- end + -- end return scaledpoints, delta end diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi index 71067d3ea..c1e051621 100644 --- a/tex/context/base/font-fea.mkvi +++ b/tex/context/base/font-fea.mkvi @@ -143,23 +143,28 @@ % hashing at this end is slower -\unexpanded\def\addfeature {\doifnextoptionalelse\font_feature_add_yes \font_feature_add_nop } -\unexpanded\def\subtractfeature{\doifnextoptionalelse\font_feature_subtract_yes\font_feature_subtract_nop} -\unexpanded\def\replacefeature {\doifnextoptionalelse\font_feature_replace_yes \font_feature_replace_nop } -\unexpanded\def\feature {\doifnextoptionalelse\font_feature_yes \font_feature_nop } +\unexpanded\def\addfeature {\doifnextoptionalelse\font_feature_add_yes \font_feature_add_nop } +\unexpanded\def\subtractfeature {\doifnextoptionalelse\font_feature_subtract_yes \font_feature_subtract_nop } +\unexpanded\def\replacefeature {\doifnextoptionalelse\font_feature_replace_yes \font_feature_replace_nop } +\unexpanded\def\resetandaddfeature{\doifnextoptionalelse\font_feature_reset_add_yes\font_feature_reset_add_nop} +\unexpanded\def\feature {\doifnextoptionalelse\font_feature_yes \font_feature_nop } -\unexpanded\def\font_feature_add_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add} -\unexpanded\def\font_feature_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_add} +\unexpanded\def\font_feature_add_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add} +\unexpanded\def\font_feature_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_add} -\unexpanded\def\font_feature_subtract_yes[#feature]{\edef\m_font_feature_asked{#feature}\font_feature_subtract} -\unexpanded\def\font_feature_subtract_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_subtract} +\unexpanded\def\font_feature_subtract_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_subtract} +\unexpanded\def\font_feature_subtract_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_subtract} -\unexpanded\def\font_feature_replace_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_replace} -\unexpanded\def\font_feature_replace_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_replace} +\unexpanded\def\font_feature_replace_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_replace} +\unexpanded\def\font_feature_replace_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_replace} -\let\doaddfeature \font_feature_add_nop % low level faster ones -\let\dosubtractfeature\font_feature_subtract_nop % low level faster ones -\let\doreplacefeature \font_feature_replace_nop % low level faster ones +\unexpanded\def\font_feature_reset_add_yes[#feature]{\edef\m_font_feature_asked{#feature}\font_feature_reset_add} +\unexpanded\def\font_feature_reset_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_reset_add} + +\let\doaddfeature \font_feature_add_nop % low level faster ones +\let\dosubtractfeature \font_feature_subtract_nop +\let\doreplacefeature \font_feature_replace_nop +\let\doreserandaddfeature\font_feature_reset_add_nop \unexpanded\def\font_feature_add {\ifnum\c_font_feature_state=\plusone @@ -225,39 +230,54 @@ \unexpanded\def\font_feature_revive_indeed {\ctxcommand{feature(true,"\m_font_feature_list")}} +\unexpanded\def\font_feature_reset_add + {\ifnum\c_font_feature_state=\plusone + \ifx\m_font_feature_asked\currentfeature\else + \font_feature_reset_add_indeed + \fi + \else + \font_feature_reset_add_indeed + \fi} + +\unexpanded\def\font_feature_reset_add_indeed + {\ctxcommand{feature("+","\s!current","\m_font_feature_asked")}% + \edef\m_font_feature_list{\s!current+\m_font_feature_asked}% also + at the lua end + \c_font_feature_state\plusone + \let\currentfeature\m_font_feature_asked} + \installcorenamespace{featureyes} \installcorenamespace{featurenop} \unexpanded\def\font_feature_yes[#method]{\csname\??featureyes\ifcsname\??featureyes#1\endcsname#1\else\s!unknown\fi\endcsname} \unexpanded\def\font_feature_nop #method{\csname\??featurenop\ifcsname\??featurenop#1\endcsname#1\else\s!unknown\fi\endcsname} -\letvalue{\??featureyes+}\addfeature -\letvalue{\??featurenop+}\addfeature - -\letvalue{\??featureyes\v!more}\addfeature -\letvalue{\??featurenop\v!more}\addfeature - -\letvalue{\??featureyes-}\subtractfeature -\letvalue{\??featurenop-}\subtractfeature - -\letvalue{\??featureyes\v!less}\subtractfeature -\letvalue{\??featurenop\v!less}\subtractfeature - -\letvalue{\??featureyes=}\replacefeature -\letvalue{\??featurenop=}\replacefeature - -\letvalue{\??featureyes\v!new}\replacefeature -\letvalue{\??featurenop\v!new}\replacefeature - -\letvalue{\??featureyes\v!reset}\resetfeature -\letvalue{\??featurenop\v!reset}\resetfeature - -\letvalue{\??featureyes\v!default}\revivefeature +\letvalue{\??featureyes +}\addfeature +\letvalue{\??featurenop +}\addfeature +\letvalue{\??featureyes -}\subtractfeature +\letvalue{\??featurenop -}\subtractfeature +\letvalue{\??featureyes =}\replacefeature +\letvalue{\??featurenop =}\replacefeature +\letvalue{\??featureyes !}\resetandaddfeature +\letvalue{\??featurenop !}\resetandaddfeature +\letvalue{\??featureyes >}\revivefeature +\letvalue{\??featurenop >}\revivefeature +\letvalue{\??featureyes <}\resetfeature +\letvalue{\??featurenop <}\resetfeature + +\letvalue{\??featureyes\v!more }\addfeature % add set to previous set and combine with font set +\letvalue{\??featurenop\v!more }\addfeature +\letvalue{\??featureyes\v!less }\subtractfeature % subtract set from previous set and combine with font set +\letvalue{\??featurenop\v!less }\subtractfeature +\letvalue{\??featureyes\v!new }\replacefeature % replace font set +\letvalue{\??featurenop\v!new }\replacefeature +\letvalue{\??featureyes\v!reset }\resetfeature % forget sets and revert to font set +\letvalue{\??featurenop\v!reset }\resetfeature +\letvalue{\??featureyes\v!default}\revivefeature % make sure the current set is used on top of the font set \letvalue{\??featurenop\v!default}\revivefeature - -\letvalue{\??featureyes\v!old}\revivefeature -\letvalue{\??featurenop\v!old}\revivefeature - +\letvalue{\??featureyes\v!old }\revivefeature +\letvalue{\??featurenop\v!old }\revivefeature +\letvalue{\??featureyes\v!local }\resetandaddfeature +\letvalue{\??featurenop\v!local }\resetandaddfeature \letvalue{\??featureyes\s!unknown}\empty \letvalue{\??featurenop\s!unknown}\empty diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua index d2562d08a..e6d2ed992 100644 --- a/tex/context/base/font-otd.lua +++ b/tex/context/base/font-otd.lua @@ -24,7 +24,9 @@ local constructors = fonts.constructors local specifiers = fonts.specifiers local fontdata = hashes.identifiers ------ fontresources = hashes.resources -- not yet defined +local fontresources = hashes.resources +local fontproperties = hashes.properties +local fontdynamics = hashes.dynamics local contextsetups = specifiers.contextsetups local contextnumbers = specifiers.contextnumbers @@ -38,24 +40,33 @@ local registerotffeature = otffeatures.register local fontdynamics = { } hashes.dynamics = fontdynamics -local a_to_script = { } -local a_to_language = { } - setmetatableindex(fontdynamics, function(t,font) local d = fontdata[font].shared.dynamics or false t[font] = d return d end) +local a_to_script = { } +local a_to_language = { } + +-- we can have a scripts hash in fonts.hashes + function otf.setdynamics(font,attribute) local features = contextsetups[contextnumbers[attribute]] -- can be moved to caller if features then local dynamics = fontdynamics[font] - local script = features.script or 'dflt' - local language = features.language or 'dflt' + dynamic = contextmerged[attribute] or 0 + local script, language + if dynamic == 2 then + language = features.language or fontproperties[font].language or "dflt" + script = features.script or fontproperties[font].script or "dflt" + else + language = features.language or "dflt" + script = features.script or "dflt" + end if script == "auto" then -- checkedscript and resources are defined later so we cannot shortcut them -- todo: make installer - script = definers.checkedscript(fontdata[font],hashes.resources[font],features) + script = definers.checkedscript(fontdata[font],fontresources[font],features) end local ds = dynamics[script] -- can be metatable magic (less testing) if not ds then @@ -72,7 +83,7 @@ function otf.setdynamics(font,attribute) local tfmdata = fontdata[font] a_to_script [attribute] = script a_to_language[attribute] = language - -- we need to save some values + -- we need to save some values .. quite messy local properties = tfmdata.properties local shared = tfmdata.shared local s_script = properties.script @@ -122,6 +133,8 @@ local resolved = { } -- we only resolve a font,script,language,attribute pair o local wildcard = "*" local default = "dflt" +-- what about analyze in local and not in font + local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic) local features = sequence.features if features then @@ -136,19 +149,20 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr if e_e then local languages = scripts[script] or scripts[wildcard] if languages then - local valid, what = false + -- local valid, what = false + local valid = false -- not languages[language] or languages[default] or languages[wildcard] because we want tracing -- only first attribute match check, so we assume simple fina's -- default can become a font feature itself if languages[language] then valid = e_e -- was true - what = language + -- what = language -- elseif languages[default] then -- valid = true -- what = default elseif languages[wildcard] then valid = e_e -- was true - what = wildcard + -- what = wildcard end if valid then local attribute = autofeatures[kind] or false @@ -163,8 +177,8 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr -- end if trace_applied then report_process( - "%s font %s, dynamic %s (%s), kind %a, script %a, language %a (%s), value %a, action %s, name %a", - font,attr or 0,dynamic,kind,script,language,what,valid,sequence.name) + "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a", + font,attr or 0,dynamic,kind,script,language,sequence.name,valid) end return { valid, attribute, sequence.chain or 0, kind, sequence } end @@ -185,6 +199,8 @@ end -- return v -- end) +-- there is some fuzzy language/script state stuff in properties (temporary) + function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in special parbuilder) local script, language, s_enabled, a_enabled, dynamic @@ -193,19 +209,22 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia dynamic = contextmerged[attr] or 0 local features = contextsetups[contextnumbers[attr]] -- could be a direct list -- local features = contextresolved[attr] - language = features.language or "dflt" - script = features.script or "dflt" a_enabled = features -- location based - -- if dynamic == 1 or dynamic == -2 then - -- s_enabled = tfmdata.shared.features -- font based - -- end - if dynamic == 2 then -- or dynamic == -2 then + if dynamic == 1 then -- or dynamic == -1 then + -- replace + language = features.language or "dflt" + script = features.script or "dflt" + elseif dynamic == 2 then -- or dynamic == -2 then -- merge + local properties = tfmdata.properties s_enabled = tfmdata.shared.features -- font based - -- elseif dynamic == 1 then -- or dynamic == -1 then - -- -- replace - -- else - -- -- error + language = features.language or properties.language or "dflt" + script = features.script or properties.script or "dflt" + else + -- error + local properties = tfmdata.properties + language = properties.language or "dflt" + script = properties.script or "dflt" end else local properties = tfmdata.properties diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua index 92ac3ad41..49ce887b4 100644 --- a/tex/context/base/luat-sto.lua +++ b/tex/context/base/luat-sto.lua @@ -100,17 +100,17 @@ function lua.collectgarbage(threshold) end end --- we also need to count at generation time (nicer for message) - ---~ if lua.bytecode then -- from 0 upwards ---~ local i, b = storage.min, lua.bytecode ---~ while b[i] do ---~ storage.noftables = i ---~ b[i]() ---~ b[i] = nil ---~ i = i + 1 ---~ end ---~ end +-- -- we also need to count at generation time (nicer for message) +-- +-- if lua.bytecode then -- from 0 upwards +-- local i, b = storage.min, lua.bytecode +-- while b[i] do +-- storage.noftables = i +-- b[i]() +-- b[i] = nil +-- i = i + 1 +-- end +-- end statistics.register("stored bytecode data", function() local nofmodules = (storage.nofmodules > 0 and storage.nofmodules) or (status.luabytecodes - lua.firstbytecode - 1) diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex a964404da..4a0cd3914 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex 39ea14a55..97231902e 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/util-lua.lua b/tex/context/base/util-lua.lua index cabcc3c9a..f3be9dcd2 100644 --- a/tex/context/base/util-lua.lua +++ b/tex/context/base/util-lua.lua @@ -63,10 +63,10 @@ if jit or status.luatex_version >= 74 then return true, 0 end else - report_lua("fatal error in file %a",luafile) + report_lua("fatal error %a in file %a",1,luafile) end else - report_lua("fatal error in file %a",luafile) + report_lua("fatal error %a in file %a",2,luafile) end return false, 0 end @@ -102,7 +102,7 @@ if jit or status.luatex_version >= 74 then if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then code = load(code) if not code then - report_lua("fatal error in file %a",name) + report_lua("fatal error %a in file %a",3,name) end register(name) code = dump(code,true) diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index bfc5d6232..f14aeae94 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 03/16/13 01:51:00 +-- merge date : 03/16/13 13:40:54 do -- begin closure to overcome local limits and interference |