grph-inc.mkxl /size: 37 Kb    last modification: 2024-01-16 09:02
1%D \module
2%D   [       file=grph-inc, % moved from core-fig
3%D        version=2006.08.26, % overhaul of 1997.03.31
4%D          title=\CONTEXT\ Graphic Macros,
5%D       subtitle=Figure Inclusion,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14% \enabledirectives[graphics.conversion.eps.cleanup.ai]
15
16% \setupexternalfigures[directory=dirfile://./test/**]
17% \externalfigure[crappname(2).eps][frame=on]
18
19% todo: messages
20
21\writestatus{loading}{ConTeXt Graphic Macros / Figure Inclusion}
22
23\registerctxluafile{grph-img}{}
24\registerctxluafile{grph-inc}{autosuffix}
25\registerctxluafile{grph-bmp}{}
26\registerctxluafile{grph-chk}{}
27\registerctxluafile{grph-con}{}
28\registerctxluafile{grph-fil}{}
29%registerctxluafile{grph-mem}{} % obsolete
30\registerctxluafile{grph-u3d}{} % this will become a module
31%registerctxluafile{grph-swf}{} % this will become a module
32
33\unprotect
34
35%D Including graphics is complicated by the fact that  we need to locate them first,
36%D optionally manipulate them and scale then next. Lookups are to be done as efficient
37%D as possible and inclusion of the data might happens only once. In \MKIV\ much of this
38%D is delegated to the \LUA\ end. There is not so much less code as in \MKII\ but it's
39%D more powerful, flexible, pluggable and some of the extended functionality has been
40%D moved from modules to the core. The overall functionality is rather stable and has
41%D not changed much over the years.
42
43\ifdefined\dotagfigure \else \aliased\let\dotagfigure\relax \fi
44
45\installcorenamespace{externalfigure}
46\installcorenamespace{externalfigureinstance}
47\installcorenamespace{externalfigurecollection}
48
49\installframedcommandhandler \??externalfigure {externalfigure} \??externalfigure
50
51\aliased\let\setupexternalfigures\setupexternalfigure
52
53\setupexternalfigures[% we really need the defaults
54   \c!method         =,
55   \c!label          =,
56   \c!size           =,
57   \c!conversion     =,
58   \c!resolution     =,
59   \c!prefix         =,
60   \c!cache          =,
61   \c!page           =\zerocount,
62   \c!file           =,
63   \c!display        =,
64   \c!mask           =,
65   \c!range          =,
66   \c!preset         =\v!yes,
67   \c!split          =,
68   \c!color          =,
69   \c!arguments      =,
70   \c!symbol         =\v!no,
71   \c!controls       =\v!no,
72   \c!resources      =,
73   \c!preview        =\v!no,
74   \c!repeat         =\v!no,
75   \c!foregroundcolor=,
76   \c!interaction    =\v!none,
77   \c!hfactor        =,
78   \c!wfactor        =,
79   \c!factor         =,
80   \c!defaultwidth   =8\lineheight,
81   \c!defaultheight  =6\lineheight,
82   \c!maxwidth       =\externalfigureparameter\c!width,
83   \c!maxheight      =\externalfigureparameter\c!height,
84   \c!xscale         =,
85   \c!yscale         =,
86   \c!scale          =,
87   \c!sx             =\externalfigureparameter\c!s,
88   \c!sy             =\externalfigureparameter\c!s,
89   \c!s              =1,
90   \c!width          =,
91   \c!height         =,
92   \c!lines          =,
93   \c!grid           =,
94   \c!bodyfont       =\bodyfontsize,
95   \c!object         =\v!yes,
96   \c!corner         =\v!rectangular,
97   \c!frame          =\v!off,
98   \c!option         =,
99   \c!reset          =\v!no,
100   \c!directory      =,
101   \c!radius         =.5\bodyfontsize,
102   \c!background     =,
103   \c!splitcolor     =\s!white,
104   \c!order          =,
105   \c!equalwidth     =,
106   \c!equalheight    =,
107   \c!location       ={\v!local,\v!global},
108   \c!frames         =\v!off,
109   \c!ymax           =24,
110   \c!xmax           =,
111   \c!align          =\v!none, % New, for Tacos extremely large graphics.
112   \c!crossreference =\v!no,
113   \c!transform      =\v!auto,
114   \c!userpassword   =,
115   \c!ownerpassword  =,
116   \c!compact        =,
117   \c!metadata       =\v!page, % page | document | yes | no
118   \c!cmyk           =,
119   \c!crop           =\v!yes,
120  ]
121
122%D Defining figures.
123
124\newinteger\c_grph_include_nesting
125
126\newtoks   \everyexternalfigureresets % for the moment still public
127\newtoks   \everyexternalfigurechecks % for the moment still public
128
129% \useexternalfigure[alpha][cow]
130% \useexternalfigure[beta] [cow]       [width=1cm]
131% \useexternalfigure[gamma][cow][alpha]
132% \useexternalfigure[delta][cow][alpha][width=2cm]
133%
134% full width : \externalfigure[cow]               \par
135% 3cm width  : \externalfigure[cow]  [width=3cm]  \par
136% full width : \externalfigure[alpha]             \par
137% 1cm width  : \externalfigure[beta]              \par
138% full width : \externalfigure[gamma]             \par
139% 2cm width  : \externalfigure[delta]             \par
140% 4cm width  : \externalfigure[beta] [width=4cm]  \par
141% 5cm width  : \externalfigure[gamma][width=5cm]  \par
142%
143% \defineexternalfigure[a][width=10cm]
144% \defineexternalfigure[b][width=5cm]
145% \externalfigure[cow][a]
146% \externalfigure[cow][b][height=8cm]
147%
148% \useexternalfigure[x][cow][width=10cm,height=1cm]
149% \externalfigure[x]
150% \externalfigure[x][width=3cm]
151%
152% [label] [filename]
153% [label] [filename] [parent]
154% [label] [filename] [parent] [settings]
155% [label] [filename]          [settings]
156%
157% new: more convenient/efficient than
158%
159%   \use..[a][a][setting] \externalfigure[b][a]
160%
161% is equivalent to:
162%
163%   \def..[a][setting]    \externalfigure[b][a]
164%
165% see x-res modules for usage:
166%
167% \defineexternalfigure[name][settings]
168
169%D Defining is persistent, i.e.\ when you redefine an instance, the already set
170%D parameters need to be set again or otherwise the old values will be used.
171%D
172%D New: \type {method=auto}: strips suffix and uses \quote {order} which is handy in
173%D some of four workflows where sources are used for web and print and where the web
174%D tools need a suffix (like gif) which we don't want as we want a high quality
175%D format.
176
177\newconditional\c_grph_include_trace_inheritance
178
179\installtextracker
180  {graphics.inheritance}
181  {\c_grph_include_trace_inheritance\conditionaltrue}
182  {\c_grph_include_trace_inheritance\conditionalfalse}
183
184\installcorenamespace{externalfiguredefinition}
185
186\aliased\let\defineexternalfigures\defineexternalfigure
187
188% label file parent settings
189% label file settings
190% label file parent
191
192\permanent\tolerant\protected\def\useexternalfigure[#1]#*[#2]#*[#S#3]#*[#S#4]%
193  {\ifempty{#1}%
194     \ifempty{#2}\else
195       \ifhastok={#3}%
196         \grph_include_use_indeed{#2}{#2}{#3}{#4}%
197       \else
198         \grph_include_use_indeed{#2}{#2}\empty{#4}%
199       \fi
200     \fi
201   \orelse\ifempty{#2}%
202     \ifhastok={#3}%
203       \grph_include_use_indeed{#1}{#1}\empty{#3}%
204     \else
205       \grph_include_use_indeed{#1}{#1}{#3}{#4}%
206     \fi
207   \else
208     \ifhastok={#3}%
209       \grph_include_use_indeed{#1}{#2}\empty{#3}
210     \else
211       \grph_include_use_indeed{#1}{#2}{#3}{#4}%
212     \fi
213   \fi}
214
215\def\grph_include_use_indeed#1#2#3#4%
216  {\gdefcsname\??externalfigureinstance#1\endcsname{\grph_include_setup{#2}{#3}{#4}}%
217   \grph_include_analyze_collection[#2][#4]}
218
219% inclusion
220
221\permanent\tolerant\protected\def\externalfigure[#1]#,[#2]#,[#S#3]%
222  {\ifhastok={#2}%
223     \grph_include_place[#1][][#2]%
224   \else
225     \grph_include_place[#1][#2][#3]%
226   \fi}
227
228% todo: chain them
229
230\def\grph_include_setup#1#2#3% name parent settings
231  {\cdef\m_grph_include_name  {#1}%
232   \cdef\m_grph_include_parent{#2}%
233   \ifempty\m_grph_include_name \else
234     \let\p_grph_include_name\m_grph_include_name
235   \fi
236   \ifempty\m_grph_include_parent \else
237     \grph_include_inherit_from_parent\m_grph_include_parent
238   \fi
239   \setupcurrentexternalfigure[#3]}
240
241\def\grph_include_inherit_from_parent#1%
242  {\ifcsname\??externalfigure#1:\s!parent\endcsname
243     \let\currentexternalfigure#1%
244   \fi
245   \ifcsname\??externalfigureinstance#1\endcsname
246     \ifconditional\c_grph_include_trace_inheritance\writestatus\m!figures{inheriting from instance: #1}\fi
247     \csname\??externalfigureinstance#1\endcsname
248   \fi}
249
250\newtoks\t_grph_include_local_settings
251
252\appendtoks
253   \enforced\let\textunderscore\letterunderscore % {\string _} % space needed as _ is now letter in unprotected mode (probably no longer needed)
254   %
255   \dontcomplain
256   \restorecatcodes
257   \forgetall
258\to \t_grph_include_local_settings
259
260\def\grph_include_place_inherit
261  {\ifconditional\c_grph_include_trace_inheritance
262     \writestatus\m!figures{label: \p_grph_include_label, name: \p_grph_include_name, parent: \p_grph_include_parent}%
263   \fi
264   \ifempty\p_grph_include_parent
265     % nothing to be done
266   \orelse\ifx\p_grph_include_parent\p_grph_include_label
267     % redundant
268   \else
269     \grph_include_inherit_from_parent\p_grph_include_parent
270   \fi
271   \ifempty\p_grph_include_label
272     % nothing to be done
273   \else
274     \grph_include_inherit_from_parent\p_grph_include_label
275   \fi}
276
277\def\grph_include_place[#1][#S#2][#S#3]% [label][file][settings] | [file][settings] | [file][parent][settings]
278  {\bgroup
279   \advanceby\c_grph_include_nesting\plusone
280   \cdef\currentexternalfigure{\the\c_grph_include_nesting}%
281   \checkexternalfigureparent % each inherits from the root
282   %
283   \expand\everyexternalfigureresets
284   %
285   \edef\p_grph_include_label{#1}%
286   \let\p_grph_include_name\p_grph_include_label
287   \ifhastok={#2}%
288     % [label] [settings]
289     \let\p_grph_include_parent\p_grph_include_label
290     \grph_include_place_inherit
291     \setupcurrentexternalfigure[#2]%
292   \else
293     % [label] [parent] [settings]
294     \edef\p_grph_include_parent{#2}%
295     \ifempty\p_grph_include_parent
296        \let\p_grph_include_parent\p_grph_include_label
297     \fi
298     \grph_include_place_inherit
299     \setupcurrentexternalfigure[#3]%
300   \fi
301   %
302   \expand\everyexternalfigurechecks
303   %
304   \expand\t_grph_include_local_settings
305   %
306   \edef\p_width    {\externalfigureparameter\c!width}%
307   \edef\p_height   {\externalfigureparameter\c!height}%
308   \edef\p_label    {\externalfigureparameter\c!label}%
309   \edef\p_reference{\externalfigureparameter\c!reference}%
310   %
311   \dostarttagged\t!image\empty
312   \clf_figure_push {
313        name         {\p_grph_include_name}%
314        label        {\ifempty\p_label\p_grph_include_label\else\p_label\fi}%
315        page         {\externalfigureparameter\c!page}%
316        file         {\externalfigureparameter\c!file}%
317        size         {\externalfigureparameter\c!size}%
318        object       {\externalfigureparameter\c!object}%
319        prefix       {\externalfigureparameter\c!prefix}%
320        cache        {\externalfigureparameter\c!cache}%
321        format       {\externalfigureparameter\c!method}%
322        preset       {\externalfigureparameter\c!prefix}%
323        controls     {\externalfigureparameter\c!controls}%
324        resources    {\externalfigureparameter\c!resources}%
325        preview      {\externalfigureparameter\c!preview}%
326        display      {\externalfigureparameter\c!display}%
327        mask         {\externalfigureparameter\c!mask}%
328        range        {\externalfigureparameter\c!range}%
329        conversion   {\externalfigureparameter\c!conversion}%
330        resolution   {\externalfigureparameter\c!resolution}%
331        color        {\externalfigureparameter\c!color}% unprocessed raw key
332        cmyk         {\externalfigureparameter\c!cmyk}% kind of special
333        arguments    {\externalfigureparameter\c!arguments}% used for converters
334        repeat       {\externalfigureparameter\c!repeat}%
335        transform    {\externalfigureparameter\c!transform}%
336        compact      {\externalfigureparameter\c!compact}% experiment, share fonts
337        metadata     {\externalfigureparameter\c!metadata}%
338        userpassword {\externalfigureparameter\c!userpassword}%
339        ownerpassword{\externalfigureparameter\c!ownerpassword}%
340        crop         {\externalfigureparameter\c!crop}%
341    \ifempty\p_width \else
342        width  \dimexpr\p_width\relax
343    \fi
344    \ifempty\p_height \else
345        height \dimexpr\p_height\relax
346    \fi
347   }%\relax
348   \clf_figure_identify
349   \relax
350   \ifconditional\c_grph_include_test_only
351      \ifcase\figurestatus \else
352        \clf_figure_check
353        \clf_figure_dummy
354        \clf_figure_scale
355        \clf_figure_done
356      \fi
357      \grph_include_set_mode
358   \else
359      \ifcase\figurestatus
360        \clf_figure_dummy
361        \clf_figure_scale
362      \else
363        \clf_figure_check
364        \clf_figure_include
365        \clf_figure_scale
366      \fi
367      \clf_figure_done
368      \grph_include_set_mode
369      \grph_include_finalize
370   \fi
371   \clf_figure_pop
372   \dotagfigure
373   %
374   \scratchcounter\zerocount
375   \edef\p_crossreference{\externalfigureparameter\c!crossreference}%
376   \iflocation\iftrialtypesetting\else
377     \ifempty\p_crossreference
378        % nothing
379     \orelse\ifx\p_crossreference\v!no
380        % nothing
381     \orelse\ifx\p_crossreference\v!yes
382       \ifhastok={#2}%
383         \scratchcounter\clf_figure_register_page{#1}{}{#2}\relax
384       \else
385         \scratchcounter\clf_figure_register_page{#1}{#2}{#3}\relax
386       \fi
387     \else
388       \scratchcounter-\p_crossreference % passed by repeater
389     \fi
390   \fi\fi
391   \naturalvpack
392     attr \imageattribute \plustwo
393   \ifnum\scratchcounter>\zerocount
394     {\strc_references_cross_forward {ex:\number \scratchcounter}{\box\foundexternalfigure}}%
395   \orelse\ifnum\scratchcounter<\zerocount
396     {\strc_references_cross_backward{ex:\number-\scratchcounter}{\box\foundexternalfigure}}%
397   \else
398     {\box\foundexternalfigure}%
399   \fi
400   %
401 % \naturalvpack attr \imageattribute \plustwo \bgroup
402 %   \ifcmpnum\scratchcounter\zerocount
403 %     \strc_references_cross_backward{ex:\number-\scratchcounter}{\box\foundexternalfigure}%
404 %   \or % equal
405 %     \box\foundexternalfigure%
406 %   \or % more
407 %     \strc_references_cross_forward {ex:\number \scratchcounter}{\box\foundexternalfigure}%
408 %   \fi
409 % \egroup
410   %
411   \dostoptagged
412   \egroup}
413
414\permanent\protected\def\setfigureconversion[#1]#*[#2]%
415  {\clf_setfigureconversion{#1}{#2}}
416
417%D Next we provide a cross referenced scale-up mechanism:
418
419\def\strc_references_cross_forward#1#2%
420  {\begingroup
421   \strc_references_set_simple_internal_reference{cross:b:#1}%
422   \naturalhpack
423      attr \destinationattribute\number\lastdestinationattribute
424      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:f:#1]}}%
425   \endgroup}
426
427\def\strc_references_cross_backward#1#2%
428  {\begingroup
429   \strc_references_set_simple_internal_reference{cross:f:#1}%
430   \naturalhpack
431      attr \destinationattribute\number\lastdestinationattribute
432      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:b:#1]}}%
433   \endgroup}
434
435\aliased\let\doexternalfigurerepeat\gobblefourarguments % called from lua end
436
437\permanent\tolerant\protected\def\placeregisteredexternalfigures[#1]%
438  {\page
439   \begingroup
440   \enforced\protected\def\doexternalfigurerepeat{\grph_include_place_registered_indeed{#1}}%
441   \dorecurse\clf_figure_nof_registered_pages
442    {\page
443     \clf_figure_flush_registered_pages\recurselevel
444     \page}%
445   \endgroup
446   \page}
447
448\protected\def\grph_include_place_registered_indeed#1#2#3#4#5% called from lua end
449  {\grph_include_place[#2][#3][#4,%
450     \c!hfactor=,\c!wfactor=,\c!factor=,%
451     \c!maxwidth=,\c!maxheight=,%
452     \c!xscale=,\c!yscale=,\c!scale=,%
453     \c!sx=,\c!sy=,\c!s=,%
454     \c!width=,\c!height=,%
455     \c!crossreference=#5,%
456     #1]}
457
458%D Scaling:
459
460\mutable\let\dowithfigure\relax % name might change (into a proper hook)
461
462\permanent\protected\def\doscalefigure % used at lua end
463  {\global\setbox\foundexternalfigure\vpack{\scale[\v!figure]{\dowithfigure{\box\foundexternalfigure}}}}
464
465\definescale % some day we will inherit
466  [\v!figure]
467  [\c!hfactor    =\externalfigureparameter\c!hfactor,
468   \c!wfactor    =\externalfigureparameter\c!wfactor,
469   \c!factor     =\externalfigureparameter\c!factor,
470   \c!maxwidth   =\externalfigureparameter\c!maxwidth,
471   \c!maxheight  =\externalfigureparameter\c!maxheight,
472   \c!equalwidth =\externalfigureparameter\c!equalwidth,
473   \c!equalheight=\externalfigureparameter\c!equalheight,
474   \c!xscale     =\externalfigureparameter\c!xscale,
475   \c!yscale     =\externalfigureparameter\c!yscale,
476   \c!scale      =\externalfigureparameter\c!scale,
477   \c!sx         =\externalfigureparameter\c!sx,
478   \c!sy         =\externalfigureparameter\c!sy,
479   \c!s          =\externalfigureparameter\c!s,
480   \c!width      =\externalfigureparameter\c!width,
481   \c!height     =\externalfigureparameter\c!height,
482   \c!lines      =\externalfigureparameter\c!lines]
483
484%D You can register additional suffixes with the following command:
485%D
486%D \starttyping
487%D \definegraphictypesynonym[jbig] [jb2]
488%D \definegraphictypesynonym[jbig2][jb2]
489%D \definegraphictypesynonym[jbg]  [jb2]
490%D \stoptyping
491
492\permanent\tolerant\protected\def\definegraphictypesynonym[#1]#*[#2]%
493  {\clf_registerfiguresuffix{#1}{#2}}
494
495%D Additional paths can be installed with the regular setup command. The next
496%D macro picks up the list.
497
498\permanent\protected\def\setfigurepathlist
499  {\clf_setfigurepaths{\externalfigureparameter\c!location}{\externalfigureparameter\c!directory}}
500
501%D Variables:
502
503\newbox \foundexternalfigure
504\newtoks\externalfigurepostprocessors
505
506\permanent\def\figurestatus        {\numexpr\clf_figurestatus{status}{0}\relax} % number: 0 = not found
507\permanent\def\figurewidth         {\clf_figurestatus{width}{0}sp}
508\permanent\def\figureheight        {\clf_figurestatus{height}{0}sp}
509\permanent\def\figurexscale        {\clf_figurestatus{xscale}{1}}
510\permanent\def\figureyscale        {\clf_figurestatus{yscale}{1}}
511\permanent\def\figurereference     {\clf_figurestatus{reference}{}}
512
513\permanent\def\figuresize          {\clf_figurerequest{size}{}}
514\permanent\def\figurelabel         {\clf_figurerequest{label}{}}
515\permanent\def\figurefileoriginal  {\clf_figurerequest{name}{}}
516\permanent\def\figurefilepage      {\clf_figurerequest{page}{1}}
517\permanent\def\figurefileoptions   {\clf_figurerequest{options}{}}
518\permanent\def\figurefileconversion{\clf_figurerequest{conversion}{}}
519\permanent\def\figurefileresolution{\clf_figurerequest{resolution}{}}
520\permanent\def\figurefilecolor     {\clf_figurerequest{color}{}}
521\permanent\def\figurefilearguments {\clf_figurerequest{arguments}{}}
522\permanent\def\figurefilecache     {\clf_figurerequest{cache}{}}
523\permanent\def\figurefileprefix    {\clf_figurerequest{prefix}{}}
524
525\permanent\def\figurenaturalwidth  {\clf_figureused{width}{\number\dimexpr\externalfigureparameter\c!defaultwidth\relax}sp}
526\permanent\def\figurenaturalheight {\clf_figureused{height}{\number\dimexpr\externalfigureparameter\c!defaultheight\relax}sp}
527\permanent\def\figurexresolution   {\clf_figureused{xresolution}{0}}
528\permanent\def\figureyresolution   {\clf_figureused{yresolution}{0}}
529\permanent\def\figureorientation   {\clf_figureused{orientation}{1}}
530\permanent\def\figurerotation      {\clf_figureused{rotation}{0}}
531\permanent\def\figurexsize         {\clf_figureused{xsize}{0}}
532\permanent\def\figureysize         {\clf_figureused{ysize}{0}}
533\permanent\def\figurecolordepth    {\clf_figureused{colordepth}{0}}
534\permanent\def\figuredepth         {\clf_figureused{depth}{0}}
535
536\permanent\def\figurefullname      {\clf_figureused{fullname}{}}
537\permanent\def\noffigurepages      {\clf_figureused{pages}{0}}
538
539
540% \permanent\def\figurefilepath      {\clf_figurefilepath} % public in lua
541% \permanent\def\figurefilename      {\clf_figurefilename} % public in lua
542% \permanent\def\figurefiletype      {\clf_figurefiletype} % public in lua
543
544\permanent\let\naturalfigurewidth  \figurenaturalwidth
545\permanent\let\naturalfigureheight \figurenaturalheight
546
547\aliased\let\figurescalewidth    \figurewidth
548\aliased\let\figurescaleheight   \figureheight
549\aliased\let\figurescalexscale   \figurexscale
550\aliased\let\figurescaleyscale   \figureyscale
551
552%D Abuse:
553%D
554%D \starttyping
555%D \externalfigure[rubish.pdf] \ifcase\figurestatus\relax \ctxlua{os.exit(999)} \fi
556%D \stoptyping
557
558%D Calculating:
559
560% \enabletrackers[figures.conversion]
561% \externalfigure[demo.svg]
562% \externalfigure[demo.svg][conversion=png]
563
564%D The following registers are used (if only to be downward compatible).
565
566\newconditional\c_grph_include_skip
567\newconditional\c_grph_include_test_only
568\newconditional\c_grph_include_level      \c_grph_include_level\conditionalfalse  % true=background false=normal
569\newconditional\c_grph_include_flush      \c_grph_include_flush\conditionaltrue  % true=place      false=ignore
570
571\newsystemmode\v!figure
572
573\def\grph_include_set_mode
574  {\ifcase\figurestatus
575     \globalresetsystemmode\v!figure % todo, also: \v!resource
576   \else
577     \globalsetsystemmode  \v!figure % todo, also: \v!resource
578   \fi}
579
580\appendtoks
581    \clf_setfigurepaths
582      {\externalfigureparameter\c!location}%
583      {\externalfigureparameter\c!directory}%
584    \clf_figure_reset
585      \foundexternalfigure
586      \externalfigureparameter\c!defaultwidth
587      \externalfigureparameter\c!defaultheight
588    \relax
589\to \everyexternalfigureresets
590
591\appendtoks
592    \edef\p_option{\externalfigureparameter\c!option}%
593    \ifx\p_option\v!frame
594      \c_grph_include_skip\conditionalfalse
595      \letexternalfigureparameter\c!frame\v!on
596    \orelse\ifx\p_option\v!empty
597      \c_grph_include_skip\conditionaltrue
598      \letexternalfigureparameter\c!frame\v!off
599    \else
600      \c_grph_include_skip\conditionalfalse
601    \fi
602    % fake color in gray bitmaps, assumes that
603    % a transparent color is used
604    \edef\p_foregroundcolor{\externalfigureparameter\c!foregroundcolor}%
605    \ifempty\p_foregroundcolor \else
606        \setexternalfigureparameter\c!background{\v!foreground,\v!color}%
607        \letexternalfigureparameter\c!backgroundcolor\p_foregroundcolor
608    \fi
609\to \everyexternalfigurechecks
610
611%D Internal graphics are handled at the \TEX\ end:
612
613% strut=none also avoids the \noindent! otherwise we're in hmode when
614% blank happens and we get a lineskip
615
616\def\grph_include_process_tex#1%
617  {\framed
618     [\c!strut=\v!none,\c!align=\v!normal,\c!frame=\v!off,
619      \c!offset=\v!overlay,\c!width=\v!fit,\c!height=\v!fit]
620     {\blank[\v!disable]%
621      #1\endgraf
622      \removelastskip}} % disable should stay here!
623
624
625% used al lua end:
626
627\permanent\protected\def\docheckfigurebuffer  #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\getbuffer[#1]}}}
628\permanent\protected\def\docheckfiguretex     #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\input{#1}}}}
629\permanent\protected\def\docheckfigurecld     #1{\global\setbox\foundexternalfigure\vbox {\cldprocessfile{#1}}}
630\permanent\protected\def\docheckfiguremps     #1{\global\setbox\foundexternalfigure\vpack{\convertMPtoPDF{#1}11}}
631\permanent\protected\def\docheckfiguremprun #1#2{\global\setbox\foundexternalfigure\vpack{\useMPrun{#1}{#2}}}
632
633\permanent\protected\def\relocateexternalfigure
634  {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup
635     %
636     % The \vss can (!) introduce 1 sp excess visible in xform which in itself
637     % is not that important but some don't like these cosmetic side effects, for
638     % instance we can get:
639     %
640     % vss   : \vbox(845.1575+0.0)x597.23125, glue set 845.15747fil, direction TLT
641     % vskip : \vbox(845.1575+0.0)x597.23125, direction TLT
642     %
643     % or
644     %
645     % 1 0 0 1 0 0.00003 cm
646     % 1 0 0 1 0 0       cm
647     %
648     % This is a known property of using glue and can even depend on the architecture
649     % (float implementation). Anyway, let's for now use a skip. Of course this can
650     % shift the issue elsewhere, as vss is used a lot elsewhere.
651     %
652   % \vss
653     \vkern\ht\foundexternalfigure
654     %
655     \ht\foundexternalfigure\zeropoint
656     \dp\foundexternalfigure\zeropoint
657     \hpack to \wd\foundexternalfigure\bgroup
658        \box\foundexternalfigure
659        \hss
660     \egroup
661   \egroup}
662
663\permanent\protected\def\startfoundexternalfigure#1#2% ht wd
664  {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup}
665
666\permanent\protected\def\stopfoundexternalfigure
667  {\hss\egroup\egroup}
668
669\permanent\protected\def\emptyfoundexternalfigure % sort of obsolete
670  {\startfoundexternalfigure{\externalfigureparameter\c!defaultwidth}{\externalfigureparameter\c!defaultheight}%
671   \stopfoundexternalfigure}
672
673% \doifmodeelse{*\v!last}
674%   {\c_grph_include_flush\conditionaltrue}
675%   {\c_grph_include_flush\conditionalfalse}%
676
677\def\grph_include_finalize
678  {\global\setbox\foundexternalfigure\vbox
679     {\ifcase\figurestatus
680        \letexternalfigureparameter\c!frame\v!on
681      \fi
682      \ifconditional\c_grph_include_flush
683        \ifconditional\c_grph_include_level % probably background
684          \ifconditional\c_grph_include_skip
685            % nothing
686            \fakebox\foundexternalfigure
687          \orelse\ifcase\figurestatus
688            % nothing
689          \else
690            \expand\externalfigurepostprocessors
691            \box\foundexternalfigure
692          \fi
693        \else
694          \iftrialtypesetting \else \feedbackexternalfigure \fi
695          \c_grph_include_level\conditionaltrue
696          \ifconditional\c_grph_include_skip
697            \ifcase\figurestatus
698              \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
699            \else
700              \grph_include_replacement\figurelabel\figurefullname{skipped}%
701            \fi
702          \orelse\ifcase\figurestatus
703            \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
704          \else
705            \expand\externalfigurepostprocessors
706            \edef\p_reset{\externalfigureparameter\c!reset}%
707            \ifx\p_reset\v!yes
708              \wd\foundexternalfigure\figurewidth
709              \ht\foundexternalfigure\figureheight
710              \dp\foundexternalfigure\zeropoint
711              \box\foundexternalfigure
712            \else
713              \letexternalfigureparameter\c!offset\v!overlay
714              \letexternalfigureparameter\c!width \figurewidth
715              \letexternalfigureparameter\c!height\figureheight
716              \inheritedexternalfigureframed{\box\foundexternalfigure}%
717            \fi
718          \fi
719        \fi
720      \else
721        % maybe also \expand\externalfigurepostprocessors
722        \iftrialtypesetting \else \feedbackexternalfigure \fi
723      \fi}}
724
725\mutable\let\feedbackexternalfigure\relax % hook
726
727\permanent\tolerant\protected\def\getfiguredimensions[#1]#*[#S#2]%
728  {\startnointerference % we can use \nospaces\plusone
729     \c_grph_include_test_only\conditionaltrue
730     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
731   \stopnointerference}
732
733\permanent\protected\def\doifelsefigure#1%
734  {\getfiguredimensions[#1]% so data is available !
735   \ifcase\figurestatus
736     \expandafter\secondoftwoarguments
737   \else
738     \expandafter\firstoftwoarguments
739   \fi}
740
741\aliased\let\doiffigureelse\doifelsefigure
742
743% No placement, handy for preprocessing:
744
745\permanent\tolerant\protected\def\registerexternalfigure[#1]#*[#S#2]#*[#S#3]%
746  {\startnointerference
747     \c_grph_include_test_only
748     \c_grph_include_flush\conditionalfalse % == test ?
749     \externalfigure[#1][#2][#3]% or
750     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
751   \stopnointerference}
752
753% Helpers will be replaced when xforms are accessible at the lua end but then
754% we need to do the object offset there too.
755
756\permanent\protected\def\dosetfigureobject#1#2%
757  {\setobject{#1}{#2}\vpack{\box\foundexternalfigure}}
758
759\permanent\protected\def\doboxfigureobject#1#2%
760  {\global\setbox\foundexternalfigure\vpack{\getobject{#1}{#2}}} % probably one vbox too many
761
762% Figure bases
763
764\permanent\protected\def\usefigurebase[#1]%
765  {\clf_usefigurebase{#1}}
766
767\appendtoks
768   \setfigurepathlist  % the path may be used elsewhere too (as in x-res-04)
769\to \everysetupexternalfigure
770
771\appendtoks
772    \clf_setfigurelookuporder{\externalfigureparameter\c!order}%
773\to \everysetupexternalfigure
774
775\definecolor[missingfigurecolor][s=.8]
776
777\def\grph_include_replacement#1#2#3%
778  {\bgroup
779   \letexternalfigureparameter\c!width\figurewidth
780   \letexternalfigureparameter\c!height\figureheight
781   \letexternalfigureparameter\c!background\v!color
782   \setexternalfigureparameter\c!backgroundcolor{missingfigurecolor}%
783   \setexternalfigureparameter\c!align{\v!middle,\v!lohi}% we default to \v!none
784   \inheritedexternalfigureframed
785     {\ttxx \nohyphens
786%       name: \detokenize\expandafter{\normalexpanded{#1}}\crlf
787%       file: \detokenize\expandafter{\normalexpanded{#2}}\crlf
788      name: \expandeddetokenize{#1}\crlf
789      file: \expandeddetokenize{#2}\crlf
790      state: #3
791      }%
792   \egroup}
793
794% maybe setuphandler
795
796\newconditional\c_grph_include_in_collection
797
798\newdimension  \d_grph_include_collection_minwidth
799\newdimension  \d_grph_include_collection_maxwidth
800\newdimension  \d_grph_include_collection_minheight
801\newdimension  \d_grph_include_collection_maxheight
802
803\def\grph_include_analyze_collection[#1][#S#2]%
804  {\ifconditional\c_grph_include_in_collection
805      \c_grph_include_in_collection\conditionalfalse
806      \getfiguredimensions[#1][#2]%
807      \c_grph_include_in_collection\conditionaltrue
808      \scratchdimen\naturalfigurewidth
809      \ifdim\scratchdimen>\d_grph_include_collection_maxwidth  \d_grph_include_collection_maxwidth \scratchdimen \fi
810      \ifdim\scratchdimen<\d_grph_include_collection_minwidth  \d_grph_include_collection_minwidth \scratchdimen \fi
811      \scratchdimen\naturalfigureheight
812      \ifdim\scratchdimen>\d_grph_include_collection_maxheight \d_grph_include_collection_maxheight\scratchdimen \fi
813      \ifdim\scratchdimen<\d_grph_include_collection_minheight \d_grph_include_collection_minheight\scratchdimen \fi
814   \fi}
815
816\mutable\lettonothing\currentexternalfigurecollection
817
818\permanent\protected\def\startexternalfigurecollection[#1]%
819  {\begingroup
820   \cdef\currentexternalfigurecollection{#1}%
821   \c_grph_include_in_collection\conditionaltrue
822   \d_grph_include_collection_minwidth \maxdimen
823   \d_grph_include_collection_maxwidth \zeropoint
824   \d_grph_include_collection_minheight\maxdimen
825   \d_grph_include_collection_maxheight\zeropoint}
826
827\permanent\protected\def\stopexternalfigurecollection
828  {\xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!minwidth \endcsname{\the\d_grph_include_collection_minwidth }%
829   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!maxwidth \endcsname{\the\d_grph_include_collection_maxwidth }%
830   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!minheight\endcsname{\the\d_grph_include_collection_minheight}%
831   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!maxheight\endcsname{\the\d_grph_include_collection_maxheight}%
832   \endgroup}
833
834\permanent\def\externalfigurecollectionparameter#1#2%
835  {\csname
836     \ifcsname\??externalfigurecollection#1:#2\endcsname
837       \??externalfigurecollection#1:#2%
838     \else
839       \s!empty
840     \fi
841   \endcsname}
842
843\permanent\def\externalfigurecollectionminwidth #1{\externalfigurecollectionparameter{#1}\c!minwidth }
844\permanent\def\externalfigurecollectionmaxwidth #1{\externalfigurecollectionparameter{#1}\c!maxwidth }
845\permanent\def\externalfigurecollectionminheight#1{\externalfigurecollectionparameter{#1}\c!minheight}
846\permanent\def\externalfigurecollectionmaxheight#1{\externalfigurecollectionparameter{#1}\c!maxheight}
847
848\aliased\let\efcparameter\externalfigurecollectionparameter % still needed ?
849\aliased\let\efcminwidth \externalfigurecollectionminwidth  % still needed ?
850\aliased\let\efcmaxwidth \externalfigurecollectionmaxwidth  % still needed ?
851\aliased\let\efcminheight\externalfigurecollectionminheight % still needed ?
852\aliased\let\efcmaxheight\externalfigurecollectionmaxheight % still needed ?
853
854% \startexternalfigurecollection[name]
855%     \useexternalfigure[cow] [cow.pdf]
856%     \useexternalfigure[mill][mill.png]
857% \stopexternalfigurecollection
858% \starttext
859% \bTABLE
860%     \bTR
861%         \bTD \externalfigure[cow] [height=\externalfigurecollectionmaxheight{name}] \eTD
862%         \bTD \externalfigure[mill][height=\externalfigurecollectionmaxheight{name}] \eTD
863%     \eTR
864% \eTABLE
865% \stoptext
866
867\permanent\protected\def\overlayfigure#1%
868  {\externalfigure[#1][\c!width=\d_overlay_width,\c!height=\d_overlay_height]}
869
870% Experimental (will become cleaner):
871
872\permanent\tolerant\protected\def\includesvgfile[#1]#*[#S#2]%
873  {\hbox\bgroup % no \dontleavehmode
874   \getdummyparameters[\c!offset=\zeropoint,#2]%
875   \clf_includesvgfile{#1}\dimexpr\dummyparameter\c!offset\relax
876   \egroup}
877
878\permanent\tolerant\protected\def\includesvgbuffer[#1]#*[#S#2]%
879  {\hbox\bgroup % no \dontleavehmode
880   \getdummyparameters[\c!offset=\zeropoint,#2]%
881   \clf_includesvgbuffer{#1}\dimexpr\dummyparameter\c!offset\relax
882   \egroup}
883
884% Bonus:
885
886\useexternalfigure
887  [\v!buffer]
888  [\jobname.buffer]
889  [\c!object=\v!no]
890
891% Another two:
892
893\defineexternalfigure
894  [\v!inline]
895  [\c!height=\lineheight]
896
897\permanent\protected\def\combinationwidth
898  {\dimexpr
899     (\textwidth
900     -\effectiveleftskip
901     -\effectiverightskip
902     -\numexpr\combinationparameter\c!nx-\plusone\relax\dimexpr\combinationparameter\c!distance\relax
903     )/\combinationparameter\c!nx
904   \relax}
905
906\pushoverloadmode
907    \newuserunit \combinationwidth cx % combination width
908\popoverloadmode
909
910\definemeasure
911  [\v!combination]
912  [\combinationwidth]
913
914\defineexternalfigure
915  [\v!combination]
916  [\c!width=\combinationwidth]
917
918% \startcombination[nx=2,ny=1]
919%     {\externalfigure[dummy][combination]} {}
920%     {\externalfigure[dummy][combination]} {}
921% \stopcombination
922
923% \startcombination[nx=2,ny=1]
924%     {\externalfigure[dummy][width=\measure{combination}]} {}
925%     {\externalfigure[dummy][width=\measure{combination}]} {}
926% \stopcombination
927
928% \startcombination[nx=2,ny=2]
929%     {\externalfigure[dummy][combination]} {}
930%     {\externalfigure[dummy][combination]} {}
931%     {\externalfigure[dummy][combination]} {}
932%     {\externalfigure[dummy][combination]} {}
933% \stopcombination
934
935% \startcombination[nx=3,ny=1]
936%     {\externalfigure[dummy][combination]} {}
937%     {\externalfigure[dummy][combination]} {}
938%     {\externalfigure[dummy][combination]} {}
939% \stopcombination
940
941% \startcombination[nx=4,ny=1]
942%     {\externalfigure[dummy][combination]} {}
943%     {\externalfigure[dummy][combination]} {}
944%     {\externalfigure[dummy][combination]} {}
945%     {\externalfigure[dummy][combination]} {}
946% \stopcombination
947
948\permanent\protected\def\inlinefigure[#1]%
949  {\dontleavehmode
950   \sbox{\externalfigure[#1][\v!inline]}}
951
952%D Needs to be done global:
953
954\definelayer[epdfcontent]
955
956%D Experiment:
957%D
958%D \starttyping
959%D \registerfiguremask[mymask] {
960%D     {
961%D         {   0, 100, 0x00 },
962%D         { 101, 200, 0x7F },
963%D         { 201, 255, 0xFF },
964%D     }
965%D }
966%D
967%D \dontleavehmode \externalfigure
968%D     [proofs.png]
969%D     [background=color,
970%D      backgroundcolor=yellow,
971%D      mask=mymask,
972%D      width=5cm]
973%D \stOPtyping
974
975\protect \endinput
976
977%D Moved here because this already old code is nowhere documents (so I need to check
978%D it:
979%
980% \starttyping
981% \starttext
982%
983% \startluaparameterset [u3d:myset:controls:1]
984%     view = {
985%         name = 'default',
986%         bg = {1,1,1},
987%         mag = 100,
988%         coo = {0,0,0},
989%         c2c = {0,0,1},
990%         rot = {40,0,60},
991%         roo = 6,
992%         lights = 'CAD'
993%     },
994%     js = 'cloudq.js'
995% \stopluaparameterset
996%
997% \startluaparameterset [u3d:myset:controls:2]
998%     views = {
999%         {
1000%             name = 'AnglePositioning',
1001%             bg = {1,1,1},
1002%             azimuth = 45,
1003%             altitude = 45,
1004%             roo = 50,
1005%             aac = 2.5,
1006%             lights = 'Artwork'
1007%         },
1008%         {
1009%             name = 'RotationPositioning',
1010%             bg = {1,1,1},
1011%             rot = {0,45,45},
1012%             roo = 50,
1013%             aac = 2.5,
1014%             lights = 'Artwork'
1015%         },
1016%         {
1017%             name = 'VectorPositioning',
1018%             bg = {1,0,0},
1019%             c2c = {1,1,math.sqrt(2)},
1020%             roo = 50,
1021%             aac = 2.5,
1022%             lights = 'CAD'
1023%         },
1024%         {
1025%             name = 'PositionPositioning',
1026%             bg = {1,0,0},
1027%             pos = {1+25,1+25,1+50/math.sqrt(2)},
1028%             aac = 2.5,
1029%             lights = 'CAD'
1030%         },
1031%         {
1032%             name = 'ortho',
1033%             bg = {1,1,1},
1034%             mag = 300,
1035%             lights = 'CAD',
1036%             crossection = {}
1037%         }
1038%     },
1039%     view = {
1040%         name = 'default',
1041%         bg = {1,1,1},
1042%         c2c = {-1,-1,0},
1043%         roo = 50,
1044%         aac = 2.5,
1045%         roll = 45,
1046%         lights = 'CAD',
1047%         crossection = {
1048%             normal = {-1,-1,-1},
1049%             transparent = true
1050%         },
1051%         nodes = {
1052%             {
1053%                 name = 'xlabel',
1054%                 visible = false
1055%             },
1056%             {
1057%                 name = 'ylabel',
1058%                 opacity = 0.5
1059%             },
1060%             {
1061%                 name = 'zlabel',
1062%                 rendermode = 'Wireframe'
1063%             }
1064%         }
1065%     }
1066% \stopluaparameterset
1067%
1068% \useexternalfigure
1069%   [cloudq]
1070%   [cloudq.u3d]
1071%   [width=0.7\textwidth,
1072%    height=.7\textwidth,
1073%    display=u3d:myset:display:1,
1074%    controls=u3d:myset:controls:1]
1075%
1076% \useexternalfigure
1077%   [axes]
1078%   [axes.u3d]
1079%   [width=0.7\textwidth,
1080%    height=.7\textwidth,
1081%    controls=u3d:myset:controls:1]
1082%
1083% \startluaparameterset[u3d:myset:display:2]
1084%     toolbar = true,
1085%     preview = 'cloudq.png'
1086% \stopluaparameterset
1087% \startluaparameterset[u3d:myset:display:3]
1088%     toolbar = true,
1089%     tree = false,
1090%     preview = 'axes.png'
1091% \stopluaparameterset
1092% \startluaparameterset[u3d:myset:display:4]
1093%     toolbar = true,
1094%     tree = false,
1095%     view = {
1096%         name = 'view',
1097%         bg = {0.1,0.1,0.1},
1098%         c2c = {-1,-1,0},
1099%         roo = 50,
1100%         aac = 2.5,
1101%         roll = 45,
1102%         lights = 'Red'
1103%     }
1104% \stopluaparameterset
1105% \startluaparameterset[u3d:myset:display:5]
1106%     toolbar = true,
1107%     tree = false,
1108%     view = 'ortho'
1109% \stopluaparameterset
1110%
1111% \placefigure[here]{none}{\externalfigure[cloudq][frame=on,display=u3d:myset:display:2]}
1112% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:3]}
1113% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:4]}
1114% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:5,width=0.5\textwidth,height=.5\textwidth]}
1115%
1116% \stoptext
1117