summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/documents/general/manuals/luatex.pdfbin1524771 -> 1517157 bytes
-rw-r--r--doc/context/documents/general/manuals/musings.pdfbin5724100 -> 5761923 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin853357 -> 853368 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin853974 -> 853968 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin857333 -> 857333 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin849625 -> 849625 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin856329 -> 856332 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin346962 -> 346968 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin431242 -> 431246 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin344856 -> 344862 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin347385 -> 347384 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin346375 -> 346375 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin345409 -> 345410 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin508246 -> 508251 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin846683 -> 846863 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin851446 -> 851451 bytes
-rw-r--r--doc/context/sources/general/manuals/musings/musings-roadmap.tex372
-rw-r--r--doc/context/sources/general/manuals/musings/musings.tex2
-rw-r--r--scripts/context/lua/mtxrun.lua72
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua72
-rw-r--r--scripts/context/stubs/unix/mtxrun72
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua72
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-fr.mkii1
-rw-r--r--tex/context/base/mkiv/back-pdf.mkiv1
-rw-r--r--tex/context/base/mkiv/bibl-tra.mkiv2
-rw-r--r--tex/context/base/mkiv/cldf-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-con.lua2
-rw-r--r--tex/context/base/mkiv/font-imp-quality.lua6
-rw-r--r--tex/context/base/mkiv/font-otc.lua18
-rw-r--r--tex/context/base/mkiv/font-oto.lua52
-rw-r--r--tex/context/base/mkiv/font-set.mkvi2
-rw-r--r--tex/context/base/mkiv/grph-img.lua747
-rw-r--r--tex/context/base/mkiv/grph-inc.lua212
-rw-r--r--tex/context/base/mkiv/grph-inc.mkiv1
-rw-r--r--tex/context/base/mkiv/l-macro-imp-optimize.lua1
-rw-r--r--tex/context/base/mkiv/l-number.lua4
-rw-r--r--tex/context/base/mkiv/lpdf-img.lua1061
-rw-r--r--tex/context/base/mkiv/pack-com.mkiv4
-rw-r--r--tex/context/base/mkiv/pack-lyr.mkiv4
-rw-r--r--tex/context/base/mkiv/page-lin.mkvi4
-rw-r--r--tex/context/base/mkiv/page-set.mkiv10
-rw-r--r--tex/context/base/mkiv/scrn-fld.mkvi2
-rw-r--r--tex/context/base/mkiv/spac-pag.mkiv4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26105 -> 26098 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin269460 -> 270199 bytes
-rw-r--r--tex/context/base/mkiv/strc-con.mkvi4
-rw-r--r--tex/context/base/mkiv/strc-flt.mkvi18
-rw-r--r--tex/context/base/mkiv/strc-mat.mkiv6
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi8
-rw-r--r--tex/context/base/mkiv/strc-num.mkiv8
-rw-r--r--tex/context/base/mkiv/strc-pag.mkiv2
-rw-r--r--tex/context/base/mkiv/strc-ref.mkvi4
-rw-r--r--tex/context/base/mkiv/strc-reg.mkiv20
-rw-r--r--tex/context/base/mkiv/strc-sec.mkiv14
-rw-r--r--tex/context/base/mkiv/strc-syn.mkiv4
-rw-r--r--tex/context/base/mkiv/symb-imp-mvs.mkiv18
-rw-r--r--tex/context/base/mkiv/syst-aux.mkiv4
-rw-r--r--tex/context/base/mkiv/syst-ini.mkiv12
-rw-r--r--tex/context/base/mkiv/tabl-tab.mkiv16
-rw-r--r--tex/context/base/mkiv/tabl-tbl.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-drp.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-fln.mkiv2
-rw-r--r--tex/context/base/mkiv/util-sac.lua64
-rw-r--r--tex/context/interface/mkii/keys-fr.xml1
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin857333 -> 857333 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60774 -> 60773 bytes
-rw-r--r--tex/context/modules/mkiv/m-format.mkiv4
-rw-r--r--tex/context/modules/mkiv/s-fonts-charts.mkiv65
-rw-r--r--tex/context/modules/mkiv/s-fonts-complete.mkiv119
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.lua87
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.mkiv12
-rw-r--r--tex/context/modules/mkiv/s-maps.mkiv8
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua65
77 files changed, 3093 insertions, 288 deletions
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf
index 82d0931a9..3af62acd7 100644
--- a/doc/context/documents/general/manuals/luatex.pdf
+++ b/doc/context/documents/general/manuals/luatex.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/musings.pdf b/doc/context/documents/general/manuals/musings.pdf
index 8c956b7c4..7573569b9 100644
--- a/doc/context/documents/general/manuals/musings.pdf
+++ b/doc/context/documents/general/manuals/musings.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index d1c49f8b1..db96bb54f 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index aa6cee0e1..f65a41e0d 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index d8dc51e14..e1e1bc1cd 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 5b4822110..cca294dfd 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index 5e7251c8c..789088c63 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 9e9c44e8d..7d38dea46 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index 7727c6c80..0fc61cd85 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index b78b69945..21537aa94 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index afd504957..8ca776be2 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index b530df9c3..a2691c1e8 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index 1d448a5af..4e1491898 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index f565c5543..bbd19ee43 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 304a63658..a1fdf1440 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 39ecb74ad..c67652ac4 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/musings/musings-roadmap.tex b/doc/context/sources/general/manuals/musings/musings-roadmap.tex
new file mode 100644
index 000000000..f8771ba42
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-roadmap.tex
@@ -0,0 +1,372 @@
+% language=uk
+
+% \showfontkerns
+
+\startcomponent musings-roadmap
+
+\environment musings-style
+
+\startchapter[title={\METATEX, a roadmap}]
+
+% \startlines \setupalign[flushright]
+% Hans Hagen
+% Hasselt NL
+% September 2018
+% \stoplines
+
+\startsection[title={Introduction}]
+
+Here I will shortly wrap up the state of \LUATEX\ and \CONTEXT\ in fall 2018. I
+made the first draft of this article as preparation for the \CONTEXT\ meeting
+where we also discussed the future. I updated the text afterwards to match the
+decisions made there. It's also a personal summary of thoughts and discussions
+with team members about where to move next.
+
+\stopsection
+
+\startsection[title={The state of affairs}]
+
+After a dozen years the development of \LUATEX\ has reached a state where adding
+more functionality and|/|or opening up more of the internals makes not much
+sense. Apart from fixes and maybe some minor extensions, version 1.10 is what you
+get. Users can do enough in \LUA\ and there is not much to gain in convenience
+and performance. Of course some of the code can and will be cleaned up, as we
+still see the effects of going from \PASCAL\ to \CWEB\ to \CCODE. In the process
+consistency is on the radar so we might occasionally add a helper. But we also
+don't want to move too far away from the original code, which is for instance why
+we keep names, keys and other properties found in original \TEX, which in turn
+leads to some inconsistencies with extensions added over time. We have to accept
+that.
+
+Because \LUATEX\ development is closely related to \CONTEXT\ development,
+especially \MKIV, we've also reached the moment that we can get rid of some older
+code and assume the latest \LUATEX\ to be used. Because we do so much in \LUA\
+the question is always to what extent the benefits outweigh the drawbacks. Just
+in case you wonder why we use \LUA\ extensively, the main reason is that it is
+easier and more efficient to manage data in this language and modern typesetting
+needs much data. It also permits us to extend regular \TEX\ functionality. But,
+one should not overrate the impact: we still let \TEX\ do what \TEX\ is best at!
+
+Performance is quite important. It doesn't make sense to create a powerful
+typesetting system where processing a page takes a second. We have discussed
+performance before since one of the complaints about \LUATEX\ is that it is slow.
+A simple, basic test is this:
+
+\starttyping
+\starttext
+ \dorecurse{1000}{\input tufte \par}
+\stoptext
+\stoptyping
+
+This involves 1000 times loading a file (and reporting that on the console, which
+can influence runtime), typesetting paragraphs, splitting of a page and of course
+loading fonts and saving to the \PDF\ file. When I run this on a modest machine,
+I get these (relative) timings for the (about) 225 pages:
+
+\starttabulate[|l|c|c|c|c|]
+\BC \TEX\ engine used \BC \PDFTEX \BC \LUATEX \BC \LUAJITTEX \BC \XETEX \NC \NR
+\BC runtime in seconds \NC 2.0 \NC 3.9 \NC 3.0 \NC 8.4 \NC \NR
+\stoptabulate
+
+Now, as expected the 8 bit \PDFTEX\ is the winner here but \LUATEX\ is not doing
+that bad. I don't know why \XETEX\ is so much slower, maybe because its 64 bit
+binary is less optimal. I once noticed that a 64 bit \PDFTEX\ performed worse on
+such a test than \LUATEX, for which I always use 64 bit binaries.
+
+If you consider that often much more is done than in this example, you can take
+my word that \LUATEX\ quickly outpaces \PDFTEX\ on more complex tasks. In that
+sense it is now our benchmark. It must be said that the \MKIV\ code is probably a
+bit more efficient than the \MKII\ code but that doesn't matter much in this
+simple test because hardly any macro magic happens here; it mostly tests basic
+font processing, paragraph building and page construction. I don't think that I
+can squeeze out more pages per second, at least not without users telling me
+where they encounter bottlenecks that don't result from their style coding. It's
+no problem to write inefficient macros (or styles) so normally a user should
+first carefully check her|/|his own work. Using a more modern \CPU\ with proper
+caching and an \SSD\ helps too.
+
+So, to summarize, we can say that with version 1.10 \LUATEX\ is sort of finished.
+Our mission is now to make \LUATEX\ robust and stable. Things can be added and
+improved, but these are small and mostly consistency related.
+
+\stopsection
+
+\startsection[title={More in \LUA}]
+
+Till now I always managed to add functionality to \CONTEXT\ without hampering
+performance too much. Of course the biggest challenge is always in handling fonts
+and common features like color because that all happens in \LUA. So, the question
+is, what if we delegate more of the core functionality to \LUA ? I will discuss a
+few options because the \CONTEXT\ developers and users need to agree on the path
+to follow. One question there is, are the possible performance hits (which can be
+an inconvenience) compensated by better and easier typesetting.
+
+Fonts, colors, special typesetting features like spaced kerning, protrusion,
+expansion, but also dropped caps, line numbering, marginal notes, tables,
+structure related things, floats and spacing are not open for much discussion.
+All the things that happen in \LUA\ combined with macros is there and will stay.
+But how about hyphenation, paragraph building and page building? And how about a
+leaner and meaner, future safe engine?
+
+Hyphenation is handled in the \TEX\ core. But in \CONTEXT\ already for years one
+can also use a \LUA\ based variant. There is room for extensions and improvements
+there. Interesting is that performance is more or less the same, so this is an
+area where we might switch to the \LUA\ method eventually. It compares to fonts,
+where node mode is more or less the standard and base mode the old way.
+
+Building the paragraphs in \LUA\ is also available in \MKIV, although it needs an
+update. Again performance is not that bad, so when we add features not possible
+(or hard to do) in regular \TEX, it might actually pay of to default to the
+par builder written in \LUA.
+
+The page builder is also doable in \LUA\ but so far I only played a bit with a
+\LUA\ based variant. I might pick up that thread. However, when we would switch to
+\LUA\ there, it might have a bit of a penalty, unless we combine it with some
+other mechanisms which is not entirely trivial, as it would mean a diversion from
+the way \TEX\ does it normally.
+
+How about math? We could at some point do math rendering in \LUA\ but because the
+core mechanism is the standard, it doesn't really makes much sense. It would also
+touch the soul of \TEX. But, I might give it a try, just for fun, so that I can
+play with it a bit. It's typically something for cold and rainy days with some
+music in the background.
+
+We already use \LUA\ in the frontend: locating and reading files in \TEX,
+\XML, \LUA\ and whatever input format. Normalization and manipulation is all
+active and available. The backend is also depending on \LUA, like support for
+special \PDF\ features and exporting to \XML . The engine still handles the page
+stream conversion, font inclusion and object management.
+
+The inclusion of images is also handled by the engine, although in \CONTEXT\ we
+can delegate \PDF\ inclusion to \LUA. Interesting is that this has no performance
+hit.
+
+With some juggling the page stream conversion can also be done in \LUA, and I
+might move that code into the \CONTEXT\ distribution. Here we do have a
+performance hit: about one second more runtime on the 14 seconds needed for the
+300 page \LUATEX\ manual and just over more than half a second on a 11 second
+\LUAJITTEX\ run. The manual has lots of tables, verbatim, indices and uses color
+as well as a more than average number of fonts and much time is spent in \LUA. So
+there is a price to pay there. I tried to speed that up but there is not much to
+gain there.
+
+So, say that we default to \LUA\ based hyphenation, which enables some new
+functionality, \LUA\ based par building, which permits some heuristics for corner
+cases, and \LUA\ based page building, which might result in more control over
+tricky cases. A total performance hit of some 5\% is probably acceptable,
+especially because by that time I might have replaced my laptop and won't notice
+the degrade. This still fits in the normal progress and doesn't really demand a
+roadmap or wider acceptance. And of course we would still use the same strategies
+as implemented in traditional \TEX\ as default anyway.
+
+\stopsection
+
+\startsection[title={A more drastic move}]
+
+More fundamental is the question whether we delegate more backend activity to
+\LUA\ code. If we decide to handle the page stream in \LUA, then the next
+question is, why not also delegate object management and font inclusion to
+\LUA. Now, keep in mind that this is all very \CONTEXT\ specific! Already for
+more than a decade we delegate a lot to \LUA, and also we have a rather tight
+control over this core functionality. This would mean that \CONTEXT\ doesn't
+really need the backend code in the engine. \footnote {For generic packages like
+TikZ we (can) provide some primitive emulators, which is rather trivial to
+implement.}
+
+That situation is actually not unique. For instance, already for a while we don't
+need the \LUATEX\ font loader either, as loading the \OPENTYPE\ files is done in
+\LUA. So, we could also get rid of the font loader code. Currently some code is
+shared with the font inclusion in the backend but that can be isolated.
+
+You can see a \TEX\ engine as being made from several parts, but the core really
+concerns only two processes: reading, storing and expanding macros on the one
+hand, and converting a stream of characters into lines, paragraphs, pages etc.
+Fonts are mostly an abstraction: they are visible in so called glyph nodes as
+font identifier (a number) and character code (also a number) properties. The
+result, nowadays being \PDF, is also an abstraction: at some point the engine
+converts the to be shipped out box in \PDF\ instructions, and in our case,
+relatively simple ones. The backend registers which characters and fonts are used
+and also includes the right resources. But, the backend is not part of the core
+as such! It has been introduced in \PDFTEX\ and is a so called extension.
+
+So, what does that all mean for a future version of \CONTEXT\ and \LUATEX ? It
+means that we can decide to follow up with a \CONTEXT\ that does more in \LUA,
+which means not hard coded in a binary, on the one hand, but that we can also
+decide to strip the engine from non|-|core code. But, given that \LUATEX\ is also
+used in other macro packages, this would mean a different engine. We cannot say
+that \LUATEX\ is stable when we also experiment with core components.
+
+We've seen folks picking up experimental versions assuming that it is a precursor
+to official code. So, in order to move on we need to avoid confusion: we need to
+use another name. Choosing a name is always tricky but as Taco already registered
+the \METATEX\ domain, and because in the \CONTEXT\ distribution you will find
+references to \METATEX, we will use that name for the future engine. Adding \LUA\
+to that name makes sense but then the name would become too long.
+
+The main difference between \METATEX\ and \LUATEX\ would be that the former has
+no file lookup library, no hardcoded font loader, and no backend generator (but
+possibly some helpers, and these need time to evolve). We're basically back where
+\TEX\ started but instead of coding these extensions in \PASCAL\ or \CCODE\ we
+use \LUA. We're also kind of back to when we first started experimenting with
+\LUATEX\ in \CONTEXT\ where test, write and rewrite were going in parallel. But,
+as said, we cannot impose that on a wide audience.
+
+If we go for such a lean and mean follow up, then we can also do a more drastic
+cleanup of obsolete code in \CONTEXT\ (dating from \ETEX, \PDFTEX, \ALEPH, etc.).
+We then are sort of back to where it all started: we go back to the basics. This
+might mean dropping some primitives (one can define them as dummy). Of course we
+could generalize some of the \CONTEXT\ code to provide the kicked out
+functionality but would that pay of? Probably not.
+
+Just for the record: replacing the handling of macros, registers, grouping, etc.\
+to \LUA\ is not really an option as the performance hit would make a large system
+like \CONTEXT\ sort of unusable: it's no option and not even considered (although
+I must admit that I have some experimental \LUA\ based \TEX\ parser code around).
+
+It is quite likely that building \METATEX\ from source for the moment will be an
+option to the build script. But we can also decide to simplify that process,
+which is possible because we only need one binary. But in general we can assume
+that one can generate \METATEX\ and \LUATEX\ from the same source. A first step
+probably is a further isolation of the backend code. The fontloader and file
+handling code already can be made optional.
+
+Given that we only need one binary (it being \LUATEX\ or \METATEX) and nowadays
+only use \OPENTYPE\ fonts, one can even start thinking of a mini distribution,
+possibly with a zipped resource tree, something we experimented with in the early
+days of \LUATEX.
+
+Another though I have been playing with is a better separation between low level
+and high level \CONTEXT\ commands, and whether the low level layer should be more
+generic in nature (so that one can run specific packages on top of it instead of
+the whole of \CONTEXT) but that might not be worth the trouble.
+
+\stopsection
+
+\startsection[title={Interlude}]
+
+If we look at the future, it's good to also look at the past. Opening up \TEX\
+the way we did has many advantages but also potential drawbacks. It works quite
+well in \CONTEXT\ because we ship an integrated package. I don't think that there
+are many users who kick in their own callbacks. It is possible but completely up
+to the user to make sure things work out well. Performance hits, interference,
+crashes: those who interfere with the internals can sort that out themselves. I'm
+not sure how well that works out in other macro packages but it is a time bomb if
+users start doing that. Of course the documented interfaces to use \LUA\ in
+\CONTEXT\ are supported. So far I think we're not yet bitten in the tail. We keep
+this aspect out of the discussion.
+
+Another important aspect is stability of the engine. Sometimes we get suggestions
+for changes or patches that works for a specific case but for sure will have side
+effects on \CONTEXT. Just as we don't test \LATEX\ side effects, \LATEX\ users
+don't check \CONTEXT. And we're not even talking of users who expect their code
+to keep working. A tight control over the source is important but cannot be we
+will not be around for ever. This means that at some point \LUATEX\ should not be
+changed any more, even when we observe side effects we want to get rid of,
+because these side effects can be in use. This is another argument for a stripped
+down engine. The less there is to mess with, the less the mess.
+
+\stopsection
+
+\startsection[title={Audience}]
+
+So how about \CONTEXT\ itself? Of course we can make it better. We can add more
+examples and more documentation. We can try to improve support. The main question
+for us (as developers) is who actually is our audience. From the mails coming to
+the \CONTEXT\ support list it looks like a rather diverse group of users.
+
+At \TEX\ meetings there are often discussions about promoting \TEX. I can agree
+on the fact that even for simple documents it makes a lot of sense to use \TEX,
+but who will take the first hurdles? How many people really produce a lot of
+documents? And how many need \TEX\ after maybe a short period of (enforced) usage
+at the university?
+
+It's not trivial to recognize the possibilities and power of the
+\LUATEX|-|\CONTEXT\ combination. We never got any serious requests for support
+from large organizations. In fact, we do use this combination in a few projects
+for educational publishers, but there it's actually the authors and editors doing
+the work. It's seldom company policy to use tools that efficiently automate
+typesetting. I dare to say that publishers are not really an audience at all:
+they normally delegate the task. They might accept \TEX\ documents but let them
+rekey or adapt far|-|far|-|away and as cheap as possible. Thinking of it, the
+main reason for Don Knuth for writing \TEX\ in the first place was the ability to
+control the look and feel and quality. It were developments at typesetters and
+publishers that triggered development of \TEX . It was user demand. And the
+success of \TEX\ was largely due to the unique personality and competence of the
+author.
+
+System integrators qualify as audience but I fear that \TEX\ is not considered
+hip and modern. It doesn't seem to matter if you can demonstrate that it can do a
+wonderful job efficiently and relatively cheap. Also the fact that an
+installation can be very stable on the long run is of no importance. Maybe that
+audience (market place) is all about \quotation {The more we have to program and
+update regularly, the merrier.}. Marketing \TEX\ is difficult.
+
+Those who render multiple products, maintain manuals, have to render many
+documents automatically qualify as audience. But often company policies,
+preferred suppliers, so called standard tools etc.\ are used as argument against
+\TEX. It's a missed opportunity.
+
+One needs a certain mindset to recognize the potential and the question is, how
+do we reach that audience. Drawing a roadmap for that is not easy but worth
+discussing. We're open for suggestions.
+
+% \footnote {It's kind of interesting that recently the \TEX\ User Group announced
+% its presence on Facebook and Twitter. Apart from wondering how that gets updated,
+% one can also wonder how many potential (or even current) users go there, given
+% that these platforms are subjected to rise and fall. I'm on neither of them and
+% don't plan to. Kids (our future users) that I know already said goodbye to them.
+% We'll see how that works out.}
+
+\stopsection
+
+\startsection[title={Conclusion}]
+
+At the \CONTEXT\ user meeting those present agreed that moving forward this way
+makes sense. This means that we will explore a lean and mean \METATEX\ alongside
+\LUATEX. There is no rush and it's all volunteer work so we will take our time
+for this. It boils down to some reshuffling of code so that we can remove the
+built|-|in font loader, file handling, and probably also \SYNCTEX\ because we can
+emulate that. Then the backend with its font inclusion code will be cleaned up a
+bit (we even discussed only supporting modern wide fonts). It's no big deal to
+adapt \CONTEXT\ to this (so it can and will support both \LUATEX\ and \METATEX).
+Eventually the backend might go away but now we're talking years ahead. By then
+we can also explore the option to make \METATEX\ start out as a \LUA\ function
+call (the main control loop) and become reentrant. There will probably not be
+many changes to the opened up \TEX\ kernel, but we might extend the \METAPOST\
+part a bit (some of that was discussed at the meeting) especially because it is a
+nice tool to visualize big data.
+
+As with \LUATEX\ development we will go in small steps so that we keep a working
+system. Of course \LUATEX\ is always there as stable fallback. The experiments
+will mostly happen in the experimental branch and binaries will be generated
+using the compile farm on the \CONTEXT\ garden, just as happens now. This also
+limits testing and exploring to the \CONTEXT\ community so that there are no side
+effects for mainstream \LUATEX\ usage.
+
+Nowadays, instead if roadmaps, we tend to use navigational gadgets that adapt
+themselves to the situation. On the road by car this can mean a detour and when
+walking around it can be going to suggested points of interest. During the
+excursion at the meeting, we noticed that after the drivers (navigators)
+synchronized their gadget with Jano, the routes that were followed differed a
+bit. We saw cars in front of going a different direction and cars behind us
+arriving from a different direction. So, even when we talk about roadmaps, our
+route can be adapted to the situation.
+
+Now here is something to think about. If you look at the \TEX\ community you will
+notice that it's an aging community. User groups seem to loose members, although
+the \CONTEXT\ group is currently still growing. Fortunately we see a new
+generation taking interest and the \CONTEXT\ users are a pleasant mix and it
+makes me stay around. I see it as an \quote {old timers} responsibility to have
+\TEX\ and its environment in a healthy state by the time I retire from it
+(although I have no plans in that direction). In parallel to the upcoming
+development I think we will also see a change in \TEX\ use and usage. This aspect
+was also discussed at the meeting and for sure will get a follow up on the
+mailing lists and future meetings. It might as well influence the decisions we
+make the upcoming years. So far \TEX\ has never failed us in it's flexibility and
+capacity to adapt, so let's end on that positive note.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings.tex b/doc/context/sources/general/manuals/musings/musings.tex
index a49de9265..e2787dc99 100644
--- a/doc/context/sources/general/manuals/musings/musings.tex
+++ b/doc/context/sources/general/manuals/musings/musings.tex
@@ -15,7 +15,7 @@
\component musings-whytex
\component musings-staygo
\component musings-stability
- % \component musings-roadmap
+ \component musings-roadmap
\stopbodymatter
\stopproduct
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 60ca9a337..c45ed26ca 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -3461,7 +3461,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5713, stripped down to: 2304
if not modules then modules={} end modules ['l-number']={
version=1.001,
@@ -3572,6 +3572,9 @@ function number.decimaltobyte(d)
return b
end
end
+function number.idiv(i,d)
+ return floor(i/d)
+end
end -- of closure
@@ -8064,7 +8067,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 9987, stripped down to: 7878
+-- original size: 11000, stripped down to: 8650
if not modules then modules={} end modules ['util-sac']={
version=1.001,
@@ -8082,6 +8085,9 @@ function streams.open(filename,zerobased)
local f=io.loaddata(filename)
return { f,1,#f,zerobased or false }
end
+function streams.openstring(f,zerobased)
+ return { f,1,#f,zerobased or false }
+end
function streams.close()
end
function streams.size(f)
@@ -8398,19 +8404,49 @@ if sio and sio.readcardinal2 then
streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- streams.readcardinaltable=sio.readcardinaltable
- streams.readintegertable=sio.readintegertable
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
else
local readcardinal1=streams.readcardinal1
local readcardinal2=streams.readcardinal2
local readcardinal3=streams.readcardinal3
local readcardinal4=streams.readcardinal4
function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
return t
end
local readinteger1=streams.readinteger1
@@ -8418,11 +8454,19 @@ else
local readinteger3=streams.readinteger3
local readinteger4=streams.readinteger4
function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
return t
end
end
@@ -24622,8 +24666,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 984519
--- stripped bytes : 348231
+-- original bytes : 985600
+-- stripped bytes : 348489
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 60ca9a337..c45ed26ca 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -3461,7 +3461,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5713, stripped down to: 2304
if not modules then modules={} end modules ['l-number']={
version=1.001,
@@ -3572,6 +3572,9 @@ function number.decimaltobyte(d)
return b
end
end
+function number.idiv(i,d)
+ return floor(i/d)
+end
end -- of closure
@@ -8064,7 +8067,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 9987, stripped down to: 7878
+-- original size: 11000, stripped down to: 8650
if not modules then modules={} end modules ['util-sac']={
version=1.001,
@@ -8082,6 +8085,9 @@ function streams.open(filename,zerobased)
local f=io.loaddata(filename)
return { f,1,#f,zerobased or false }
end
+function streams.openstring(f,zerobased)
+ return { f,1,#f,zerobased or false }
+end
function streams.close()
end
function streams.size(f)
@@ -8398,19 +8404,49 @@ if sio and sio.readcardinal2 then
streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- streams.readcardinaltable=sio.readcardinaltable
- streams.readintegertable=sio.readintegertable
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
else
local readcardinal1=streams.readcardinal1
local readcardinal2=streams.readcardinal2
local readcardinal3=streams.readcardinal3
local readcardinal4=streams.readcardinal4
function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
return t
end
local readinteger1=streams.readinteger1
@@ -8418,11 +8454,19 @@ else
local readinteger3=streams.readinteger3
local readinteger4=streams.readinteger4
function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
return t
end
end
@@ -24622,8 +24666,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 984519
--- stripped bytes : 348231
+-- original bytes : 985600
+-- stripped bytes : 348489
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 60ca9a337..c45ed26ca 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -3461,7 +3461,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5713, stripped down to: 2304
if not modules then modules={} end modules ['l-number']={
version=1.001,
@@ -3572,6 +3572,9 @@ function number.decimaltobyte(d)
return b
end
end
+function number.idiv(i,d)
+ return floor(i/d)
+end
end -- of closure
@@ -8064,7 +8067,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 9987, stripped down to: 7878
+-- original size: 11000, stripped down to: 8650
if not modules then modules={} end modules ['util-sac']={
version=1.001,
@@ -8082,6 +8085,9 @@ function streams.open(filename,zerobased)
local f=io.loaddata(filename)
return { f,1,#f,zerobased or false }
end
+function streams.openstring(f,zerobased)
+ return { f,1,#f,zerobased or false }
+end
function streams.close()
end
function streams.size(f)
@@ -8398,19 +8404,49 @@ if sio and sio.readcardinal2 then
streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- streams.readcardinaltable=sio.readcardinaltable
- streams.readintegertable=sio.readintegertable
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
else
local readcardinal1=streams.readcardinal1
local readcardinal2=streams.readcardinal2
local readcardinal3=streams.readcardinal3
local readcardinal4=streams.readcardinal4
function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
return t
end
local readinteger1=streams.readinteger1
@@ -8418,11 +8454,19 @@ else
local readinteger3=streams.readinteger3
local readinteger4=streams.readinteger4
function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
return t
end
end
@@ -24622,8 +24666,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 984519
--- stripped bytes : 348231
+-- original bytes : 985600
+-- stripped bytes : 348489
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 60ca9a337..c45ed26ca 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -3461,7 +3461,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5713, stripped down to: 2304
if not modules then modules={} end modules ['l-number']={
version=1.001,
@@ -3572,6 +3572,9 @@ function number.decimaltobyte(d)
return b
end
end
+function number.idiv(i,d)
+ return floor(i/d)
+end
end -- of closure
@@ -8064,7 +8067,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 9987, stripped down to: 7878
+-- original size: 11000, stripped down to: 8650
if not modules then modules={} end modules ['util-sac']={
version=1.001,
@@ -8082,6 +8085,9 @@ function streams.open(filename,zerobased)
local f=io.loaddata(filename)
return { f,1,#f,zerobased or false }
end
+function streams.openstring(f,zerobased)
+ return { f,1,#f,zerobased or false }
+end
function streams.close()
end
function streams.size(f)
@@ -8398,19 +8404,49 @@ if sio and sio.readcardinal2 then
streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- streams.readcardinaltable=sio.readcardinaltable
- streams.readintegertable=sio.readintegertable
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
else
local readcardinal1=streams.readcardinal1
local readcardinal2=streams.readcardinal2
local readcardinal3=streams.readcardinal3
local readcardinal4=streams.readcardinal4
function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
return t
end
local readinteger1=streams.readinteger1
@@ -8418,11 +8454,19 @@ else
local readinteger3=streams.readinteger3
local readinteger4=streams.readinteger4
function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
return t
end
end
@@ -24622,8 +24666,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 984519
--- stripped bytes : 348231
+-- original bytes : 985600
+-- stripped bytes : 348489
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 439cdf147..72d476f01 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2018.10.08 17:44}
+\newcontextversion{2018.10.17 15:06}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 88a4cac8c..922f96320 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2018.10.08 17:44}
+\edef\contextversion{2018.10.17 15:06}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii
index 5c94eaf24..69804afcb 100644
--- a/tex/context/base/mkii/mult-fr.mkii
+++ b/tex/context/base/mkii/mult-fr.mkii
@@ -1241,6 +1241,7 @@
\setinterfaceconstant{textstyle}{styletexte}
\setinterfaceconstant{textwidth}{largeurtexte}
\setinterfaceconstant{threshold}{threshold}
+\setinterfaceconstant{time}{time}
\setinterfaceconstant{title}{titre}
\setinterfaceconstant{titlecolor}{couleurtitre}
\setinterfaceconstant{titlecommand}{titlecommand}
diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv
index 365493fff..799df2538 100644
--- a/tex/context/base/mkiv/back-pdf.mkiv
+++ b/tex/context/base/mkiv/back-pdf.mkiv
@@ -37,6 +37,7 @@
\registerctxluafile{lpdf-epd}{}
\else
\registerctxluafile{lpdf-pde}{}
+ \registerctxluafile{lpdf-img}{optimize}
\fi
\registerctxluafile{lpdf-epa}{}
diff --git a/tex/context/base/mkiv/bibl-tra.mkiv b/tex/context/base/mkiv/bibl-tra.mkiv
index 3ff07ead5..5389400f3 100644
--- a/tex/context/base/mkiv/bibl-tra.mkiv
+++ b/tex/context/base/mkiv/bibl-tra.mkiv
@@ -1500,7 +1500,7 @@
\c!numbercommand=\bibleftnumber]
\unexpanded\def\preloadbiblist
- {\globallet\preloadbiblist\relax
+ {\glet\preloadbiblist\relax
\dousepublications\jobname}
% \appendtoks \preloadbiblist \to \everysetuppublications
diff --git a/tex/context/base/mkiv/cldf-ini.mkiv b/tex/context/base/mkiv/cldf-ini.mkiv
index 67eea6892..29fb15d68 100644
--- a/tex/context/base/mkiv/cldf-ini.mkiv
+++ b/tex/context/base/mkiv/cldf-ini.mkiv
@@ -47,8 +47,8 @@
% \catcode`=\activecatcode \let\luafunction % saves 10% on the call
-% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \global\let^^A=\cldf
-% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \global\let^^B=\cldn
+% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \glet^^A=\cldf
+% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \glet^^B=\cldn
\normalprotected\def\cldprocessfile#1{\directlua{context.runfile("#1")}}
\def\cldloadfile #1{\directlua{context.loadfile("#1")}}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index c3c035160..5ce172570 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2018.10.08 17:44}
+\newcontextversion{2018.10.17 15:06}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 9b166fb03..8b144d609 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
%D has to match \type {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2018.10.08 17:44}
+\edef\contextversion{2018.10.17 15:06}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 54cf2c199..d238084d0 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -739,6 +739,8 @@ function constructors.scale(tfmdata,specification)
chr.tounicode = tounicode(isunicode)
-- in luatex > 0.85 we can do this:
-- chr.tounicode = isunicode
+ else
+-- chr.tounicode = "FFFD"
end
if hasquality then
-- we could move these calculations elsewhere (saves calculations)
diff --git a/tex/context/base/mkiv/font-imp-quality.lua b/tex/context/base/mkiv/font-imp-quality.lua
index 52eed080c..bb78d9435 100644
--- a/tex/context/base/mkiv/font-imp-quality.lua
+++ b/tex/context/base/mkiv/font-imp-quality.lua
@@ -343,8 +343,7 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd)
if v == true then
-- zero
else
- -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same
- local p = - (v[1] / 1000) * factor * left
+ local p = - (v[3] / 1000) * factor * left
characters[k].left_protruding = p
if trace_protrusion then
report_protrusions("lfbd -> %C -> %p",k,p)
@@ -376,8 +375,7 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd)
if v == true then
-- zero
else
- -- local p = v[3] / descriptions[k].width -- or 3
- local p = (v[1] / 1000) * factor * right
+ local p = (v[1] / 1000) * factor * right -- or [3] ?
characters[k].right_protruding = p
if trace_protrusion then
report_protrusions("rtbd -> %C -> %p",k,p)
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index c2e89599a..595778e34 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['font-otc'] = {
}
local insert, sortedkeys, sortedhash, tohash = table.insert, table.sortedkeys, table.sortedhash, table.tohash
-local type, next = type, next
+local type, next, tonumber = type, next, tonumber
local lpegmatch = lpeg.match
local utfbyte, utflen = utf.byte, utf.len
local sortedhash = table.sortedhash
@@ -174,6 +174,10 @@ local function addfeature(data,feature,specifications)
return
end
+ local p = lpeg.P("P")
+ * (lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)
+ * lpeg.P(-1)
+
local function tounicode(code)
if not code then
return
@@ -183,6 +187,7 @@ local function addfeature(data,feature,specifications)
end
local u = unicodes[code]
if u then
+ -- unicodes[code] = u
return u
end
if utflen(code) == 1 then
@@ -191,10 +196,19 @@ local function addfeature(data,feature,specifications)
return u
end
end
+ local u = lpegmatch(p,code)
+ if u then
+ -- unicodes[code] = u
+ return u
+ end
if not aglunicodes then
aglunicodes = fonts.encodings.agl.unicodes -- delayed
end
- return aglunicodes[code]
+ local u = aglunicodes[code]
+ if u then
+ -- unicodes[code] = u
+ return u
+ end
end
local coverup = otf.coverup
diff --git a/tex/context/base/mkiv/font-oto.lua b/tex/context/base/mkiv/font-oto.lua
index 4b986bd3b..c32a7af25 100644
--- a/tex/context/base/mkiv/font-oto.lua
+++ b/tex/context/base/mkiv/font-oto.lua
@@ -415,36 +415,42 @@ local function checkmathreplacements(tfmdata,fullname,fixitalics)
for unicode, replacement in next, changed do
local u = characters[unicode]
local r = characters[replacement]
- local n = u.next
- local v = u.vert_variants
- local h = u.horiz_variants
- if fixitalics then
- -- quite some warnings on stix ...
- local ui = u.italic
- if ui and not r.italic then
+ if u and r then
+ local n = u.next
+ local v = u.vert_variants
+ local h = u.horiz_variants
+ if fixitalics then
+ -- quite some warnings on stix ...
+ local ui = u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic = ui -- print(ui,ri)
+ end
+ end
+ if n and not r.next then
if trace_preparing then
- report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
end
- r.italic = ui -- print(ui,ri)
+ r.next = n
end
- end
- if n and not r.next then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants = v
end
- r.next = n
- end
- if v and not r.vert_variants then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ end
+ r.horiz_variants = h
end
- r.vert_variants = v
- end
- if h and not r.horiz_variants then
+ else
if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ report_prepare("error replacing %C by %U",unicode,replacement)
end
- r.horiz_variants = h
end
end
end
diff --git a/tex/context/base/mkiv/font-set.mkvi b/tex/context/base/mkiv/font-set.mkvi
index fe0fb6cad..aac83e1aa 100644
--- a/tex/context/base/mkiv/font-set.mkvi
+++ b/tex/context/base/mkiv/font-set.mkvi
@@ -46,7 +46,7 @@
% \def\font_preloads_reset_nullfont % this is needed because some macro packages (tikz) misuse \nullfont
% {\dorecurse\plusseven{\fontdimen\recurselevel\nullfont\zeropoint}% keep en eye on this as:
% \clf_resetnullfont % in luatex 0.70 this will also do the previous
-% \globallet\font_preloads_reset_nullfont\relax}
+% \glet\font_preloads_reset_nullfont\relax}
\def\font_preload_check_mode
{\doifelsemode{lmmath}
diff --git a/tex/context/base/mkiv/grph-img.lua b/tex/context/base/mkiv/grph-img.lua
new file mode 100644
index 000000000..3714b649e
--- /dev/null
+++ b/tex/context/base/mkiv/grph-img.lua
@@ -0,0 +1,747 @@
+if not modules then modules = { } end modules ['grph-img'] = {
+ version = 1.001,
+ comment = "companion to grph-inc.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- The jpg identification and inclusion code is based on the code in \LUATEX\ but as we
+-- use \LUA\ we can do it a bit cleaner. We can also use some helpers for reading from
+-- file. We could make it even more lean and mean. When all works out ok I will clean
+-- up this code a bit as we can divert more from luatex.
+
+local lower, strip = string.lower, string.strip
+local round = math.round
+local concat = table.concat
+local suffixonly = file.suffix
+
+local files = utilities.files
+local getsize = files.getsize
+local readbyte = files.readbyte
+local readstring = files.readstring
+local readcardinal = files.readcardinal
+local readcardinal2 = files.readcardinal2
+local readcardinal4 = files.readcardinal4
+local readcardinal2le = files.readcardinal2le
+local readcardinal4le = files.readcardinal4le
+local skipbytes = files.skip
+local setposition = files.setposition
+local getposition = files.getposition
+
+local setmetatableindex = table.setmetatableindex
+local setmetatablecall = table.setmetatablecall
+
+local lpdf = lpdf or { }
+local pdfmajorversion = lpdf.majorversion
+local pdfminorversion = lpdf.minorversion
+
+local graphics = graphics or { }
+local identifiers = { }
+graphics.identifiers = identifiers
+
+do
+
+ local colorspaces = {
+ [1] = 1, -- gray
+ [3] = 2, -- rgb
+ [4] = 3, -- cmyk
+ }
+
+ local tags = {
+ [0xC0] = { name = "SOF0", }, -- baseline DCT
+ [0xC1] = { name = "SOF1", }, -- extended sequential DCT
+ [0xC2] = { name = "SOF2", }, -- progressive DCT
+ [0xC3] = { name = "SOF3", supported = false }, -- lossless (sequential)
+
+ [0xC5] = { name = "SOF5", supported = false }, -- differential sequential DCT
+ [0xC6] = { name = "SOF6", supported = false }, -- differential progressive DCT
+ [0xC7] = { name = "SOF7", supported = false }, -- differential lossless (sequential)
+
+ [0xC8] = { name = "JPG", }, -- reserved for JPEG extensions
+ [0xC9] = { name = "SOF9", }, -- extended sequential DCT
+ [0xCA] = { name = "SOF10", supported = false }, -- progressive DCT
+ [0xCB] = { name = "SOF11", supported = false }, -- lossless (sequential)
+
+ [0xCD] = { name = "SOF13", supported = false }, -- differential sequential DCT
+ [0xCE] = { name = "SOF14", supported = false }, -- differential progressive DCT
+ [0xCF] = { name = "SOF15", supported = false }, -- differential lossless (sequential)
+
+ [0xC4] = { name = "DHT" }, -- define Huffman table(s)
+
+ [0xCC] = { name = "DAC" }, -- define arithmetic conditioning table
+
+ [0xD0] = { name = "RST0", zerolength = true }, -- restart
+ [0xD1] = { name = "RST1", zerolength = true }, -- restart
+ [0xD2] = { name = "RST2", zerolength = true }, -- restart
+ [0xD3] = { name = "RST3", zerolength = true }, -- restart
+ [0xD4] = { name = "RST4", zerolength = true }, -- restart
+ [0xD5] = { name = "RST5", zerolength = true }, -- restart
+ [0xD6] = { name = "RST6", zerolength = true }, -- restart
+ [0xD7] = { name = "RST7", zerolength = true }, -- restart
+
+ [0xD8] = { name = "SOI", zerolength = true }, -- start of image
+ [0xD9] = { name = "EOI", zerolength = true }, -- end of image
+ [0xDA] = { name = "SOS" }, -- start of scan
+ [0xDB] = { name = "DQT" }, -- define quantization tables
+ [0xDC] = { name = "DNL" }, -- define number of lines
+ [0xDD] = { name = "DRI" }, -- define restart interval
+ [0xDE] = { name = "DHP" }, -- define hierarchical progression
+ [0xDF] = { name = "EXP" }, -- expand reference image(s)
+
+ [0xE0] = { name = "APP0" }, -- application marker, used for JFIF
+ [0xE1] = { name = "APP1" }, -- application marker
+ [0xE2] = { name = "APP2" }, -- application marker
+ [0xE3] = { name = "APP3" }, -- application marker
+ [0xE4] = { name = "APP4" }, -- application marker
+ [0xE5] = { name = "APP5" }, -- application marker
+ [0xE6] = { name = "APP6" }, -- application marker
+ [0xE7] = { name = "APP7" }, -- application marker
+ [0xE8] = { name = "APP8" }, -- application marker
+ [0xE9] = { name = "APP9" }, -- application marker
+ [0xEA] = { name = "APP10" }, -- application marker
+ [0xEB] = { name = "APP11" }, -- application marker
+ [0xEC] = { name = "APP12" }, -- application marker
+ [0xED] = { name = "APP13" }, -- application marker
+ [0xEE] = { name = "APP14" }, -- application marker, used by Adobe
+ [0xEF] = { name = "APP15" }, -- application marker
+
+ [0xF0] = { name = "JPG0" }, -- reserved for JPEG extensions
+ [0xFD] = { name = "JPG13" }, -- reserved for JPEG extensions
+ [0xFE] = { name = "COM" }, -- comment
+
+ [0x01] = { name = "TEM", zerolength = true }, -- temporary use
+ }
+
+ -- More can be found in http://www.exif.org/Exif2-2.PDF but basically we have
+ -- good old tiff tags here.
+
+ local function read_APP1_Exif(f, xres, yres, orientation) -- untested
+ local position = false
+ local readcardinal2 = readcardinal2
+ local readcardinal4 = readcardinal4
+ -- endian II|MM
+ while true do
+ position = getposition(f)
+ local b = readbyte(f)
+ if b == 0 then
+ -- next one
+ elseif b == 0x4D and readbyte(f) == 0x4D then -- M
+ -- big endian
+ break
+ elseif b == 0x49 and readbyte(f) == 0x49 then -- I
+ -- little endian
+ readcardinal2 = readcardinal2le
+ readcardinal4 = readcardinal4le
+ break
+ else
+ -- warning "bad exif data"
+ return xres, yres, orientation
+ end
+ end
+ -- version
+ local version = readcardinal2(f)
+ if version ~= 42 then
+ return xres, yres, orientation
+ end
+ -- offset to records
+ local offset = readcardinal4(f)
+ if not offset then
+ return xres, yres, orientation
+ end
+ setposition(f,position + offset)
+ local entries = readcardinal2(f)
+ if not entries or entries == 0 then
+ return xres, yres, orientation
+ end
+ local x_res, y_res, x_res_ms, y_res_ms, x_temp, y_temp
+ local res_unit, res_unit_ms
+ for i=1,entries do
+ local tag = readcardinal2(f)
+ local kind = readcardinal2(f)
+ local size = readcardinal4(f)
+ local value = 0
+ local num = 0
+ local den = 0
+ if kind == 1 or kind == 7 then -- byte | undefined
+ value = readbyte(f)
+ skipbytes(f,3)
+ elseif kind == 3 or kind == 8 then -- (un)signed short
+ value = readcardinal2(f)
+ skipbytes(f,2)
+ elseif kind == 4 or kind == 9 then -- (un)signed long
+ value = readcardinal4(f)
+ elseif kind == 5 or kind == 10 then -- (s)rational
+ local offset = readcardinal4(f)
+ local saved = getposition(f)
+ setposition(f,position+offset)
+ num = readcardinal4(f)
+ den = readcardinal4(f)
+ setposition(f,saved)
+ else -- 2 -- ascii
+ skipbytes(f,4)
+ end
+ if tag == 274 then -- orientation
+ orientation = value
+ elseif tag == 282 then -- x resolution
+ if den ~= 0 then
+ x_res = num/den
+ end
+ elseif tag == 283 then -- y resolution
+ if den ~= 0 then
+ y_res = num/den
+ end
+ elseif tag == 296 then -- resolution unit
+ if value == 2 then
+ res_unit = 1
+ elseif value == 3 then
+ res_unit = 2.54
+ end
+ elseif tag == 0x5110 then -- pixel unit
+ res_unit_ms = value == 1
+ elseif tag == 0x5111 then -- x pixels per unit
+ x_res_ms = value
+ elseif tag == 0x5112 then -- y pixels per unit
+ y_res_ms = value
+ end
+ end
+ if x_res and y_res and res_unit and res_unit > 0 then
+ x_temp = round(x_res * res_unit)
+ y_temp = round(y_res * res_unit)
+ elseif x_res_ms and y_res_ms and res_unit_ms then
+ x_temp = round(x_res_ms * 0.0254) -- in meters
+ y_temp = round(y_res_ms * 0.0254) -- in meters
+ end
+ if x_temp and a_temp and x_temp > 0 and y_temp > 0 then
+ if (x_temp ~= x_res or y_temp ~= y_res) and x_res ~= 0 and y_res ~= 0 then
+ -- exif resolution differs from already found resolution
+ elseif x_temp == 1 or y_temp == 1 then
+ -- exif resolution is kind of weird
+ else
+ return x_temp, y_temp, orientation
+ end
+ end
+ return round(xres), round(yres), orientation
+ end
+
+ function identifiers.jpg(filename)
+ local specification = {
+ filename = filename,
+ filetype = "jpg",
+ }
+ if not filename or filename == "" then
+ specification.error = "invalid filename"
+ return specification -- error
+ end
+ local f = io.open(filename,"rb")
+ if not f then
+ specification.error = "unable to open file"
+ return specification -- error
+ end
+ specification.xres = 0
+ specification.yres = 0
+ specification.orientation = 1
+ specification.totalpages = 1
+ specification.pagenum = 1
+ specification.length = 0
+ local banner = readcardinal2(f)
+ if banner ~= 0xFFD8 then
+ specification.error = "no jpeg file"
+ return specification -- error
+ end
+ local xres = 0
+ local yres = 0
+ local orientation = 1
+ local okay = false
+ local filesize = getsize(f) -- seek end
+ local majorversion = pdfmajorversion and pdfmajorversion() or 2
+ local minorversion = pdfminorversion and pdfminorversion() or 2
+ while getposition(f) < filesize do
+ local b = readbyte(f)
+ if not b then
+ break
+ elseif b ~= 0xFF then
+ if not okay then
+ -- or check for size
+ specification.error = "incomplete file"
+ end
+ break
+ end
+ local category = readbyte(f)
+ local position = getposition(f)
+ local length = 0
+ local tagdata = tags[category]
+ if not tagdata then
+ specification.error = "invalid tag"
+ break
+ elseif tagdata.supported == false then
+ specification.error = "unsupported " .. tagdata.comment
+ break
+ end
+ local name = tagdata.name
+ if name == "SOF2" then
+ if majorversion < 2 or minorversion <= 2 then
+ specification.error = "no progressive DCT in PDF <= 1.2"
+ break
+ end
+ elseif name == "SOF0" or name == "SOF1" then
+ length = readcardinal2(f)
+ specification.colordepth = readcardinal(f)
+ specification.ysize = readcardinal2(f)
+ specification.xsize = readcardinal2(f)
+ specification.colorspace = colorspaces[readcardinal(f)]
+ if not specification.colorspace then
+ specification.error = "unsupported color space"
+ break
+ end
+ okay = true
+ elseif name == "APP0" then
+ length = readcardinal2(f)
+ if length > 6 then
+ local format = readstring(f,5)
+ if format == "JFIF\000" then
+ skipbytes(f,2)
+ units = readcardinal(f)
+ xres = readcardinal2(f)
+ yres = readcardinal2(f)
+ if units == 1 then
+ -- pixels per inch
+ if xres == 1 or yres == 1 then
+ -- warning
+ end
+ elseif units == 2 then
+ -- pixels per cm */
+ xres = xres * 2.54
+ yres = yres * 2.54
+ else
+ xres = 0
+ yres = 0
+ end
+ end
+ end
+ elseif name == "APP1" then
+ length = readcardinal2(f)
+ if length > 7 then
+ local format = readstring(f,5)
+ if format == "Exif\000" then
+ xres, yres, orientation = read_APP1_Exif(f,xres,yres,orientation)
+ end
+ end
+ elseif not tagdata.zerolength then
+ length = readcardinal2(f)
+ end
+ if length > 0 then
+ setposition(f,position+length)
+ end
+ end
+ f:close()
+ if not okay then
+ specification.error = "invalid file"
+ elseif not specification.error then
+ if xres == 0 and yres ~= 0 then
+ xres = yres
+ end
+ if yres == 0 and xres ~= 0 then
+ yres = xres
+ end
+ end
+ specification.xres = xres
+ specification.yres = yres
+ specification.orientation = orientation
+ specification.length = filesize
+ return specification
+ end
+
+end
+
+do
+
+ local function read_boxhdr(specification,f)
+ local size = readcardinal4(f)
+ local kind = readstring(f,4)
+ if kind then
+ kind = strip(lower(kind))
+ else
+ kind = ""
+ end
+ if size == 1 then
+ size = readcardinal4(f) * 0xFFFF0000 + readcardinal4(f)
+ end
+ if size == 0 and kind ~= "jp2c" then -- move this
+ specification.error = "invalid size"
+ end
+ return kind, size
+ end
+
+ local function scan_ihdr(specification,f)
+ specification.ysize = readcardinal4(f)
+ specification.xsize = readcardinal4(f)
+ skipbytes(f,2) -- nc
+ specification.colordepth = readcardinal(f) + 1
+ skipbytes(f,3) -- c unkc ipr
+ end
+
+ local function scan_resc_resd(specification,f)
+ local vr_n = readcardinal2(f)
+ local vr_d = readcardinal2(f)
+ local hr_n = readcardinal2(f)
+ local hr_d = readcardinal2(f)
+ local vr_e = readcardinal(f)
+ local hr_e = readcardinal(f)
+ specification.xres = math.round((hr_n / hr_d) * math.exp(hr_e * math.log(10.0)) * 0.0254)
+ specification.yres = math.round((vr_n / vr_d) * math.exp(vr_e * math.log(10.0)) * 0.0254)
+ end
+
+ local function scan_res(specification,f,last)
+ local pos = getposition(f)
+ while true do
+ local kind, size = read_boxhdr(specification,f)
+ pos = pos + size
+ if kind == "resc" then
+ if specification.xres == 0 and specification.yres == 0 then
+ scan_resc_resd(specification,f)
+ if getposition(f) ~= pos then
+ specification.error = "invalid resc"
+ return
+ end
+ end
+ elseif tpos == "resd" then
+ scan_resc_resd(specification,f)
+ if getposition(f) ~= pos then
+ specification.error = "invalid resd"
+ return
+ end
+ elseif pos > last then
+ specification.error = "invalid res"
+ return
+ elseif pos == last then
+ break
+ end
+ if specification.error then
+ break
+ end
+ setposition(f,pos)
+ end
+ end
+
+ local function scan_jp2h(specification,f,last)
+ local okay = false
+ local pos = getposition(f)
+ while true do
+ local kind, size = read_boxhdr(specification,f)
+ pos = pos + size
+ if kind == "ihdr" then
+ scan_ihdr(specification,f)
+ if getposition(f) ~= pos then
+ specification.error = "invalid ihdr"
+ return false
+ end
+ okay = true
+ elseif kind == "res" then
+ scan_res(specification,f,pos)
+ elseif pos > last then
+ specification.error = "invalid jp2h"
+ return false
+ elseif pos == last then
+ break
+ end
+ if specification.error then
+ break
+ end
+ setposition(f,pos)
+ end
+ return okay
+ end
+
+ function identifiers.jp2(filename)
+ local specification = {
+ filename = filename,
+ filetype = "jp2",
+ }
+ if not filename or filename == "" then
+ specification.error = "invalid filename"
+ return specification -- error
+ end
+ local f = io.open(filename,"rb")
+ if not f then
+ specification.error = "unable to open file"
+ return specification -- error
+ end
+ specification.xres = 0
+ specification.yres = 0
+ specification.orientation = 1
+ specification.totalpages = 1
+ specification.pagenum = 1
+ specification.length = 0
+ local xres = 0
+ local yres = 0
+ local orientation = 1
+ local okay = false
+ local filesize = getsize(f) -- seek end
+ local majorversion = pdfmajorversion and pdfmajorversion() or 2
+ local minorversion = pdfminorversion and pdfminorversion() or 2
+ --
+ local pos = 0
+ -- signature
+ local kind, size = read_boxhdr(specification,f)
+ pos = pos + size
+ setposition(f,pos)
+ -- filetype
+ local kind, size = read_boxhdr(specification,f)
+ if kind ~= "ftyp" then
+ specification.error = "missing ftyp box"
+ return specification
+ end
+ pos = pos + size
+ setposition(f,pos)
+ while not okay do
+ local kind, size = read_boxhdr(specification,f)
+ pos = pos + size
+ if kind == "jp2h" then
+ okay = scan_jp2h(specification,f,pos)
+ elseif kind == "jp2c" and not okay then
+ specification.error = "no ihdr box found"
+ return specification
+ end
+ setposition(f,pos)
+ end
+ --
+ f:close()
+ if not okay then
+ specification.error = "invalid file"
+ elseif not specification.error then
+ if xres == 0 and yres ~= 0 then
+ xres = yres
+ end
+ if yres == 0 and xres ~= 0 then
+ yres = xres
+ end
+ end
+ specification.xres = xres
+ specification.yres = yres
+ specification.orientation = orientation
+ specification.length = filesize
+ return specification
+ end
+
+end
+
+do
+
+ -- 0 = gray "image b"
+ -- 2 = rgb "image c"
+ -- 3 = palette "image c" + "image i"
+ -- 4 = gray + alpha "image b"
+ -- 6 = rgb + alpha "image c"
+
+ -- for i=1,length/3 do
+ -- palette[i] = readstring(f,3)
+ -- end
+
+ local function grab(t,f,once)
+ if once then
+ for i=1,#t do
+ local l = t[i]
+ setposition(f,l.offset)
+ t[i] = readstring(f,l.length)
+ end
+ local data = concat(t)
+ return data
+ else
+ local data = { }
+ for i=1,#t do
+ local l = t[i]
+ setposition(f,l.offset)
+ data[i] = readstring(f,l.length)
+ end
+ return concat(data)
+ end
+ end
+
+ function identifiers.png(filename)
+ local specification = {
+ filename = filename,
+ filetype = "png",
+ }
+ if not filename or filename == "" then
+ specification.error = "invalid filename"
+ return specification -- error
+ end
+ local f = io.open(filename,"rb")
+ if not f then
+ specification.error = "unable to open file"
+ return specification -- error
+ end
+ specification.xres = 0
+ specification.yres = 0
+ specification.orientation = 1
+ specification.totalpages = 1
+ specification.pagenum = 1
+ specification.offset = 0
+ specification.length = 0
+ local filesize = getsize(f) -- seek end
+ local tables = { }
+ local banner = readstring(f,8)
+ if banner ~= "\137PNG\013\010\026\010" then
+ specification.error = "no png file"
+ return specification -- error
+ end
+ while true do
+ local position = getposition(f)
+ if position >= filesize then
+ break
+ end
+ local length = readcardinal4(f)
+ if not length then
+ break
+ end
+ local kind = readstring(f,4)
+ if kind then
+ kind = lower(kind)
+ else
+ break
+ end
+ if kind == "ihdr" then -- metadata
+ specification.xsize = readcardinal4(f)
+ specification.ysize = readcardinal4(f)
+ specification.colordepth = readcardinal(f)
+ specification.colorspace = readcardinal(f)
+ specification.compression = readcardinal(f)
+ specification.filter = readcardinal(f)
+ specification.interlace = readcardinal(f)
+ tables[kind] = true
+ elseif kind == "iend" then
+ tables[kind] = true
+ break
+ elseif kind == "phys" then
+ local x = readcardinal4(f)
+ local y = readcardinal4(f)
+ local u = readcardinal(f)
+ if u == 1 then -- meters
+ -- x = round(0.0254 * x)
+ -- y = round(0.0254 * y)
+ end
+ specification.xres = x
+ specification.yres = y
+ tables[kind] = true
+ elseif kind == "idat" or kind == "plte" or kind == "gama" or kind == "trns" then
+ local t = tables[kind]
+ if not t then
+ t = setmetatablecall(grab)
+ tables[kind] = t
+ end
+ t[#t+1] = {
+ offset = getposition(f),
+ length = length,
+ }
+ else
+ tables[kind] = true
+ end
+ setposition(f,position+length+12) -- #size #kind #crc
+ end
+ specification.tables = tables
+ return specification
+ end
+
+end
+
+do
+
+ local function gray(t,k)
+ local v = 0
+ t[k] = v
+ return v
+ end
+
+ local function rgb(t,k)
+ local v = { 0, 0, 0 }
+ t[k] = v
+ return v
+ end
+
+ local function cmyk(t,k)
+ local v = { 0, 0, 0, 0 }
+ t[k] = v
+ return v
+ end
+
+ function identifiers.bitmap(specification)
+ local xsize = specification.xsize or 0
+ local ysize = specification.ysize or 0
+ local width = specification.width or xsize * 65536
+ local height = specification.height or ysize * 65536
+ local colordepth = specification.colordepth or 1 -- 1 .. 2
+ local colorspace = specification.colorspace or 1 -- 1 .. 3
+ local pixel = false
+ local data = specification.data
+ local mask = specification.mask
+ if colorspace == 1 or colorspace == "gray" then
+ pixel = gray
+ colorspace = 1
+ elseif colorspace == 2 or colorspace == "rgb" then
+ pixel = rgb
+ colorspace = 2
+ elseif colorspace == 3 or colorspace == "cmyk" then
+ pixel = cmyk
+ colorspace = 3
+ else
+ return
+ end
+ -- maybe alpha some day
+ if colordepth == 8 then
+ colordepth = 1
+ elseif colordepth == 16 then
+ colordepth = 2
+ end
+ if colordepth > 1 then
+ -- not yet
+ return
+ end
+ if data then
+ -- assume correct data
+ else
+ data = { }
+ for i=1,ysize do
+ data[i] = setmetatableindex(pixel)
+ end
+ end
+ if mask == true then
+ mask = { }
+ for i=1,ysize do
+ mask[i] = setmetatableindex(gray)
+ end
+ end
+ local specification = {
+ xsize = xsize,
+ ysize = ysize,
+ width = width,
+ height = height,
+ colordepth = colordepth,
+ colorspace = colorspace,
+ data = data,
+ mask = mask,
+ }
+ return specification
+ end
+
+end
+
+function graphics.identify(filename,filetype)
+ local identify = filetype and identifiers[filetype]
+ if identify then
+ return identify(filename)
+ end
+ local identify = identifiers[suffixonly(filename)]
+ if identify then
+ return identify(filename)
+ end
+ -- auto
+ return {
+ filename = filename,
+ filetype = filetype,
+ error = "identification failed",
+ }
+end
+
+-- inspect(identifiers.jpg("t:/sources/hacker.jpg"))
+-- inspect(identifiers.png("t:/sources/mill.png"))
diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua
index 09084606d..553c60463 100644
--- a/tex/context/base/mkiv/grph-inc.lua
+++ b/tex/context/base/mkiv/grph-inc.lua
@@ -60,6 +60,8 @@ local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
local replacetemplate = utilities.templates.replace
+-- local bpfactor = number.dimenfactors.bp
+
local images = img
local hasscheme = url.hasscheme
@@ -2139,6 +2141,126 @@ local function pdf_checker(data)
return checkers.generic(data)
end
+local function wrappedidentify(identify,filename)
+ local wrapup = function() report_inclusion("fatal error reading %a",filename) end
+ local _, result = xpcall(identify,wrapup,filename)
+ return result or { error = "fatal error" }
+end
+
+local function jpg_checker(data)
+ local request = data.request
+ local used = data.used
+ if request and used and not request.scanimage then
+ local identify = graphics.identify
+ local inject = lpdf.injectors.jpg
+ local found = false
+ request.scanimage = function(t)
+ local filename = t.filename
+ local result = wrappedidentify(identify,filename)
+ local xsize = result.xsize or 0
+ local ysize = result.ysize or 0
+ found = not result.error
+ return {
+ filename = filename,
+ width = xsize * 65536,
+ height = ysize * 65536,
+ depth = 0,
+ colordepth = result.colordepth or 0,
+ xres = result.xres,
+ yres = result.yres,
+ xsize = xsize,
+ ysize = ysize,
+ rotation = result.rotation or 0,
+ colorspace = result.colorspace or 0,
+ }
+ end
+ request.copyimage = function(t)
+ if found then
+ found = false
+ return inject(t)
+ end
+ end
+ end
+ return checkers.generic(data)
+end
+
+local function jp2_checker(data) -- idem as jpg
+ local request = data.request
+ local used = data.used
+ if request and used and not request.scanimage then
+ local identify = graphics.identify
+ local inject = lpdf.injectors.jp2
+ local found = false
+ request.scanimage = function(t)
+ local filename = t.filename
+ local result = wrappedidentify(identify,filename)
+ local xsize = result.xsize or 0
+ local ysize = result.ysize or 0
+ found = not result.error
+ return {
+ filename = filename,
+ width = xsize * 65536,
+ height = ysize * 65536,
+ depth = 0,
+ colordepth = result.colordepth or 0,
+ xres = result.xres,
+ yres = result.yres,
+ xsize = xsize,
+ ysize = ysize,
+ rotation = result.rotation or 0,
+ colorspace = result.colorspace or 0,
+ }
+ end
+ request.copyimage = function(t)
+ if found then
+ found = false
+ return inject(t)
+ end
+ end
+ end
+ return checkers.generic(data)
+end
+
+local function png_checker(data) -- same as jpg (for now)
+ local request = data.request
+ local used = data.used
+ if request and used and not request.scanimage then
+ local identify = graphics.identify
+ local inject = lpdf.injectors.png
+ local found = false
+ request.scanimage = function(t)
+ local filename = t.filename
+ local result = wrappedidentify(identify,filename)
+ local xsize = result.xsize or 0
+ local ysize = result.ysize or 0
+ found = not result.error
+ return {
+ filename = filename,
+ width = xsize * 65536,
+ height = ysize * 65536,
+ depth = 0,
+ colordepth = result.colordepth or 0,
+ xres = result.xres,
+ yres = result.yres,
+ xsize = xsize,
+ ysize = ysize,
+ rotation = result.rotation or 0,
+ colorspace = result.colorspace or 0,
+ tables = result.tables,
+ interlace = result.interlace,
+ filter = result.filter,
+ }
+ end
+ request.copyimage = function(t)
+ if found then
+ found = false
+ return inject(t)
+ end
+ end
+ end
+ return checkers.generic(data)
+end
+
directives.register("graphics.pdf.uselua",function(v)
if v then
report("%s Lua based PDF inclusion","enabling")
@@ -2149,6 +2271,37 @@ directives.register("graphics.pdf.uselua",function(v)
end
end)
+directives.register("graphics.jpg.uselua",function(v)
+ if v then
+ report("%s Lua based JPG inclusion","enabling")
+ checkers.jpg = jpg_checker
+ else
+ report("%s Lua based JPG inclusion","disabling")
+ checkers.jpg = nil
+ end
+end)
+
+directives.register("graphics.jp2.uselua",function(v)
+ if v then
+ report("%s Lua based JP2 inclusion","enabling")
+ checkers.jp2 = jp2_checker
+ else
+ report("%s Lua based JP2 inclusion","disabling")
+ checkers.jp2 = nil
+ end
+end)
+
+directives.register("graphics.png.uselua",function(v)
+ if v then
+ report("%s Lua based PNG inclusion","enabling")
+ checkers.png = png_checker
+ else
+ report("%s Lua based PNG inclusion","disabling")
+ checkers.png = nil
+ end
+end)
+
+
-- directives.enable("graphics.pdf.uselua")
--
-- local filename = "luatex.pdf"
@@ -2160,3 +2313,62 @@ end)
-- context.stopTEXpage()
-- end)
-- end
+
+-- This is experimental, for the moment here:
+
+local bitmaps = { }
+graphics.bitmaps = bitmaps
+
+local report_bitmap = logs.reporter("graphics","bitmap")
+
+function bitmaps.new(xsize,ysize,colorspace,colordepth,mask)
+ if not xsize or not ysize or xsize == 0 or ysize == 0 then
+ report_bitmap("provide 'xsize' and 'ysize' larger than zero")
+ return
+ end
+ if not colorspace then
+ report_bitmap("provide 'colorspace' (1, 2, 3, 'gray', 'rgb', 'cmyk'")
+ return
+ end
+ if not colordepth then
+ report_bitmap("provide 'colordepth' (1, 2)")
+ return
+ end
+ return graphics.identifiers.bitmap {
+ colorspace = colorspace,
+ colordepth = colordepth,
+ xsize = xsize,
+ ysize = ysize,
+ mask = mask and true or nil,
+ }
+end
+
+local function flush(bitmap)
+ img.write(lpdf.injectors.bitmap(bitmap))
+end
+
+bitmaps.flush = flush
+
+function bitmaps.tocontext(bitmap,width,height)
+ if type(width) == "number" then
+ width = width .. "sp"
+ end
+ if type(height) == "number" then
+ height = height .. "sp"
+ end
+ if not height and not height then
+ width = bitmap.xsize .. "bp"
+ height = bitmap.ysize .. "bp"
+ end
+ context.scale (
+ {
+ width = width,
+ height = height,
+ },
+ function()
+ flush(bitmap)
+ end
+ )
+end
+
+
diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv
index 371725271..cefb114e9 100644
--- a/tex/context/base/mkiv/grph-inc.mkiv
+++ b/tex/context/base/mkiv/grph-inc.mkiv
@@ -20,6 +20,7 @@
\writestatus{loading}{ConTeXt Graphic Macros / Figure Inclusion}
+\registerctxluafile{grph-img}{}
\registerctxluafile{grph-inc}{}
\registerctxluafile{grph-con}{}
\registerctxluafile{grph-fil}{}
diff --git a/tex/context/base/mkiv/l-macro-imp-optimize.lua b/tex/context/base/mkiv/l-macro-imp-optimize.lua
index 856cab038..982548785 100644
--- a/tex/context/base/mkiv/l-macro-imp-optimize.lua
+++ b/tex/context/base/mkiv/l-macro-imp-optimize.lua
@@ -57,6 +57,7 @@ lua.macros.resolvestring [[
#define extract(a,b) ((a>>b)&0x1)
#define lshift(a,b) ((a<<b)&0xFFFFFFFF)
#define rshift(a,b) ((a>>b)&0xFFFFFFFF)
+#define intdiv(a,b) (a//b)
]]
end
diff --git a/tex/context/base/mkiv/l-number.lua b/tex/context/base/mkiv/l-number.lua
index a83e8f8f9..dc4a93b0e 100644
--- a/tex/context/base/mkiv/l-number.lua
+++ b/tex/context/base/mkiv/l-number.lua
@@ -232,3 +232,7 @@ function number.decimaltobyte(d)
return b
end
end
+
+function number.idiv(i,d)
+ return floor(i/d) -- i//d in 5.3
+end
diff --git a/tex/context/base/mkiv/lpdf-img.lua b/tex/context/base/mkiv/lpdf-img.lua
new file mode 100644
index 000000000..28890887a
--- /dev/null
+++ b/tex/context/base/mkiv/lpdf-img.lua
@@ -0,0 +1,1061 @@
+if not modules then modules = { } end modules ['lpdf-img'] = {
+ version = 1.001,
+ comment = "companion to lpdf-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat, remove, insert = table.concat, table.remove, table.insert
+local ceil = math.ceil
+local char, find = string.char, string.find
+local idiv = number.idiv
+local band, rshift = bit32.band, bit32.rshift
+
+local loaddata = io.loaddata
+local setmetatableindex = table.setmetatableindex
+
+local streams = utilities.streams
+local openstring = streams.openstring
+local readstring = streams.readstring
+local readbytetable = streams.readbytetable
+
+local lpdf = lpdf or { }
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfconstant = lpdf.constant
+local pdfstring = lpdf.string
+local pdfflushstreamobject = lpdf.flushstreamobject
+local pdfreference = lpdf.reference
+
+local pdfmajorversion = lpdf.majorversion
+local pdfminorversion = lpdf.minorversion
+
+local newimage = img.new
+
+local trace = false
+
+local report_jpg = logs.reporter("graphics","jpg")
+local report_jp2 = logs.reporter("graphics","jp2")
+local report_png = logs.reporter("graphics","png")
+
+local injectors = { }
+lpdf.injectors = injectors
+
+local chars = setmetatableindex(function(t,k) -- share this one
+ local v = (k <= 0 and "\000") or (k >= 255 and "\255") or char(k)
+ t[k] = v
+ return v
+end)
+
+do
+
+ function injectors.jpg(specification)
+ if specification.error then
+ return
+ end
+ local filename = specification.filename
+ if not filename then
+ return
+ end
+ local colorspace = specification.colorspace or jpg_gray
+ local attributes = specification.attr
+ local decodearray = nil
+ ----- procset = colorspace == 0 and "image b" or "image c"
+ if colorspace == 1 then
+ colorspace = "DeviceGray"
+ elseif colorspace == 2 then
+ colorspace = "DeviceRGB"
+ elseif colorspace == 3 then
+ colorspace = "DeviceCMYK"
+ decodearray = pdfarray { 1, 0, 1, 0, 1, 0, 1, 0 }
+ end
+ -- todo: set filename
+ local xsize = specification.xsize
+ local ysize = specification.ysize
+ local colordepth = specification.colordepth
+ local content = loaddata(filename)
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ BBox = pdfarray { 0, 0, xsize, ysize },
+ Width = xsize,
+ Height = ysize,
+ BitsPerComponent = colordepth,
+ Filter = pdfconstant("DCTDecode"),
+ ColorSpace = pdfconstant(colorspace),
+ Decode = decodearray,
+ Length = #content, -- specification.length
+ }
+ if attributes then
+ -- todo: add attributes to d
+ end
+ if trace then
+ report_jpg("%s: width %i, height %i, colordepth %i, size %i",filename,xsize,ysize,colordepth,#content)
+ end
+ return newimage {
+ bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate
+ nolength = true,
+ nobbox = true,
+ notype = true,
+ stream = content,
+ attr = xobject(),
+ }
+ end
+
+end
+
+do
+
+ function injectors.jp2(specification)
+ if specification.error then
+ return
+ end
+ local filename = specification.filename
+ if not filename then
+ return
+ end
+ local attributes = specification.attr
+ -- todo: set filename
+ local xsize = specification.xsize
+ local ysize = specification.ysize
+ local content = loaddata(filename)
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ BBox = pdfarray { 0, 0, xsize, ysize },
+ Width = xsize,
+ Height = ysize,
+ Filter = pdfconstant("JPXDecode"),
+ Length = #content, -- specification.length
+ }
+ if attributes then
+ -- todo: add attributes to d
+ end
+ if trace then
+ report_jp2("%s: width %i, height %i, size %i",filename,xsize,ysize,#content)
+ end
+ return newimage {
+ bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate
+ nolength = true,
+ nobbox = true,
+ notype = true,
+ stream = content,
+ attr = xobject(),
+ }
+ end
+
+end
+
+do
+
+ -- We don't like interlaced files. You can deinterlace them beforehand because otherwise
+ -- each run you add runtime. Actually, even masked images can best be converted to PDF
+ -- beforehand.
+
+ -- The amount of code is larger that I like and looks somewhat redundant but we sort of
+ -- optimize a few combinations that happen often.
+
+ local function convert(t,len)
+ if len then
+local n = 0
+ for i=1,#t,len do
+ t[i] = ""
+n = n + 1
+ end
+ end
+ for i=1,#t do
+ local ti = t[i]
+ if ti ~= "" then
+ t[i] = chars[ti]
+ end
+ end
+ return concat(t)
+ end
+
+ local function zero(t,k)
+ return 0
+ end
+
+ local function bump(txt,t,xsize,ysize,bpp)
+ local l = xsize * bpp + 1
+ print(txt,">",xsize,ysize,bpp,l)
+ for i=1,ysize do
+ local f = (i-1) * l + 1
+ print(txt,i,":",concat(t," ",f,f+l-1))
+ end
+ end
+
+ local function decodeall(t,xsize,ysize,bpp)
+ local len = xsize * bpp + 1
+ local n = 1
+ local m = len - 1
+ for i=1,ysize do
+ local filter = t[n]
+t[n] = 0 -- not needed
+ if filter == 0 then
+ elseif filter == 1 then
+ for j=n+bpp+1,n+m do
+ t[j] = (t[j] + t[j-bpp]) % 256
+ end
+ elseif filter == 2 then
+ for j=n+1,n+m do
+ t[j] = (t[j] + t[j-len]) % 256
+ end
+ elseif filter == 3 then
+ for j=n+1,n+bpp do
+ t[j] = (t[j] + idiv(t[j-len],2)) % 256
+ end
+ for j=n+bpp+1,n+m do
+ t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256
+ end
+ elseif filter == 4 then
+ for j=n+1,n+bpp do
+ local p = j - len
+ local b = t[p]
+ if b < 0 then
+ b = - b
+ end
+ if b > 0 then
+ t[j] = (t[j] + b) % 256
+ end
+ end
+ for j=n+bpp+1,n+m do
+ local p = j - len
+ local a = t[j-bpp]
+ local b = t[p]
+ local c = t[p-bpp]
+ local pa = b - c
+ local pb = a - c
+ local pc = pa + pb
+ if pa < 0 then pa = - pa end
+ if pb < 0 then pb = - pb end
+ if pc < 0 then pc = - pc end
+ t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256
+ end
+ end
+ n = n + len
+ end
+ end
+
+ local xstart = { 0, 4, 0, 2, 0, 1, 0 }
+ local xstep = { 8, 8, 4, 4, 2, 2, 1 }
+ local ystart = { 0, 0, 4, 0, 2, 0, 1 }
+ local ystep = { 8, 8, 8, 4, 4, 2, 2 }
+ ----- xmax = { 8, 4, 4, 2, 2, 1, 1 } -- for block fill
+ ----- ymax = { 8, 8, 4, 4, 2, 2, 1 } -- for block fill
+
+ local function newoutput(width,height)
+ local t = { }
+ for i=1,height*width do
+ t[i] = 0
+ end
+ return t
+ end
+
+ local function expand(t,xsize,ysize,parts,factor) -- we don't compact
+ local o = { }
+ local k = 0
+ local l = ceil(xsize*parts/8) + 1
+ local n = 1
+ if factor then
+ if parts == 4 then
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,4),0x0F) * 0x11 ; k = k + 1 ; o[k] = band(rshift(v,0),0x0F) * 0x11
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ elseif parts == 2 then
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,6),0x03) * 0x55 ; k = k + 1 ; o[k] = band(rshift(v,4),0x03) * 0x55
+ k = k + 1 ; o[k] = band(rshift(v,2),0x03) * 0x55 ; k = k + 1 ; o[k] = band(rshift(v,0),0x03) * 0x55
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ else
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,7),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,6),0x01) * 0xFF
+ k = k + 1 ; o[k] = band(rshift(v,5),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,4),0x01) * 0xFF
+ k = k + 1 ; o[k] = band(rshift(v,3),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,2),0x01) * 0xFF
+ k = k + 1 ; o[k] = band(rshift(v,1),0x01) * 0xFF ; k = k + 1 ; o[k] = band(rshift(v,0),0x01) * 0xFF
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ end
+ else
+ if parts == 4 then
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,4),0x0F) ; k = k + 1 ; o[k] = band(rshift(v,0),0x0F)
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ elseif parts == 2 then
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,6),0x03) ; k = k + 1 ; o[k] = band(rshift(v,4),0x03)
+ k = k + 1 ; o[k] = band(rshift(v,2),0x03) ; k = k + 1 ; o[k] = band(rshift(v,0),0x03)
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ else
+ for i=1,ysize do
+ k = k + 1 ; o[k] = t[n]
+ for j=n+1,n+l do
+ local v = t[j]
+ k = k + 1 ; o[k] = band(rshift(v,7),0x01) ; k = k + 1 ; o[k] = band(rshift(v,6),0x01)
+ k = k + 1 ; o[k] = band(rshift(v,5),0x01) ; k = k + 1 ; o[k] = band(rshift(v,4),0x01)
+ k = k + 1 ; o[k] = band(rshift(v,3),0x01) ; k = k + 1 ; o[k] = band(rshift(v,2),0x01)
+ k = k + 1 ; o[k] = band(rshift(v,1),0x01) ; k = k + 1 ; o[k] = band(rshift(v,0),0x01)
+ end
+ k = i * (xsize + 1)
+ n = n + l
+ end
+ end
+ end
+ for i=#o,k+1,-1 do
+ o[i] = nil
+ end
+ return o
+ end
+
+ local function deinterlaceXX(s,xsize,ysize,bytes,parts,factor)
+ local output = newoutput(xsize*bytes,ysize)
+ for pass=1,7 do
+ local ystart = ystart[pass]
+ local ystep = ystep[pass]
+ local xstart = xstart[pass]
+ local xstep = xstep[pass]
+ local nx = idiv(xsize + xstep - xstart - 1,xstep)
+ local ny = idiv(ysize + ystep - ystart - 1,ystep)
+ if nx > 0 and ny > 0 then
+ local input
+ if parts then
+ local nxx = ceil(nx*parts/8)
+ input = readbytetable(s,ny*(nxx+1))
+ setmetatableindex(input,zero)
+ decodeall(input,nxx,ny,bytes)
+ input = expand(input,nx,ny,parts,factor)
+ else
+ input = readbytetable(s,ny*(nx*bytes+1))
+ setmetatableindex(input,zero)
+ decodeall(input,nx,ny,bytes)
+ end
+ local l = nx*bytes + 1
+ for i=ny,1,-1 do
+ remove(input,(i-1)*l+1)
+ end
+ local xstep = xstep * bytes
+ local xstart = xstart * bytes
+ local xsize = xsize * bytes
+ local target = ystart * xsize + xstart + 1
+ local ystep = ystep * xsize
+ local start = 1
+ local blobs = bytes - 1
+ for j=0,ny-1 do
+ local target = target + j * ystep
+ for i=1,nx do
+ for i=0,blobs do
+ output[target+i] = input[start]
+ start= start + 1
+ end
+ target = target + xstep
+ end
+ end
+ end
+ end
+ return output
+ end
+
+ local function deinterlaceYY(s,xsize,ysize,bytes,parts,factor)
+ local input
+ if parts then
+ local nxx = ceil(xsize*parts/8)
+ input = readbytetable(s,ysize*(nxx+1))
+ setmetatableindex(input,zero)
+ decodeall(input,nxx,ysize,bytes)
+ input = expand(input,xsize,ysize,parts,factor)
+ else
+ input = readbytetable(s,ysize*(xsize*bytes+1))
+ setmetatableindex(input,zero)
+ decodeall(input,xsize,ysize,bytes)
+ end
+ local l = xsize*bytes + 1
+ local n = 1
+ for i=1,ysize do
+ input[n] = ""
+ n = n + l
+ end
+ return input
+ end
+
+ local function analyze(colordepth,colorspace,palette,mask)
+ local bytes, parts, factor
+ if palette then
+ if colordepth == 16 then
+ return 2, false, false
+ elseif colordepth == 8 then
+ return 1, false, false
+ elseif colordepth == 4 then
+ return 1, 4, false
+ elseif colordepth == 2 then
+ return 1, 2, false
+ elseif colordepth == 1 then
+ return 1, 1, false
+ end
+ elseif colorspace == "DeviceGray" then
+ if colordepth == 16 then
+ return mask and 4 or 2, false, false
+ elseif colordepth == 8 then
+ return mask and 2 or 1, false, false
+ elseif colordepth == 4 then
+ return 1, 4, true
+ elseif colordepth == 2 then
+ return 1, 2, true
+ elseif colordepth == 1 then
+ return 1, 1, true
+ end
+ else
+ if colordepth == 16 then
+ return mask and 8 or 6, false, false
+ elseif colordepth == 8 then
+ return mask and 4 or 3, false, false
+ elseif colordepth == 4 then
+ return 3, 4, true
+ elseif colordepth == 2 then
+ return 3, 2, true
+ elseif colordepth == 1 then
+ return 3, 1, true
+ end
+ end
+ return false, false, false
+ end
+
+ local function deinterlace(content,xsize,ysize,colordepth,colorspace,palette,mask)
+ local bytes, parts, factor = analyze(colordepth,colorspace,palette,mask)
+ if bytes then
+ content = zlib.decompress(content)
+ local s = openstring(content)
+ local r = deinterlaceXX(s,xsize,ysize,bytes,parts,factor)
+ return r, parts and 8 or false
+ end
+ end
+
+ local function decompose(content,xsize,ysize,colordepth,colorspace,palette,mask)
+ local bytes, parts, factor = analyze(colordepth,colorspace,palette,mask)
+ if bytes then
+ content = zlib.decompress(content)
+ local s = openstring(content)
+ local r = deinterlaceYY(s,xsize,ysize,bytes,parts,factor)
+ return r, parts and 8 or false
+ end
+ end
+
+ -- 1 (palette used), 2 (color used), and 4 (alpha channel used)
+
+ -- paeth:
+ --
+ -- p = a + b - c
+ -- pa = abs(p - a) => a + b - c - a => b - c
+ -- pb = abs(p - b) => a + b - c - b => a - c
+ -- pc = abs(p - c) => a + b - c - c => a + b - c - c => a - c + b - c => pa + pb
+
+ local function prepareimage(content,xsize,ysize,depth,colorspace,mask)
+ local bpp = (depth == 16 and 2 or 1) * ((colorspace == "DeviceRGB" and 3 or 1) + mask) local len = bpp * xsize + 1
+ local s = openstring(content)
+ local t = readbytetable(s,#content)
+ setmetatableindex(t,zero)
+ return t, bpp, len
+ end
+
+ local function filtermask08(xsize,ysize,t,bpp,len,n)
+ local mask = { }
+ local l = 0
+ local m = len - n
+ for i=1,ysize do
+ for j=n+bpp,n+m,bpp do
+ l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = ""
+ end
+ n = n + len
+ end
+ return concat(mask)
+ end
+
+ local function filtermask16(xsize,ysize,t,bpp,len,n)
+ local mask = { }
+ local l = 0
+ local m = len - n
+ for i=1,ysize do
+ for j=n+bpp-1,n+m-1,bpp do
+ l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = ""
+ j = j + 1
+ l = l + 1 ; mask[l] = chars[t[j]] ; t[j] = ""
+ end
+ n = n + len
+ end
+ return concat(mask)
+ end
+
+ local function decodemask08(content,xsize,ysize,depth,colorspace)
+ local t, bpp, len = prepareimage(content,xsize,ysize,depth,colorspace,1)
+ local bpp2 = mask and (bpp + bpp) or bpp
+ local n = 1
+ local m = len - 1
+ for i=1,ysize do
+ local filter = t[n]
+ if filter == 0 then
+ elseif filter == 1 then
+ for j=n+bpp2,n+m,bpp do
+ t[j] = (t[j] + t[j-bpp]) % 256
+ end
+ elseif filter == 2 then
+ for j=n+bpp,n+m,bpp do
+ t[j] = (t[j] + t[j-len]) % 256
+ end
+ elseif filter == 3 then
+ local j = n + bpp
+ t[j] = (t[j] + idiv(t[j-len],2)) % 256
+ for j=n+bpp2,n+m,bpp do
+ t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256
+ end
+ elseif filter == 4 then
+ local j = n + bpp
+ local p = j - len
+ local b = t[p]
+ if b < 0 then
+ b = - b
+ end
+ if b > 0 then
+ t[j] = (t[j] + b) % 256
+ end
+ for j=n+bpp2,n+m,bpp do
+ local p = j - len
+ local a = t[j-bpp]
+ local b = t[p]
+ local c = t[p-bpp]
+ local pa = b - c
+ local pb = a - c
+ local pc = pa + pb
+ if pa < 0 then pa = - pa end
+ if pb < 0 then pb = - pb end
+ if pc < 0 then pc = - pc end
+ t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256
+ end
+ end
+ n = n + len
+ end
+ local mask = filtermask08(xsize,ysize,t,bpp,len,1)
+ return convert(t), mask
+ end
+
+ local function decodemask16(content,xsize,ysize,depth,colorspace)
+ local t, bpp, len = prepareimage(content,xsize,ysize,depth,colorspace,1)
+ local bpp2 = bpp + bpp
+ local n = 1
+ local m = len - 1
+ for i=1,ysize do
+ local filter = t[n]
+ if filter == 0 then
+ elseif filter == 1 then
+ for j=n+bpp2,n+m,bpp do
+ local k = j - 1
+ t[j] = (t[j] + t[j-bpp]) % 256
+ t[k] = (t[k] + t[k-bpp]) % 256
+ end
+ elseif filter == 2 then
+ for j=n+bpp,n+m,bpp do
+ local k = j - 1
+ t[j] = (t[j] + t[j-len]) % 256
+ t[k] = (t[k] + t[k-len]) % 256
+ end
+ elseif filter == 3 then
+ local j = n + bpp
+ local k = j - 1
+ t[j] = (t[j] + idiv(t[j-len],2)) % 256
+ t[k] = (t[k] + idiv(t[k-len],2)) % 256
+ for j=n+bpp2,n+m,bpp do
+ local k = j - 1
+ t[j] = (t[j] + idiv(t[j-bpp] + t[j-len],2)) % 256
+ t[k] = (t[k] + idiv(t[k-bpp] + t[k-len],2)) % 256
+ end
+ elseif filter == 4 then
+ for i=-1,0 do
+ local j = n + bpp + i
+ local p = j - len
+ local b = t[p]
+ if b < 0 then
+ b = - b
+ end
+ if b > 0 then
+ t[j] = (t[j] + b) % 256
+ end
+ for j=n+i+bpp2,n+i+m,bpp do
+ local p = j - len
+ local a = t[j-bpp]
+ local b = t[p]
+ local c = t[p-bpp]
+ local pa = b - c
+ local pb = a - c
+ local pc = pa + pb
+ if pa < 0 then pa = - pa end
+ if pb < 0 then pb = - pb end
+ if pc < 0 then pc = - pc end
+ t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256
+ end
+ end
+ end
+ n = n + len
+ end
+ local mask = filtermask16(xsize,ysize,t,bpp,len,1)
+ return convert(t), mask
+ end
+
+ local function full(t,k) local v = "\xFF" t[k] = v return v end
+
+ local function create(content,palette,transparent,xsize,ysize,colordepth,colorspace)
+ if palette then
+ --
+ local s = openstring(transparent)
+ local n = #transparent
+ local r = { }
+ for i=0,n-1 do
+ r[i] = readstring(s,1)
+ end
+ setmetatableindex(r,full)
+ --
+ local c = zlib.decompress(content)
+ local s = openstring(c)
+ --
+ local o = { }
+ local len = ceil(xsize*colordepth/8) + 1
+ local m = len - 1
+ local u = setmetatableindex(zero)
+ --
+ for i=1,ysize do
+ local t = readbytetable(s,len)
+ local k = (i-1) * xsize
+ local filter = t[1]
+ if filter == 0 then
+ elseif filter == 1 then
+ for j=3,len do
+ t[j] = (t[j] + t[j-1]) % 256
+ end
+ elseif filter == 2 then
+ for j=2,len do
+ t[j] = (t[j] + u[j]) % 256
+ end
+ elseif filter == 3 then
+ local j = 2
+ t[j] = (t[j] + idiv(u[j],2)) % 256
+ for j=3,len do
+ t[j] = (t[j] + idiv(t[j-1] + u[j],2)) % 256
+ end
+ elseif filter == 4 then
+ local j = 2
+ local p = j - len
+ local b = t[p]
+ if b < 0 then
+ b = - b
+ end
+ if b > 0 then
+ t[j] = (t[j] + b) % 256
+ end
+ for j=3,len do
+ local p = j - len
+ local a = t[j-1]
+ local b = t[p]
+ local c = t[p-1]
+ local pa = b - c
+ local pb = a - c
+ local pc = pa + pb
+ if pa < 0 then pa = - pa end
+ if pb < 0 then pb = - pb end
+ if pc < 0 then pc = - pc end
+ t[j] = (t[j] + ((pa <= pb and pa <= pc and a) or (pb <= pc and b) or c)) % 256
+ end
+ end
+ if colordepth == 8 then
+ for j=2,len do
+ local v = t[j]
+ k = k + 1 ; o[k] = r[v] or "\xFF"
+ end
+ elseif colordepth == 4 then
+ for j=2,len do
+ local v = t[j]
+ k = k + 1 ; o[k] = r[band(rshift(v,4),0x0F)]
+ k = k + 1 ; o[k] = r[band(rshift(v,0),0x0F)]
+ end
+ elseif colordepth == 2 then
+ for j=2,len do
+ local v = t[j]
+ k = k + 1 ; o[k] = r[band(rshift(v,6),0x03)]
+ k = k + 1 ; o[k] = r[band(rshift(v,4),0x03)]
+ k = k + 1 ; o[k] = r[band(rshift(v,2),0x03)]
+ k = k + 1 ; o[k] = r[band(rshift(v,0),0x03)]
+ end
+ else
+ for j=2,len do
+ local v = t[j]
+ k = k + 1 ; o[k] = r[band(rshift(v,7),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,6),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,5),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,4),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,3),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,2),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,2),0x01)]
+ k = k + 1 ; o[k] = r[band(rshift(v,1),0x01)]
+ end
+ end
+ u = t
+ end
+ return concat(o,"",1,ysize * xsize)
+ end
+ end
+
+ local alwaysdecode = false
+
+ directives.register("graphics.png.decode", function(v)
+ alwaysdecode = v
+ end)
+
+ function injectors.png(specification)
+ if specification.error then
+ return
+ end
+ local filename = specification.filename
+ if not filename then
+ return
+ end
+ local colorspace = specification.colorspace
+ if not colorspace then
+ return
+ end
+ local interlace = specification.interlace or 0
+ if interlace == 1 then
+ interlace = true
+ elseif interlace == 0 then
+ interlace = false
+ else
+ report_png("unknown interlacing %i",interlace)
+ return
+ end
+ local tables = specification.tables
+ if not tables then
+ return
+ end
+ local idat = tables.idat
+ if not idat then
+ return
+ end
+ local pngfile = io.open(filename,"rb")
+ if not pngfile then
+ return
+ end
+ local content = idat(pngfile,true)
+ tables.idat = false
+ --
+ -- if tables.gama then
+ -- report_png("ignoring gamma correction")
+ -- end
+ --
+ local xsize = specification.xsize
+ local ysize = specification.ysize
+ local colordepth = specification.colordepth or 8
+ local mask = false
+ local transparent = false
+ local palette = false
+ local colors = 1
+ if colorspace == 0 then -- gray | image b
+ colorspace = "DeviceGray"
+ transparent = true
+ elseif colorspace == 2 then -- rgb | image c
+ colorspace = "DeviceRGB"
+ colors = 3
+ transparent = true
+ elseif colorspace == 3 then -- palette | image c+i
+ colorspace = "DeviceRGB"
+ palette = true
+ transparent = true
+ elseif colorspace == 4 then -- gray | alpha | image b
+ colorspace = "DeviceGray"
+ mask = true
+ elseif colorspace == 6 then -- rgb | alpha | image c
+ colorspace = "DeviceRGB"
+ colors = 3
+ mask = true
+ else
+ report_png("unknown colorspace %i",colorspace)
+ return
+ end
+ --
+ if transparent then
+ local trns = tables.trns
+ if trns then
+ transparent = trns(pngfile,true)
+ if transparent == "" then
+ transparent = false
+ end
+ tables.trns = false
+ else
+ transparent = false
+ end
+ end
+ --
+ local decode = alwaysdecode
+ local major = pdfmajorversion()
+ local minor = pdfminorversion()
+ if major > 1 then
+ -- we're okay
+ elseif minor < 5 and colordepth == 16 then
+ report_png("16 bit colordepth not supported in pdf < 1.5")
+ return
+ elseif minor < 4 and (mask or transparent) then
+ report_png("alpha channels not supported in pdf < 1.4")
+ return
+ elseif minor < 2 then
+ decode = true
+ end
+ --
+ -- todo: compresslevel (or delegate)
+ --
+ if palette then
+ local plte = tables.plte
+ if plte then
+ palette = plte(pngfile,true)
+ if palette == "" then
+ palette = false
+ end
+ tables.plte = false
+ else
+ palette = false
+ end
+ end
+ --
+ if interlace then
+ local r, p = deinterlace(content,xsize,ysize,colordepth,colorspace,palette,mask)
+ if not r then
+ return
+ end
+ if p then
+ colordepth = p
+ end
+ if mask then
+ local bpp = (colordepth == 16 and 2 or 1) * ((colorspace == "DeviceRGB" and 3 or 1) + 1)
+ local len = bpp * xsize -- + 1
+ if colordepth == 8 then -- bpp == 1
+ mask = filtermask08(xsize,ysize,r,bpp,len,0)
+ elseif colordepth == 16 then -- bpp == 2
+ mask = filtermask16(xsize,ysize,r,bpp,len,0)
+ else
+ report_png("mask can't be split from the image")
+ return
+ end
+ end
+ decode = true
+ content = convert(r)
+ content = zlib.compress(content)
+ elseif mask then
+ local decoder
+ if colordepth == 8 then
+ decoder = decodemask08
+ elseif colordepth == 16 then
+ decoder = decodemask16
+ end
+ if not decoder then
+ report_png("mask can't be split from the image")
+ return
+ end
+ content = zlib.decompress(content)
+ content, mask = decoder(content,xsize,ysize,colordepth,colorspace)
+ content = zlib.compress(content)
+ decode = false
+ elseif transparent then
+ if palette then
+ mask = create(content,palette,transparent,xsize,ysize,colordepth,colorspace)
+ else
+ pallette = false
+ end
+ elseif decode then
+ local r, p = decompose(content,xsize,ysize,colordepth,colorspace,palette)
+ if not r then
+ return
+ end
+ if p then
+ colordepth = p
+ end
+ content = convert(r)
+ content = zlib.compress(content)
+ end
+ if palette then
+ palette = pdfarray {
+ pdfconstant("Indexed"),
+ pdfconstant("DeviceRGB"),
+ idiv(#palette,3),
+ pdfreference(pdfflushstreamobject(palette)),
+ }
+ end
+ pngfile:close()
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ BBox = pdfarray { 0, 0, xsize, ysize },
+ Width = xsize,
+ Height = ysize,
+ BitsPerComponent = colordepth,
+ Filter = pdfconstant("FlateDecode"),
+ ColorSpace = palette or pdfconstant(colorspace),
+ Length = #content,
+ }
+ if mask then
+ local d = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ Width = xsize,
+ Height = ysize,
+ BitsPerComponent = palette and 8 or colordepth,
+ ColorSpace = pdfconstant("DeviceGray"),
+ }
+ xobject.SMask = pdfreference(pdfflushstreamobject(mask,d()))
+ end
+ if not decode then
+ xobject.DecodeParms = pdfdictionary {
+ Colors = colors,
+ Columns = xsize,
+ BitsPerComponent = colordepth,
+ Predictor = 15,
+ }
+ end
+ if attributes then
+ -- todo: add attributes to d
+ end
+ if trace then
+ report_png("%s: width %i, height %i, colordepth: %i, size: %i, palette %l, mask: %l, transparent %l, decode %l",filename,xsize,ysize,colordepth,#content,palette,mask,transparent,decode)
+ end
+ return newimage {
+ bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate
+ nolength = true,
+ nobbox = true,
+ notype = true,
+ stream = content,
+ attr = xobject(),
+ }
+ end
+
+end
+
+do
+
+ local function pack(specification,what)
+ local t = { }
+ local n = 0
+ local s = specification.colorspace
+ local d = specification.data
+ local x = specification.xsize
+ local y = specification.ysize
+ if what == "mask" then
+ d = specification.mask
+ s = 1
+ end
+ if s == 1 then
+ for i=1,y do
+ local r = d[i]
+ for j=1,x do
+ n = n + 1 ; t[n] = chars[r[j]]
+ end
+ end
+ elseif s == 2 then
+ for i=1,y do
+ local r = d[i]
+ for j=1,x do
+ local c = r[j]
+ n = n + 1 ; t[n] = chars[c[1]]
+ n = n + 1 ; t[n] = chars[c[2]]
+ n = n + 1 ; t[n] = chars[c[3]]
+ end
+ end
+ elseif s == 3 then
+ for i=1,y do
+ local r = d[i]
+ for j=1,x do
+ local c = r[j]
+ n = n + 1 ; t[n] = chars[c[1]]
+ n = n + 1 ; t[n] = chars[c[2]]
+ n = n + 1 ; t[n] = chars[c[3]]
+ n = n + 1 ; t[n] = chars[c[4]]
+ end
+ end
+ end
+ return concat(t)
+ end
+
+ function injectors.bitmap(specification)
+ local data = specification.data
+ if not data then
+ return
+ end
+ local xsize = specification.xsize or 0
+ local ysize = specification.ysize or 0
+ if xsize == 0 or ysize == 0 then
+ return
+ end
+ local colorspace = specification.colorspace or 1
+ if colorspace == 1 then
+ colorspace = "DeviceGray"
+ elseif colorspace == 2 then
+ colorspace = "DeviceRGB"
+ elseif colorspace == 3 then
+ colorspace = "DeviceCMYK"
+ end
+ local colordepth = (specification.colordepth or 2) == 16 or 8
+ local content = pack(specification,"data")
+ local mask = specification.mask
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ BBox = pdfarray { 0, 0, xsize, ysize },
+ Width = xsize,
+ Height = ysize,
+ BitsPerComponent = colordepth,
+ ColorSpace = pdfconstant(colorspace),
+ Length = #content, -- specification.length
+ }
+ if mask then
+ local d = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Image"),
+ Width = xsize,
+ Height = ysize,
+ BitsPerComponent = colordepth,
+ ColorSpace = pdfconstant("DeviceGray"),
+ }
+ xobject.SMask = pdfreference(pdfflushstreamobject(pack(specification,"mask"),d()))
+ end
+ return newimage {
+ bbox = { 0, 0, specification.width/xsize, specification.height/ysize }, -- mandate
+ -- nolength = true,
+ nobbox = true,
+ notype = true,
+ stream = content,
+ attr = xobject(),
+ }
+ end
+
+end
diff --git a/tex/context/base/mkiv/pack-com.mkiv b/tex/context/base/mkiv/pack-com.mkiv
index b69f812e5..badda0127 100644
--- a/tex/context/base/mkiv/pack-com.mkiv
+++ b/tex/context/base/mkiv/pack-com.mkiv
@@ -437,10 +437,10 @@
\nointerlineskip % indeed
\combinationparameter\c!inbetween
\global\c_pack_combinations_x\c_pack_combinations_max
- \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes
+ \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes
\else
\global\setbox\b_pack_combinations_captions\emptybox
- \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop
+ \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop
\fi}%
\pack_combinations_flush_captions_indeed
\crcr}
diff --git a/tex/context/base/mkiv/pack-lyr.mkiv b/tex/context/base/mkiv/pack-lyr.mkiv
index 99a0dfb2a..e7070cfde 100644
--- a/tex/context/base/mkiv/pack-lyr.mkiv
+++ b/tex/context/base/mkiv/pack-lyr.mkiv
@@ -293,8 +293,8 @@
{\setbox\b_layers\emptybox
\d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax
\d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax
- \globallet\lastlayerxpos\!!zeropoint
- \globallet\lastlayerypos\!!zeropoint
+ \glet\lastlayerxpos\!!zeropoint
+ \glet\lastlayerypos\!!zeropoint
\doifinset\v!bottom\p_pack_layers_corner\pack_layers_set_bottom_positions
\doifinset\v!right \p_pack_layers_corner\pack_layers_set_right_positions
\doifinset\v!middle\p_pack_layers_corner\pack_layers_set_middle_positions
diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi
index 4348d6770..6470a8094 100644
--- a/tex/context/base/mkiv/page-lin.mkvi
+++ b/tex/context/base/mkiv/page-lin.mkvi
@@ -275,8 +275,8 @@
\fi\fi\fi
\fi
\the\beforeeverylinenumbering
- \globallet\page_postprocessors_page \page_postprocessors_linenumbers_page
- \globallet\page_postprocessors_column\page_postprocessors_linenumbers_column
+ \glet\page_postprocessors_page \page_postprocessors_linenumbers_page
+ \glet\page_postprocessors_column\page_postprocessors_linenumbers_column
\global\settrue\page_postprocessors_needed_box % see core-rul.mkiv
\ifcase\c_page_lines_mode\relax
\page_lines_start_update % continue
diff --git a/tex/context/base/mkiv/page-set.mkiv b/tex/context/base/mkiv/page-set.mkiv
index f2755195a..dd145b322 100644
--- a/tex/context/base/mkiv/page-set.mkiv
+++ b/tex/context/base/mkiv/page-set.mkiv
@@ -487,7 +487,7 @@
\let\OTRSETbalht\zeropoint
\def\OTRSETreducegridbox % for the moment no difference between methods
- {\globallet\OTRSETbalht\zeropoint
+ {\glet\OTRSETbalht\zeropoint
\ifcase\OTRSETbalancemethod
% no balancing
\else
@@ -578,7 +578,7 @@
\else
\page_otr_construct_and_shipout\box\OTRfinalpagebox\zerocount % three arguments
\fi \fi
- \globallet\OTRSETbalht\zeropoint
+ \glet\OTRSETbalht\zeropoint
\egroup
\fi}
@@ -1624,12 +1624,12 @@
\ifnum\columnsetlevel=\plusone
\bgroup
\saveinterlinespace
- \globallet\columnsetpage\!!plusone
+ \glet\columnsetpage\!!plusone
\def\currentcolumnset{#2}%
\insidecolumnstrue % will be different flag in addition
\setupoutputroutine[\s!columnset]%
\doifelsenothing{#1}
- {\globallet\OTRSETlist\s!default}
+ {\glet\OTRSETlist\s!default}
{\xdef\OTRSETlist{#1}}%
\OTRSETstartnextpage
\OTRSETassignwidths
@@ -1659,7 +1659,7 @@
\global\setbox\OTRfinalpagebox\OTRSETmakegridbox
\ht\OTRfinalpagebox\textheight % signals output that there is content
\OTRSETdofinaloutput
- \globallet\OTRSETbalht\zeropoint
+ \glet\OTRSETbalht\zeropoint
\egroup}
{}}
diff --git a/tex/context/base/mkiv/scrn-fld.mkvi b/tex/context/base/mkiv/scrn-fld.mkvi
index 41d117480..7710a32dc 100644
--- a/tex/context/base/mkiv/scrn-fld.mkvi
+++ b/tex/context/base/mkiv/scrn-fld.mkvi
@@ -480,7 +480,7 @@
\let\resetfields\relax
-\def\scrn_field_load_scripts{\useJSscripts[fld]\globallet\scrn_field_load_scripts\relax}
+\def\scrn_field_load_scripts{\useJSscripts[fld]\glet\scrn_field_load_scripts\relax}
\newconditional\fieldlabelshown
\newconditional\fieldframeshown
diff --git a/tex/context/base/mkiv/spac-pag.mkiv b/tex/context/base/mkiv/spac-pag.mkiv
index 89a5ce36d..9adc591ed 100644
--- a/tex/context/base/mkiv/spac-pag.mkiv
+++ b/tex/context/base/mkiv/spac-pag.mkiv
@@ -170,9 +170,9 @@
\fi
\ifpagechanged
\letgvalue{\??pagechanges#2:#1}\m_spac_pagestates_realpage
- \globallet\lastchangedpage\m_spac_pagestates_realpage
+ \glet\lastchangedpage\m_spac_pagestates_realpage
\else
- \globallet\lastchangedpage\realfolio
+ \glet\lastchangedpage\realfolio
\fi}
\def\changedpagestate#1#2%
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 31155292e..20a7f18e1 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index b1227d969..b48b2651a 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-con.mkvi b/tex/context/base/mkiv/strc-con.mkvi
index 0e5f3d8a5..d67307ba7 100644
--- a/tex/context/base/mkiv/strc-con.mkvi
+++ b/tex/context/base/mkiv/strc-con.mkvi
@@ -1016,9 +1016,9 @@
\fi \fi
\fi
\ifx\currentconstructionlist\empty
- \globallet\currentconstructionlist\currentconstructiontitle
+ \glet\currentconstructionlist\currentconstructiontitle
\fi
- \globallet\currentconstructioncoding\s!tex
+ \glet\currentconstructioncoding\s!tex
\fi
%
\ifx\currentconstructiontitle\v!none % will become obsolete
diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi
index 805a6edc7..28fa950c7 100644
--- a/tex/context/base/mkiv/strc-flt.mkvi
+++ b/tex/context/base/mkiv/strc-flt.mkvi
@@ -425,7 +425,7 @@
%D {\global\advance\c_strc_floats_n\plusone
%D \xdef\strc_float_realpage{\datasetvariable\s!float{\number\c_strc_floats_n}\s!page}%
%D \ifx\strc_float_realpage\empty
-%D \globallet\strc_float_realpage\realpageno % \realfolio
+%D \glet\strc_float_realpage\realpageno % \realfolio
%D \fi}
%D \stoptyping
%D
@@ -444,7 +444,7 @@
{\global\advance\c_strc_floats_n\plusone
\xdef\strc_float_realpage{\pagestaterealpage\s!float{\number\c_strc_floats_n}}%
\ifx\strc_float_realpage\empty
- \globallet\strc_float_realpage\realpageno % \realfolio
+ \glet\strc_float_realpage\realpageno % \realfolio
\fi}
%D test case:
@@ -955,9 +955,9 @@
\def\strc_floats_place_packaged_boxes_indeed#userdata%
{\bgroup
\ifconditional\usesamefloatnumber
- \globallet\currentfloatnumber \previousfloatnumber
- \globallet\currentfloatattribute \empty
- \globallet\currentfloatsynchronize\relax
+ \glet\currentfloatnumber \previousfloatnumber
+ \glet\currentfloatattribute \empty
+ \glet\currentfloatsynchronize\relax
\else
\edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}%
\edef\currentfloatgroup {\floatcaptionparameter\c!group}%
@@ -989,10 +989,10 @@
\s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,%
\s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi]%
[#userdata]%
- \globallet\previousfloatnumber \m_strc_counters_last_registered_index
- \globallet\currentfloatnumber \m_strc_counters_last_registered_index
- \globallet\currentfloatattribute \m_strc_counters_last_registered_attribute
- \globallet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
+ \glet\previousfloatnumber \m_strc_counters_last_registered_index
+ \glet\currentfloatnumber \m_strc_counters_last_registered_index
+ \glet\currentfloatattribute \m_strc_counters_last_registered_attribute
+ \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
\fi
%
\global\setfalse\usesamefloatnumber % one shot
diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv
index 89912d904..0b80a26cd 100644
--- a/tex/context/base/mkiv/strc-mat.mkiv
+++ b/tex/context/base/mkiv/strc-mat.mkiv
@@ -208,9 +208,9 @@
\c!reference=#1,\c!title=\namedformulaentry,\c!bookmark=]%
[#2]%
\glet\namedformulaentry\empty % \relax
- \globallet#3\m_strc_counters_last_registered_index
- \globallet#4\m_strc_counters_last_registered_synchronize
- \globallet#5\m_strc_counters_last_registered_attribute}
+ \glet#3\m_strc_counters_last_registered_index
+ \glet#4\m_strc_counters_last_registered_synchronize
+ \glet#5\m_strc_counters_last_registered_attribute}
% modes: 0=unset, 1=forced, 2=none, 3=reference
diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index 403247b9c..3ce01ef34 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -456,7 +456,7 @@
\edef\currentnotenumber{\clf_storenote{\currentnote}\currentconstructionlistentry}%
\settrue\processingnote
\ifconditional\c_strc_notes_skip
- \globallet\lastnotesymbol\strc_notes_inject_symbol_nop
+ \glet\lastnotesymbol\strc_notes_inject_symbol_nop
\else
\iftypesettinglines % otherwise problems with \type <crlf> {xxx}
\ignorelines % makes footnotes work in \startlines ... \stoplines
@@ -465,7 +465,7 @@
\strc_notes_inject_symbol_yes
\else
\unskip\unskip
- \globallet\lastnotesymbol\strc_notes_inject_symbol_yes
+ \glet\lastnotesymbol\strc_notes_inject_symbol_yes
\fi
\fi
\ifconditional\postponingnotes % todo: per note class
@@ -734,7 +734,7 @@
\dostoptagged
\egroup
\endgroup
- \globallet\lastnotesymbol\relax}
+ \glet\lastnotesymbol\relax}
\unexpanded\def\strc_notes_inject_dummy % temp hack
{\removeunwantedspaces
@@ -745,7 +745,7 @@
\fi
\nobreak
\hpack to .5\emwidth{}%
- \globallet\lastnotesymbol\relax}
+ \glet\lastnotesymbol\relax}
\unexpanded\def\strc_notes_inject_separator % patch by WS due to request on list
{\edef\p_textseparator{\noteparameter\c!textseparator}%
diff --git a/tex/context/base/mkiv/strc-num.mkiv b/tex/context/base/mkiv/strc-num.mkiv
index cca66a6f5..747df29a5 100644
--- a/tex/context/base/mkiv/strc-num.mkiv
+++ b/tex/context/base/mkiv/strc-num.mkiv
@@ -578,9 +578,9 @@
\xdef\currentstructurecomponentlist {#2\c!list}%
\xmlstopraw
\ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \glet\currentstructurecomponentlist\currentstructurecomponenttitle
\fi
- \globallet\currentstructurecomponentcoding\s!xml
+ \glet\currentstructurecomponentcoding\s!xml
\else
\ifx\currentstructurecomponentexpansion\v!yes
\xdef\currentstructurecomponenttitle {#2\c!title}%
@@ -600,9 +600,9 @@
\fi \fi
\fi
\ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \glet\currentstructurecomponentlist\currentstructurecomponenttitle
\fi
- \globallet\currentstructurecomponentcoding\s!tex
+ \glet\currentstructurecomponentcoding\s!tex
\fi
%
\setnextinternalreference
diff --git a/tex/context/base/mkiv/strc-pag.mkiv b/tex/context/base/mkiv/strc-pag.mkiv
index 949806c82..01361e2c5 100644
--- a/tex/context/base/mkiv/strc-pag.mkiv
+++ b/tex/context/base/mkiv/strc-pag.mkiv
@@ -263,7 +263,7 @@
\def\currentpage{\the\realpageno}% rather useless
\appendtoks
- \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage \fi
+ \ifnum\realpageno>\lastpage \glet\lastpage\lastrealpage \fi
\to \everyinitializepagecounters
% States:
diff --git a/tex/context/base/mkiv/strc-ref.mkvi b/tex/context/base/mkiv/strc-ref.mkvi
index 0ae2cfccc..47719ffe2 100644
--- a/tex/context/base/mkiv/strc-ref.mkvi
+++ b/tex/context/base/mkiv/strc-ref.mkvi
@@ -212,14 +212,14 @@
\xmlstartraw
\xdef\currentreferencedata{#text}% data, no text else conflict
\xmlstopraw
- \globallet\currentreferencecoding\s!xml
+ \glet\currentreferencecoding\s!xml
\else
\ifx\currentreferenceexpansion\v!yes
\xdef\currentreferencedata{#text}%
\else
\xdef\currentreferencedata{\detokenize{#text}}%
\fi
- \globallet\currentreferencecoding\s!tex
+ \glet\currentreferencecoding\s!tex
\fi
% beware, the structures.references.set writes a
\setnextinternalreference
diff --git a/tex/context/base/mkiv/strc-reg.mkiv b/tex/context/base/mkiv/strc-reg.mkiv
index 21779f479..559e1bd42 100644
--- a/tex/context/base/mkiv/strc-reg.mkiv
+++ b/tex/context/base/mkiv/strc-reg.mkiv
@@ -176,33 +176,33 @@
\xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml}
+ \glet\currentregistercoding\s!xml}
\def\strc_registers_register_page_expand_yes_entries
{\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
\xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_nop_entries
{\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
\xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
\xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_xml
{\xmlstartraw
\xdef\currentregisterentries{\registerparameter\c!entries}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml}
+ \glet\currentregistercoding\s!xml}
\def\strc_registers_register_page_expand_yes
{\xdef\currentregisterentries{\registerparameter\c!entries}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_nop
{\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
- \globallet\currentregistercoding\s!tex}
+ \glet\currentregistercoding\s!tex}
\def\strc_registers_register_page_expand_xml_keys
{\xmlstartraw
@@ -434,14 +434,14 @@
\xmlstartraw
\xdef\currentregisterentries{\registerparameter\c!entries}%
\xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \glet\currentregistercoding\s!xml
\else
\ifx\currentregisterexpansion\v!yes
\xdef\currentregisterentries{\registerparameter\c!entries}%
\else
\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
\fi
- \globallet\currentregistercoding\s!tex
+ \glet\currentregistercoding\s!tex
\fi
% I hate this kind of mess ... but it's a user request.
\ifx\currentregisterentries\empty
@@ -524,7 +524,7 @@
\xdef\currentregisterentries{\detokenize{#3}}% not ok yet
\xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
\xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \glet\currentregistercoding\s!xml
\else
\ifx\currentregisterexpansion\v!yes
\xdef\currentregisterentries{#3}% not ok yet
@@ -533,7 +533,7 @@
\xdef\currentregisterentries{\detokenize{#3}}% not ok yet
\xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
\fi
- \globallet\currentregistercoding\s!tex
+ \glet\currentregistercoding\s!tex
\fi
\setnextinternalreference
% we could consider storing register entries in list
diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv
index 8f6038da7..cff73718a 100644
--- a/tex/context/base/mkiv/strc-sec.mkiv
+++ b/tex/context/base/mkiv/strc-sec.mkiv
@@ -116,7 +116,7 @@
% \settrialtypesetting
\the\everypreroll
\nodestostring\tempstring{#1}%
- \globallet\currentstructurebookmark\tempstring
+ \glet\currentstructurebookmark\tempstring
\endgroup}
% zeros:
@@ -156,9 +156,9 @@
\strc_sectioning_autobookmark\currentstructuretitle
\fi \fi \fi
\ifx\currentstructurelist\empty
- \globallet\currentstructurelist\currentstructuretitle
+ \glet\currentstructurelist\currentstructuretitle
\fi
- \globallet\currentstructurecoding\s!xml
+ \glet\currentstructurecoding\s!xml
\else
\ifx\currentstructureexpansion\v!yes
\xdef\currentstructuretitle {\structureparameter\c!title}%
@@ -185,9 +185,9 @@
\fi \fi
\fi
\ifx\currentstructurelist\empty
- \globallet\currentstructurelist\currentstructuretitle
+ \glet\currentstructurelist\currentstructuretitle
\fi
- \globallet\currentstructurecoding\s!tex
+ \glet\currentstructurecoding\s!tex
\fi
\setnextinternalreference
\storeinternalreference\currentstructurename{\the\locationcount}%
@@ -1206,7 +1206,7 @@
\else
\strc_sectioning_check_layout
\fi
- \globallet\previoushead\currenthead}
+ \glet\previoushead\currenthead}
\def\strc_sectioning_handle_page_yes
{\ifconditional\c_strc_sectioning_ignore_page
@@ -1230,7 +1230,7 @@
\fi
\global\c_strc_sectioning_preceding_level\currentheadlevel
\fi
- \globallet\previoushead\currenthead}
+ \glet\previoushead\currenthead}
\unexpanded\def\strc_sectioning_prevent_page_break#1% see strc-con
{\ifconditional\c_strc_sectioning_auto_break
diff --git a/tex/context/base/mkiv/strc-syn.mkiv b/tex/context/base/mkiv/strc-syn.mkiv
index 1fb079f04..7f71e88f5 100644
--- a/tex/context/base/mkiv/strc-syn.mkiv
+++ b/tex/context/base/mkiv/strc-syn.mkiv
@@ -114,14 +114,14 @@
\xmlstartraw
\xdef#2{#4}%
\xmlstopraw
- \globallet#3\s!xml
+ \glet#3\s!xml
\else
\ifx#1\v!yes
\xdef#2{#4}%
\else
\xdef#2{\detokenize{#4}}%
\fi
- \globallet#3\s!tex
+ \glet#3\s!tex
\fi}
%D We now use a simple list variant:
diff --git a/tex/context/base/mkiv/symb-imp-mvs.mkiv b/tex/context/base/mkiv/symb-imp-mvs.mkiv
index 9902fc9e8..f6a38214f 100644
--- a/tex/context/base/mkiv/symb-imp-mvs.mkiv
+++ b/tex/context/base/mkiv/symb-imp-mvs.mkiv
@@ -254,10 +254,16 @@
\stopsymbolset
-%D \showsymbolset[astronomic]
-%D \showsymbolset[zodiac]
-%D \showsymbolset[europe]
-%D \showsymbolset[martinvogel 1]
-%D \showsymbolset[martinvogel 2]
+\continueifinputfile{symb-imp-mvs.mkiv}
-\endinput
+\usemodule[article-basic]
+
+\starttext
+
+\startsubject[title={Astronomic}] \showsymbolset[astronomic] \stopsubject
+\startsubject[title={Zodiac}] \showsymbolset[zodiac] \stopsubject
+\startsubject[title={Europe}] \showsymbolset[europe] \stopsubject
+\startsubject[title={Martinvogel 1}] \showsymbolset[martinvogel 1] \stopsubject
+\startsubject[title={Martinvogel 2}] \showsymbolset[martinvogel 2] \stopsubject
+
+\stoptext
diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv
index a23563f3c..9c959a105 100644
--- a/tex/context/base/mkiv/syst-aux.mkiv
+++ b/tex/context/base/mkiv/syst-aux.mkiv
@@ -594,10 +594,6 @@
%D tokens will save us some $300\times4=1200$ bytes of format file on a 32~bit
%D system. Not that it matters much today. This shortcut is already defined:
-\ifdefined\glet\else
- \unexpanded\def\glet{\global\let}
-\fi
-
\let\globallet\glet
%D \macros
diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv
index 10c1fa113..f7b73a30e 100644
--- a/tex/context/base/mkiv/syst-ini.mkiv
+++ b/tex/context/base/mkiv/syst-ini.mkiv
@@ -610,10 +610,6 @@
%D A few shortcuts:
-\ifdefined\glet \else
- \normalprotected\def\glet{\global\let}
-\fi
-
\normalprotected\def\udef {\normalprotected\def }
\normalprotected\def\ugdef{\normalprotected\gdef}
\normalprotected\def\uedef{\normalprotected\edef}
@@ -940,12 +936,12 @@
% \bgroup
% \catcode`\^^M=\activecatcode%
% \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}%
-% \global\let^^M\par%
+% \glet^^M\par%
% \egroup
%
% \bgroup
% \gdef\obeyspaces{\catcode`\ \activecatcode}%
-% \obeyspaces\global\let =\space%
+% \obeyspaces\glet =\space%
% \egroup
\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\par}
@@ -1252,10 +1248,6 @@
\let\normalstartdmath \Ustartdisplaymath
\let\normalstopdmath \Ustopdisplaymath
-%D For now:
-
-\ifdefined\glet \else \normalprotected\def\glet{\global\let} \fi
-
\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi
\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi
diff --git a/tex/context/base/mkiv/tabl-tab.mkiv b/tex/context/base/mkiv/tabl-tab.mkiv
index 244ead530..631f29bc0 100644
--- a/tex/context/base/mkiv/tabl-tab.mkiv
+++ b/tex/context/base/mkiv/tabl-tab.mkiv
@@ -688,7 +688,7 @@
% extensions
\newtableformatkey q%
- {\letempty\!tqStyle
+ {\let\!tqStyle\empty
\futurelet\!tnext\!tqTestForBracket}
\newtableformatkey Q%
@@ -1691,8 +1691,8 @@
\starttablenoalign
\nobreak
\tabl_table_set_action\tableunknownstate
- \globalletempty\tabl_tables_check_auto_row
- \globalletempty\tabl_tables_chuck_auto_row
+ \glet\tabl_tables_check_auto_row\empty
+ \glet\tabl_tables_chuck_auto_row\empty
\global\currenttablecolumn\zerocount
\stoptablenoalign}
@@ -1816,21 +1816,21 @@
%D the last row.
\unexpanded\def\tabl_table_AR
- {\globallet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed
- \globallet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed}
+ {\glet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed
+ \glet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed}
\let\tabl_tables_check_auto_row\empty
\let\tabl_tables_chuck_auto_row\empty
\def\tabl_tables_check_auto_row_indeed
- {\globallet\tabl_tables_check_auto_row\empty
+ {\glet\tabl_tables_check_auto_row\empty
\ifnum\tableactionstate=\tablerulestate \FR\else
\ifnum\tableactionstate=\tableunknownstate\FR\else
\MR\fi\fi}
\def\tabl_tables_chuck_auto_row_indeed
- {\globalletempty\tabl_tables_check_auto_row
- \globalletempty\tabl_tables_chuck_auto_row
+ {\glet\tabl_tables_check_auto_row\empty
+ \glet\tabl_tables_chuck_auto_row\empty
\ifnum\tableactionstate=\tablerulestate \SR\else
\ifnum\tableactionstate=\tableunknownstate\SR\else
\LR\fi\fi}
diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv
index 97a4f63c0..75839caed 100644
--- a/tex/context/base/mkiv/tabl-tbl.mkiv
+++ b/tex/context/base/mkiv/tabl-tbl.mkiv
@@ -2235,7 +2235,7 @@
% \def\tabulatedoHRfive % horizontal rule line (break untested)
% {\starttabulatenoalign
-% \globallet\dotabulateautoline\dotabulatelinerule
+% \glet\dotabulateautoline\dotabulatelinerule
% %\ifcase#1\or % todo: check what this does
% \ifnum\noftabulatelines=\zerocount
% \glet\dotabulateautoline\donothing
diff --git a/tex/context/base/mkiv/typo-drp.mkiv b/tex/context/base/mkiv/typo-drp.mkiv
index 371ea38d6..183925108 100644
--- a/tex/context/base/mkiv/typo-drp.mkiv
+++ b/tex/context/base/mkiv/typo-drp.mkiv
@@ -118,7 +118,7 @@
\kern\zeropoint % we need a node
\p_text
\endgroup
- \globallet\typo_initial_handle\relax}
+ \glet\typo_initial_handle\relax}
\let\typo_initial_handle\relax
diff --git a/tex/context/base/mkiv/typo-fln.mkiv b/tex/context/base/mkiv/typo-fln.mkiv
index 37348be29..533c197cd 100644
--- a/tex/context/base/mkiv/typo-fln.mkiv
+++ b/tex/context/base/mkiv/typo-fln.mkiv
@@ -91,7 +91,7 @@
\kern\zeropoint % we need a node
% \hskip\zeropoint\s!plus\emwidth\relax % can be an option
\endgroup
- \globallet\typo_firstline_handle\relax}
+ \glet\typo_firstline_handle\relax}
\let\typo_firstline_handle\relax
diff --git a/tex/context/base/mkiv/util-sac.lua b/tex/context/base/mkiv/util-sac.lua
index 09c3819c5..62ce6bc1c 100644
--- a/tex/context/base/mkiv/util-sac.lua
+++ b/tex/context/base/mkiv/util-sac.lua
@@ -21,6 +21,10 @@ function streams.open(filename,zerobased)
return { f, 1, #f, zerobased or false }
end
+function streams.openstring(f,zerobased)
+ return { f, 1, #f, zerobased or false }
+end
+
function streams.close()
-- dummy
end
@@ -389,8 +393,32 @@ end
if sio and sio.readcardinaltable then
- streams.readcardinaltable = sio.readcardinaltable
- streams.readintegertable = sio.readintegertable
+ local readcardinaltable = sio.readcardinaltable
+ local readintegertable = sio.readintegertable
+
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ return readcardinaltable(f[1],i,n,b)
+ end
+
+ function utilities.streams.readintegertable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
+ return readintegertable(f[1],i,n,b)
+ end
else
@@ -400,11 +428,19 @@ else
local readcardinal4 = streams.readcardinal4
function streams.readcardinaltable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
local t = { }
- if b == 1 then for i=1,n do t[i] = readcardinal1(f) end
- elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end
- elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end
- elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end
+ if b == 1 then for i=1,n do t[i] = readcardinal1(f[1],i) end
+ elseif b == 2 then for i=1,n do t[i] = readcardinal2(f[1],i) end
+ elseif b == 3 then for i=1,n do t[i] = readcardinal3(f[1],i) end
+ elseif b == 4 then for i=1,n do t[i] = readcardinal4(f[1],i) end end
return t
end
@@ -414,11 +450,19 @@ else
local readinteger4 = streams.readinteger4
function streams.readintegertable(f,n,b)
+ local i = f[2]
+ local s = f[3]
+ local p = i + n * b
+ if p > s then
+ f[2] = s + 1
+ else
+ f[2] = p
+ end
local t = { }
- if b == 1 then for i=1,n do t[i] = readinteger1(f) end
- elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end
- elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end
- elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end
+ if b == 1 then for i=1,n do t[i] = readinteger1(f[1],i) end
+ elseif b == 2 then for i=1,n do t[i] = readinteger2(f[1],i) end
+ elseif b == 3 then for i=1,n do t[i] = readinteger3(f[1],i) end
+ elseif b == 4 then for i=1,n do t[i] = readinteger4(f[1],i) end end
return t
end
diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml
index 5ab324b97..c5da3adca 100644
--- a/tex/context/interface/mkii/keys-fr.xml
+++ b/tex/context/interface/mkii/keys-fr.xml
@@ -1247,6 +1247,7 @@
<cd:constant name='textstyle' value='styletexte'/>
<cd:constant name='textwidth' value='largeurtexte'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titre'/>
<cd:constant name='titlecolor' value='couleurtitre'/>
<cd:constant name='titlecommand' value='titlecommand'/>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index d8dc51e14..e1e1bc1cd 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index fac1c6288..b8ae1bd64 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/m-format.mkiv b/tex/context/modules/mkiv/m-format.mkiv
index f9dd348a4..3a0a5bebd 100644
--- a/tex/context/modules/mkiv/m-format.mkiv
+++ b/tex/context/modules/mkiv/m-format.mkiv
@@ -217,7 +217,7 @@
\doglobal\newcounter\formatlinesubcounter
\reshapebox
{\doglobal\increment\formatlinesubcounter}
- \global\let\formatlinemaxcounter\formatlinesubcounter
+ \glet\formatlinemaxcounter\formatlinesubcounter
\reshapebox
{\doglobal\decrement\formatlinesubcounter
\ifnum\formatlinesubcounter=\zerocount
@@ -303,7 +303,7 @@
\doglobal\newcounter\formatlinesubcounter
\reshapebox
{\doglobal\increment\formatlinesubcounter}%
- \global\let\formatlinemaxcounter\formatlinesubcounter
+ \glet\formatlinemaxcounter\formatlinesubcounter
\reshapebox
{\doglobal\decrement\formatlinesubcounter
\ifnum\formatlinesubcounter=\zerocount
diff --git a/tex/context/modules/mkiv/s-fonts-charts.mkiv b/tex/context/modules/mkiv/s-fonts-charts.mkiv
index 50cd589e4..d8d0975de 100644
--- a/tex/context/modules/mkiv/s-fonts-charts.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-charts.mkiv
@@ -169,36 +169,39 @@
\starttext
- \showfontchart[filename=LucidaBrightOT.otf,page=yes]
- \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes]
- \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes]
- \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes]
-
- \showfontchart[filename=LucidaSansOT.otf,page=yes]
- \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes]
- \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes]
- \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes]
-
- \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes]
- \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes]
- \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes]
- \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes]
-
- \showfontchart[filename=LucidaConsoleDK.otf,page=yes]
- \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes]
- \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes]
- \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes]
-
- \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes]
- \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes]
- \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes]
- \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes]
-
- \showfontchart[filename=LucidaBrightMathOT.otf,page=yes]
- \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes]
-
- \showfontchart[filename=LucidaBlackletterOT.otf,page=yes]
- \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes]
- \showfontchart[filename=LucidaHandwritingOT.otf,page=yes]
+% \showfontchart[filename=veramono.ttf,page=yes]
+ \showfontchart[filename=CoelacanthSubhdHeavy.otf,page=yes]
+
+% \showfontchart[filename=LucidaBrightOT.otf,page=yes]
+% \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes]
+% \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes]
+% \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes]
+
+% \showfontchart[filename=LucidaSansOT.otf,page=yes]
+% \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes]
+% \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes]
+% \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes]
+
+% \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes]
+% \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes]
+% \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes]
+% \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes]
+
+% \showfontchart[filename=LucidaConsoleDK.otf,page=yes]
+% \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes]
+% \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes]
+% \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes]
+
+% \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes]
+% \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes]
+% \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes]
+% \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes]
+
+% \showfontchart[filename=LucidaBrightMathOT.otf,page=yes]
+% \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes]
+
+% \showfontchart[filename=LucidaBlackletterOT.otf,page=yes]
+% \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes]
+% \showfontchart[filename=LucidaHandwritingOT.otf,page=yes]
\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-complete.mkiv b/tex/context/modules/mkiv/s-fonts-complete.mkiv
index afdd79b4c..83aa708df 100644
--- a/tex/context/modules/mkiv/s-fonts-complete.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-complete.mkiv
@@ -29,23 +29,36 @@
local descriptions = tfmdata.descriptions or { }
local data = characters.data
-- context.setuptabulate { header = "repeat" }
- context.starttabulatehead()
- NC() bold("unicode")
- NC() bold("visual")
- NC() bold("index")
- NC() bold("glyph")
- NC() bold("adobe")
- NC() bold("context")
- NC() NR()
- context.stoptabulatehead()
- context.starttabulate { "|l|c|l|p|p|p|" }
+ -- context.starttabulatehead()
+ -- NC() bold("unicode")
+ -- NC() bold("visual")
+ -- NC() bold("index")
+ -- NC() bold("tounicode")
+ -- NC() bold("unicodes")
+ -- NC() bold("glyph")
+ -- NC() bold("adobe")
+ -- NC() bold("context")
+ -- NC() NR()
+ -- context.stoptabulatehead()
+ context.starttabulate { "|l|c|p(8em)|l|l|p|p|p|" }
+ NC() bold("unicode")
+ NC() bold("visual")
+ NC() bold("unicodes")
+ NC() bold("tounicode")
+ NC() bold("index")
+ NC() bold("glyph")
+ NC() bold("adobe")
+ NC() bold("context")
+ NC() NR()
for unicode, chr in fonts.iterators.characters(tfmdata) do
local des, dat = descriptions[unicode], data[unicode]
- local index = chr.index or 0
- local cname = (dat and dat.contextname) or ""
- local aname = (dat and dat.adobename) or ""
- local gname = (des and des.name) or ""
- local mname = dat and dat.mathname
+ local index = chr.index or 0
+ local tounicode = chr.tounicode
+ local isunicode = chr.unicode
+ local cname = (dat and dat.contextname) or ""
+ local aname = (dat and dat.adobename) or ""
+ local gname = (des and des.name) or ""
+ local mname = dat and dat.mathname
if type(mname) ~= "string" then
mname = ""
end
@@ -70,12 +83,52 @@
cname = mname
end
end
- NC() tttf() context("U+%05X",unicode)
- NC() char(unicode)
- NC() tttf() context("%05X",index)
- NC() if gname ~= "" then tttf() escaped(gname) end
- NC() if aname ~= "" then tttf() context(aname) end
- NC() if cname ~= "" then tttf() context(cname) end
+ NC()
+ tttf()
+ context("%05X",unicode)
+ NC()
+ char(unicode)
+ NC()
+ if isunicode then
+ tttf()
+ if type(isunicode) == "table" then
+ for i=1,#isunicode do
+ if i > 1 then
+ if i % 2 ~= 0 then
+ context.crlf()
+ else
+ context.space()
+ end
+ end
+ context("%05X",isunicode[i])
+ end
+ else
+ context("%05X",isunicode)
+ end
+ end
+ NC()
+ if tounicode then
+ tttf()
+ context(tounicode)
+ end
+ NC()
+ tttf()
+ context("%05X",index)
+ NC()
+ if gname ~= "" then
+ tttf()
+ escaped(gname)
+ end
+ NC()
+ if aname ~= "" then
+ tttf()
+ context(aname)
+ end
+ NC()
+ if cname ~= "" then
+ tttf()
+ context(cname)
+ end
NC() NR()
end
context.stoptabulate()
@@ -100,14 +153,13 @@
\font\TestFont=#1 at #2
\setuplayout[style=\TestFont]
\setupheadertexts[]
- \setupfootertexts[#1 -- \pagenumber]
- \setupfootertexts[pagenumber]
+ \setupfootertexts[#1\space\endash\space\pagenumber]
\setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm]
\TestFont
\nonknuthmode
\startcolumns[n=#3]
- \TestFont
- \ctxlua { moduledata.fonts.complete.all() }
+ \TestFont
+ \ctxlua { moduledata.fonts.complete.all() }
\stopcolumns
\page
\endgroup}
@@ -125,14 +177,16 @@
\TestFontB \setupinterlinespace[line=1.2\dimexpr#2\relax] \raggedcenter
\nonknuthmode
\startcolumns[n=#3]
- \TestFontB
- \ctxlua { moduledata.fonts.complete.glyphs() }
+ \TestFontB
+ \ctxlua { moduledata.fonts.complete.glyphs() }
\stopcolumns
\page
\endgroup}
\continueifinputfile{s-fonts-complete.mkiv}
+\usemodule[art-01] \setuplayout[overview] \setupbodyfont[8pt]
+
\starttext
% \ShowCompleteFont{name:dejavusansmono}{10pt}{1}
@@ -140,7 +194,7 @@
% \ShowCompleteFont{name:officinasansbookitcregular}{10pt}{2}
% \ShowCompleteFont{name:officinaserifbookitcregular}{10pt}{2}
% \ShowCompleteFont{name:serpentineserifeflight}{10pt}{2}
-\ShowCompleteFont{name:lmroman10-regular}{10pt}{1}
+% \ShowCompleteFont{name:lmroman10-regular}{10pt}{1}
% \ShowCompleteFont{name:lmtypewriter10-regular}{10pt}{2}
% \ShowCompleteFont{lt55485}{10pt}{2}
% \ShowCompleteFont{lmr10}{10pt}{2}
@@ -157,4 +211,13 @@
% \ShowCompleteFont{name:palatinonovaregular}{11pt}{2}
% \ShowCompleteFont{pirat.ttf}{12pt}{1}
+\setuplayout[overview][footer=1cm] \setuplayout[overview]% \setupheadertexts[aegean.ttf]
+
+\ShowCompleteFont{file:aegean} {8pt}{1}
+% \ShowCompleteFont{file:tsukurimashouminchops}{8pt}{1}
+% \ShowCompleteFont{file:tsukurimashoumincho} {8pt}{1}
+% \ShowCompleteFont{file:tsukurimashoukakups} {8pt}{1}
+% \ShowCompleteFont{file:tsukurimashoukaku} {8pt}{1}
+% \ShowCompleteFont{file:akkadian} {8pt}{1}
+
\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-system.lua b/tex/context/modules/mkiv/s-fonts-system.lua
index e05eef0fa..5d2692473 100644
--- a/tex/context/modules/mkiv/s-fonts-system.lua
+++ b/tex/context/modules/mkiv/s-fonts-system.lua
@@ -39,6 +39,8 @@ local sortedhash = table.sortedhash
local formatters = string.formatters
local concat = table.concat
local lower = string.lower
+local gsub = string.gsub
+local find = string.find
local function allfiles(specification)
local pattern = lower(specification.pattern or "")
@@ -202,3 +204,88 @@ function moduledata.fonts.system.showinstalledglyphnames(specification)
end
table.save("s-fonts-system-glyph-names.lua",names)
end
+
+-- -- --
+
+-- local skip = {
+-- "adobeblank",
+-- "veramo",
+-- "unitedstates",
+-- "tirek",
+-- "svbasicmanual",
+-- "sahel",
+-- "prsprorg",
+-- "piratdia",
+-- "notoserifthai",
+-- "coelacanthsubhdheavy",
+-- }
+
+-- local function bad(name)
+-- name = lower(name)
+-- for i=1,#skip do
+-- if find(name,skip[i]) then
+-- return true
+-- end
+-- end
+-- end
+
+-- function moduledata.fonts.system.showprivateglyphnames(specification)
+-- specification = interfaces.checkedspecification(specification)
+-- local paths = caches.getreadablepaths()
+-- local files = { }
+-- local names = table.setmetatableindex("table")
+-- local f_u = formatters["%04X"]
+-- for i=1,#paths do
+-- local list = dir.glob(paths[i].."/fonts/o*/**.tmc")
+-- for i=1,#list do
+-- files[list[i]] = true
+-- end
+-- end
+-- for filename in table.sortedhash(files) do
+-- logs.report("system","fontfile: %s",file.nameonly(filename))
+-- local data = table.load(filename)
+-- if data and data.format == "truetype" or data.format == "opentype" then
+-- local basename = file.basename(data.resources.filename)
+-- local cleanname = gsub(basename," ","")
+-- if not bad(cleanname) then
+-- local descriptions = data.descriptions
+-- if descriptions then
+-- local done = 0
+-- for u, d in sortedhash(descriptions) do
+-- local dn = d.name
+-- local du = d.unicode
+-- if dn and du and (u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF)) and not find(dn,"notdef") then
+-- if type(du) == "table" then
+-- local t = { }
+-- for i=1,#du do
+-- t[i] = f_u(du[i])
+-- end
+-- du = concat(t," ")
+-- end
+-- if done == 0 then
+-- logs.report("system","basename: %s",basename)
+-- context.starttitle { title = basename }
+-- context.start()
+-- context.definefont( { "tempfont" }, { "file:" .. cleanname })
+-- context.starttabulate { "|T||T|T|" }
+-- end
+-- NC() context("%U",u)
+-- NC() context.tempfont() context.char(u) -- could be getglyph
+-- NC() ctx_verbatim(dn)
+-- NC() context(du)
+-- NC() NR()
+-- done = done + 1
+-- end
+-- end
+-- if done > 0 then
+-- logs.report("system","privates: %i",done)
+-- context.stoptabulate()
+-- context.stop()
+-- context.stoptitle()
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+
diff --git a/tex/context/modules/mkiv/s-fonts-system.mkiv b/tex/context/modules/mkiv/s-fonts-system.mkiv
index 5613701d9..03599b0df 100644
--- a/tex/context/modules/mkiv/s-fonts-system.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-system.mkiv
@@ -27,22 +27,24 @@
\installmodulecommandluasingle \showinstalledfonts {moduledata.fonts.system.showinstalled}
\installmodulecommandluasingle \cacheinstalledfonts {moduledata.fonts.system.cacheinstalled}
\installmodulecommandluasingle \showinstalledglyphnames {moduledata.fonts.system.showinstalledglyphnames}
+%installmodulecommandluasingle \showprivateglyphnames {moduledata.fonts.system.showprivateglyphnames}
\stopmodule
\continueifinputfile{s-fonts-system.mkiv}
-\usemodule[art-01] \setuplayout[overview] \setupbodyfont[7pt]
+\usemodule[art-01] \setuplayout[overview] \setupbodyfont[6pt]
\starttext
% \showinstalledfonts
-% \enabletrackers[otf.keepnames]
+ \enabletrackers[otf.keepnames]
-% \cacheinstalledfonts[threshold=4000000,suffixes={otf,ttf,afm,pfb}]
-% \cacheinstalledfonts[threshold=2000000,suffixes={otf,ttf,afm,pfb}]
+ \cacheinstalledfonts[suffixes={otf,ttf,afm}]
+% \cacheinstalledfonts[threshold=4000000,suffixes={otf,ttf,afm}]
+% \cacheinstalledfonts[threshold=2000000,suffixes={otf,ttf,afm}]
- \showinstalledglyphnames
+% \showinstalledglyphnames
\stoptext
diff --git a/tex/context/modules/mkiv/s-maps.mkiv b/tex/context/modules/mkiv/s-maps.mkiv
index c7541babc..28e88af98 100644
--- a/tex/context/modules/mkiv/s-maps.mkiv
+++ b/tex/context/modules/mkiv/s-maps.mkiv
@@ -135,11 +135,11 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% 3 versions of layout with matching headers
-\definepapersize
+\definepapersize
[maps]
[width=21cm,height=26.5cm]
-\setuppapersize
+\setuppapersize
[maps][maps]
\setuplayout[
@@ -360,9 +360,9 @@
\xdef\MapsNumber{\the\numexpr (\the\year-1990)*2+1\relax}%
\fi }%
\doifnothing\MapsRunningAuthor
- {\global\let\MapsRunningAuthor\MapsAuthor}%
+ {\glet\MapsRunningAuthor\MapsAuthor}%
\doifnothing\MapsRunningTitle
- {\global\let\MapsRunningTitle\MapsTitle}}%
+ {\glet\MapsRunningTitle\MapsTitle}}%
\def\dostartArticle[#1]{%
\MapsBibData[#1]
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 90f8f4f00..f97f82489 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 10/08/18 17:44:41
+-- merge date : 10/17/18 15:06:55
do -- begin closure to overcome local limits and interference
@@ -9668,6 +9668,7 @@ function constructors.scale(tfmdata,specification)
if isunicode then
chr.unicode=isunicode
chr.tounicode=tounicode(isunicode)
+ else
end
if hasquality then
local ve=character.expansion_factor
@@ -23846,35 +23847,41 @@ local function checkmathreplacements(tfmdata,fullname,fixitalics)
for unicode,replacement in next,changed do
local u=characters[unicode]
local r=characters[replacement]
- local n=u.next
- local v=u.vert_variants
- local h=u.horiz_variants
- if fixitalics then
- local ui=u.italic
- if ui and not r.italic then
+ if u and r then
+ local n=u.next
+ local v=u.vert_variants
+ local h=u.horiz_variants
+ if fixitalics then
+ local ui=u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic=ui
+ end
+ end
+ if n and not r.next then
if trace_preparing then
- report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
end
- r.italic=ui
+ r.next=n
end
- end
- if n and not r.next then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants=v
end
- r.next=n
- end
- if v and not r.vert_variants then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ end
+ r.horiz_variants=h
end
- r.vert_variants=v
- end
- if h and not r.horiz_variants then
+ else
if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ report_prepare("error replacing %C by %U",unicode,replacement)
end
- r.horiz_variants=h
end
end
end
@@ -31743,7 +31750,7 @@ if not modules then modules={} end modules ['font-otc']={
license="see context related readme files"
}
local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
-local type,next=type,next
+local type,next,tonumber=type,next,tonumber
local lpegmatch=lpeg.match
local utfbyte,utflen=utf.byte,utf.len
local sortedhash=table.sortedhash
@@ -31881,6 +31888,7 @@ local function addfeature(data,feature,specifications)
if not specifications then
return
end
+ local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
local function tounicode(code)
if not code then
return
@@ -31898,10 +31906,17 @@ local function addfeature(data,feature,specifications)
return u
end
end
+ local u=lpegmatch(p,code)
+ if u then
+ return u
+ end
if not aglunicodes then
aglunicodes=fonts.encodings.agl.unicodes
end
- return aglunicodes[code]
+ local u=aglunicodes[code]
+ if u then
+ return u
+ end
end
local coverup=otf.coverup
local coveractions=coverup.actions