pdfvariable handling

This commit is contained in:
Marcel Krüger 2020-06-30 15:14:24 +02:00
parent 01bc7c0f77
commit b506fd4357
3 changed files with 74 additions and 16 deletions

View File

@ -324,14 +324,15 @@ local function do_dest(prop, p, n, x, y)
assert(cur_page, "Destinations can not appear outside of a page") assert(cur_page, "Destinations can not appear outside of a page")
local id = prop.dest_id local id = prop.dest_id
local dest_type = prop.dest_type local dest_type = prop.dest_type
local off = pdfvariable.linkmargin
local data local data
if dest_type == "xyz" then if dest_type == "xyz" then
local x, y = projected(p.matrix, x, y) local x, y = projected(p.matrix, x, y)
local zoom = prop.xyz_zoom local zoom = prop.xyz_zoom
if zoom then if zoom then
data = string.format("[%i 0 R/XYZ %.5f %.5f %.3f]", cur_page, sp2bp(x), sp2bp(y), prop.zoom/1000) data = string.format("[%i 0 R/XYZ %.5f %.5f %.3f]", cur_page, sp2bp(x-off), sp2bp(y+off), prop.zoom/1000)
else else
data = string.format("[%i 0 R/XYZ %.5f %.5f null]", cur_page, sp2bp(x), sp2bp(y)) data = string.format("[%i 0 R/XYZ %.5f %.5f null]", cur_page, sp2bp(x-off), sp2bp(y+off))
end end
elseif dest_type == "fitr" then elseif dest_type == "fitr" then
local m = p.matrix local m = p.matrix
@ -341,23 +342,23 @@ local function do_dest(prop, p, n, x, y)
local urx, ury = projected(x+prop.width, x + prop.height) local urx, ury = projected(x+prop.width, x + prop.height)
local left, lower, right, upper = math.min(llx, lrx, ulx, urx), math.min(lly, lry, uly, ury), local left, lower, right, upper = math.min(llx, lrx, ulx, urx), math.min(lly, lry, uly, ury),
math.max(llx, lrx, ulx, urx), math.max(lly, lry, uly, ury) math.max(llx, lrx, ulx, urx), math.max(lly, lry, uly, ury)
data = string.format("[%i 0 R/FitR %.5f %.5f %.5f %.5f]", cur_page, sp2bp(left), sp2bp(lower), sp2bp(right), sp2bp(upper)) data = string.format("[%i 0 R/FitR %.5f %.5f %.5f %.5f]", cur_page, sp2bp(left-off), sp2bp(lower-off), sp2bp(right+off), sp2bp(upper+off))
elseif dest_type == "fit" then elseif dest_type == "fit" then
data = string.format("[%i 0 R/Fit]", cur_page) data = string.format("[%i 0 R/Fit]", cur_page)
elseif dest_type == "fith" then elseif dest_type == "fith" then
local x, y = projected(p.matrix, x, y) local x, y = projected(p.matrix, x, y)
data = string.format("[%i 0 R/FitH %.5f]", cur_page, sp2bp(y)) data = string.format("[%i 0 R/FitH %.5f]", cur_page, sp2bp(y+off))
elseif dest_type == "fitv" then elseif dest_type == "fitv" then
local x, y = projected(p.matrix, x, y) local x, y = projected(p.matrix, x, y)
data = string.format("[%i 0 R/FitV %.5f]", cur_page, sp2bp(x)) data = string.format("[%i 0 R/FitV %.5f]", cur_page, sp2bp(x-off))
elseif dest_type == "fitb" then elseif dest_type == "fitb" then
data = string.format("[%i 0 R/FitB]", cur_page) data = string.format("[%i 0 R/FitB]", cur_page)
elseif dest_type == "fitbh" then elseif dest_type == "fitbh" then
local x, y = projected(p.matrix, x, y) local x, y = projected(p.matrix, x, y)
data = string.format("[%i 0 R/FitBH %.5f]", cur_page, sp2bp(y)) data = string.format("[%i 0 R/FitBH %.5f]", cur_page, sp2bp(y+off))
elseif dest_type == "fitbv" then elseif dest_type == "fitbv" then
local x, y = projected(p.matrix, x, y) local x, y = projected(p.matrix, x, y)
data = string.format("[%i 0 R/FitBV %.5f]", cur_page, sp2bp(x)) data = string.format("[%i 0 R/FitBV %.5f]", cur_page, sp2bp(x-off))
end end
if pfile:written(dests[id]) then if pfile:written(dests[id]) then
texio.write_nl(string.format("Duplicate destination %q", id)) texio.write_nl(string.format("Duplicate destination %q", id))

