%D \module %D [ file=mp-grph.mpii, %D version=2000.12.14, %D title=\CONTEXT\ \METAPOST\ graphics, %D subtitle=graphic text support, %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. %D Under construction. if known context_grph : endinput ; fi ; boolean context_grph ; context_grph := true ; string CRLF ; CRLF := char 10 & char 13 ; picture _currentpicture_ ; numeric _fig_nesting_ ; _fig_nesting_ := 0 ; def beginfig (expr c) = _fig_nesting_ := _fig_nesting_ + 1 ; if _fig_nesting_ = 1 : begingroup charcode := c ; resetfig ; scantokens extra_beginfig ; fi ; enddef ; def endfig = ; % safeguard if _fig_nesting_ = 1 : scantokens extra_endfig; shipit ; endgroup ; fi ; _fig_nesting_ := _fig_nesting_ - 1 ; enddef; def resetfig = clearxy ; clearit ; clearpen ; pickup defaultpen ; interim linecap := linecap ; interim linejoin := linejoin ; interim miterlimit := miterlimit ; save _background_ ; color _background_ ; _background_ := background ; save background ; color background ; background := _background_ ; drawoptions () ; enddef ; def protectgraphicmacros = save showtext ; save beginfig ; let beginfig = begingraphictextfig ; save endfig ; let endfig = endgraphictextfig ; save end ; let end = relax ; interim prologues := prologues ; resetfig ; % resets currentpicture enddef ; numeric currentgraphictext ; currentgraphictext := 0 ; string graphictextformat ; graphictextformat := "plain" ; string graphictextstring ; graphictextstring := "" ; string graphictextfile ; graphictextfile := "dummy.mpo" ; def data_mpo_file = job_name & "-mpgraph.mpo" enddef ; def data_mpy_file = job_name & "-mpgraph.mpy" enddef ; if unknown mplib : def savegraphictext (expr str) = if (graphictextstring<>"") : write graphictextstring to data_mpo_file ; graphictextstring := "" ; fi ; write str to data_mpo_file ; let erasegraphictextfile = relax ; enddef ; def erasegraphictextfile = write EOF to data_mpo_file ; let erasegraphictextfile = relax ; enddef ; extra_beginfig := extra_beginfig & " erasegraphictextfile ;" ; fi ; def begingraphictextfig (expr n) = foundpicture := n ; scratchpicture := nullpicture ; enddef ; def endgraphictextfig = if foundpicture = currentgraphictext : expandafter endinput else : scratchpicture := nullpicture ; fi ; enddef ; def loadfigure primary filename = doloadfigure (filename) enddef ; def doloadfigure (expr filename) text figureattributes = begingroup ; save figurenumber, figurepicture, number, fixedplace ; numeric figurenumber ; figurenumber := 0 ; boolean figureshift ; figureshift := true ; picture figurepicture ; figurepicture := currentpicture ; def number primary n = hide(figurenumber := n) enddef ; def fixedplace = hide(figureshift := false) enddef ; protectgraphicmacros ; % defaults interim linecap := rounded ; interim linejoin := rounded ; interim miterlimit := 10 ; % currentpicture := nullpicture ; draw fullcircle figureattributes ; % expand number currentpicture := nullpicture ; def beginfig (expr n) = currentpicture := nullpicture ; if (figurenumber=n) or (figurenumber=0) : let endfig = endinput ; fi ; enddef ; let endfig = relax ; readfile(filename) ; if figureshift : currentpicture := currentpicture shifted -llcorner currentpicture ; fi ; addto figurepicture also currentpicture figureattributes ; currentpicture := figurepicture ; endgroup ; enddef ; def graphictext primary t = dographictext(t) enddef ; def dographictext (expr t) = begingroup ; save figurepicture ; picture figurepicture ; figurepicture := currentpicture ; currentpicture := nullpicture ; if graphictextformat<>"" : graphictextstring := "% format=" & graphictextformat & CRLF & graphictextstring ; graphictextformat := "" ; fi ; currentgraphictext := currentgraphictext + 1 ; if unknown mplib : savegraphictext ("\startTEXpage[scale=10000]" & t & "\stopTEXpage") ; fi ; dofinishgraphictext enddef ; def redographictext primary t = regraphictext(t) enddef ; def regraphictext (expr t) = begingroup ; save figurepicture ; picture figurepicture ; figurepicture := currentpicture ; currentpicture := nullpicture ; save currentgraphictext ; numeric currentgraphictext ; currentgraphictext := t ; dofinishgraphictext enddef ; %D Believe it or not, but it took me half a day to uncover %D the following neccessity: %D %D \starttypen %D save withfillcolor, withdrawcolor ; %D \stoptypen %D %D When we have more than one graphictext, these will be %D defined after the first graphic. For some obscure reason, %D this means that in the next graphic they will be called, but %D afterwards the data and boolean are not set. Don't ask me %D why. def dofinishgraphictext text x_op_x = protectgraphicmacros ; % resets currentpicture interim linecap := butt ; % normally rounded interim linejoin := mitered ; % normally rounded interim miterlimit := 10 ; % todo let normalwithshade = withshade ; save foundpicture, scratchpicture, str ; save fill, draw, withshade, reversefill, outlinefill ; save withfillcolor, withdrawcolor ; % quite important numeric foundpicture ; picture scratchpicture ; string str ; def draw expr p = % the first, naive implementation was: % addto scratchpicture doublepath p withpen currentpen ; % but it is better to turn lines into fills addto scratchpicture contour boundingbox image (addto currentpicture doublepath p withpen currentpen) ; enddef ; def fill expr p = addto scratchpicture contour p withpen currentpen ; enddef ; def f_op_f = enddef ; boolean f_color ; f_color := false ; def d_op_d = enddef ; boolean d_color ; d_color := false ; def s_op_s = enddef ; boolean s_color ; s_color := false ; boolean reverse_fill ; reverse_fill := false ; boolean outline_fill ; outline_fill := false ; def reversefill = hide(reverse_fill := true ) enddef ; def outlinefill = hide(outline_fill := true ) enddef ; def withshade primary c = hide(def s_op_s = normalwithshade c enddef ; s_color := true ) enddef ; def withfillcolor primary c = hide(def f_op_f = withcolor c enddef ; f_color := true ) enddef ; def withdrawcolor primary c = hide(def d_op_d = withcolor c enddef ; d_color := true ) enddef ; scratchpicture := nullpicture ; addto scratchpicture doublepath origin x_op_x ; % pre-roll for i within scratchpicture : % Below here is a dirty tricky test! if (urcorner dashpart i) = origin : outline_fill := false ; fi ; endfor ; scratchpicture := nullpicture ; readfile(data_mpy_file) ; scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ; if not d_color and not f_color : d_color := true ; fi if s_color : d_color := false ; f_color := false ; fi ; currentpicture := figurepicture ; if d_color and not reverse_fill : for i within scratchpicture : if f_color and outline_fill : addto currentpicture doublepath pathpart i _op_ x_op_x f_op_f dashed nullpicture ; fi ; if filled i : addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; fi ; endfor ; fi ; if f_color : for i within scratchpicture : if filled i : addto currentpicture contour pathpart i _op_ x_op_x f_op_f withpen pencircle scaled 0 ; fi ; endfor ; fi ; if d_color and reverse_fill : for i within scratchpicture : if filled i : addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; fi ; endfor ; fi ; if s_color : for i within scratchpicture : if filled i : addto currentpicture contour pathpart i _op_ x_op_x s_op_s ; fi ; endfor ; else : for i within scratchpicture : if stroked i : addto currentpicture doublepath pathpart i _op_ x_op_x d_op_d ; fi ; endfor ; fi ; endgroup ; enddef ; def resetgraphictextdirective = graphictextstring := "" ; enddef ; def graphictextdirective text t = graphictextstring := graphictextstring & t & CRLF ; enddef ; % example % % % graphictextformat := "context" ; % % graphictextformat := "plain" ; % % beginfig (1) ; % graphictext % "\vbox{\hsize10cm \input tufte }" % scaled 8 % withdrawcolor blue % withfillcolor red % withpen pencircle scaled 2pt ; % endfig ; % % beginfig(1) ; % loadfigure "gracht.mp" rotated 20 ; % loadfigure "koe.mp" number 1 scaled 2 ; % endfig ;