grph-inc.mkxl /size: 37 Kb    last modification: 2025-02-21 11:03
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        =preset:\s!default,
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_label    {\externalfigureparameter\c!label}%
307   %
308   \dostarttaggednodetail\t!image
309   \clf_figure_push {
310        name         {\p_grph_include_name}%
311      % label        {\ifempty\p_label\p_grph_include_label\else\p_label\fi}%
312        label        {\ifempty{\externalfigureparameter\c!label}\p_grph_include_label\else\lastnamedcs\fi}%
313        page         {\externalfigureparameter\c!page}%
314        file         {\externalfigureparameter\c!file}%
315        size         {\externalfigureparameter\c!size}%
316        object       {\externalfigureparameter\c!object}%
317        prefix       {\externalfigureparameter\c!prefix}%
318        cache        {\externalfigureparameter\c!cache}%
319        format       {\externalfigureparameter\c!method}%
320        preset       {\externalfigureparameter\c!prefix}%
321        controls     {\externalfigureparameter\c!controls}%
322        resources    {\externalfigureparameter\c!resources}%
323        preview      {\externalfigureparameter\c!preview}%
324        display      {\externalfigureparameter\c!display}%
325        mask         {\externalfigureparameter\c!mask}%
326        range        {\externalfigureparameter\c!range}%
327        conversion   {\externalfigureparameter\c!conversion}%
328        resolution   {\externalfigureparameter\c!resolution}%
329        color        {\externalfigureparameter\c!color}% unprocessed raw key
330        cmyk         {\externalfigureparameter\c!cmyk}% kind of special
331        arguments    {\externalfigureparameter\c!arguments}% used for converters
332        repeat       {\externalfigureparameter\c!repeat}%
333        transform    {\externalfigureparameter\c!transform}%
334        compact      {\externalfigureparameter\c!compact}% experiment, share fonts
335        metadata     {\externalfigureparameter\c!metadata}%
336        userpassword {\externalfigureparameter\c!userpassword}%
337        ownerpassword{\externalfigureparameter\c!ownerpassword}%
338        crop         {\externalfigureparameter\c!crop}%
339    \ifchkdimexpr\externalfigureparameter\c!width\or
340        width  \lastchkdimension
341    \fi
342    \ifchkdimexpr\externalfigureparameter\c!height\or
343        height \lastchkdimension
344    \fi
345   }%\relax
346   \clf_figure_identify
347   \relax
348   \ifconditional\c_grph_include_test_only
349      \ifcase\figurestatus \else
350        \clf_figure_check
351        \clf_figure_dummy
352        \clf_figure_scale
353        \clf_figure_done
354      \fi
355      \grph_include_set_mode
356   \else
357      \ifcase\figurestatus
358        \clf_figure_dummy
359        \clf_figure_scale
360      \else
361        \clf_figure_check
362        \clf_figure_include
363        \clf_figure_scale
364      \fi
365      \clf_figure_done
366      \grph_include_set_mode
367      \grph_include_finalize
368   \fi
369   \clf_figure_pop
370   \dotagfigure
371   %
372   \scratchcounter\zerocount
373   \edef\p_crossreference{\externalfigureparameter\c!crossreference}%
374   \iflocation\iftrialtypesetting\else
375     \ifempty\p_crossreference
376        % nothing
377     \orelse\ifx\p_crossreference\v!no
378        % nothing
379     \orelse\ifx\p_crossreference\v!yes
380       \ifhastok={#2}%
381         \scratchcounter\clf_figure_register_page{#1}{}{#2}\relax
382       \else
383         \scratchcounter\clf_figure_register_page{#1}{#2}{#3}\relax
384       \fi
385     \else
386       \scratchcounter-\p_crossreference % passed by repeater
387     \fi
388   \fi\fi
389   \naturalvpack
390     attr \imageattribute \plustwo
391   \ifnum\scratchcounter>\zerocount
392     {\strc_references_cross_forward {ex:\number \scratchcounter}{\box\foundexternalfigure}}%
393   \orelse\ifnum\scratchcounter<\zerocount
394     {\strc_references_cross_backward{ex:\number-\scratchcounter}{\box\foundexternalfigure}}%
395   \else
396     {\box\foundexternalfigure}%
397   \fi
398   %
399 % \naturalvpack attr \imageattribute \plustwo \bgroup
400 %   \ifcmpnum\scratchcounter\zerocount
401 %     \strc_references_cross_backward{ex:\number-\scratchcounter}{\box\foundexternalfigure}%
402 %   \or % equal
403 %     \box\foundexternalfigure%
404 %   \or % more
405 %     \strc_references_cross_forward {ex:\number \scratchcounter}{\box\foundexternalfigure}%
406 %   \fi
407 % \egroup
408   %
409   \dostoptagged
410   \egroup}
411
412\permanent\protected\def\setfigureconversion[#1]#*[#2]%
413  {\clf_setfigureconversion{#1}{#2}}
414
415%D Next we provide a cross referenced scale-up mechanism:
416
417\def\strc_references_cross_forward#1#2%
418  {\begingroup
419   \strc_references_set_simple_internal_reference{cross:b:#1}%
420   \naturalhpack
421      attr \destinationattribute\number\lastdestinationattribute
422      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:f:#1]}}%
423   \endgroup}
424
425\def\strc_references_cross_backward#1#2%
426  {\begingroup
427   \strc_references_set_simple_internal_reference{cross:f:#1}%
428   \naturalhpack
429      attr \destinationattribute\number\lastdestinationattribute
430      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:b:#1]}}%
431   \endgroup}
432
433\aliased\let\doexternalfigurerepeat\gobblefourarguments % called from lua end
434
435\permanent\tolerant\protected\def\placeregisteredexternalfigures[#1]%
436  {\page
437   \begingroup
438   \enforced\protected\def\doexternalfigurerepeat{\grph_include_place_registered_indeed{#1}}%
439   \dorecurse\clf_figure_nof_registered_pages
440    {\page
441     \clf_figure_flush_registered_pages\recurselevel
442     \page}%
443   \endgroup
444   \page}
445
446\protected\def\grph_include_place_registered_indeed#1#2#3#4#5% called from lua end
447  {\grph_include_place[#2][#3][#4,%
448     \c!hfactor=,\c!wfactor=,\c!factor=,%
449     \c!maxwidth=,\c!maxheight=,%
450     \c!xscale=,\c!yscale=,\c!scale=,%
451     \c!sx=,\c!sy=,\c!s=,%
452     \c!width=,\c!height=,%
453     \c!crossreference=#5,%
454     #1]}
455
456%D Scaling:
457
458\mutable\let\dowithfigure\relax % name might change (into a proper hook)
459
460\permanent\protected\def\doscalefigure % used at lua end
461  {\global\setbox\foundexternalfigure\vpack{\scale[\v!figure]{\dowithfigure{\box\foundexternalfigure}}}}
462
463\definescale % some day we will inherit
464  [\v!figure]
465  [\c!hfactor    =\externalfigureparameter\c!hfactor,
466   \c!wfactor    =\externalfigureparameter\c!wfactor,
467   \c!factor     =\externalfigureparameter\c!factor,
468   \c!maxwidth   =\externalfigureparameter\c!maxwidth,
469   \c!maxheight  =\externalfigureparameter\c!maxheight,
470   \c!equalwidth =\externalfigureparameter\c!equalwidth,
471   \c!equalheight=\externalfigureparameter\c!equalheight,
472   \c!xscale     =\externalfigureparameter\c!xscale,
473   \c!yscale     =\externalfigureparameter\c!yscale,
474   \c!scale      =\externalfigureparameter\c!scale,
475   \c!sx         =\externalfigureparameter\c!sx,
476   \c!sy         =\externalfigureparameter\c!sy,
477   \c!s          =\externalfigureparameter\c!s,
478   \c!width      =\externalfigureparameter\c!width,
479   \c!height     =\externalfigureparameter\c!height,
480   \c!lines      =\externalfigureparameter\c!lines]
481
482%D You can register additional suffixes with the following command:
483%D
484%D \starttyping
485%D \definegraphictypesynonym[jbig] [jb2]
486%D \definegraphictypesynonym[jbig2][jb2]
487%D \definegraphictypesynonym[jbg]  [jb2]
488%D \stoptyping
489
490\permanent\tolerant\protected\def\definegraphictypesynonym[#1]#*[#2]%
491  {\clf_registerfiguresuffix{#1}{#2}}
492
493%D Additional paths can be installed with the regular setup command. The next
494%D macro picks up the list.
495
496\permanent\protected\def\setfigurepathlist
497  {\clf_setfigurepaths{\externalfigureparameter\c!location}{\externalfigureparameter\c!directory}}
498
499%D Variables:
500
501\newbox \foundexternalfigure
502\newtoks\externalfigurepostprocessors
503
504\permanent\untraced\def\figurestatus        {\numexpr\clf_figurestatus{status}{0}\relax} % number: 0 = not found
505\permanent\untraced\def\figurewidth         {\clf_figurestatus{width}{0}sp}
506\permanent\untraced\def\figureheight        {\clf_figurestatus{height}{0}sp}
507\permanent\untraced\def\figuredepth         {\clf_figurestatus{depth}{0}sp}
508\permanent\untraced\def\figurexscale        {\clf_figurestatus{xscale}{1}}
509\permanent\untraced\def\figureyscale        {\clf_figurestatus{yscale}{1}}
510\permanent\untraced\def\figurereference     {\clf_figurestatus{reference}{}}
511
512\permanent\untraced\def\figuresize          {\clf_figurerequest{size}{}}
513\permanent\untraced\def\figurelabel         {\clf_figurerequest{label}{}}
514\permanent\untraced\def\figurefileoriginal  {\clf_figurerequest{name}{}}
515\permanent\untraced\def\figurefilepage      {\clf_figurerequest{page}{1}}
516\permanent\untraced\def\figurefileoptions   {\clf_figurerequest{options}{}}
517\permanent\untraced\def\figurefileconversion{\clf_figurerequest{conversion}{}}
518\permanent\untraced\def\figurefileresolution{\clf_figurerequest{resolution}{}}
519\permanent\untraced\def\figurefilecolor     {\clf_figurerequest{color}{}}
520\permanent\untraced\def\figurefilearguments {\clf_figurerequest{arguments}{}}
521\permanent\untraced\def\figurefilecache     {\clf_figurerequest{cache}{}}
522\permanent\untraced\def\figurefileprefix    {\clf_figurerequest{prefix}{}}
523
524\permanent\untraced\def\figurenaturalwidth  {\clf_figureused{width}{\number\dimexpr\externalfigureparameter\c!defaultwidth\relax}sp}
525\permanent\untraced\def\figurenaturalheight {\clf_figureused{height}{\number\dimexpr\externalfigureparameter\c!defaultheight\relax}sp}
526\permanent\untraced\def\figurexresolution   {\clf_figureused{xresolution}{0}}
527\permanent\untraced\def\figureyresolution   {\clf_figureused{yresolution}{0}}
528\permanent\untraced\def\figureorientation   {\clf_figureused{orientation}{1}}
529\permanent\untraced\def\figurerotation      {\clf_figureused{rotation}{0}}
530\permanent\untraced\def\figurexsize         {\clf_figureused{xsize}{0}}
531\permanent\untraced\def\figureysize         {\clf_figureused{ysize}{0}}
532\permanent\untraced\def\figurecolordepth    {\clf_figureused{colordepth}{0}}
533
534\permanent\untraced\def\figurefullname      {\clf_figureused{fullname}{}}
535\permanent\untraced\def\noffigurepages      {\clf_figureused{pages}{0}}
536
537% \permanent\untraced\def\figurefilepath      {\clf_figurefilepath} % public in lua
538% \permanent\untraced\def\figurefilename      {\clf_figurefilename} % public in lua
539% \permanent\untraced\def\figurefiletype      {\clf_figurefiletype} % public in lua
540
541\permanent\let\naturalfigurewidth  \figurenaturalwidth
542\permanent\let\naturalfigureheight \figurenaturalheight
543
544\aliased\let\figurescalewidth    \figurewidth
545\aliased\let\figurescaleheight   \figureheight
546\aliased\let\figurescalexscale   \figurexscale
547\aliased\let\figurescaleyscale   \figureyscale
548
549%D Abuse:
550%D
551%D \starttyping
552%D \externalfigure[rubish.pdf] \ifcase\figurestatus\relax \ctxlua{os.exit(999)} \fi
553%D \stoptyping
554
555%D Calculating:
556
557% \enabletrackers[figures.conversion]
558% \externalfigure[demo.svg]
559% \externalfigure[demo.svg][conversion=png]
560
561%D The following registers are used (if only to be downward compatible).
562
563\newconditional\c_grph_include_skip
564\newconditional\c_grph_include_test_only
565\newconditional\c_grph_include_level      \c_grph_include_level\conditionalfalse  % true=background false=normal
566\newconditional\c_grph_include_flush      \c_grph_include_flush\conditionaltrue  % true=place      false=ignore
567
568\newsystemmode\v!figure
569
570\def\grph_include_set_mode
571  {\ifcase\figurestatus
572     \globalresetsystemmode\v!figure % todo, also: \v!resource
573   \else
574     \globalsetsystemmode  \v!figure % todo, also: \v!resource
575   \fi}
576
577\appendtoks
578    \clf_setfigurepaths
579      {\externalfigureparameter\c!location}%
580      {\externalfigureparameter\c!directory}%
581    \clf_figurereset
582      \foundexternalfigure
583      {\externalfigureparameter\c!defaultwidth}%
584      {\externalfigureparameter\c!defaultheight}%
585    \relax
586\to \everyexternalfigureresets
587
588\appendtoks
589    \edef\p_option{\externalfigureparameter\c!option}%
590    \ifx\p_option\v!frame
591      \c_grph_include_skip\conditionalfalse
592      \letexternalfigureparameter\c!frame\v!on
593    \orelse\ifx\p_option\v!empty
594      \c_grph_include_skip\conditionaltrue
595      \letexternalfigureparameter\c!frame\v!off
596    \else
597      \c_grph_include_skip\conditionalfalse
598    \fi
599    % fake color in gray bitmaps, assumes that
600    % a transparent color is used
601    \edef\p_foregroundcolor{\externalfigureparameter\c!foregroundcolor}%
602    \ifempty\p_foregroundcolor \else
603        \setexternalfigureparameter\c!background{\v!foreground,\v!color}%
604        \letexternalfigureparameter\c!backgroundcolor\p_foregroundcolor
605    \fi
606\to \everyexternalfigurechecks
607
608%D Internal graphics are handled at the \TEX\ end:
609
610% strut=none also avoids the \noindent! otherwise we're in hmode when
611% blank happens and we get a lineskip
612
613\def\grph_include_process_tex#1%
614  {\framed
615     [\c!strut=\v!none,\c!align=\v!normal,\c!frame=\v!off,
616      \c!offset=\v!overlay,\c!width=\v!fit,\c!height=\v!fit]
617     {\blank[\v!disable]%
618      #1\endgraf
619      \removelastskip}} % disable should stay here!
620
621
622% used al lua end:
623
624\permanent\protected\def\docheckfigurebuffer  #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\getbuffer[#1]}}}
625\permanent\protected\def\docheckfiguretex     #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\input{#1}}}}
626\permanent\protected\def\docheckfigurecld     #1{\global\setbox\foundexternalfigure\vbox {\cldprocessfile{#1}}}
627\permanent\protected\def\docheckfiguremps     #1{\global\setbox\foundexternalfigure\vpack{\convertMPtoPDF{#1}11}}
628\permanent\protected\def\docheckfiguremprun #1#2{\global\setbox\foundexternalfigure\vpack{\useMPrun{#1}{#2}}}
629
630\permanent\protected\def\relocateexternalfigure
631  {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup
632     %
633     % The \vss can (!) introduce 1 sp excess visible in xform which in itself
634     % is not that important but some don't like these cosmetic side effects, for
635     % instance we can get:
636     %
637     % vss   : \vbox(845.1575+0.0)x597.23125, glue set 845.15747fil, direction TLT
638     % vskip : \vbox(845.1575+0.0)x597.23125, direction TLT
639     %
640     % or
641     %
642     % 1 0 0 1 0 0.00003 cm
643     % 1 0 0 1 0 0       cm
644     %
645     % This is a known property of using glue and can even depend on the architecture
646     % (float implementation). Anyway, let's for now use a skip. Of course this can
647     % shift the issue elsewhere, as vss is used a lot elsewhere.
648     %
649   % \vss
650     \vkern\ht\foundexternalfigure
651     %
652     \ht\foundexternalfigure\zeropoint
653     \dp\foundexternalfigure\zeropoint
654     \hpack to \wd\foundexternalfigure\bgroup
655        \box\foundexternalfigure
656        \hss
657     \egroup
658   \egroup}
659
660\permanent\protected\def\startfoundexternalfigure#1#2% ht wd
661  {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup}
662
663\permanent\protected\def\stopfoundexternalfigure
664  {\hss\egroup\egroup}
665
666\permanent\protected\def\emptyfoundexternalfigure % sort of obsolete
667  {\startfoundexternalfigure{\externalfigureparameter\c!defaultwidth}{\externalfigureparameter\c!defaultheight}%
668   \stopfoundexternalfigure}
669
670% \doifmodeelse{*\v!last}
671%   {\c_grph_include_flush\conditionaltrue}
672%   {\c_grph_include_flush\conditionalfalse}%
673
674\def\grph_include_finalize
675  {\global\setbox\foundexternalfigure\vbox
676     {\ifcase\figurestatus
677        \letexternalfigureparameter\c!frame\v!on
678      \fi
679      \ifconditional\c_grph_include_flush
680        \ifconditional\c_grph_include_level % probably background
681          \ifconditional\c_grph_include_skip
682            % nothing
683            \fakebox\foundexternalfigure
684          \orelse\ifcase\figurestatus
685            % nothing
686          \else
687            \expand\externalfigurepostprocessors
688            \box\foundexternalfigure
689          \fi
690        \else
691          \iftrialtypesetting \else \feedbackexternalfigure \fi
692          \c_grph_include_level\conditionaltrue
693          \ifconditional\c_grph_include_skip
694            \ifcase\figurestatus
695              \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
696            \else
697              \grph_include_replacement\figurelabel\figurefullname{skipped}%
698            \fi
699          \orelse\ifcase\figurestatus
700            \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
701          \else
702            \expand\externalfigurepostprocessors
703            \edef\p_reset{\externalfigureparameter\c!reset}%
704            \ifx\p_reset\v!yes
705              \wd\foundexternalfigure\figurewidth
706              \ht\foundexternalfigure\figureheight
707              \dp\foundexternalfigure\zeropoint
708              \box\foundexternalfigure
709            \else
710              \letexternalfigureparameter\c!offset\v!overlay
711              \letexternalfigureparameter\c!width \figurewidth
712              \letexternalfigureparameter\c!height\figureheight
713              \inheritedexternalfigureframed{\box\foundexternalfigure}%
714            \fi
715          \fi
716        \fi
717      \else
718        % maybe also \expand\externalfigurepostprocessors
719        \iftrialtypesetting \else \feedbackexternalfigure \fi
720      \fi}}
721
722\mutable\let\feedbackexternalfigure\relax % hook
723
724\permanent\tolerant\protected\def\getfiguredimensions[#1]#*[#S#2]%
725  {\startnointerference % we can use \nospaces\plusone
726     \c_grph_include_test_only\conditionaltrue
727     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
728   \stopnointerference}
729
730\permanent\protected\def\doifelsefigure#1%
731  {\getfiguredimensions[#1]% so data is available !
732   \ifcase\figurestatus
733     \expandafter\secondoftwoarguments
734   \else
735     \expandafter\firstoftwoarguments
736   \fi}
737
738\aliased\let\doiffigureelse\doifelsefigure
739
740% No placement, handy for preprocessing:
741
742\permanent\tolerant\protected\def\registerexternalfigure[#1]#*[#S#2]#*[#S#3]%
743  {\startnointerference
744     \c_grph_include_test_only
745     \c_grph_include_flush\conditionalfalse % == test ?
746     \externalfigure[#1][#2][#3]% or
747     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
748   \stopnointerference}
749
750% Helpers will be replaced when xforms are accessible at the lua end but then
751% we need to do the object offset there too.
752
753\permanent\protected\def\dosetfigureobject#1#2%
754  {\setobject{#1}{#2}\vpack{\box\foundexternalfigure}}
755
756\permanent\protected\def\doboxfigureobject#1#2%
757  {\global\setbox\foundexternalfigure\vpack{\getobject{#1}{#2}}} % probably one vbox too many
758
759% Figure bases
760
761\permanent\protected\def\usefigurebase[#1]%
762  {\clf_usefigurebase{#1}}
763
764\appendtoks
765   \setfigurepathlist  % the path may be used elsewhere too (as in x-res-04)
766\to \everysetupexternalfigure
767
768\appendtoks
769    \clf_setfigurelookuporder{\externalfigureparameter\c!order}%
770\to \everysetupexternalfigure
771
772\definecolor[missingfigurecolor][s=.8]
773
774\def\grph_include_replacement#1#2#3%
775  {\bgroup
776   \letexternalfigureparameter\c!width\figurewidth
777   \letexternalfigureparameter\c!height\figureheight
778   \letexternalfigureparameter\c!background\v!color
779   \setexternalfigureparameter\c!backgroundcolor{missingfigurecolor}%
780   \setexternalfigureparameter\c!align{\v!middle,\v!lohi}% we default to \v!none
781   \inheritedexternalfigureframed
782     {\ttxx \nohyphens
783%       name: \detokenize\expandafter{\normalexpanded{#1}}\crlf
784%       file: \detokenize\expandafter{\normalexpanded{#2}}\crlf
785      name: \expandeddetokenize{#1}\crlf
786      file: \expandeddetokenize{#2}\crlf
787      state: #3
788      }%
789   \egroup}
790
791% maybe setuphandler
792
793\newconditional\c_grph_include_in_collection
794
795\newdimension  \d_grph_include_collection_minwidth
796\newdimension  \d_grph_include_collection_maxwidth
797\newdimension  \d_grph_include_collection_minheight
798\newdimension  \d_grph_include_collection_maxheight
799
800\def\grph_include_analyze_collection[#1][#S#2]%
801  {\ifconditional\c_grph_include_in_collection
802      \c_grph_include_in_collection\conditionalfalse
803      \getfiguredimensions[#1][#2]%
804      \c_grph_include_in_collection\conditionaltrue
805      \scratchdimen\naturalfigurewidth
806      \ifdim\scratchdimen>\d_grph_include_collection_maxwidth  \d_grph_include_collection_maxwidth \scratchdimen \fi
807      \ifdim\scratchdimen<\d_grph_include_collection_minwidth  \d_grph_include_collection_minwidth \scratchdimen \fi
808      \scratchdimen\naturalfigureheight
809      \ifdim\scratchdimen>\d_grph_include_collection_maxheight \d_grph_include_collection_maxheight\scratchdimen \fi
810      \ifdim\scratchdimen<\d_grph_include_collection_minheight \d_grph_include_collection_minheight\scratchdimen \fi
811   \fi}
812
813\mutable\lettonothing\currentexternalfigurecollection
814
815\permanent\protected\def\startexternalfigurecollection[#1]%
816  {\begingroup
817   \cdef\currentexternalfigurecollection{#1}%
818   \c_grph_include_in_collection\conditionaltrue
819   \d_grph_include_collection_minwidth \maxdimen
820   \d_grph_include_collection_maxwidth \zeropoint
821   \d_grph_include_collection_minheight\maxdimen
822   \d_grph_include_collection_maxheight\zeropoint}
823
824\permanent\protected\def\stopexternalfigurecollection
825  {\xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!minwidth \endcsname{\the\d_grph_include_collection_minwidth }%
826   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!maxwidth \endcsname{\the\d_grph_include_collection_maxwidth }%
827   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!minheight\endcsname{\the\d_grph_include_collection_minheight}%
828   \xdefcsname\??externalfigurecollection\currentexternalfigurecollection:\c!maxheight\endcsname{\the\d_grph_include_collection_maxheight}%
829   \endgroup}
830
831\permanent\def\externalfigurecollectionparameter#1#2%
832  {\csname
833     \ifcsname\??externalfigurecollection#1:#2\endcsname
834       \??externalfigurecollection#1:#2%
835     \else
836       \s!empty
837     \fi
838   \endcsname}
839
840\permanent\def\externalfigurecollectionminwidth #1{\externalfigurecollectionparameter{#1}\c!minwidth }
841\permanent\def\externalfigurecollectionmaxwidth #1{\externalfigurecollectionparameter{#1}\c!maxwidth }
842\permanent\def\externalfigurecollectionminheight#1{\externalfigurecollectionparameter{#1}\c!minheight}
843\permanent\def\externalfigurecollectionmaxheight#1{\externalfigurecollectionparameter{#1}\c!maxheight}
844
845\aliased\let\efcparameter\externalfigurecollectionparameter % still needed ?
846\aliased\let\efcminwidth \externalfigurecollectionminwidth  % still needed ?
847\aliased\let\efcmaxwidth \externalfigurecollectionmaxwidth  % still needed ?
848\aliased\let\efcminheight\externalfigurecollectionminheight % still needed ?
849\aliased\let\efcmaxheight\externalfigurecollectionmaxheight % still needed ?
850
851% \startexternalfigurecollection[name]
852%     \useexternalfigure[cow] [cow.pdf]
853%     \useexternalfigure[mill][mill.png]
854% \stopexternalfigurecollection
855% \starttext
856% \bTABLE
857%     \bTR
858%         \bTD \externalfigure[cow] [height=\externalfigurecollectionmaxheight{name}] \eTD
859%         \bTD \externalfigure[mill][height=\externalfigurecollectionmaxheight{name}] \eTD
860%     \eTR
861% \eTABLE
862% \stoptext
863
864\permanent\protected\def\overlayfigure#1%
865  {\externalfigure[#1][\c!width=\d_overlay_width,\c!height=\d_overlay_height]}
866
867% Experimental (will become cleaner):
868
869\permanent\tolerant\protected\def\includesvgfile[#1]#*[#S#2]%
870  {\hbox\bgroup % no \dontleavehmode
871   \getdummyparameters[\c!offset=\zeropoint,#2]%
872   \clf_includesvgfile{#1}{\dummyparameter\c!offset}%
873   \egroup}
874
875\permanent\tolerant\protected\def\includesvgbuffer[#1]#*[#S#2]%
876  {\hbox\bgroup % no \dontleavehmode
877   \getdummyparameters[\c!offset=\zeropoint,#2]%
878   \clf_includesvgbuffer{#1}{\dummyparameter\c!offset}%
879   \egroup}
880
881% Bonus:
882
883\useexternalfigure
884  [\v!buffer]
885  [\jobname.buffer]
886  [\c!object=\v!no]
887
888% Another two:
889
890\defineexternalfigure
891  [\v!inline]
892  [\c!height=\lineheight]
893
894\permanent\untraced\protected\def\combinationwidth
895  {\dimexpr
896     (\textwidth-\effectiveleftskip-\effectiverightskip
897     -\numexpr(\combinationparameter\c!nx)-\plusone\relax\dimexpr\combinationparameter\c!distance\relax
898     )/(\combinationparameter\c!nx)%
899   \relax}
900
901\pushoverloadmode
902    \newuserunit \combinationwidth cx % combination width
903\popoverloadmode
904
905\definemeasure
906  [\v!combination]
907  [\combinationwidth]
908
909\defineexternalfigure
910  [\v!combination]
911  [\c!width=\combinationwidth]
912
913% \startcombination[nx=2,ny=1]
914%     {\externalfigure[dummy][combination]} {}
915%     {\externalfigure[dummy][combination]} {}
916% \stopcombination
917
918% \startcombination[nx=2,ny=1]
919%     {\externalfigure[dummy][width=\measure{combination}]} {}
920%     {\externalfigure[dummy][width=\measure{combination}]} {}
921% \stopcombination
922
923% \startcombination[nx=2,ny=2]
924%     {\externalfigure[dummy][combination]} {}
925%     {\externalfigure[dummy][combination]} {}
926%     {\externalfigure[dummy][combination]} {}
927%     {\externalfigure[dummy][combination]} {}
928% \stopcombination
929
930% \startcombination[nx=3,ny=1]
931%     {\externalfigure[dummy][combination]} {}
932%     {\externalfigure[dummy][combination]} {}
933%     {\externalfigure[dummy][combination]} {}
934% \stopcombination
935
936% \startcombination[nx=4,ny=1]
937%     {\externalfigure[dummy][combination]} {}
938%     {\externalfigure[dummy][combination]} {}
939%     {\externalfigure[dummy][combination]} {}
940%     {\externalfigure[dummy][combination]} {}
941% \stopcombination
942
943\permanent\protected\def\inlinefigure[#1]%
944  {\dontleavehmode
945   \sbox{\externalfigure[#1][\v!inline]}}
946
947%D Needs to be done global:
948
949\definelayer[epdfcontent]
950
951%D Experiment:
952%D
953%D \starttyping
954%D \registerfiguremask[mymask] {
955%D     {
956%D         {   0, 100, 0x00 },
957%D         { 101, 200, 0x7F },
958%D         { 201, 255, 0xFF },
959%D     }
960%D }
961%D
962%D \dontleavehmode \externalfigure
963%D     [proofs.png]
964%D     [background=color,
965%D      backgroundcolor=yellow,
966%D      mask=mymask,
967%D      width=5cm]
968%D \stOPtyping
969
970\protect \endinput
971
972%D Moved here because this already old code is nowhere documents (so I need to check
973%D it:
974%
975% \starttyping
976% \starttext
977%
978% \startluaparameterset [u3d:myset:controls:1]
979%     view = {
980%         name = 'default',
981%         bg = {1,1,1},
982%         mag = 100,
983%         coo = {0,0,0},
984%         c2c = {0,0,1},
985%         rot = {40,0,60},
986%         roo = 6,
987%         lights = 'CAD'
988%     },
989%     js = 'cloudq.js'
990% \stopluaparameterset
991%
992% \startluaparameterset [u3d:myset:controls:2]
993%     views = {
994%         {
995%             name = 'AnglePositioning',
996%             bg = {1,1,1},
997%             azimuth = 45,
998%             altitude = 45,
999%             roo = 50,
1000%             aac = 2.5,
1001%             lights = 'Artwork'
1002%         },
1003%         {
1004%             name = 'RotationPositioning',
1005%             bg = {1,1,1},
1006%             rot = {0,45,45},
1007%             roo = 50,
1008%             aac = 2.5,
1009%             lights = 'Artwork'
1010%         },
1011%         {
1012%             name = 'VectorPositioning',
1013%             bg = {1,0,0},
1014%             c2c = {1,1,math.sqrt(2)},
1015%             roo = 50,
1016%             aac = 2.5,
1017%             lights = 'CAD'
1018%         },
1019%         {
1020%             name = 'PositionPositioning',
1021%             bg = {1,0,0},
1022%             pos = {1+25,1+25,1+50/math.sqrt(2)},
1023%             aac = 2.5,
1024%             lights = 'CAD'
1025%         },
1026%         {
1027%             name = 'ortho',
1028%             bg = {1,1,1},
1029%             mag = 300,
1030%             lights = 'CAD',
1031%             crossection = {}
1032%         }
1033%     },
1034%     view = {
1035%         name = 'default',
1036%         bg = {1,1,1},
1037%         c2c = {-1,-1,0},
1038%         roo = 50,
1039%         aac = 2.5,
1040%         roll = 45,
1041%         lights = 'CAD',
1042%         crossection = {
1043%             normal = {-1,-1,-1},
1044%             transparent = true
1045%         },
1046%         nodes = {
1047%             {
1048%                 name = 'xlabel',
1049%                 visible = false
1050%             },
1051%             {
1052%                 name = 'ylabel',
1053%                 opacity = 0.5
1054%             },
1055%             {
1056%                 name = 'zlabel',
1057%                 rendermode = 'Wireframe'
1058%             }
1059%         }
1060%     }
1061% \stopluaparameterset
1062%
1063% \useexternalfigure
1064%   [cloudq]
1065%   [cloudq.u3d]
1066%   [width=0.7\textwidth,
1067%    height=.7\textwidth,
1068%    display=u3d:myset:display:1,
1069%    controls=u3d:myset:controls:1]
1070%
1071% \useexternalfigure
1072%   [axes]
1073%   [axes.u3d]
1074%   [width=0.7\textwidth,
1075%    height=.7\textwidth,
1076%    controls=u3d:myset:controls:1]
1077%
1078% \startluaparameterset[u3d:myset:display:2]
1079%     toolbar = true,
1080%     preview = 'cloudq.png'
1081% \stopluaparameterset
1082% \startluaparameterset[u3d:myset:display:3]
1083%     toolbar = true,
1084%     tree = false,
1085%     preview = 'axes.png'
1086% \stopluaparameterset
1087% \startluaparameterset[u3d:myset:display:4]
1088%     toolbar = true,
1089%     tree = false,
1090%     view = {
1091%         name = 'view',
1092%         bg = {0.1,0.1,0.1},
1093%         c2c = {-1,-1,0},
1094%         roo = 50,
1095%         aac = 2.5,
1096%         roll = 45,
1097%         lights = 'Red'
1098%     }
1099% \stopluaparameterset
1100% \startluaparameterset[u3d:myset:display:5]
1101%     toolbar = true,
1102%     tree = false,
1103%     view = 'ortho'
1104% \stopluaparameterset
1105%
1106% \placefigure[here]{none}{\externalfigure[cloudq][frame=on,display=u3d:myset:display:2]}
1107% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:3]}
1108% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:4]}
1109% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:5,width=0.5\textwidth,height=.5\textwidth]}
1110%
1111% \stoptext
1112