View File

@ -11,7 +11,8 @@ local texmeta = getmetatable(tex)
local texmetaoldindex = texmeta.__index local texmetaoldindex = texmeta.__index
local texmetaoldnewindex = texmeta.__newindex local texmetaoldnewindex = texmeta.__newindex
local tex_variables = {} local tex_variables = __luametalatex__preserved_tex_variables or {}
__luametalatex__preserved_tex_variables = nil
function texmeta.__index(t, k) function texmeta.__index(t, k)
return tex_variables[k] or texmetaoldindex(t, k) return tex_variables[k] or texmetaoldindex(t, k)
@ -33,10 +34,14 @@ local function tex_variable(value, scanner, name, default)
return set_local(tex_variables, name, scanner(), scanning == 'global') return set_local(tex_variables, name, scanner(), scanning == 'global')
end end
end, 'global', 'protected', 'value') end, 'global', 'protected', 'value')
tex_variables[name] = default if status.ini_version then
tex_variables[name] = default
end
end end
local real_pdf_variables, pdf_variable_names = {}, {} local real_pdf_variables = __luametalatex__preserved_real_pdf_variables or {}
__luametalatex__preserved_real_pdf_variables = nil
local pdf_variable_names = {}
local pdf_toks_map = {} local pdf_toks_map = {}
local pdf_variables = setmetatable(pdf.variable, { local pdf_variables = setmetatable(pdf.variable, {
__index = function(_, k) __index = function(_, k)
@ -88,17 +93,26 @@ else
end end
end end
local function pdf_variable(value, scanner, name, default) local function pdf_variable(value, scanner, name, default, force_default)
pdf_variable_names[#pdf_variable_names+1] = name pdf_variable_names[#pdf_variable_names+1] = name
token.luacmd('pdfvariable ' .. name, function(_, scanning) token.luacmd('pdfvariable ' .. name, function(_, scanning)
if scanning == 'value' then if scanning == 'value' then
return value, real_pdf_variables[name] return value, real_pdf_variables[name]
elseif force_default then
token.scan_keyword'='
local new = scanner()
if new ~= default then
texio.write_nl('term and log', string.format("Unsupported PDF variable: \z
%q is not supported and fixed to %i, but you tried to set it to %i", name, default, new))
end
else else
token.scan_keyword'=' token.scan_keyword'='
return set_local(real_pdf_variables, name, scanner(), scanning == 'global') return set_local(real_pdf_variables, name, scanner(), scanning == 'global')
end end
end, 'global', 'protected', 'value') end, 'global', 'protected', 'value')
real_pdf_variables[name] = default if status.ini_version then
real_pdf_variables[name] = default
end
end end
tex_variable(count_code, token.scan_int, 'suppressfontnotfounderror', 0) tex_variable(count_code, token.scan_int, 'suppressfontnotfounderror', 0)
@ -113,10 +127,30 @@ tex_variable(count_code, token.scan_int, 'pagedirection', 0)
pdf_variable(dimen_code, token.scan_dimen, 'horigin', tex.sp'1in') pdf_variable(dimen_code, token.scan_dimen, 'horigin', tex.sp'1in')
pdf_variable(dimen_code, token.scan_dimen, 'vorigin', tex.sp'1in') pdf_variable(dimen_code, token.scan_dimen, 'vorigin', tex.sp'1in')
pdf_variable(dimen_code, token.scan_dimen, 'linkmargin', tex.sp'0pt') pdf_variable(dimen_code, token.scan_dimen, 'linkmargin', tex.sp'0pt')
pdf_variable(dimen_code, token.scan_dimen, 'destmargin', tex.sp'0pt')
pdf_variable(count_code, token.scan_int, 'majorversion', 1) pdf_variable(count_code, token.scan_int, 'majorversion', 1)
pdf_variable(count_code, token.scan_int, 'minorversion', 7) pdf_variable(count_code, token.scan_int, 'minorversion', 7)
pdf_variable(count_code, token.scan_int, 'compresslevel', 0) pdf_variable(count_code, token.scan_int, 'compresslevel', 0)
pdf_variable(count_code, token.scan_int, 'objcompresslevel', 0) -- 0 is actually the only supported value right now, so this is basically ignored
pdf_variable(count_code, token.scan_int, 'objcompresslevel', 0, true) -- TODO ... not particularly urgent
pdf_variable(count_code, token.scan_int, 'decimaldigits', 4, true) -- Will probably stay fixed, but should be more consistent
pdf_variable(count_code, token.scan_int, 'gentounicode', 0, true) -- We expect the fontloader to generade tounicode tables. Might change at some point
-- These two are ignored, but that is consistent with pdfTeX as long as imageapplygamma is 0:
pdf_variable(count_code, token.scan_int, 'gamma', 1000)
pdf_variable(count_code, token.scan_int, 'imagegamma', 1000)
pdf_variable(count_code, token.scan_int, 'imageapplygamma', 0, true)
pdf_variable(count_code, token.scan_int, 'imagehicolor', 1, true) -- We don't consider ancient PDF versions, no no reason to strip images
pdf_variable(count_code, token.scan_int, 'imageaddfilename', 0, true) -- Could be added, but I never saw a reason for this anyway.
pdf_variable(count_code, token.scan_int, 'inclusionerrorlevel', -1, true) -- FIXME: At least a warning should be supported
pdf_variable(count_code, token.scan_int, 'inclusioncopyfonts', 0, true) -- Would be fragile and restrict our ability to use "creative" font constructs
pdf_variable(count_code, token.scan_int, 'uniqueresname', 0, true) -- I add this if you show me a usecase
pdf_variable(count_code, token.scan_int, 'pagebox', 2, true) -- TODO (1: media, 2: crop, 3: bleed, 4: trim, 5: art
pdf_variable(count_code, token.scan_int, 'forcepagebox', 0, true) -- Considered obsolete even in pdfTeX
pdf_variable(count_code, token.scan_int, 'imageresolution', 72, true) -- TODO Also 0 should be the same as 72 ?!?!?!?
-- The following two relate to pk fonts which we don't support, so they are ignored on a different level
pdf_variable(count_code, token.scan_int, 'pkresolution', 72)
-- pdf_variable(toks_code, token.scan_string, 'pkmode', '')
pdf_toks('pageresources', '') pdf_toks('pageresources', '')
@ -128,3 +162,20 @@ local dir_regs = require 'luametalatex-dir-registers'
dir_regs 'textdir' dir_regs 'textdir'
dir_regs 'bodydir' dir_regs 'bodydir'
dir_regs 'pagedir' dir_regs 'pagedir'
if status.ini_version then
-- Run in pre_dump callback:
lua.prepared_code[#lua.prepared_code+1] = function()
local settings = " "
for k,v in next, {__luametalatex__preserved_tex_variables = tex_variables,
__luametalatex__preserved_real_pdf_variables = real_pdf_variables,} do
local entries = {}
for kk,vv in next, v do
-- entries[#entries+1] = string.format("[%q=%i],", kk, vv) -- If we ever get more compicated names here
entries[#entries+1] = string.format("%s=%i,", kk, vv)
end
settings = string.format("%s%s={%s}", settings, k, table.concat(entries))
end
return settings
end
end

View File

@ -119,7 +119,8 @@ callback_register('handle_error_hook', function()
return 3 return 3
end) end)
callback_register('pre_dump', function() callback_register('pre_dump', function()
lua.prepared_code[1] = string.format("fixupluafunctions(%i)", fixupluafunctions()) local prepared = lua.prepared_code
prepared[1] = string.format("fixupluafunctions(%i)", fixupluafunctions())
for i=0,0 do -- maybeFIXME: In practise only one language is preloaded in LuaTeX anyway for i=0,0 do -- maybeFIXME: In practise only one language is preloaded in LuaTeX anyway
-- for i=0,tex.count[19] do -- Sometimes catches reserved language ids which are not used yet -- for i=0,tex.count[19] do -- Sometimes catches reserved language ids which are not used yet
-- for i=0,lang.new():id()-1 do -- lang.new():id() is always 0 in luametatex?!? -- for i=0,lang.new():id()-1 do -- lang.new():id() is always 0 in luametatex?!?
@ -148,9 +149,14 @@ callback_register('pre_dump', function()
else else
str = str .. 'end' str = str .. 'end'
end end
lua.prepared_code[#lua.prepared_code+1] = str prepared[#prepared+1] = str
end end
lua.bytecode[1] = assert(load(table.concat(lua.prepared_code, ' '))) for i=2,#prepared do
if type(prepared[i]) ~= 'string' then
prepared[i] = assert(prepared[i]())
end
end
lua.bytecode[1] = assert(load(table.concat(prepared, ' ')))
end) end)
function texconfig.init() function texconfig.init()
lua.bytecode[2]() lua.bytecode[2]()