Significantly improved image support
Except for te TeX interface, image inclusions are working (for PDF image at least, but everything else can be converted)
This commit is contained in:
parent
602bcb0583
commit
5c45cbc2e3
65
ltexpl.ltx
65
ltexpl.ltx
@ -1,65 +0,0 @@
|
||||
%%
|
||||
%% This is file `ltexpl.ltx',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% ltexpl.dtx (with options: `2ekernel')
|
||||
%%
|
||||
%% This is a generated file.
|
||||
%%
|
||||
%% The source is maintained by the LaTeX Project team and bug
|
||||
%% reports for it can be opened at https://latex-project.org/bugs.html
|
||||
%% (but please observe conditions on bug reports sent to that address!)
|
||||
%%
|
||||
%%
|
||||
%% Copyright (C) 1993-2019
|
||||
%% The LaTeX3 Project and any individual authors listed elsewhere
|
||||
%% in this file.
|
||||
%%
|
||||
%% This file was generated from file(s) of the LaTeX base system.
|
||||
%% --------------------------------------------------------------
|
||||
%%
|
||||
%% It may be distributed and/or modified under the
|
||||
%% conditions of the LaTeX Project Public License, either version 1.3c
|
||||
%% of this license or (at your option) any later version.
|
||||
%% The latest version of this license is in
|
||||
%% https://www.latex-project.org/lppl.txt
|
||||
%% and version 1.3c or later is part of all distributions of LaTeX
|
||||
%% version 2008 or later.
|
||||
%%
|
||||
%% This file has the LPPL maintenance status "maintained".
|
||||
%%
|
||||
%% This file may only be distributed together with a copy of the LaTeX
|
||||
%% base system. You may however distribute the LaTeX base system without
|
||||
%% such generated files.
|
||||
%%
|
||||
%% The list of all files belonging to the LaTeX base distribution is
|
||||
%% given in the file `manifest.txt'. See also `legal.txt' for additional
|
||||
%% information.
|
||||
%%
|
||||
%% The list of derived (unpacked) files belonging to the distribution
|
||||
%% and covered by LPPL is defined by the unpacking scripts (with
|
||||
%% extension .ins) which are part of the distribution.
|
||||
%%% From File: ltexpl.dtx
|
||||
\input luametalatex-baseregisters
|
||||
\IfFileExists{expl3.ltx}
|
||||
{%
|
||||
\ifnum0%
|
||||
\ifdefined\pdffilesize 1\fi
|
||||
\ifdefined\filesize 1\fi
|
||||
\ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi
|
||||
>0 %
|
||||
\else
|
||||
\message{Skipping expl3-dependent extensions}
|
||||
\expandafter\endinput
|
||||
\fi
|
||||
}
|
||||
{%
|
||||
\message{Skipping expl3-dependent extensions}%
|
||||
\endinput
|
||||
}%
|
||||
\input{expl3.ltx}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `ltexpl.ltx'.
|
@ -37,7 +37,6 @@ return function(name)
|
||||
local setter = tex["set" .. name]
|
||||
assert(getter and setter, "direction parameter undefined")
|
||||
local idx = token.luacmd(name, set_xdir, "protected", "global", "value")
|
||||
-- names[idx] = name
|
||||
getters[idx] = getter
|
||||
setters[idx] = setter
|
||||
return idx
|
||||
|
@ -136,6 +136,7 @@ end
|
||||
local basename = ((1-lpeg.S'\\/')^0*lpeg.S'\\/')^0*lpeg.C((1-lpeg.P'.tfm'*-1)^0)
|
||||
return function(name, size)
|
||||
local filename = kpse.find_file(name, 'tfm', true)
|
||||
if not filename then return end
|
||||
local f = io.open(filename)
|
||||
if not f then return end
|
||||
local buf = f:read'*a'
|
||||
|
@ -1,5 +1,5 @@
|
||||
do
|
||||
local ourpath = arg[0]:match('^%-%-lua=(.*)luametalatex%-init%.lua$')
|
||||
local ourpath = arg[0]:match('^%-%-lua=(.*[/\\])[^/\\]*%.lua$')
|
||||
kpse = assert(package.loadlib(ourpath .. 'kpse.so', 'luaopen_kpse'))()
|
||||
end
|
||||
do
|
||||
@ -35,6 +35,7 @@ local read_tfm = require'luametalatex-font-tfm'
|
||||
local read_vf = require'luametalatex-font-vf'
|
||||
font.read_tfm = read_tfm
|
||||
font.read_vf = read_vf
|
||||
local callback_register = callback.register
|
||||
require'module'
|
||||
font.fonts = {}
|
||||
function font.getfont(id)
|
||||
@ -51,7 +52,7 @@ function font.define(f)
|
||||
font.fonts[i] = f
|
||||
return i
|
||||
end
|
||||
callback.register('define_font', function(name, size)
|
||||
callback_register('define_font', function(name, size)
|
||||
local f = read_tfm(name, size)
|
||||
local id = font.define(f)
|
||||
if status.ini_version then
|
||||
@ -59,12 +60,26 @@ callback.register('define_font', function(name, size)
|
||||
end
|
||||
return id
|
||||
end)
|
||||
callback.register('find_log_file', function(name) return name end)
|
||||
-- callback.register('find_read_file', function(i, name) return kpse.find_file(name, 'tex', true) end)
|
||||
callback.register('find_data_file', function(name, ...) return kpse.find_file(name, 'tex', true) end)
|
||||
callback.register('read_data_file', function(name) error[[TODO]]return kpse.find_file(name, 'tex', true) end)
|
||||
callback_register('find_log_file', function(name) return name end)
|
||||
do
|
||||
local function normal_find_data_file(name)
|
||||
return kpse.find_file(name, 'tex', true)
|
||||
end
|
||||
if status.ini_version then
|
||||
callback_register('find_data_file', function(name)
|
||||
if name == 'ltexpl.ltx' then
|
||||
callback_register('find_data_file', normal_find_data_file)
|
||||
name = 'luametalatex-ltexpl-hook'
|
||||
end
|
||||
return normal_find_data_file(name)
|
||||
end)
|
||||
else
|
||||
callback_register('find_data_file', normal_find_data_file)
|
||||
end
|
||||
end
|
||||
callback_register('read_data_file', function(name) error[[TODO]]return kpse.find_file(name, 'tex', true) end)
|
||||
-- local file_meta = {\
|
||||
callback.register('open_data_file', function(name)
|
||||
callback_register('open_data_file', function(name)
|
||||
local f = io.open(name)
|
||||
return setmetatable({
|
||||
reader = function() return f:read() end,
|
||||
@ -73,13 +88,13 @@ callback.register('open_data_file', function(name)
|
||||
__gc = function()f:close()end,
|
||||
})
|
||||
end)
|
||||
callback.register('find_format_file', function(name) return kpse.find_file(name, 'fmt', true) end)
|
||||
callback.register('handle_error_hook', function()
|
||||
callback_register('find_format_file', function(name) return kpse.find_file(name, 'fmt', true) end)
|
||||
callback_register('handle_error_hook', function()
|
||||
repeat
|
||||
texio.write_nl'? '
|
||||
local line = io.read()
|
||||
if not line then
|
||||
error[[TODO: Handle EOL]]
|
||||
tex.fatalerror'End of line encountered on terminal'
|
||||
end
|
||||
if line == "" then return 3 end
|
||||
local first = line:sub(1,1):upper()
|
||||
@ -102,10 +117,9 @@ callback.register('handle_error_hook', function()
|
||||
\z H for help, X to quit.'
|
||||
end
|
||||
until false
|
||||
-- print('handle')
|
||||
return 3
|
||||
end)
|
||||
callback.register('pre_dump', function()
|
||||
callback_register('pre_dump', function()
|
||||
lua.prepared_code[1] = string.format("fixupluafunctions(%i)", fixupluafunctions())
|
||||
lua.bytecode[1] = assert(load(table.concat(lua.prepared_code, ' ')))
|
||||
end)
|
||||
|
@ -29,6 +29,7 @@ local getexpansion = direct.getexpansion
|
||||
local getchar = direct.getchar
|
||||
local rangedimensions = direct.rangedimensions
|
||||
local traverse_id = direct.traverse_id
|
||||
local getdata = direct.getdata
|
||||
|
||||
local dir_id = node.id'dir'
|
||||
|
||||
@ -97,8 +98,6 @@ local function totext(p, fid)
|
||||
p.font.font = f
|
||||
return false -- Return true if we need a new textmatrix
|
||||
end
|
||||
local inspect = require'inspect'
|
||||
local function show(t) print(inspect(t)) end
|
||||
function topage(p)
|
||||
local last = p.mode
|
||||
if last == page then return end
|
||||
@ -218,19 +217,31 @@ function nodehandler.vlist(p, list, x, y0, outerlist, origin, level)
|
||||
y = y - (d or 0)
|
||||
end
|
||||
end
|
||||
do
|
||||
local rulesubtypes = {}
|
||||
for i, n in next, node.subtypes'rule' do
|
||||
rulesubtypes[n] = i
|
||||
end
|
||||
local box_rule = rulesubtypes.box
|
||||
local image_rule = rulesubtypes.image
|
||||
local user_rule = rulesubtypes.user
|
||||
local empty_rule = rulesubtypes.empty
|
||||
local outline_rule = rulesubtypes.outline
|
||||
local ship_img = require'luametalatex-pdf-image'.ship
|
||||
function nodehandler.rule(p, n, x, y, outer)
|
||||
if getwidth(n) == -1073741824 then setwidth(n, getwidth(outer)) end
|
||||
if getheight(n) == -1073741824 then setheight(n, getheight(outer)) end
|
||||
if getdepth(n) == -1073741824 then setdepth(n, getdepth(outer)) end
|
||||
local sub = getsubtype(n)
|
||||
if sub == 1 then
|
||||
if sub == box_rule then
|
||||
error[[We can't handle boxes yet]]
|
||||
elseif sub == 2 then
|
||||
error[[We can't handle images yet]]
|
||||
elseif sub == 3 then
|
||||
elseif sub == 4 then
|
||||
elseif sub == image_rule then
|
||||
if getwidth(n) <= 0 or getdepth(n) + getheight(n) <= 0 then return end
|
||||
ship_img(getdata(n), p, n, x, y)
|
||||
elseif sub == empty_rule then
|
||||
elseif sub == user_rule then
|
||||
error[[We can't handle user rules yet]]
|
||||
elseif sub == 9 then
|
||||
elseif sub == outline_rule then
|
||||
error[[We can't handle outline rules yet]]
|
||||
else
|
||||
if getwidth(n) <= 0 or getdepth(n) + getheight(n) <= 0 then return end
|
||||
@ -238,6 +249,7 @@ function nodehandler.rule(p, n, x, y, outer)
|
||||
p.strings[#p.strings+1] = gsub(format("%f %f %f %f re f", sp2bp(x), sp2bp(y - getdepth(n)), sp2bp(getwidth(n)), sp2bp(getdepth(n) + getheight(n))), '%.?0+ ', ' ')
|
||||
end
|
||||
end
|
||||
end
|
||||
function nodehandler.boundary() end
|
||||
function nodehandler.disc(p, n, x, y, list, ...) -- FIXME: I am not sure why this can happen, let's assume we can use .replace
|
||||
for n in traverse(getreplace(n)) do
|
||||
|
@ -1,4 +1,9 @@
|
||||
local rawset = rawset
|
||||
local setdata = node.direct.setdata
|
||||
local nodenew = node.direct.new
|
||||
local getwhd = node.direct.getwhd
|
||||
local setwhd = node.direct.setwhd
|
||||
local tonode = node.direct.tonode
|
||||
|
||||
local reserve
|
||||
|
||||
@ -18,8 +23,8 @@ local boxmap = {
|
||||
}
|
||||
|
||||
-- FIXME:
|
||||
local function to_sp(bp) return bp*65536//1 end
|
||||
local function to_bp(sp) return sp/65536 end
|
||||
local function to_sp(bp) return bp*65781.76//1 end
|
||||
local function to_bp(sp) return sp/65781.76 end
|
||||
|
||||
local function get_box(page, box)
|
||||
box = boxmap[box]
|
||||
@ -63,16 +68,12 @@ local function scan_pdf(img)
|
||||
local page = pdfe.getpage(file, img.page)
|
||||
local bbox = img.bbox or get_box(page, img.pagebox or 'crop') or {0, 0, 0, 0}
|
||||
img.bbox = bbox
|
||||
img.rotation = (page.Rotation or 0) % 360
|
||||
if img.rotation < 0 then img.rotation = img.rotation + 360 end
|
||||
if img.rotation % 2 == 0 then
|
||||
img.rotation = (360 - (page.Rotate or 0)) % 360
|
||||
assert(img.rotation % 90 == 0, "Invalid /Rotate")
|
||||
img.rotation = img.rotation / 90
|
||||
if img.rotation < 0 then img.rotation = img.rotation + 4 end
|
||||
img.xsize = bbox[3] - bbox[1]
|
||||
img.ysize = bbox[4] - bbox[2]
|
||||
else
|
||||
img.xsize = bbox[4] - bbox[2]
|
||||
img.ysize = bbox[3] - bbox[1]
|
||||
end
|
||||
img.transform = img.transform or 0
|
||||
end
|
||||
|
||||
local pdfe_deepcopy = require'luametalatex-pdfe-deepcopy'
|
||||
@ -151,11 +152,12 @@ local function scan(img)
|
||||
scan_pdf(real)
|
||||
setmetatable(img, restricted_meta)
|
||||
end
|
||||
img.transform = img.transform or 0
|
||||
-- (Re)Set dimensions
|
||||
if img.depth and img.height and img.width then
|
||||
return img
|
||||
end
|
||||
local flipped = img.transform % 2 == 1
|
||||
local flipped = (img.transform + real.rotation) % 2 == 1
|
||||
if not (img.depth or img.height) then img.depth = 0 end
|
||||
if not img.width and not (img.height and img.depth) then
|
||||
local total_y
|
||||
@ -186,42 +188,76 @@ local function scan(img)
|
||||
return img
|
||||
end
|
||||
|
||||
local img_by_objnum = {}
|
||||
local function img_from_objnum(objnum, img)
|
||||
img = img or {}
|
||||
real_images[img] = assert(img_by_objnum[objnum])
|
||||
return setmetatable(img, restricted_meta)
|
||||
end
|
||||
|
||||
-- Noop if already reserved
|
||||
function reserve(img, pfile)
|
||||
local real = assert(real_images[img])
|
||||
local obj = real.objnum or pfile:getobj()
|
||||
real.objnum = obj
|
||||
return img, obj
|
||||
img_by_objnum[obj] = real
|
||||
return obj
|
||||
end
|
||||
|
||||
local function write_img(pfile, img)
|
||||
local _, objnum = reserve(img, pfile)
|
||||
local objnum = reserve(img, pfile)
|
||||
local real = real_images[img]
|
||||
if not real.written then
|
||||
real.written = true
|
||||
write_pdf(real, pfile)
|
||||
end
|
||||
end
|
||||
local function do_img(prop, p, n, x, y, outer)
|
||||
local img = prop.img
|
||||
img.height, img.depth, img.width = prop.height, prop.depth, prop.width
|
||||
scan(img)
|
||||
local function do_img(data, p, n, x, y)
|
||||
local img = {}
|
||||
img_from_objnum(data >> 3, img)
|
||||
-- scan(img)
|
||||
write_img(p.file, img)
|
||||
local real = real_images[img]
|
||||
local total_height = img.height + img.depth
|
||||
local mirror = data & 4 == 4
|
||||
local rotate = (data + img.rotation) % 8
|
||||
local width, height, depth = getwhd(n)
|
||||
height = height + depth
|
||||
local bbox = real.bbox
|
||||
x, y = to_bp(x - bbox[1]), to_bp(y - img.depth + bbox[2])
|
||||
local xsize, ysize = img.xsize, img.ysize
|
||||
local a, b, c, d, e, f = 1, 0, 0, 1, -bbox[1], -bbox[2]
|
||||
if mirror then
|
||||
a, e = -a, -e+xsize
|
||||
end
|
||||
print(img.rotation, rotate, data, a, b, c, d, e, f)
|
||||
for i=1,rotate do
|
||||
a, b, c, d, e, f = -b, a, -d, c, -f+ysize, e
|
||||
xsize, ysize = ysize, xsize
|
||||
end
|
||||
print(a, b, c, d, e, f)
|
||||
local xscale, yscale = width / xsize, height / ysize
|
||||
a, c, e = a*xscale, c*xscale, e*xscale
|
||||
b, d, f = b*yscale, d*yscale, f*yscale
|
||||
e, f = to_bp(x + e), to_bp(y - depth + f)
|
||||
p.resources.XObject['Im' .. tostring(real.objnum)] = real.objnum
|
||||
pdf.write('page', string.format('q 1 0 0 1 %f %f cm /Im%i Do Q', x, y, real.objnum), nil, nil, p)
|
||||
pdf.write('page', string.format('q %f %f %f %f %f %f cm /Im%i Do Q', a, b, c, d, e, f, real.objnum), nil, nil, p)
|
||||
end
|
||||
local ruleid = node.id'rule'
|
||||
local ruletypes = node.subtypes'rule'
|
||||
local imagerule
|
||||
for n, name in next, ruletypes do
|
||||
if name == 'image' then
|
||||
imagerule = n
|
||||
break
|
||||
end
|
||||
end
|
||||
assert(imagerule)
|
||||
local function node(img, pfile)
|
||||
pfile = pfile or pdf.__get_pfile()
|
||||
local n = _ENV.node.new('whatsit', 42) -- image
|
||||
_ENV.node.setproperty(n, {
|
||||
handle = do_img,
|
||||
img = img,
|
||||
})
|
||||
return n
|
||||
scan(img)
|
||||
local n = nodenew(ruleid, imagerule) -- image
|
||||
setdata(n, (reserve(img, pfile) << 3) | ((img.transform or 0) & 7))
|
||||
setwhd(n, img.width or -0x40000000, img.height or -0x40000000, img.depth or -0x40000000)
|
||||
return tonode(n)
|
||||
end
|
||||
|
||||
--[[
|
||||
@ -237,4 +273,5 @@ return {
|
||||
scan = scan,
|
||||
write = write,
|
||||
node = node,
|
||||
ship = do_img,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user