[NTG-context] maximum of \externalfigure in MP
andrea valle
valle at di.unito.it
Tue Nov 8 11:31:51 CET 2005
(Taco, thanks for all the infos. Now, just trying to understand).
Why the bug manifest itself in this particular tex file? I mean: I have
made other pieces, both with far less either with far more included
pdfs and everything was ok.
What's special in the bug-raiser tex we discussed about?
Thanks
-a-
On 7 Nov 2005, at 12:22, Taco Hoekwater wrote:
> andrea valle wrote:
>> It's the same file but I commented out a part of the section
>> dedicated to importing and drawing little notes attached to
>> arrowlines between music fragments.
>> Everything not commented is now displayed: on my machine it seems to
>> be deterministic.
>
> Ok, got it. There is a bug in mp-spec.mp (inside metafun). Because
> of a wrapping number, it fails to recognize the fact that there are
> embedded specials at all. Attached is an updated version of
> mp-spec.mp.
>
> The corrected definition of add_special_signal is:
>
> vardef add_special_signal = % write the version number
> if (length _global_specials_<>0) or (length _local_specials_ <>0) :
> special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ )
> ;
> fi ;
> enddef ;
>
> It now tests for "not equal to zero" instead of "larger than zero":
> because of all the included files, the string _local_specials_ becomes
> longer than the maximum number 'length' can return, so it returns
> -32768 instead, and that is of course less than zero.
>
>
> Don't forget that you have to re-create the metafun format as well!
>
> Cheers, Taco
> %D \module
> %D [ file=mp-spec.mp,
> %D version=1999.6.26,
> %D title=\CONTEXT\ \METAPOST\ graphics,
> %D subtitle=special extensions,
> %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 licen-en.pdf for
> %C details.
>
> % Spot colors are not handled by mptopdf !
>
> % (r,g,b) => cmyk : r=123 g= 1 b=hash
> % => spot : r=123 g= 2 b=hash
> % => transparent rgb : r=123 g= 3 b=hash
> % => transparent cmyk : r=123 g= 4 b=hash
> % => transparent spot : r=123 g= 5 b=hash
> % => rest : r=123 g=n>10 b=whatever
>
> %D This module is rather preliminary and subjected to
> %D changes. Here we closely cooperates with the \METAPOST\
> %D to \PDF\ converter module built in \CONTEXT\ and provides
> %D for instance shading. More information can be found in
> %D type {supp-mpe.tex}.
>
> if unknown context_tool : input mp-tool ; fi ;
> if known context_spec : endinput ; fi ;
>
> boolean context_spec ; context_spec := true ;
>
> numeric _special_counter_ ; _special_counter_ := 0 ;
> numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved
> numeric _special_signal_ ; _special_signal_ := 123 ;
>
> %D When set to \type {true}, shading will be supported. Some
> %D day I will also write an additional directive.
>
> boolean _inline_specials_ ; _inline_specials_ := false ;
>
> %D Because we want to output only those specials that are
> %D actually used in a figure, we need a bit complicated
> %D bookkeeping and collection of specials. At the cost of some
> %D obscurity, we now have rather efficient resources.
>
> string _global_specials_ ; _global_specials_ := "" ;
> string _local_specials_ ; _local_specials_ := "" ;
>
> vardef add_special_signal = % write the version number
> if (length _global_specials_<>0) or (length _local_specials_ <>0) :
> special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ;
> fi ;
> enddef ;
>
> vardef add_extra_specials =
> scantokens _global_specials_ ;
> scantokens _local_specials_ ;
> enddef ;
>
> vardef reset_extra_specials =
> % only local ones
> _local_specials_ := "" ;
> enddef ;
>
> boolean insidefigure ; insidefigure := false ;
>
> % todo: alleen als special gebruikt flush
>
> extra_beginfig :=
> " insidefigure := true ; " &
> " reset_extra_specials ; " &
> extra_beginfig ;
>
> extra_endfig :=
> " add_special_signal ; " &
> extra_endfig &
> " add_extra_specials ; " &
> " reset_extra_specials ; " &
> " insidefigure := false ; " ;
>
> def set_extra_special (expr s) =
> if insidefigure :
> _local_specials_ := _local_specials_ & s ;
> else :
> _global_specials_ := _global_specials_ & s ;
> fi
> enddef ;
>
> def flush_special (expr typ, siz, dat) =
> _special_counter_ := _special_counter_ + 1 ;
> if _inline_specials_ :
> set_extra_special
> ( "special "
> & "(" & ditto
> & dat & " "
> & decimal _special_counter_ & " "
> & decimal typ & " "
> & decimal siz
> & " special"
> & ditto & ");" ) ;
> else :
> set_extra_special
> ( "special "
> & "(" & ditto
> & "%%MetaPostSpecial: "
> & decimal siz & " "
> & dat & " "
> & decimal _special_counter_ & " "
> & decimal typ
> & ditto & ");" ) ;
> fi ;
> enddef ;
>
> %D The next hack is needed in case you use a version of
> %D \METAPOST\ that does not provide you the means to configure
> %D the buffer size. Patrick Gundlach suggested to use arrays
> %D in this case.
>
> boolean bufferhack ; bufferhack := false ; % true ;
>
> if bufferhack :
>
> string _global_specials_[] ; numeric _nof_global_specials_ ;
> string _local_specials_[] ; numeric _nof_local_specials_ ;
>
> _nof_global_specials_ := _nof_local_specials_ := 0 ;
>
> vardef add_special_signal = % write the version number
> if (_nof_global_specials_>0) or (_nof_local_specials_>0) :
> special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ )
> ;
> fi ;
> enddef ;
>
> vardef add_extra_specials =
> for i=1 upto _nof_global_specials_ :
> scantokens _global_specials_[i] ;
> endfor;
> for i=1 upto _nof_local_specials_ :
> scantokens _local_specials_[i] ;
> endfor;
> enddef ;
>
> vardef reset_extra_specials =
> string _local_specials_[] ; _nof_local_specials_ := 0 ;
> enddef ;
>
> def set_extra_special (expr s) =
> if insidefigure :
> _local_specials_[incr(_nof_local_specials_)] := s ;
> else :
> _global_specials_[incr(_nof_global_specials_)] := s ;
> fi
> enddef ;
>
> fi ;
>
> %D So far for this hack.
>
> %D Shade allocation.
>
> newinternal shadefactor ; shadefactor := 1 ;
>
> pair shadeoffset ; shadeoffset := origin ;
>
> vardef define_linear_shade (expr a, b, ca, cb) =
> flush_special(30, 15, "0 1 " & decimal shadefactor & " " &
> dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " &
> dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ;
> _special_counter_
> enddef ;
>
> vardef define_circular_shade (expr a, b, ra, rb, ca, cb) =
> flush_special(31, 17, "0 1 " & decimal shadefactor & " " &
> dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " &
> decimal ra & " " &
> dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " &
> decimal rb ) ;
> _special_counter_
> enddef ;
>
> %D A few predefined shading macros.
>
> boolean trace_shades ; trace_shades := false ;
>
> % if (n=1) : a := llcorner p ; b := urcorner p ;
> % elseif (n=2) : a := llcorner p ; b := ulcorner p ;
> % elseif (n=3) : a := lrcorner p ; b := ulcorner p ;
> % else : a := llcorner p ; b := lrcorner p ;
> % fi ;
>
> def set_linear_vector (suffix a,b)(expr p,n) =
> if (n=1) : a := llcorner p ;
> b := urcorner p ;
> elseif (n=2) : a := lrcorner p ;
> b := ulcorner p ;
> elseif (n=3) : a := urcorner p ;
> b := llcorner p ;
> elseif (n=4) : a := ulcorner p ;
> b := lrcorner p ;
> elseif (n=5) : a := .5[ulcorner p,llcorner p] ;
> b := .5[urcorner p,lrcorner p] ;
> elseif (n=6) : a := .5[llcorner p,lrcorner p] ;
> b := .5[ulcorner p,urcorner p] ;
> elseif (n=7) : a := .5[lrcorner p,urcorner p] ;
> b := .5[llcorner p,ulcorner p] ;
> elseif (n=8) : a := .5[urcorner p,ulcorner p] ;
> b := .5[lrcorner p,llcorner p] ;
> else : a := .5[ulcorner p,llcorner p] ;
> b := .5[urcorner p,lrcorner p] ;
> fi ;
> enddef ;
>
> def linear_shade (expr p, n, ca, cb) =
> begingroup ;
> save a, b, sh ; pair a, b ;
> set_linear_vector(a,b)(p,n) ;
> fill p withshade define_linear_shade (a,b,ca,cb) ;
> if trace_shades :
> drawarrow a -- b withpen pencircle scaled 1pt ;
> fi ;
> endgroup ;
> enddef ;
>
> vardef predefined_linear_shade (expr p, n, ca, cb) =
> save a, b, sh ; pair a, b ;
> set_linear_vector(a,b)(p,n) ;
> set_shade_vector(a,b)(p,n) ;
> define_linear_shade (a,b,ca,cb)
> enddef ;
>
> def set_circular_vector (suffix ab, r)(expr p,n) =
> if (n=1) : ab := llcorner p ;
> elseif (n=2) : ab := lrcorner p ;
> elseif (n=3) : ab := urcorner p ;
> elseif (n=4) : ab := ulcorner p ;
> else : ab := center p ; r := .5r ;
> fi ;
> enddef ;
>
> def circular_shade (expr p, n, ca, cb) =
> begingroup ;
> save ab, r ; pair ab ; numeric r ;
> r := (xpart lrcorner p - xpart llcorner p) ++
> (ypart urcorner p - ypart lrcorner p) ;
> set_circular_vector(ab,r)(p,n) ;
> fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ;
> if trace_shades :
> drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt ;
> fi ;
> endgroup ;
> enddef ;
>
> vardef predefined_circular_shade (expr p, n, ca, cb) =
> save ab, r ; pair ab ; numeric r ;
> r := (xpart lrcorner p - xpart llcorner p) ++
> (ypart urcorner p - ypart lrcorner p) ;
> set_circular_vector(ab,r)(p,n) ;
> define_circular_shade(ab,ab,0,r,ca,cb)
> enddef ;
>
> %D Since a \type {fill p withshade s} syntax looks better
> %D than some macro, we implement a new primary.
>
> primarydef p withshade sc = % == p withcolor shadecolor(sh)
> hide (_color_counter_ := _color_counter_ + 1)
> p withcolor (_special_signal_/1000,_color_counter_/1000,sc/1000)
> enddef ;
>
> vardef shadecolor(expr sc) =
> hide (_color_counter_ := _color_counter_ + 1)
> (_special_signal_/1000,_color_counter_/1000,sc/1000)
> enddef ;
>
> %D Figure inclusion.
>
> %numeric cef ; cef := 0 ;
>
> def externalfigure primary filename =
> doexternalfigure (filename)
> enddef ;
>
> def doexternalfigure (expr filename) text transformation =
> begingroup ; save p, t ; picture p ; transform t ;
> p := nullpicture ; t := identity transformation ;
> flush_special(10, 9,
> dddecimal (xxpart t, yxpart t, xypart t) & " " &
> dddecimal (yypart t, xpart t, ypart t) & " " & filename) ;
> addto p contour unitsquare scaled 0 ;
> setbounds p to unitsquare transformed t ;
> _color_counter_ := _color_counter_ + 1 ;
> draw p withcolor
> (_special_signal_/1000,_color_counter_/1000,_special_counter_/1000) ;
> %draw p withcolor
> (_special_signal_/1000,cef/1000,_special_counter_/1000) ;
> endgroup ;
> enddef ;
>
> %D Experimental:
>
> %numeric currenthyperlink ; currenthyperlink := 0 ;
>
> def hyperlink primary t = dohyperlink(t) enddef ;
> def hyperpath primary t = dohyperpath(t) enddef ;
>
> def dohyperlink (expr destination) text transformation =
> begingroup ; save somepath ; path somepath ;
> somepath := fullsquare transformation ;
> dohyperpath(destination) somepath ;
> endgroup ;
> enddef ;
>
> def dohyperpath (expr destination) expr somepath =
> begingroup ;
> flush_special(20, 7,
> ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " &
> ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " "
> & destination) ;
> % currenthyperlink := currenthyperlink + 1 ;
> _color_counter_ := _color_counter_ + 1 ;
> fill boundingbox unitsquare scaled 0 withcolor
>
> (_special_signal_/1000,_color_counter_/1000,_special_counter_/1000) ;
> %
> (_special_signal_/1000,currenthyperlink/1000,_special_counter_/1000) ;
> endgroup ;
> enddef ;
>
> % \setupinteraction[state=start]
> % \setupcolors [state=start]
> %
> % Hello There! \blank
> %
> % \startMPcode
> % pickup pencircle scaled 5 ;
> % draw fullcircle scaled 4cm withcolor red ;
> % hyperpath "nextpage" boundingbox currentpicture ;
> % draw origin withcolor blue ;
> % \stopMPcode
> %
> % \blank Does it work or not?
> %
> % \startMPcode
> % pickup pencircle scaled 5 ;
> % draw fullcircle scaled 4cm withcolor red ;
> % hyperpath "nextpage" fullcircle scaled 4cm ;
> % draw origin withcolor blue ;
> % draw fullcircle scaled 4cm shifted (1cm,1cm);
> % \stopMPcode
> %
> % \blank Does it work or not? \page Hello There! \blank
> %
> % \startMPcode
> % pickup pencircle scaled 5 ;
> % draw fullcircle scaled 2cm shifted (-2cm,-1cm) ;
> % draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ;
> % draw fullcircle scaled 1cm ;
> % hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ;
> % draw origin withcolor blue ;
> % \stopMPcode
> %
> % \blank Does it work or not?
>
> _cmyk_counter_ := 0 ;
>
> extra_endfig := " resetcmykcolors ; " & extra_endfig ;
>
> def resetcmykcolors =
> numeric cmykcolorhash[][][][] ;
> enddef ;
>
> resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true
>
> string cmykcolorpattern[] ; % needed for transparancies
>
> vardef cmyk(expr c,m,y,k) =
> if cmykcolors :
> save ok ; boolean ok ;
> if unknown cmykcolorhash[c][m][y][k] :
> ok := false ; % not yet defined
> elseif cmykcolorhash[c][m][y][k] = -1 :
> ok := false ; % locally defined and undefined
> else :
> ok := true ; % globally already defined
> fi ;
> if not ok :
> save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ;
> _cmyk_counter_ := _cmyk_counter_ + 1 ;
> cmykcolorpattern[_cmyk_counter_/1000] := s ;
> cmykcolorhash[c][m][y][k] := _cmyk_counter_ ;
> flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ;
> _local_specials_ := _local_specials_ &
> " cmykcolorhash[" & decimal c & "][" & decimal m &
> "][" & decimal y & "][" & decimal k & "] := -1 ; " ;
> fi ;
> (_special_signal_/1000,1/1000,cmykcolorhash[c][m][y][k]/1000)
> else :
> (1-c-k,1-m-k,1-y-k)
> fi
> enddef ;
>
> % newcolor truecyan, truemagenta, trueyellow ;
> %
> % truecyan = cmyk (1,0,0,0) ;
> % truemagenta = cmyk (0,1,0,0) ;
> % trueyellow = cmyk (0,0,1,0) ;
>
> %D Spot colors
>
> _spotcolor_counter_ := 0 ;
> _spotcolor_number_ := 0 ;
>
> extra_endfig := " resetspotcolors ; " & extra_endfig ;
>
> def resetspotcolors =
> numeric spotcolorhash[][] ;
> enddef ;
>
> resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true
>
> string spotcolorpattern[] ; % needed for transparancies
>
> % vardef spotcolor(expr p, s) =
> % if spotcolors :
> % save ok, pc_tag ; boolean ok ; string pc_tag ;
> % pc_tag := "_pct_"&p ;
> % if not unstringed(pc_tag) :
> % _spotcolor_number_ := _spotcolor_number_ + 1 ;
> % setunstringed(pc_tag,_spotcolor_number_) ;
> % fi ;
> % pp := getunstringed(pc_tag) ;
> % if unknown spotcolorhash[pp][s] :
> % ok := false ; % not yet defined
> % elseif spotcolorhash[pp][s] = -1 :
> % ok := false ; % locally defined and undefined
> % else :
> % ok := true ; % globally already defined
> % fi ;
> % if not ok :
> % save ss ; string ss ; ss := p & " " & decimal s ;
> % _spotcolor_counter_ := _spotcolor_counter_ + 1 ;
> % spotcolorpattern[_spotcolor_counter_/1000] := ss ;
> % spotcolorhash[pp][s] := _spotcolor_counter_ ;
> % flush_special(2, 5, decimal _spotcolor_counter_ & " " & ss) ;
> % _local_specials_ := _local_specials_ &
> % "spotcolorhash["&decimal pp&"]["&decimal s&"]:=-1;" ;
> % fi ;
> % (_special_signal_/1000,2/1000,spotcolorhash[pp][s]/1000)
> % else :
> % (1-s,1-s,1-s)
> % fi
> % enddef ;
>
> % vardef spotcolor(expr p, s) =
> % if spotcolors :
> % save ok, pc_tag ; boolean ok ; string pc_tag ;
> % pc_tag := "_pct_"&p ;
> % if not unstringed(pc_tag) :
> % _spotcolor_number_ := _spotcolor_number_ + 1 ;
> % setunstringed(pc_tag,_spotcolor_number_) ;
> % fi ;
> % pp := getunstringed(pc_tag) ;
> % if unknown spotcolorhash[pp][s] :
> % ok := false ; % not yet defined
> % elseif spotcolorhash[pp][s] = -1 :
> % ok := false ; % locally defined and undefined
> % else :
> % ok := true ; % globally already defined
> % fi ;
> % if not ok :
> % save ss ; string ss ; ss := p & " " & decimal s ;
> % _spotcolor_counter_ := _spotcolor_counter_ + 1 ;
> % spotcolorpattern[_spotcolor_counter_/1000] := ss ;
> % spotcolorhash[pp][s] := _spotcolor_counter_ ;
> % flush_special(2, 5, decimal _spotcolor_counter_ & " " & ss) ;
> % _local_specials_ := _local_specials_ &
> % "spotcolorhash["&decimal pp&"]["&decimal s&"]:=-1;" ;
> % fi ;
> % (_special_signal_/1000,2/1000,spotcolorhash[pp][s]/1000)
> % else :
> % (1-s,1-s,1-s)
> % fi
> % enddef ;
>
> vardef spotcolor(expr p, s) =
> multitonecolor(p, 1, "", decimal s)
> enddef ;
>
> vardef multitonecolor(expr n, f, d, p) = % name fractions names factors
> if spotcolors :
> save ok, pc_tag ; boolean ok ; string pc_tag ;
> pc_tag := "_pct_" & n ;
> if not unstringed(pc_tag) :
> _spotcolor_number_ := _spotcolor_number_ + 1 ;
> setunstringed(pc_tag,_spotcolor_number_) ;
> fi ;
> pp := getunstringed(pc_tag) ;
> pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi &
> "_" & p ; % check for d empty
> if not unstringed(pc_tag) :
> _spotcolor_number_ := _spotcolor_number_ + 1 ;
> setunstringed(pc_tag,_spotcolor_number_) ;
> fi ;
> ps := getunstringed(pc_tag) ;
> if unknown spotcolorhash[pp][ps] :
> ok := false ; % not yet defined
> elseif spotcolorhash[pp][ps] = -1 :
> ok := false ; % locally defined and undefined
> else :
> ok := true ; % globally already defined
> fi ;
> if not ok :
> save ss ; string ss ; ss := n & " " & decimal f & " " & if d =
> "" : n else : d fi & " " & p ;
> _spotcolor_counter_ := _spotcolor_counter_ + 1 ;
> spotcolorpattern[_spotcolor_counter_/1000] := ss ;
> spotcolorhash[pp][ps] := _spotcolor_counter_ ;
> flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ;
> _local_specials_ := _local_specials_ &
> "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ;
> fi ;
> (_special_signal_/1000,2/1000,spotcolorhash[pp][ps]/1000)
> else :
> .5white
> fi
> enddef ;
>
> %D Transparency
>
> normaltransparent := 1 ; multiplytransparent := 2 ;
> screentransparent := 3 ; overlaytransparent := 4 ;
> softlighttransparent := 5 ; hardlighttransparent := 6 ;
> colordodgetransparent := 7 ; colorburntransparent := 8 ;
> darkentransparent := 9 ; lightentransparent := 10 ;
> differencetransparent := 11 ; exclusiontransparent := 12 ;
>
> % nottransparent := 0 ;
> % compatibletransparent := 99 ;
>
> % fill fullcircle scaled 10cm withcolor transparant(.8,3,color) ;
>
> % vardef transparent(expr n, t, c) =
> % save s, ss, nn, cc, is_cmyk, is_spot, ok ;
> % string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot,
> ok ;
> % % transparancy type
> % if string n :
> % if expandafter known scantokens(n&"transparent") :
> % nn := scantokens(n&"transparent") ;
> % else :
> % nn := 0 ;
> % fi
> % else : % nn := min(n,13)
> % nn := if n<13 : n else : nn := 0 fi ;
> % fi ;
> % % we need to expand the color (can be cmyk(..) or predefined)
> % cc := c ; % expand color
> % % check for cmyk special
> % is_cmyk := (redpart cc = _special_signal_/1000)
> % and (greenpart cc = 1/1000) ;
> % is_spot := (redpart cc = _special_signal_/1000)
> % and (greenpart cc = 2/1000) ;
> % % build special string, fetch cmyk components
> % s := decimal nn & " " & decimal t & " " &
> % if is_cmyk : cmykcolorpattern[bluepart cc]
> % elseif is_spot : spotcolorpattern[bluepart cc]
> % else : dddecimal cc fi ;
> % % check if this one is already used
> % ss := "tr_" & s ;
> % % efficiency hack
> % if expandafter unknown scantokens(ss) :
> % ok := false ; % not yet defined
> % elseif scantokens(ss) < 0 :
> % ok := false ; % locally defined and undefined
> % else :
> % ok := true ; % globally already defined
> % fi ;
> % if not ok :
> % if is_spot :
> % flush_special(5, 6, s) ;
> % elseif is_cmyk :
> % flush_special(4, 8, s) ;
> % else :
> % flush_special(3, 7, s) ;
> % fi ;
> % scantokens(ss) := _special_counter_ ;
> % _local_specials_ := _local_specials_ &
> % "scantokens(" & ditto & ss & ditto & ") := -1 ;" ;
> % fi ;
> % % go ahead
> % if is_spot :
> % (_special_signal_/1000,5/1000,scantokens(ss)/1000)
> % elseif is_cmyk :
> % (_special_signal_/1000,4/1000,scantokens(ss)/1000)
> % else :
> % (_special_signal_/1000,3/1000,scantokens(ss)/1000)
> % fi
> % enddef ;
>
> vardef transparent(expr n, t, c) =
> save s, ss, nn, cc, is_cmyk, is_spot, ok ;
> string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ;
> % transparancy type
> if string n :
> if expandafter known scantokens(n&"transparent") :
> nn := scantokens(n&"transparent") ;
> else :
> nn := 0 ;
> fi
> else : % nn := min(n,13)
> nn := if n<13 : n else : nn := 0 fi ;
> fi ;
> % we need to expand the color (can be cmyk(..) or predefined)
> cc := c ; % expand color
> % check for cmyk special
> is_cmyk := (redpart cc = _special_signal_/1000)
> and (greenpart cc = 1/1000) ;
> is_spot := (redpart cc = _special_signal_/1000)
> and (greenpart cc = 2/1000) ;
> % build special string, fetch cmyk components
> s := decimal nn & " " & decimal t & " " &
> if is_cmyk : cmykcolorpattern[bluepart cc]
> elseif is_spot : spotcolorpattern[bluepart cc]
> else : dddecimal cc fi ;
> % check if this one is already used
> ss := cleanstring("tr_" & s) ;
> % we now have rather unique names, i.e. a color spec of .234 becomes
> % tr..._234.... and metapost gives a number overflow (parse error)
> % for variables like tr_12345678 which may result from many decimal
> % positions (imo mp bug)
> ss := asciistring(ss) ;
> % efficiency hack
> if expandafter unknown scantokens(ss) :
> ok := false ; % not yet defined
> elseif scantokens(ss) < 0 :
> ok := false ; % locally defined and undefined
> else :
> ok := true ; % globally already defined
> fi ;
> if not ok :
> if is_spot :
> flush_special(5, 8, s) ;
> elseif is_cmyk :
> flush_special(4, 8, s) ;
> else :
> flush_special(3, 7, s) ;
> fi ;
> scantokens(ss) := _special_counter_ ;
> _local_specials_ := _local_specials_ &
> "scantokens(" & ditto & ss & ditto & ") := -1 ;" ;
> fi ;
> % go ahead
> if is_spot :
> (_special_signal_/1000,5/1000,scantokens(ss)/1000)
> elseif is_cmyk :
> (_special_signal_/1000,4/1000,scantokens(ss)/1000)
> else :
> (_special_signal_/1000,3/1000,scantokens(ss)/1000)
> fi
> enddef ;
>
> %D This function returns true of false, dependent on transparency.
>
> vardef is_transparent(text t) =
> begingroup ; save transparent ; save _c_, _b_ ;
> vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ;
> boolean _b_ ; _b_ := false ;
> color _c_ ; _c_ := t ; _b_
> endgroup
> enddef ;
>
> %D This function returns the not transparent color.
>
> vardef not_transparent(text t) =
> begingroup ; save transparent ;
> vardef transparent(expr nn, tt, cc) = cc enddef ;
> t endgroup
> enddef ;
>
> %D Basic position tracking:
>
> def register (expr label, width, height, offset) =
> begingroup ;
> flush_special(50, 7,
> ddecimal offset & " " &
> decimal width & " " &
> decimal height & " " & label) ;
> endgroup ;
> enddef ;
>
> %D We cannot scale cmyk colors directly since this spoils
> %D the trigger signal (such colors are no real colors).
>
> vardef scaledcmyk(expr c,m,y,k,sf) =
> cmyk(sf*c,sf*m,sf*y,sf*k)
> enddef ;
>
> vardef scaledcmykasrgb(expr c,m,y,k,sf) =
> (sf*(1-c-k,1-m-k,1-y-k))
> enddef ;
>
> vardef scaledrgbascmyk(expr c,m,y,k,sf) =
> scaledcmyk(1-c,1-m,1-y,0,sf)
> enddef ;
>
> vardef scaledrgb(expr r,g,b,sf) =
> (sf*(r,g,b))
> enddef ;
>
> vardef scaledgray(expr s,sf) =
> (sf*(s,s,s))
> enddef ;
>
> % spotcolor is already scaled
>
> endinput ;
>
> % just an exercise (due to a question by Chof on the context mailing
> list); scaling of
> % 'special' colors is not possible and the next solution is incomplete
> (spot colors,
> % transparency, etc); watch the the tricky chained macro construction
>
> % vardef normalgray(expr s ) = (s,s,s) enddef ;
> % vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ;
> % vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean
> ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif
> cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi
> ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " &
> decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ;
> cmykcolorpattern[_cmyk_counter_/1000] := s ; cmykcolorhash[c][m][y][k]
> := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " &
> s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" &
> decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k &
> "] := -1 ; " ; fi ;
> (_special_signal_/1000,1/1000,cmykcolorhash[c][m][y][k]/1000) else :
> (1-c-k,1-m-k,1-y-k) fi enddef ;
>
> % vardef gray(expr s) = normalgray(s ) enddef ;
> % vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ;
> % vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ;
>
> % numeric _scaled_color_t_ ;
> % color _scaled_color_c_ ;
>
> % def withscaledcolor =
> % hide (
> % _scaled_color_t_ := 0 ; % direct
> % def gray(expr s) =
> % hide (
> % _gray_s_ := s ;
> % _scaled_color_t_ := 1; % gray
> % )
> % 0
> % enddef ;
> % def rgb (expr r,g,b) =
> % hide (
> % _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ;
> % _scaled_color_t_ := 2 ; % rgb
> % )
> % 0
> % enddef ;
> % def cmyk (expr c,m,y,k) =
> % hide (
> % _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ;
> _cmyk_k_ := k ;
> % _scaled_color_t_ := 3 ; % cmyk
> % )
> % 0
> % enddef ; )
> % dowithscaledcolor
> % enddef ;
>
> % def dowithscaledcolor expr t =
> % hide (
> % if color t : _scaled_color_c_ := t fi ;
> % vardef gray(expr s) = normalgray(s) enddef ;
> % vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ;
> % vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ;
> % )
> % enddef ;
>
> % def by expr s =
> % if _scaled_color_t_ = 0 :
> % withcolor s*_scaled_color_c_
> % elseif _scaled_color_t_ = 1 :
> % withcolor gray(s*_gray_s_)
> % elseif _scaled_color_t_ = 2 :
> % withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_)
> % elseif _scaled_color_t_ = 3 :
> % withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_,
> s*_cmyk_k_)
> % fi
> % enddef ;
>
> % fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ;
> % fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ;
> % fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ;
> % fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ;
> _______________________________________________
> ntg-context mailing list
> ntg-context at ntg.nl
> http://www.ntg.nl/mailman/listinfo/ntg-context
>
Andrea Valle
DAMS - Facoltà di Scienze della Formazione
Università degli Studi di Torino
andrea.valle at unito.it
More information about the ntg-context
mailing list