%D \module %D [ file=core-obj, %D version=1998.01.15, %D title=\CONTEXT\ Core Macros, %D subtitle=Object Handling, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{Context Core Macros / Object Handling} \unprotect \startmessages dutch library: references 30: onbekend object -- 31: dubbel object -- \stopmessages \startmessages english library: references 30: unknown object -- 31: duplicate object -- \stopmessages \startmessages german library: references 30: unbekanntes Object -- 31: doppeltes Object -- \stopmessages \startmessages czech library: references 30: neznamy objekt -- 31: duplicitni object -- \stopmessages \startmessages italian library: references 30: oggetto sconosciuto -- 31: oggetto duplicato -- \stopmessages \startmessages norwegian library: references 30: ukjent objekt -- 31: duplikat objekt -- \stopmessages \startmessages romanian library: references 30: obiect necunoscut -- 31: obiect duplicat -- \stopmessages %D \macros %D {setobject,getobject,ifinobject} %D %D Boxes can be considered reuable objects. Unfortunaltely once %D passed to the \DVI\ file, such objects cannot be reused. In %D \PDF\ however, reusing is possible and sometimes even a %D necessity. Therefore, \CONTEXT\ supports reusable objects. %D %D During the \TEX\ processing run, boxes can serve the purpose %D of objects, and the \DVI\ driver module implements objects %D using packed boxes. %D %D The \PDF\ and \PDFTEX\ driver modules implement objects %D using \PDF\ forms. There is no (real) restriction on the %D number of objects there. %D %D The first application of objects in \CONTEXT\ concerned %D \METAPOST\ graphics and fill||in form fields. The first %D application can save lots of bytes, while the latter use is %D more a necessity than byte saving. %D %D \starttypen %D \setobject{class}{name}\somebox{} %D \getobject{class}{name} %D \stoptypen %D %D Here \type{\somebox} can be whatever box specification suits %D \TEX. We save the dimensions of an object, although some %D drivers will do so themselves. This means that when for %D instance using \PDFTEX\ we could save a hash entry plus some %D 20+ memory locations per object by delegating this %D housekeeping to the driver. The current approach permits %D us to keep the box characteristic too. \newif\ifinobject \def\presetobject#1#2% {\doifundefined{\r!object#1::#2} {\setxvalue{\r!object#1::#2}{NOT YET FLUSHED}}} \def\dosetobject#1#2#3% evt \initializepaper naar \everyshipout {\initializepaper \ifundefined{\r!object#2::#3}% \expandafter\dodosetobject \else \expandafter\gobblefivearguments \fi {#1}{#2}{#3}} %D Somehow there is a rounding error problem in either \PDFTEX\ %D or in viewers, or maybe it is conforming the specs. The next %D variable compensate for it by removing the rather tight %D clip. \def\objectoffset{1cm} % \def\dodosetobject#1#2#3% % {\bgroup % \inobjecttrue % \dowithnextbox % {\bgroup % \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox % \setxvalue{\r!object#2::#3}% % {\noexpand\dohandleobject{#2}{#3} % {\ifhbox\nextbox\hbox\else\vbox\fi} % %{\the\wd\nextbox}{\the\ht\nextbox}{\the\dp\nextbox}}% % {\number\wd\nextbox}{\number\ht\nextbox}{\number\dp\nextbox}}% % \expanded % fix the dimensions since \dostartobject may use \nextbox % {\dostartobject % {#2}{#3} % {\number\wd\nextbox}{\number\ht\nextbox}{\number\dp\nextbox}}% % \ifcase#1\relax\else\ifdim\objectoffset>\!!zeropoint\relax % \scratchdimen=\objectoffset % \edef\next% % {\wd\nextbox\the\wd\nextbox % \ht\nextbox\the\ht\nextbox % \dp\nextbox\the\dp\nextbox}% % \setbox\nextbox=\vbox spread 2\scratchdimen % {\forgetall % \vss % \hbox spread 2\scratchdimen{\hss\box\nextbox\hss}% % \vss}% % \setbox\nextbox=\hbox % {\hskip-\scratchdimen\lower\scratchdimen\box\nextbox}% % \next % \fi\fi % \box\nextbox % \dostopobject % \egroup % \egroup}} \def\dodosetobject#1#2#3% {\bgroup \inobjecttrue \dowithnextbox {\bgroup \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox \setxvalue{\r!object#2::#3}% {\noexpand\dohandleobject{#2}{#3} {\ifhbox\nextbox\hbox\else\vbox\fi} %{\the\wd\nextbox}{\the\ht\nextbox}{\the\dp\nextbox}}% {\number\wd\nextbox}{\number\ht\nextbox}{\number\dp\nextbox}}% \expanded % fix the dimensions since \dostartobject may use \nextbox {\dostartobject {#2}{#3} {\number\wd\nextbox}{\number\ht\nextbox}{\number\dp\nextbox}}% \ifcase#1\relax \box\nextbox \else\ifdim\objectoffset>\!!zeropoint \scratchdimen=\objectoffset \edef\width {\the\wd\nextbox}% \edef\height{\the\ht\nextbox}% \edef\depth {\the\dp\nextbox}% \setbox\nextbox= \vbox spread 2\scratchdimen {\forgetall \vss \hbox spread 2\scratchdimen{\hss\box\nextbox\hss}% \vss}% \setbox\nextbox=\hbox {\hskip-\scratchdimen\lower\scratchdimen\box\nextbox}% \wd\nextbox=\width \ht\nextbox=\height \dp\nextbox=\depth \box\nextbox \else \box\nextbox \fi\fi \dostopobject \egroup \egroup}} \def\dogetobject#1#2#3#4#5#6% {\initializepaper \bgroup \forgetall \dontshowcomposition \setbox0=\vbox {\doinsertobject{#1}{#2}}% \setbox0=#3% {\vbox to #5\s!sp {\ifdim\ht0>#5\s!sp % or \ifdim\wd0>#4\s!sp \vss\hbox to #4\s!sp{\hss\box0\hss}\vss \else \vss\box0 \fi}}% \wd0=#4\s!sp \ht0=#5\s!sp \dp0=#6\s!sp \box0 \egroup} \def\getobject#1#2% {\let\dohandleobject\dogetobject \getvalue{\r!object#1::#2}} %D If needed one can ask for the dimensions of an object with: %D %D \starttypen %D \getobjectdimensions{class}{name} %D \stoptypen %D %D The results are reported in \type {\objectwidth}, \type %D {\objectheight} and \type {\objectdepth}. \def\dogetobjectdimensions#1#2#3#4#5#6% {\def\objectwidth {#4\s!sp}% \def\objectheight{#5\s!sp}% \def\objectdepth {#6\s!sp}} \def\getobjectdimensions#1#2% {\let\dohandleobject\dogetobjectdimensions \let\objectwidth \!!zeropoint \let\objectheight\!!zeropoint \let\objectdepth \!!zeropoint \getvalue{\r!object#1::#2}} %D Apart from this kind of objects, that have typeset content, %D we can have low level driver specific objects. Both types %D can have references to internal representations, hidden for %D the user. We keep track of such references by means of a %D dedicated cross reference mechanism. Normally, objects are %D defined before they are used, but forward referencing %D sometimes occurs. %D %D \starttypen %D \dosetobjectreference {class} {identifier} {reference value} %D \dogetobjectreference {class} {identifier} \csname %D \stoptypen %D %D These commands are to be called by the \type{\startobject}, %D \type{\stopobject} and \type{\insertobject} specials. \newif\ifobjectreferencing \objectreferencingtrue \def\checkobjectreferences% {\bgroup \setbox0=\hbox {\doutilities{objectreferences}{\jobname}{}{}{}}% \global\let\checkobjectreferences=\relax \egroup} \def\setobjectreferences% {\def\objectreference##1##2##3% {\doifundefinedelse{\r!driver##1::##2} {\setxvalue{\r!driver##1::##2}{##3}} {\showmessage{\m!references}{31}{[##1 ##2=>##3]}}}} \def\resetobjectreferences% {\let\objectreference=\gobblethreearguments} \resetobjectreferences \def\dosetobjectreference#1#2#3% {\checkobjectreferences \ifobjectreferencing \bgroup \edef\dowritereference% {\writeutilitycommand{\objectreference{#1}{#2}{#3}}}% \dowritereference \egroup \else \global\objectreferencingtrue \fi \setxvalue{\r!driver#1::#2}{#3}} \def\defaultobjectreference#1#2{0} \def\dogetobjectreference#1#2#3% {\checkobjectreferences \doifdefinedelse{\r!driver#1::#2} {\@EA\xdef\@EA#3\@EA{\csname\r!driver#1::#2\endcsname}} {\showmessage{\m!references}{30}{[#1 #2=>\defaultobjectreference{#1}{#2}]}% \xdef#3{\defaultobjectreference{#1}{#2}}}} \def\setobject {\global\objectreferencingfalse\dosetobject1} \def\settightobject{\global\objectreferencingfalse\dosetobject0} %D \macros %D {doifobjectfoundelse,doifobjectreferencefoundelse} %D %D To prevent redundant definition of objects, one can use %D the next tests: %D %D \starttypen %D \doifobjectfoundelse{class}{object}{do then}{do else} %D \doifobjectreferencefoundelse{class}{object}{do then}{do else} %D \stoptypen \def\doifobjectfoundelse#1#2#3#4% {\doifundefinedelse{\r!object#1::#2}{#4}{#3}} \def\doifobjectreferencefoundelse#1#2#3#4% {\checkobjectreferences \doifundefinedelse{\r!driver#1::#2}{#4}{#3}} %D \macros %D {doifobjectssupportedelse} %D %D Starting with reuse of graphics, we will implement object %D reuse when possible. To enable mechanisms to determine %D what method to use, we provide: %D %D \starttypen %D \doifobjectssupportedelse{true action}{false action} %D \stoptypen %D %D As we can see, currently objects depend on the special %D driver. \newif\ifobjectssupported \objectssupportedtrue \def\doifobjectssupportedelse#1#2% {\ifobjectssupported \doifspecialavailableelse\doinsertobject{#1}{#2}% \else #2% \fi} %D There is a conceptual problem here. Objects are not possible %D in \DVI, unless faked like in \type {spec-dvi}. This means %D that we must be careful in loading special drivers that do %D support objects while we still want to be able to use the %D \DVI\ output. \protect \endinput