summaryrefslogtreecommitdiff
path: root/tex/context/base/lpdf-pdx.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/lpdf-pdx.lua')
-rw-r--r--tex/context/base/lpdf-pdx.lua652
1 files changed, 563 insertions, 89 deletions
diff --git a/tex/context/base/lpdf-pdx.lua b/tex/context/base/lpdf-pdx.lua
index db1217c53..dbf8eadf2 100644
--- a/tex/context/base/lpdf-pdx.lua
+++ b/tex/context/base/lpdf-pdx.lua
@@ -6,7 +6,10 @@ if not modules then modules = { } end modules ['lpdf-pdx'] = {
license = "see context related readme files",
}
-local trace_colorprofiles = false trackers.register("backend.colorprofiles", function(v) trace_colorprofiles = v end)
+-- context --directives="backend.format=PDF/X-1a:2001" --trackers=backend.format yourfile
+
+local trace_pdfx = false trackers.register("backend.pdfx", function(v) trace_pdfx = v end)
+local trace_format = false trackers.register("backend.format", function(v) trace_format = v end)
local report_backends = logs.new("backends")
@@ -22,7 +25,10 @@ local pdfstring = lpdf.string
local pdfverbose = lpdf.verbose
local pdfobject = lpdf.object
-local lower, gmatch = string.lower, string.gmatch
+local addtoinfo, injectxmpinfo, insertxmpinfo = lpdf.addtoinfo, lpdf.injectxmpinfo, lpdf.insertxmpinfo
+
+local lower, gmatch, format, find = string.lower, string.gmatch, string.format, string.find
+local concat, serialize = table.concat, table.serialize
local channels = {
gray = 1,
@@ -38,90 +44,587 @@ local prefixes = {
cmyk = "DefaultCMYK",
}
-local profiles = { }
-local defaults = { }
-local intents = pdfarray()
-local lastprofile = nil
-
-function codeinjections.useinternalICCprofile(colorspace,filename)
- local name = lower(file.basename(filename))
- local profile = profiles[name]
- if not profile then
- local colorspace = lower(colorspace)
- local filename = resolvers.findctxfile(filename) or ""
- local channel = channels[colorspace]
- if channel and filename ~= "" then
- local a = pdfdictionary { N = channel }
- profile = pdfobject {
- compresslevel = 0,
- immediate = true, -- !
- type = "stream",
- file = filename,
- attr = a(),
- }
- profiles[name] = profile
+local pdfxspecification, pdfxformat = nil, nil
+
+-- * correspondent document wide flags (write once) needed for permission tests
+
+local pdfx = {
+ ["version"] = {
+ external_icc_profiles = 1.4, -- 'p' in name; URL reference of output intent
+ jbig2_compression = 1.4,
+ jpeg2000_compression = 1.5, -- not supported yet
+ nchannel_colorspace = 1.6, -- 'n' in name; n-channel colorspace support
+ open_prepress_interface = 1.3, -- 'g' in name; reference to external graphics
+ opentype_fonts = 1.6,
+ optional_content = 1.5,
+ transparency = 1.4,
+ object_compression = 1.5,
+ },
+ ["default"] = {
+ pdf_version = 1.7, -- todo: block tex primitive
+ format_name = "default",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ spot_colors = true,
+ calibrated_rgb_colors = true, -- unknown
+ cielab_colors = true, -- unknown
+ nchannel_colorspace = true, -- unknown
+ internal_icc_profiles = true, -- controls profile inclusion
+ external_icc_profiles = true, -- controls profile inclusion
+ include_intents = true,
+ open_prepress_interface = true, -- unknown
+ opentype_fonts = true, -- out of our control
+ optional_content = true, -- todo: block at lua level
+ transparency = true, -- todo: block at lua level
+ jbig2_compression = true, -- todo: block at lua level
+ jpeg2000_compression = true, -- todo: block at lua level
+ inject_metadata = function()
+ -- nothing
+ end
+ },
+ ["pdf/x-1a:2001"] = {
+ pdf_version = 1.3,
+ format_name = "PDF/X-1a:2001",
+ gray_scale = true,
+ cmyk_colors = true,
+ spot_colors = true,
+ internal_icc_profiles = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-1a:2001")
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ end
+ },
+ ["pdf/x-1a:2003"] = {
+ pdf_version = 1.4,
+ format_name = "PDF/X-1a:2003",
+ gray_scale = true,
+ cmyk_colors = true,
+ spot_colors = true,
+ internal_icc_profiles = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-1a:2003")
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2003</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ end
+ },
+ ["pdf/x-3:2002"] = {
+ pdf_version = 1.3,
+ format_name = "PDF/X-3:2002",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-3:2002")
+ end
+ },
+ ["pdf/x-3:2003"] = {
+ pdf_version = 1.4,
+ format_name = "PDF/X-3:2003",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ jbig2_compression = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-3:2003")
+ end
+ },
+ ["pdf/x-4"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-4",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditonClass>",false)
+ end
+ },
+ ["pdf/x-4p"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-4p",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ external_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ nchannel_colorspace = false,
+ inject_metadata = function()
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditonClass>",false)
+ end
+ },
+ ["pdf/x-5g"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5g",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ open_prepress_interface = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ -- todo
+ end
+ },
+ ["pdf/x-5pg"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5pg",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ external_icc_profiles = true,
+ include_intents = true,
+ open_prepress_interface = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ -- todo
+ end
+ },
+ ["pdf/x-5n"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5n",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ nchannel_colorspace = true,
+ inject_metadata = function()
+ -- todo
+ end
+ }
+}
+
+lpdf.pdfx = pdfx -- it does not hurt to have this one visible
+
+local filenames = {
+ "colorprofiles.xml",
+ "colorprofiles.lua",
+}
+
+local function locatefile(filename)
+ local fullname = resolvers.find_file(filename,"icc")
+ if not fullname or fullname == "" then
+ fullname = resolvers.finders.loc(filename) -- could be specific to the project
+ end
+ return fullname or ""
+end
+
+local function loadprofile(name,filename)
+ local profile = false
+ local databases = filename and filename ~= "" and aux.settings_to_array(filename) or filenames
+ for i=1,#databases do
+ local filename = locatefile(databases[i])
+ if filename and filename ~= "" then
+ local suffix = file.extname(filename)
+ local lname = lower(name)
+ if suffix == "xml" then
+ local xmldata = xml.load(filename) -- no need for caching it
+ if xmldata then
+ profile = xml.filter(xmldata,format('xml://profiles/profile/(info|filename)[lower(text())=="%s"]/../table()',lname))
+ end
+ elseif suffix == "lua" then
+ local luadata = loadfile(filename)
+ luadata = ludata and luadata()
+ if luadata then
+ profile = luadata[name] or luadata[lname] -- hashed
+ if not profile then
+ for i=1,#luadata do
+ local li = luadata[i]
+ if lower(li.info) == lname then -- indexed
+ profile = li
+ break
+ end
+ end
+ end
+ end
+ end
+ if profile then
+ if next(profile) then
+ report_backends("profile specification '%s' loaded from '%s'",name,filename)
+ return profile
+ elseif trace_pdfx then
+ report_backends("profile specification '%s' loaded from '%s' but empty",name,filename)
+ end
+ return false
+ end
end
end
- lastprofile = profile
- return profile
+ report_backends("profile specification '%s' not found in '%s'",name,concat(filenames, ", "))
end
-function codeinjections.useexternalICCprofile(colorspace,name,urls,checksum,version)
- local profile = profiles[name]
- if not profile then
+local function urls(url)
+ if not url or url == "" then
+ return nil
+ else
local u = pdfarray()
- for url in gmatch(urls,"([^, ]+)") do
- u[#u+1] = pdfdictionary {
- FS = pdfconstant("URL"),
- F = pdfstring(url),
+ for url in gmatch(url,"([^, ]+)") do
+ if find(url,"^http") then
+ u[#u+1] = pdfdictionary {
+ FS = pdfconstant("URL"),
+ F = pdfstring(url),
+ }
+ end
+ end
+ return u
+ end
+end
+
+local function profilename(filename)
+ return lower(file.basename(filename))
+end
+
+local internalprofiles = { }
+
+local function handleinternalprofile(s,include)
+ local filename, colorspace = s.filename or "", s.colorspace or ""
+ if filename == "" or colorspace == "" then
+ report_backends("error in internal profile specification: %s",serialize(s,false))
+ else
+ local tag = profilename(filename)
+ local profile = internalprofiles[tag]
+ if not profile then
+ local colorspace = lower(colorspace)
+ if include then
+ -- local fullname = resolvers.findctxfile(filename) or ""
+ local fullname = locatefile(filename)
+ local channel = channels[colorspace] or nil
+ if fullname == "" then
+ report_backends("error, couldn't locate profile '%s'",filename)
+ elseif not channel then
+ report_backends("error, couldn't resolve channel entry for colorspace '%s'",colorspace)
+ else
+ local a = pdfdictionary { N = channel }
+ profile = pdfobject { -- does a flush too
+ compresslevel = 0,
+ immediate = true, -- !
+ type = "stream",
+ file = fullname,
+ attr = a(),
+ }
+ internalprofiles[tag] = profile
+ if trace_pdfx then
+ report_backends("including '%s' color profile from '%s'",colorspace,fullname)
+ end
+ end
+ else
+ internalprofiles[tag] = true
+ if trace_pdfx then
+ report_backends("not including '%s' color profile '%s'",colorspace,filename)
+ end
+ end
+ end
+ return profile
+ end
+end
+
+local externalprofiles = { }
+
+local function handleexternalprofile(s,include) -- specification (include ignored here)
+ local name, url, filename, checksum, version, colorspace =
+ s.info or s.filename or "", s.url or "", s.filename or "", s.checksum or "", s.version or "", s.colorspace or ""
+ if false then -- somehow leads to invalid pdf
+ local iccprofile = colors.iccprofile(filename)
+ if iccprofile then
+ name = name ~= "" and name or iccprofile.tags.desc.cleaned or ""
+ url = url ~= "" and url or iccprofile.tags.dmnd.cleaned or ""
+ checksum = checksum ~= "" and checksum or file.checksum(iccprofile.fullname) or ""
+ version = version ~= "" and version or iccprofile.header.version or ""
+ colorspace = colorspace ~= "" and colorspace or iccprofile.header.colorspace or ""
+ end
+ -- table.print(iccprofile)
+ end
+ if name == "" or url == "" or checksum == "" or version == "" or colorspace == "" or filename == "" then
+ local profile = handleinternalprofile(s)
+ if profile then
+ report_backends("incomplete external profile specification, falling back to internal")
+ else
+ report_backends("error in external profile specification: %s",serialize(s,false))
+ end
+ else
+ local tag = profilename(filename)
+ local profile = externalprofiles[tag]
+ if not profile then
+ local d = pdfdictionary {
+ ProfileName = name, -- not file name!
+ ProfileCS = colorspace,
+ URLs = urls(url), -- array containing at least one URL
+ CheckSum = pdfverbose { "<", lower(checksum), ">" }, -- 16byte MD5 hash
+ ICCVersion = pdfverbose { "<", version, ">" }, -- bytes 8..11 from the header of the ICC profile, as a hex string
}
+ profile = pdfflushobject(d)
+ externalprofiles[tag] = profile
end
- local d = pdfdictionary {
- ProfileName = name, -- not file name!
- ProfileCS = colorspace,
- URLs = u, -- array containing at least one URL
- CheckSum = pdfverbose { "<", checksum, ">" }, -- 16byte MD5 hash
- ICCVersion = pdfverbose { "<", version, ">" }, -- bytes 8..11 from the header of the ICC profile, as a hex string
- }
- local n = pdfflushobject(d)
- profiles[name] = n
- lastprofile = n
- return n
+ return profile
end
end
-local loaded = { }
+local loadeddefaults = { }
-function codeinjections.useICCdefaultprofile(colorspace,filename)
- local colorspace = lower(colorspace)
- if not loaded[colorspace] then
- local n = codeinjections.useinternalICCprofile(colorspace,filename)
- if n then
+local function handledefaultprofile(s) -- specification
+ local filename, colorspace = s.filename or "", lower(s.colorspace or "")
+ if filename == "" or colorspace == "" then
+ report_backends("error in default profile specification: %s",serialize(s,false))
+ elseif not loadeddefaults[colorspace] then
+ local tag = profilename(filename)
+ local n = internalprofiles[tag] -- or externalprofiles[tag]
+ if n == true then -- not internalized
+ report_backends("no default profile '%s' for colorspace '%s'",filename,colorspace)
+ elseif n then
local a = pdfarray {
pdfconstant("ICCBased"),
pdfreference(n),
}
-- used in page /Resources, so this must be inserted at runtime
lpdf.adddocumentcolorspace(prefixes[colorspace],pdfreference(pdfflushobject(a)))
- if trace_colorprofiles then
- report_backends("including color profile '%s' from '%s'",colorspace,filename)
+ loadeddefaults[colorspace] = true
+ report_backends("setting '%s' as default '%s' color space",filename,colorspace)
+ else
+ report_backends("no default profile '%s' for colorspace '%s'",filename,colorspace)
+ end
+ elseif trace_pdfx then
+ report_backends("a default '%s' colorspace is already in use",colorspace)
+ end
+end
+
+local loadedintents, intents = { }, pdfarray()
+
+local function handleoutputintent(s)
+ local name, url, filename, id, outputcondition, info = s.info or s.filename or "", s.url or "", s.filename or "", s.id or "", s.outputcondition or "", s.info or ""
+ if name == "" or id == "" then
+ report_backends("error in output intent specification: %s",serialize(s,false))
+ elseif not loadedintents[name] then
+ local tag = profilename(filename)
+ local internal, external = internalprofiles[tag], externalprofiles[tag]
+ if internal or external then
+ local d = {
+ Type = pdfconstant("OutputIntent"),
+ S = pdfconstant("GTS_PDFX"),
+ OutputConditionIdentifier = id,
+ RegistryName = url,
+ OutputCondition = outputcondition,
+ Info = info,
+ }
+ if internal and internal ~= true then
+ d.DestOutputProfile = pdfreference(internal)
+ elseif external and external ~= true then
+ d.DestOutputProfileRef = pdfreference(external)
+ else
+ report_backends("omitting reference to profile for intent '%s'",name)
+ end
+ intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d)))
+ if trace_pdfx then
+ report_backends("setting output intent to '%s' with id '%s' (entry %s)",name,id,#intents)
+ end
+ else
+ report_backends("invalid output intent '%s'",name)
+ end
+ loadedintents[name] = true
+ elseif trace_pdfx then
+ report_backends("an output intent with name '%s' is already in use",name)
+ end
+end
+
+local function handleiccprofile(message,name,filename,how,options,alwaysinclude)
+ if name and name ~= "" then
+ local list = aux.settings_to_array(name)
+ for i=1,#list do
+ local name = list[i]
+ local profile = loadprofile(name,filename)
+ if trace_pdfx then
+ report_backends("handling %s '%s'",message,name)
+ end
+ if profile then
+ if pdfxspecification.cmyk_colors then
+ profile.colorspace = profile.colorspace or "CMYK"
+ else
+ profile.colorspace = profile.colorspace or "RGB"
+ end
+ local external = pdfxspecification.external_icc_profiles
+ local internal = pdfxspecification.internal_icc_profiles
+ local include = pdfxspecification.include_intents
+ local always, never = options[variables.always], options[variables.never]
+ if always or alwaysinclude then
+ if trace_pdfx then
+ report_backends("forcing internal profiles") -- can make preflight unhappy
+ end
+ -- internal, external = true, false
+ internal, external = not never, false
+ elseif never then
+ if trace_pdfx then
+ report_backends("forcing external profiles") -- can make preflight unhappy
+ end
+ internal, external = false, true
+ end
+ if external then
+ if trace_pdfx then
+ report_backends("handling external profiles cf. '%s'",name)
+ end
+ handleexternalprofile(profile,false)
+ else
+ if trace_pdfx then
+ report_backends("handling internal profiles cf. '%s'",name)
+ end
+ if internal then
+ handleinternalprofile(profile,always or include)
+ else
+ report_backends("no profile inclusion for '%s'",pdfxformat)
+ end
+ end
+ how(profile)
+ elseif trace_pdfx then
+ report_backends("unknown profile '%s'",name)
+ end
+ end
+ end
+end
+
+local function flushoutputintents()
+ if #intents > 0 then
+ lpdf.addtocatalog("OutputIntents",pdfreference(pdfflushobject(intents)))
+ end
+end
+
+lpdf.registerdocumentfinalizer(flushoutputintents,2,"output intents")
+
+directives.register("backend.format", function(v)
+ codeinjections.setformat(v)
+end)
+
+function codeinjections.setformat(s)
+ local format, level, profile, intent, option, filename =
+ s.format or "", s.level or "", s.profile or "", s.intent or "", s.option or "", s.file or ""
+ if format == "" then
+ -- we ignore this as we hook it in \everysetupbackend
+ else
+ local spec = pdfx[lower(format)]
+ if spec then
+ pdfxspecification, pdfxformat = spec, spec.format_name
+ report_backends("setting format to '%s'",pdfxformat)
+ local pdf_version, inject_metadata = spec.pdf_version * 10, spec.inject_metadata
+ local majorversion, minorversion = math.div(pdf_version,10), math.mod(pdf_version,10)
+ local objectcompression = pdf_version >= 15
+ tex.pdfcompresslevel = level and tonumber(level) or tex.pdfobjcompresslevel -- keep default
+ tex.pdfobjcompresslevel = objectcompression and tex.pdfobjcompresslevel or 0 -- keep default
+ tex.pdfmajorversion = majorversion
+ tex.pdfminorversion = minorversion
+ report_backends("forcing pdf version %s.%s, compression level %s, object compression %sabled",
+ majorversion,minorversion,tex.pdfcompresslevel,compression and "en" or "dis")
+ --
+ -- context.setupcolors { -- not this way
+ -- cmyk = spec.cmyk_colors and variables.yes or variables.no,
+ -- rgb = spec.rgb_colors and variables.yes or variables.no,
+ -- }
+ --
+ colors.forcesupport(
+ spec.gray_scale or false,
+ spec.rgb_colors or false,
+ spec.cmyk_colors or false,
+ spec.spot_colors or false,
+ spec.nchannel_colorspace or false
+ )
+ transparencies.forcesupport(
+ spec.transparency or false
+ )
+ viewerlayers.forcesupport(
+ spec.optional_content or false
+ )
+ viewerlayers.setfeatures(
+ spec.has_order or false -- new
+ )
+ --
+ -- spec.jbig2_compression : todo, block in image inclusion
+ -- spec.jpeg2000_compression : todo, block in image inclusion
+ --
+ if type(inject_metadata) == "function" then
+ inject_metadata()
+ end
+ local options = aux.settings_to_hash(option)
+ handleiccprofile("color profile",profile,filename,handledefaultprofile,options,true)
+ handleiccprofile("output intent",intent,filename,handleoutputintent,options,false)
+ if trace_format then
+ for k, v in table.sortedhash(pdfx.default) do
+ local v = pdfxspecification[k]
+ if type(v) ~= "function" then
+ report_backends("%s = %s",k,tostring(v or false))
+ end
+ end
end
- elseif trace_colorprofiles then
- report_backends("no color profile '%s' in '%s'",colorspace,filename)
+ function codeinjections.setformat(noname)
+ report_backends("error, format is already set to '%s', ignoring '%s'",pdfxformat,noname)
+ end
+ else
+ report_backends("error, format '%s' is not supported",format)
end
- loaded = true
- elseif trace_colorprofiles then
- report_backends("color profile '%s' is already included",colorspace)
end
end
+function codeinjections.getformatoption(key)
+ return pdfxspecification and pdfxspecification[key]
+end
+
--~ The following is somewhat cleaner but then we need to flag that there are
--~ color spaces set so that the page flusher does not optimize the (at that
--~ moment) still empty array away. So, next(d_colorspaces) should then become
--~ a different test, i.e. also on flag. I'll add that when we need more forward
--~ referencing.
--~
---~ local function embedprofile = codeinjections.useICCdefaultprofile
+--~ local function embedprofile = handledefaultprofile
--~
--~ local function flushembeddedprofiles()
--~ for colorspace, filename in next, defaults do
@@ -129,37 +632,8 @@ end
--~ end
--~ end
--~
---~ function codeinjections.useICCdefaultprofile(colorspace,filename)
---~ defaults[lower(colorspace)] = filename
+--~ local function handledefaultprofile(s)
+--~ defaults[lower(s.colorspace)] = s.filename
--~ end
--~
--~ lpdf.registerdocumentfinalizer(flushembeddedprofiles,1,"embedded color profiles")
-
-function codeinjections.usePDFXoutputintent(id,name,reference,outputcondition,info)
- local d = {
- Type = pdfconstant("OutputIntent"),
- S = pdfconstant("GTS_PDFX"),
- OutputConditionIdentifier = id,
- RegistryName = name,
- OutputCondition = outputcondition,
- Info = info,
- }
- local icc = lastprofile
- if reference == variables.yes then
- d["DestOutputProfileRef"] = pdfreference(icc)
- else
- d["DestOutputProfile"] = pdfreference(icc)
- end
- intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d)))
- if trace_colorprofiles then
- report_backends("adding output intent '%s' with id '%s' (entry %s)",name,id,#intents)
- end
-end
-
-local function flushoutputintents()
- if #intents > 0 then
- lpdf.addtocatalog("OutputIntents",pdfreference(pdfflushobject(intents)))
- end
-end
-
-lpdf.registerdocumentfinalizer(flushoutputintents,2,"output intents")