diff options
author | Karl Berry <karl@freefriends.org> | 2009-06-23 00:14:43 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-06-23 00:14:43 +0000 |
commit | b3e52d29b04fed8c4f0a8695fbca2b113a36d4ad (patch) | |
tree | ec05ec4e73895011aa3a6e0e8ab038684e03baf9 /Master/texmf-dist/tex/luatex/luamplib | |
parent | aca03c9b6823255ebc3b94d81160eb3c6d85e80d (diff) |
new luatex package luamplib
git-svn-id: svn://tug.org/texlive/trunk@13901 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luamplib')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luamplib/luamplib-createmem.lua | 55 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luamplib/luamplib.lua | 446 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luamplib/luamplib.sty | 173 |
3 files changed, 674 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib-createmem.lua b/Master/texmf-dist/tex/luatex/luamplib/luamplib-createmem.lua new file mode 100644 index 00000000000..7d3d611110c --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib-createmem.lua @@ -0,0 +1,55 @@ +-- +-- This is file `luamplib-createmem.lua', +-- generated with the docstrip utility. +-- +-- The original source files were: +-- +-- luamplib.dtx (with options: `gen-lua') +-- This is a generated file. +-- +-- Copyright (C) 2008-2009 by Hans Hagen, Taco Hoekwater and Elie Roux +-- <elie.roux@telecom-bretagne.eu>. +-- +-- This work is under the CC0 license. +-- +-- This Current Maintainer of this work is Elie Roux. +-- +-- This work consists of the main source file luamplib.dtx +-- and the derived files +-- luamplib.sty, luamplib.lua, luamplib-createmem.lua and luamplib.pdf. +-- + +kpse.set_program_name("kpsewhich") + +function finder (name, mode, ftype) + if mode == "w" then + return name + else + local result = kpse.find_file(name,ftype) + return result + end +end + +local preamble = [[ +input %s ; dump ; +]] + + +makeformat = function (name, mem_name) + local mpx = mplib.new { + ini_version = true, + find_file = finder, + job_name = mem_name, + } + if mpx then + local result + result = mpx:execute(string.format(preamble,name)) + print(string.format("dumping format %s in %s", name, mem_name)) + mpx:finish() + end +end + +makeformat("plain", "luatex-plain.mem") + +-- +-- End of File `luamplib-createmem.lua'. diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua new file mode 100644 index 00000000000..632c4140c45 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua @@ -0,0 +1,446 @@ +-- +-- This is file `luamplib.lua', +-- generated with the docstrip utility. +-- +-- The original source files were: +-- +-- luamplib.dtx (with options: `lua') +-- This is a generated file. +-- +-- Copyright (C) 2008-2009 by Hans Hagen, Taco Hoekwater and Elie Roux +-- <elie.roux@telecom-bretagne.eu>. +-- +-- This work is under the CC0 license. +-- +-- This Current Maintainer of this work is Elie Roux. +-- +-- This work consists of the main source file luamplib.dtx +-- and the derived files +-- luamplib.sty, luamplib.lua, luamplib-createmem.lua and luamplib.pdf. +-- + +luamplib = { } + +luamplib.module = { + name = "luamplib", + version = 1.01, + date = "2009/03/09", + description = "Lua functions to typeset Metapost directly with MPLib.", + author = "Hans Hagen, Taco Hoekwater & Elie Roux", + copyright = "ConTeXt Development Team & Elie Roux", + license = "CC0", +} + +luatextra.provides_module(luamplib.module) + + +local format, concat, abs = string.format, table.concat, math.abs + + +luamplib.currentformat = "plain" +luamplib.currentmem = "luatex-plain.mem" + +local currentformat = luamplib.currentformat +local currentmem = luamplib.currentmem + +function luamplib.setformat (name) + luamplib.currentformat = name +end + +function luamplib.setmemfile(name) + luamplib.currentmem = name +end + + +luamplib.finder = luamplib.finder or function(name, mode, ftype) + if mode == "w" then + return name + else + local result + if ftype == 'mem' then + local envsave = os.getenv('engine') + os.setenv('engine', 'metapost') + result = kpse.find_file(name,ftype) + os.setenv('engine', envsave) + else + result = kpse.find_file(name,ftype) + end + return result + end +end + +function luamplib.info (...) + luatextra.module_info('luamplib', format(...)) +end + +function luamplib.log (...) + luatextra.module_log('luamplib', format(...)) +end + +function luamplib.term (...) + luatextra.module_term('luamplib', format(...)) +end + +function luamplib.warning (...) + luatextra.module_warning('luamplib', format(...)) +end + +function luamplib.error (...) + luatextra.module_error('luamplib', format(...)) +end + + +luamplib.data = "" + +function luamplib.resetdata() + luamplib.data = "" +end + +function luamplib.addline(line) + luamplib.data = luamplib.data .. '\n' .. line +end + +function luamplib.processlines() + luamplib.process(luamplib.data) + luamplib.resetdata() +end + + +function luamplib.load() + local mpx = mplib.new { + ini_version = false, + mem_name = currentmem, + find_file = luamplib.finder + } + if mpx then + luamplib.log("using mem file %s", luamplib.finder(currentmem, 'r', 'mem')) + return mpx, nil + else + return nil, { status = 99, error = "out of memory or invalid format" } + end +end + + +function luamplib.report(result) + if not result then + luamplib.error("no result object") + elseif result.status > 0 then + local t, e, l, f = result.term, result.error, result.log + if l then + luamplib.log(l) + end + if t then + luamplib.term(t) + end + if e then + if result.status == 1 then + luamplib.warning(e) + else + luamplib.error(e) + end + end + if not t and not e and not l then + if result.status == 1 then + luamplib.warning("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") + else + luamplib.error("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") + end + end + else + return true + end + return false +end + +function luamplib.process(data) + local converted, result = false, {} + local mpx = luamplib.load() + if mpx and data then + local result = mpx:execute(data) + if luamplib.report(result) then + if result.fig then + converted = luamplib.convert(result) + else + luamplib.warning("no figure output") + end + end + else + luamplib.error("Mem file unloadable. Maybe generated with a different version of mplib?") + end + return converted, result +end + +local function getobjects(result,figure,f) + return figure:objects() +end + +function luamplib.convert(result, flusher) + luamplib.flush(result, flusher) + return true -- done +end + +local function pdf_startfigure(n,llx,lly,urx,ury) + tex.sprint(format("\\mplibstarttoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) +end + +local function pdf_stopfigure() + tex.sprint("\\mplibstoptoPDF") +end + +function pdf_literalcode(fmt,...) -- table + tex.sprint(format("\\mplibtoPDF{%s}",format(fmt,...))) +end + +function pdf_textfigure(font,size,text,width,height,depth) + text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost + tex.sprint(format("\\mplibtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth)) +end + +local bend_tolerance = 131/65536 + +local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 + +local function pen_characteristics(object) + if luamplib.pen_info then + local t = luamplib.pen_info(object) + rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty + divider = sx*sy - rx*ry + return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width + else + rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 + return false, 1 + end +end + +local function concat(px, py) -- no tx, ty here + return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider +end + +local function curved(ith,pth) + local d = pth.left_x - ith.right_x + if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then + d = pth.left_y - ith.right_y + if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then + return false + end + end + return true +end + +local function flushnormalpath(path,open) + local pth, ith + for i=1,#path do + pth = path[i] + if not ith then + pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord) + elseif curved(ith,pth) then + pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) + else + pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord) + end + ith = pth + end + if not open then + local one = path[1] + if curved(pth,one) then + pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) + else + pdf_literalcode("%f %f l",one.x_coord,one.y_coord) + end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + pdf_literalcode("%f %f l",one.x_coord,one.y_coord) + end + return t +end + +local function flushconcatpath(path,open) + pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty) + local pth, ith + for i=1,#path do + pth = path[i] + if not ith then + pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord)) + elseif curved(ith,pth) then + local a, b = concat(ith.right_x,ith.right_y) + local c, d = concat(pth.left_x,pth.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) + else + pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord)) + end + ith = pth + end + if not open then + local one = path[1] + if curved(pth,one) then + local a, b = concat(pth.right_x,pth.right_y) + local c, d = concat(one.left_x,one.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) + else + pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + end + return t +end + + +function luamplib.flush(result,flusher) + if result then + local figures = result.fig + if figures then + for f=1, #figures do + luamplib.info("flushing figure %s",f) + local figure = figures[f] + local objects = getobjects(result,figure,f) + local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0) + local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + local bbox = figure:boundingbox() + local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack + if urx < llx then + -- invalid + pdf_startfigure(fignum,0,0,0,0) + pdf_stopfigure() + else + pdf_startfigure(fignum,llx,lly,urx,ury) + pdf_literalcode("q") + if objects then + for o=1,#objects do + local object = objects[o] + local objecttype = object.type + if objecttype == "start_bounds" or objecttype == "stop_bounds" then + -- skip + elseif objecttype == "start_clip" then + pdf_literalcode("q") + flushnormalpath(object.path,t,false) + pdf_literalcode("W n") + elseif objecttype == "stop_clip" then + pdf_literalcode("Q") + miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + elseif objecttype == "special" then + -- not supported + elseif objecttype == "text" then + local ot = object.transform -- 3,4,5,6,1,2 + pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) + pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + pdf_literalcode("Q") + else + local cs = object.color + if cs and #cs > 0 then + pdf_literalcode(luamplib.colorconverter(cs)) + end + local ml = object.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + pdf_literalcode("%f M",ml) + end + local lj = object.linejoin + if lj and lj ~= linejoin then + linejoin = lj + pdf_literalcode("%i j",lj) + end + local lc = object.linecap + if lc and lc ~= linecap then + linecap = lc + pdf_literalcode("%i J",lc) + end + local dl = object.dash + if dl then + local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + pdf_literalcode(dashed) + end + elseif dashed then + pdf_literalcode("[] 0 d") + dashed = false + end + local path = object.path + local transformed, penwidth = false, 1 + local open = path and path[1].left_type and path[#path].right_type + local pen = object.pen + if pen then + if pen.type == 'elliptical' then + transformed, penwidth = pen_characteristics(object) -- boolean, value + pdf_literalcode("%f w",penwidth) + if objecttype == 'fill' then + objecttype = 'both' + end + else -- calculated by mplib itself + objecttype = 'fill' + end + end + if transformed then + pdf_literalcode("q") + end + if path then + if transformed then + flushconcatpath(path,open) + else + flushnormalpath(path,open) + end + if objecttype == "fill" then + pdf_literalcode("h f") + elseif objecttype == "outline" then + pdf_literalcode((open and "S") or "h S") + elseif objecttype == "both" then + pdf_literalcode("h B") + end + end + if transformed then + pdf_literalcode("Q") + end + local path = object.htap + if path then + if transformed then + pdf_literalcode("q") + end + if transformed then + flushconcatpath(path,open) + else + flushnormalpath(path,open) + end + if objecttype == "fill" then + pdf_literalcode("h f") + elseif objecttype == "outline" then + pdf_literalcode((open and "S") or "h S") + elseif objecttype == "both" then + pdf_literalcode("h B") + end + if transformed then + pdf_literalcode("Q") + end + end + if cr then + pdf_literalcode(cr) + end + end + end + end + pdf_literalcode("Q") + pdf_stopfigure() + end + end + end + end +end + +function luamplib.colorconverter(cr) + local n = #cr + if n == 4 then + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + else + local s = cr[1] + return format("%.3f g %.3f G",s,s), "0 g 0 G" + end +end +-- +-- End of File `luamplib.lua'. diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty new file mode 100644 index 00000000000..8d87e2b598f --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty @@ -0,0 +1,173 @@ +%% +%% This is file `luamplib.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% luamplib.dtx (with options: `package') +%% This is a generated file. +%% +%% Copyright (C) 2008-2009 by Hans Hagen, Taco Hoekwater and Elie Roux +%% <elie.roux@telecom-bretagne.eu>. +%% +%% This work is under the CC0 license. +%% +%% This Current Maintainer of this work is Elie Roux. +%% +%% This work consists of the main source file luamplib.dtx +%% and the derived files +%% luamplib.sty, luamplib.lua, luamplib-createmem.lua and luamplib.pdf. +%% + +\expandafter\ifx\csname ProvidesPackage\endcsname\relax + \input luatextra.sty +\else + \NeedsTeXFormat{LaTeX2e} + \ProvidesPackage{luamplib} + [2009/03/09 v1.01 mplib package for LuaTeX.] + \RequirePackage{luatextra} + \RequirePackage{fancyvrb} +\fi + + +\luaUseModule{luamplib} + + +\def\mplibsetformat#1{\directlua0{luamplib.setformat([[#1]])}} + +\def\mplibsetmemfile#1{\directlua0{luamplib.setmemfile([[#1]])}} + + +\ifnum\pdfoutput>0 + \let\mplibtoPDF\pdfliteral +\else + %\def\MPLIBtoPDF#1{\special{pdf:literal direct #1}} % not ok yet + \def\mplibtoPDF#1{} + \expandafter\ifx\csname PackageWarning\endcsname\relax + \write16{} + \write16{Warning: MPLib only works in PDF mode, no figure will be output.} + \write16{} + \else + \PackageWarning{mplib}{MPLib only works in PDF mode, no figure will be output.} + \fi +\fi + + +\expandafter\ifx\csname ProvidesPackage\endcsname\relax + +\def\mplibsetupcatcodes{ + \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 + \catcode`\_=12 \catcode`\%=12 \catcode`\&=12 \catcode`\$=12 +} + +\def\mplibcode{% + \bgroup % + \mplibsetupcatcodes % + \mplibdocode % +} + +\long\def\mplibdocode#1\endmplibcode{% + \egroup % + \mplibprocess{#1}% +} + +\long\def\mplibprocess#1{% + \luadirect{luamplib.process([[#1]])}% +} + +\else + + +\makeatletter +\begingroup +\catcode`\,=13 +\catcode`\-=13 +\gdef\FV@hack{% + \def,{\string,}% + \def-{\string-}% +} +\endgroup + + +\newcommand\mplibaddlines[1]{% + \begingroup % + \FV@hack % + \def\FV@ProcessLine##1{% + \luadirect{luamplib.addline([[##1]])}% + }% + \csname FV@SV@#1\endcsname % + \endgroup % +} + +\makeatother + + +\newenvironment{mplibcode}{% + \VerbatimEnvironment % + \begin{SaveVerbatim}{memoire}% +}{% + \end{SaveVerbatim}% + \mplibaddlines{memoire}% + \luadirect{luamplib.processlines()}% +} + +\fi + + +\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi + + +\def\mplibstarttoPDF#1#2#3#4{ + \hbox\bgroup + \xdef\MPllx{#1}\xdef\MPlly{#2}% + \xdef\MPurx{#3}\xdef\MPury{#4}% + \xdef\MPwidth{\the\dimexpr#3bp-#1bp\relax}% + \xdef\MPheight{\the\dimexpr#4bp-#2bp\relax}% + \parskip0pt% + \leftskip0pt% + \parindent0pt% + \everypar{}% + \setbox\mplibscratchbox\vbox\bgroup + \noindent +} + +\def\mplibstoptoPDF{% + \egroup % + \setbox\mplibscratchbox\hbox % + {\hskip-\MPllx bp% + \raise-\MPlly bp% + \box\mplibscratchbox}% + \setbox\mplibscratchbox\vbox to \MPheight + {\vfill + \hsize\MPwidth + \wd\mplibscratchbox0pt% + \ht\mplibscratchbox0pt% + \dp\mplibscratchbox0pt% + \box\mplibscratchbox}% + \wd\mplibscratchbox\MPwidth + \ht\mplibscratchbox\MPheight + \box\mplibscratchbox + \egroup +} + + +\def\mplibtextext#1#2#3#4#5{% + \begingroup + \setbox\mplibscratchbox\hbox + {\font\temp=#1 at #2bp% + \temp + #3}% + \setbox\mplibscratchbox\hbox + {\hskip#4 bp% + \raise#5 bp% + \box\mplibscratchbox}% + \wd\mplibscratchbox0pt% + \ht\mplibscratchbox0pt% + \dp\mplibscratchbox0pt% + \box\mplibscratchbox + \endgroup +} + +\endinput +%% +%% End of file `luamplib.sty'. |