if not modules then modules = { } end modules ['back-imp-pdp'] = { version = 1.001, comment = "companion to back-imp-pdf.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -- We don't support late literals unless it's really needed by some third party -- code. local context = context local lpdf = lpdf local pdfreserveobject = lpdf.reserveobject local pdfcompresslevel = lpdf.compresslevel local pdfobject = lpdf.object local pdfpagereference = lpdf.pagereference local pdfgetxformname = lpdf.getxformname local pdfminorversion = lpdf.minorversion local pdfmajorversion = lpdf.majorversion local tokenscanners = tokens.scanners local scanword = tokenscanners.word local scankeyword = tokenscanners.keyword local scanstring = tokenscanners.string local scaninteger = tokenscanners.integer local scanwhd = tokenscanners.whd local values = tokens.values local dimension_value = values.dimension local cardinal_value = values.cardinal local integer_value = values.integer local immediate_code = tex.flagcodes.immediate local trace = false trackers.register("backend.primitives", function(v) trace = v end) local report = logs.reporter("backend") local nodepool = nodes.pool local newliteral = nodepool.literal local newsave = nodepool.save local newrestore = nodepool.restore local newsetmatrix = nodepool.setmatrix local implement = interfaces.implement local constants = interfaces.constants local variables = interfaces.variables -- literals local function pdf_literal() context(newliteral(scanword() or "origin",scanstring())) end -- objects local lastobjnum = 0 local function pdf_obj(prefix) if scankeyword("reserveobjnum") then lastobjnum = pdfreserveobject() if trace then report("\\pdfobj reserveobjnum: object %i",lastobjnum) end else local immediate = prefix and (prefix & immediate_code) ~= 0 -- was just "true" local objnum = scankeyword("useobjnum") and scaninteger() or pdfreserveobject() local uncompress = scankeyword("uncompressed") or pdfcompresslevel() == 0 local streamobject = scankeyword("stream") local attributes = scankeyword("attr") and scanstring() or nil local fileobject = scankeyword("file") local content = scanstring() local object = streamobject and { type = "stream", objnum = objnum, immediate = immediate, attr = attributes, compresslevel = uncompress and 0 or nil, } or { type = "raw", objnum = objnum, immediate = immediate, } if fileobject then object.file = content -- object.filename = content else object.string = content end pdfobject(object) lastobjnum = objnum if trace then report("\\pdfobj: object %i",lastobjnum) end end end local function pdf_lastobj() if trace then report("\\lastobj: object %i",lastobjnum) end return cardinal_value, lastobjnum end local function pdf_pagereference() return cardinal_value, pdfpagereference() end local function pdf_refobj() local objnum = scaninteger() if trace then report("\\refobj: object %i (todo)",objnum) end end -- annotations local lastobjnum = 0 local function pdf_annot() if scankeyword("reserveobjnum") then lastobjnum = pdfreserveobject() if trace then report("\\pdfannot reserveobjnum: object %i",lastobjnum) end else local width = false local height = false local depth = false local data = false local object = false local attr = false -- if scankeyword("useobjnum") then object = scancount() report("\\pdfannot useobjectnum is not (yet) supported") end local width, height, depth = scanwhd() if scankeyword("attr") then attr = scanstring() end data = scanstring() context(backends.nodeinjections.annotation(width or 0,height or 0,depth or 0,data or "")) end end local function pdf_dest() local name = false local zoom = false local view = false local width = false local height = false local depth = false if scankeyword("num") then report("\\pdfdest num is not (yet) supported") elseif scankeyword("name") then name = scanstring() end if scankeyword("xyz") then view = "xyz" if scankeyword("zoom") then report("\\pdfdest zoom is ignored") zoom = scancount() -- will be divided by 1000 in the backend end elseif scankeyword("fitbh") then view = "fitbh" elseif scankeyword("fitbv") then view = "fitbv" elseif scankeyword("fitb") then view = "fitb" elseif scankeyword("fith") then view = "fith" elseif scankeyword("fitv") then view = "fitv" elseif scankeyword("fitr") then view = "fitr" width, height, depth = scanwhd() elseif scankeyword("fit") then view = "fit" end context(backends.nodeinjections.destination(width or 0,height or 0,depth or 0,{ name or "" },view or "fit")) end -- management local function pdf_save() context(newsave()) end local function pdf_restore() context(newrestore()) end local function pdf_setmatrix() context(newsetmatrix(scanstring())) end -- extras -- extensions: literal dest annot save restore setmatrix obj refobj colorstack -- startlink endlink startthread endthread thread outline glyphtounicode fontattr -- mapfile mapline includechars catalog info names trailer local extensions = { literal = pdf_literal, obj = pdf_obj, refobj = pdf_refobj, dest = pdf_dest, annot = pdf_annot, save = pdf_save, restore = pdf_restore, setmatrix = pdf_setmatrix, } local function pdf_extension() local w = scanword(false) if w then local e = extensions[w] if e then e() else report("\\pdfextension: unsupported %a",w) end end end -- feedbacks: colorstackinit creationdate fontname fontobjnum fontsize lastannot -- lastlink lastobj pageref retval revision version xformname local feedbacks = { lastobj = pdf_lastobj, pageref = pdf_pagereference, xformname = function() context(pdfgetxformname ()) end, } local function pdf_feedback() local w = scanword(false) if w then local f = feedbacks[w] if f then return f() else report("\\pdffeedback: unsupported %a",w) end end end -- variables: (integers:) compresslevel decimaldigits gamma gentounicode -- ignoreunknownimages imageaddfilename imageapplygamma imagegamma imagehicolor -- imageresolution inclusioncopyfonts inclusionerrorlevel majorversion minorversion -- objcompresslevel omitcharset omitcidset pagebox pkfixeddpi pkresolution -- recompress suppressoptionalinfo uniqueresname (dimensions:) destmargin horigin -- linkmargin threadmargin vorigin xformmargin (tokenlists:) pageattr pageresources -- pagesattr pkmode trailerid xformattr xformresources local variables = { minorversion = function() context(pdfminorversion()) end, majorversion = function() context(pdfmajorversion()) end, } local function pdf_variable() local w = scanword(false) if w then local f = variables[w] if f then f() else report("\\pdfvariable: unsupported %a",w) end else print("missing variable") end end -- kept (also because tikz needs including the pdftex primitives): implement { name = "pdfextension", actions = pdf_extension, public = true, untraced = true } -- , protected = true } implement { name = "pdffeedback", actions = pdf_feedback, public = true, usage = "value", untraced = true } -- expandable / todo : value implement { name = "pdfvariable", actions = pdf_variable, public = true, untraced = true } -- expandable / todo : value implement { name = "pdfliteral", actions = pdf_literal, public = true, untraced = true, protected = true } implement { name = "pdfobj", actions = pdf_obj, public = true, usage = "value", protected = true } implement { name = "pdflastobj", actions = pdf_lastobj, public = true, usage = "value", protected = true } implement { name = "pdfrefobj", actions = pdf_refobj, public = true, untraced = true, protected = true } --------- { name = "pdfannot", actions = pdf_annot } --------- { name = "pdfdest", actions = pdf_dest } --------- { name = "pdfsave", actions = pdf_save } --------- { name = "pdfrestore", actions = pdf_restore } --------- { name = "pdfsetmatrix", actions = pdf_setmatrix } -- implement { -- name = "pdfstrcmp", -- arguments = "2 strings", -- usage = "value", -- public = true, -- actions = function(a,b) return integer_value, (a < b and -1) or (a > b and 1) or 0 end -- }