%D \module
%D   [       file=mp-page.mpii,
%D        version=1999.03.10,
%D          title=\CONTEXT\ \METAPOST\ graphics,
%D       subtitle=page enhancements,
%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.

%D This module is rather preliminary and subjected to
%D changes.

if known context_page : endinput ; fi ;

boolean context_page ; context_page := true ;

if unknown PageStateAvailable :
  boolean PageStateAvailable ; PageStateAvailable := false ;
fi ;

if unknown OnRightPage :
  boolean OnRightPage ; OnRightPage := true ;
fi ;

if unknown OnOddPage :
  boolean OnOddPage ; OnOddPage := true ;
fi ;

if unknown InPageBody :
  boolean InPageBody ; InPageBody := false ;
fi ;

def SaveTextAreas =
  path    SavedTextAreas  []  ;
  path    SavedTextColumns[]  ;
  numeric NOfSavedTextAreas   ;
  numeric NOfSavedTextColumns ;
  for i=1 upto NOfTextAreas :
    SavedTextAreas[i] := TextAreas[i] ;
  endfor ;
  for i=1 upto NOfTextColumns :
    SavedTextColumns[i] := TextColumns[i] ;
  endfor ;
  NOfSavedTextAreas   := NOfTextAreas ;
  NOfSavedTextColumns := NOfTextColumns ;
enddef ;

def ResetTextAreas =
  path TextAreas[], TextColumns[] ;
  numeric NOfTextAreas   ; NOfTextAreas   := 0 ;
  numeric NOfTextColumns ; NOfTextColumns := 0 ;
  numeric nofmultipars   ; nofmultipars   := 0 ;
  TextAreas[0] := TextColumns[0] := origin -- cycle ;
enddef ;

ResetTextAreas ; SaveTextAreas ; ;

def RegisterTextArea (expr x, y, w, h, d) =
  begingroup ; save p ; path p ;
    p := unitsquare xyscaled(w,h+d) shifted (x,y-d) ;
    if NOfTextAreas>0 :
      % if needed, concatenate areas
      if (round(llcorner TextAreas[NOfTextAreas]) = round(ulcorner p)) and
         (round(lrcorner TextAreas[NOfTextAreas]) = round(urcorner p)) :
        p := ulcorner TextAreas[NOfTextAreas] --
             urcorner TextAreas[NOfTextAreas] --
             lrcorner p --
             llcorner p --
             cycle ;
      else :
        NOfTextAreas := NOfTextAreas + 1 ;
      fi ;
    else :
      NOfTextAreas := NOfTextAreas + 1 ;
    fi ;
    TextAreas[NOfTextAreas] := p ;
    if NOfTextColumns>0 :
      if (round(xpart llcorner TextColumns[NOfTextColumns]) = round(xpart ulcorner p)) and
         (round(xpart lrcorner TextColumns[NOfTextColumns]) = round(xpart urcorner p)) :
        p := ulcorner TextColumns[NOfTextColumns] --
             urcorner TextColumns[NOfTextColumns] --
             lrcorner p --
             llcorner p --
             cycle ;
      else :
        NOfTextColumns := NOfTextColumns + 1 ;
      fi ;
    else :
      NOfTextColumns := NOfTextColumns + 1 ;
    fi ;
    TextColumns[NOfTextColumns] := p ;
  endgroup ;
enddef ;

%D We store a local area in slot zero.

def RegisterLocalTextArea (expr x, y, w, h, d) =
  TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ;
enddef ;

def ResetLocalTextArea =
  TextAreas[0] := TextColumns[0] := origin -- cycle ;
enddef ;

ResetLocalTextArea ;

vardef InsideTextArea (expr _i_, _xy_) =
  ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and
    (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and
    (round(ypart _xy_) >= round(ypart llcorner TextAreas[_i_])) and
    (round(ypart _xy_) <= round(ypart urcorner TextAreas[_i_])) )
enddef ;

vardef InsideSavedTextArea (expr _i_, _xy_) =
  ( (round(xpart _xy_) >= round(xpart llcorner SavedTextAreas[_i_])) and
    (round(xpart _xy_) <= round(xpart lrcorner SavedTextAreas[_i_])) and
    (round(ypart _xy_) >= round(ypart llcorner SavedTextAreas[_i_])) and
    (round(ypart _xy_) <= round(ypart urcorner SavedTextAreas[_i_])) )
enddef ;

vardef InsideSomeTextArea (expr _xy_) =
  save ok ; boolean ok ; ok := false ;
  for i := 1 upto NOfTextAreas :
    if InsideTextArea(i,_xy_) : ok := true ; fi ;
    exitif ok ;
  endfor ;
  ok
enddef ;

vardef InsideSomeSavedTextArea (expr _xy_) =
  save ok ; boolean ok ; ok := false ;
  for i := 1 upto NOfSavedTextAreas :
    if InsideSavedTextArea(i,_xy_) : ok := true ; fi ;
    exitif ok ;
  endfor ;
  ok
enddef ;

vardef TextAreaX (expr x) =
  numeric _TextAreaX_ ; _TextAreaX_ := 0 ;
  for i := 1 upto NOfTextAreas :
    if (round(x) >= round(xpart llcorner TextAreas[i])) and
       (round(x) <= round(xpart lrcorner TextAreas[i])) :
      _TextAreaX_ := xpart llcorner TextAreas[i] ;
    fi ;
  endfor ;
  _TextAreaX_
enddef ;

vardef TextAreaY (expr y) =
  numeric _TextAreaY_ ; _TextAreaY_ := 0 ;
  for i := 1 upto NOfTextAreas :
    if (round(y) >= round(ypart llcorner TextAreas[NOfTextAreas])) and
       (round(y) <= round(ypart ulcorner TextAreas[NOfTextAreas])) :
      _TextAreaY_ := ypart llcorner TextAreas[NOfTextAreas] ;
    fi ;
  endfor ;
  _TextAreaY_
enddef ;

vardef TextAreaXY (expr x, y) =
  pair _TextAreaXY_ ; _TextAreaXY_ := origin ;
  for i := 1 upto NOfTextAreas :
    if (round(x) >= round(xpart llcorner TextAreas[i])) and
       (round(x) <= round(xpart lrcorner TextAreas[i])) and
       (round(y) >= round(ypart llcorner TextAreas[i])) and
       (round(y) <= round(ypart ulcorner TextAreas[i])) :
      _TextAreaXY_ := llconer TextAreas[i] ;
    fi ;
  endfor ;
  _TextAreaXY_
enddef ;

vardef TextAreaW (expr x) =
  numeric _TextAreaW_ ; _TextAreaW_ := 0 ;
  for i := 1 upto NOfTextAreas :
    if (round(x) >= round(xpart llcorner TextAreas[i])) and
       (round(x) <= round(xpart lrcorner TextAreas[i])) :
      _TextAreaW_ := bbwidth(TextAreas[i]) ;
    fi ;
  endfor ;
  _TextAreaW_
enddef ;

vardef TextAreaH (expr y) =
  numeric _TextAreaH_ ; _TextAreaH_ := 0 ;
  for i := 1 upto NOfTextAreas :
    if (round(y) >= round(ypart llcorner TextAreas[i])) and
       (round(y) <= round(ypart ulcorner TextAreas[i])) :
      _TextAreaH_ := bbheight(TextAreas[i]) ;
    fi ;
  endfor ;
  _TextAreaH_
enddef ;

vardef TextAreaWH (expr x, y) =
  pair _TextAreaWH_ ; _TextAreaWH_ := origin ;
  for i := 1 upto NOfTextAreas :
    if (round(x) >= round(xpart llcorner TextAreas[i])) and
       (round(x) <= round(xpart lrcorner TextAreas[i])) and
       (round(y) >= round(ypart llcorner TextAreas[i])) and
       (round(y) <= round(ypart ulcorner TextAreas[i])) :
      _TextAreaWH_ := (bbwidth(TextAreas[i]),bbheight(TextAreas[i])) ;
    fi ;
  endfor ;
  _TextAreaWH_
enddef ;

string CurrentLayout ;

CurrentLayout       := "default" ;

PageNumber          := 0 ;
PaperHeight         := 845.04684pt  ;
PaperWidth          := 597.50787pt  ;
PrintPaperHeight    := 845.04684pt  ;
PrintPaperWidth     := 597.50787pt  ;
TopSpace            :=  71.12546pt  ;
BottomSpace         :=   0.0pt      ;
BackSpace           :=  71.13275pt  ;
CutSpace            :=   0.0pt      ;
MakeupHeight        := 711.3191pt   ;
MakeupWidth         := 426.78743pt  ;
TopHeight           :=   0.0pt      ;
TopDistance         :=   0.0pt      ;
HeaderHeight        :=  56.90294pt  ;
HeaderDistance      :=   0.0pt      ;
TextHeight          := 597.51323pt  ;
FooterDistance      :=   0.0pt      ;
FooterHeight        :=  56.90294pt  ;
BottomDistance      :=   0.0pt      ;
BottomHeight        :=   0.0pt      ;
LeftEdgeWidth       :=   0.0pt      ;
LeftEdgeDistance    :=   0.0pt      ;
LeftMarginWidth     :=   75.58197pt ;
LeftMarginDistance  :=   11.99829pt ;
TextWidth           :=  426.78743pt ;
RightMarginDistance :=   11.99829pt ;
RightMarginWidth    :=   75.58197pt ;
RightEdgeDistance   :=    0.0pt     ;
RightEdgeWidth      :=    0.0pt     ;

PageOffset          :=    0.0pt     ;
PageDepth           :=    0.0pt     ;

LayoutColumns       :=    0         ;
LayoutColumnDistance:=    0.0pt     ;
LayoutColumnWidth   :=    0.0pt     ;

LeftEdge             :=  -4 ; Top             := -40 ;
LeftEdgeSeparator    :=  -3 ; TopSeparator    := -30 ;
LeftMargin           :=  -2 ; Header          := -20 ;
LeftMarginSeparator  :=  -1 ; HeaderSeparator := -10 ;
Text                 :=   0 ; Text            :=   0 ;
RightMarginSeparator :=  +1 ; FooterSeparator := +10 ;
RightMargin          :=  +2 ; Footer          := +20 ;
RightEdgeSeparator   :=  +3 ; BottomSeparator := +30 ;
RightEdge            :=  +4 ; Bottom          := +40 ;

Margin      := LeftMargin  ; % obsolete
Edge        := LeftEdge    ; % obsolete
InnerMargin := RightMargin ; % obsolete
InnerEdge   := RightEdge   ; % obsolete
OuterMargin := LeftMargin  ; % obsolete
OuterEdge   := LeftEdge    ; % obsolete

InnerMarginWidth     := 0pt ;
OuterMarginWidth     := 0pt ;
InnerMarginDistance  := 0pt ;
OuterMarginDistance  := 0pt ;

InnerEdgeWidth     := 0pt ;
OuterEdgeWidth     := 0pt ;
InnerEdgeDistance  := 0pt ;
OuterEdgeDistance  := 0pt ;

path Area [][] ; pair Location [][] ; path Field [][] ;  path Page ;
numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ;
numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ;

for VerPos=Top step 10 until Bottom:
  for HorPos=LeftEdge step 1 until RightEdge:
    Area[HorPos][VerPos] := origin--cycle ;
    Area[VerPos][HorPos] := Area[HorPos][VerPos] ;
    Location[HorPos][VerPos] := origin ;
    Location[VerPos][HorPos] := Location[HorPos][VerPos] ;
    Field[HorPos][VerPos] := origin--cycle ;
    Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
  endfor ;
endfor ;

% def LoadPageState =
%   scantokens "input mp-state.tmp" ;
% enddef ;

def SwapPageState =
  if not OnRightPage :
           BackSpace := PaperWidth-MakeupWidth-BackSpace ;
            CutSpace := PaperWidth-MakeupWidth-CutSpace ;
                   i := LeftMarginWidth ;
     LeftMarginWidth := RightMarginWidth ;
    RightMarginWidth := i ;
                   i := LeftMarginDistance ;
  LeftMarginDistance := RightMarginDistance ;
 RightMarginDistance := i ;
                   i := LeftEdgeWidth ;
       LeftEdgeWidth := RightEdgeWidth ;
      RightEdgeWidth := i ;
                   i := LeftEdgeDistance ;
    LeftEdgeDistance := RightEdgeDistance ;
   RightEdgeDistance := i ;

% these are now available as ..Width and ..Distance

              Margin := LeftMargin ;
                Edge := LeftEdge ;
         InnerMargin := RightMargin ;
           InnerEdge := RightEdge ;
         OuterMargin := LeftMargin ;
           OuterEdge := LeftEdge ;
  else :
              Margin := RightMargin ;
                Edge := RightEdge ;
         InnerMargin := LeftMargin ;
           InnerEdge := LeftEdge ;
         OuterMargin := RightMargin ;
           OuterEdge := RightEdge ;
  fi ;
enddef ;

def SetPageAreas =

  numeric Vsize[], Hsize[], Vstep[], Hstep[] ;

  Vsize[Top]             = TopHeight ;
  Vsize[TopSeparator]    = TopDistance ;
  Vsize[Header]          = HeaderHeight ;
  Vsize[HeaderSeparator] = HeaderDistance ;
  Vsize[Text]            = TextHeight ;
  Vsize[FooterSeparator] = FooterDistance ;
  Vsize[Footer]          = FooterHeight ;
  Vsize[BottomSeparator] = BottomDistance ;
  Vsize[Bottom]          = BottomHeight ;

  Vstep[Top]             = Vstep[TopSeparator]   +Vsize[TopSeparator] ;
  Vstep[TopSeparator]    = PaperHeight-TopSpace ;
  Vstep[Header]          = Vstep[TopSeparator]   -Vsize[Header] ;
  Vstep[HeaderSeparator] = Vstep[Header]         -Vsize[HeaderSeparator] ;
  Vstep[Text]            = Vstep[HeaderSeparator]-Vsize[Text] ;
  Vstep[FooterSeparator] = Vstep[Text]           -Vsize[FooterSeparator] ;
  Vstep[Footer]          = Vstep[FooterSeparator]-Vsize[Footer] ;
  Vstep[BottomSeparator] = Vstep[Footer]         -Vsize[BottomSeparator] ;
  Vstep[Bottom]          = Vstep[BottomSeparator]-Vsize[Bottom] ;

  Hsize[LeftEdge]             = LeftEdgeWidth ;
  Hsize[LeftEdgeSeparator]    = LeftEdgeDistance ;
  Hsize[LeftMargin]           = LeftMarginWidth ;
  Hsize[LeftMarginSeparator]  = LeftMarginDistance ;
  Hsize[Text]                 = MakeupWidth ;
  Hsize[RightMarginSeparator] = RightMarginDistance ;
  Hsize[RightMargin]          = RightMarginWidth ;
  Hsize[RightEdgeSeparator]   = RightEdgeDistance ;
  Hsize[RightEdge]            = RightEdgeWidth ;

  Hstep[LeftEdge]             = Hstep[LeftEdgeSeparator]   -Hsize[LeftEdge] ;
  Hstep[LeftEdgeSeparator]    = Hstep[LeftMargin]          -Hsize[LeftEdgeSeparator] ;
  Hstep[LeftMargin]           = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ;
  Hstep[LeftMarginSeparator]  = Hstep[Text]                -Hsize[LeftMarginSeparator] ;
  Hstep[Text]                 = BackSpace ;
  Hstep[RightMarginSeparator] = Hstep[Text]                +Hsize[Text] ;
  Hstep[RightMargin]          = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ;
  Hstep[RightEdgeSeparator]   = Hstep[RightMargin]         +Hsize[RightMargin] ;
  Hstep[RightEdge]            = Hstep[RightEdgeSeparator]  +Hsize[RightEdgeSeparator] ;

  for VerPos=Top step 10 until Bottom:
    for HorPos=LeftEdge step 1 until RightEdge:
      Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ;
      Area[VerPos][HorPos] := Area[HorPos][VerPos] ;
      Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ;
      Location[VerPos][HorPos] := Location[HorPos][VerPos] ;
      Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ;
      Field[VerPos][HorPos] := Field[HorPos][VerPos] ;
    endfor ;
  endfor ;

  Page := unitsquare xscaled PaperWidth yscaled PaperHeight ;

enddef ;

def BoundPageAreas =

 % pickup pencircle scaled 0pt ;

  bboxmargin := 0 ; setbounds currentpicture to Page ;

enddef ;

def StartPage =

  begingroup ;

  if PageStateAvailable :
    LoadPageState ;
    SwapPageState ;
  fi ;

  SetPageAreas ;
  BoundPageAreas ;

enddef ;

def StopPage =

  BoundPageAreas ;

  endgroup ;

enddef ;

def OverlayBox =
  (unitsquare xyscaled (OverlayWidth,OverlayHeight))
enddef ;

% handy

def innerenlarged =
  hide(LoadPageState)
  if OnRightPage : leftenlarged  else : rightenlarged fi
enddef ;

def outerenlarged =
  hide(LoadPageState)
  if OnRightPage : rightenlarged else : leftenlarged  fi
enddef ;

% obsolete

def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ;
def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ;
def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ;
def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ;

def Enlarged (expr p, d) =
  (llEnlarged (p,d) --
   lrEnlarged (p,d) --
   urEnlarged (p,d) --
   ulEnlarged (p,d) -- cycle)
enddef ;

% New:

def position_anchor_bar(expr p_b_self, p_e_self, y_b_self, y_e_self, h_b_self, d_e_self,
        distance, linewidth, linecolor) =
    StartPage ;
      path p ; p :=
      if p_b_self=p_e_self :
        (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) --
        (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ;
      elseif RealPageNumber=p_b_self :
        (xpart ulcorner Field[Text][Text],y_b_self+h_b_self) --
        (llcorner Field[Text][Text]) ;
      elseif RealPageNumber=p_e_self :
        (ulcorner Field[Text][Text]) --
        (xpart llcorner Field[Text][Text],y_e_self-d_e_self) ;
      else :
        (ulcorner Field[Text][Text]) --
        (llcorner Field[Text][Text]) ;
      fi ;
      p := p shifted (-llcorner Field[Text][Text]-(distance,0)) ;
      interim linecap := butt ;
      draw p
        withpen pencircle scaled linewidth
        withcolor linecolor ;
    StopPage ;
enddef ;

% Crop stuff

vardef crop_marks_lines (expr box, length, offset, nx, ny) =
    save p ; picture p ; save w, h, x, y ; numeric w, h, x, y  ;
    p := image (
        x := if nx = 0 : 1 else : nx - 1 fi ;
        y := if ny = 0 : 1 else : ny - 1 fi ;
        w := bbwidth (box) / x ;
        h := bbheight(box) / y ;
        for i=0 upto y :
            draw ((llcorner box) -- (llcorner box) shifted (-length,0)) shifted (-offset,i*h) ;
            draw ((lrcorner box) -- (lrcorner box) shifted ( length,0)) shifted ( offset,i*h) ;
        endfor ;
        for i=0 upto x :
            draw ((llcorner box) -- (llcorner box) shifted (0,-length)) shifted (i*w,-offset) ;
            draw ((ulcorner box) -- (ulcorner box) shifted (0, length)) shifted (i*w, offset) ;
        endfor ;
    ) ;
    setbounds p to box ;
    p
enddef ;

vardef crop_marks_cmyk =
    save p ; picture p ; p := image (
        fill ulcircle   scaled 12.5 withcolor (1,0,0,0) ;
        fill urcircle   scaled 12.5 withcolor (0,1,0,0) ;
        fill lrcircle   scaled 12.5 withcolor (0,0,1,0) ;
        fill llcircle   scaled 12.5 withcolor (0,0,0,1) ;
        draw (-10,0) -- (10,0) ;
        draw (0,-10) -- (0,10) ;
        draw fullcircle scaled 12.5 ;
    ) ;
    setbounds p to fullsquare scaled 20 ;
    p
enddef ;

vardef crop_marks_gray =
    save p ; picture p ; p := image (
        fill ulcircle   scaled 12.5 withcolor (0.00) ;
        fill urcircle   scaled 12.5 withcolor (0.25) ;
        fill lrcircle   scaled 12.5 withcolor (0.50) ;
        fill llcircle   scaled 12.5 withcolor (0.75) ;
        draw (-10,0) -- (10,0) ;
        draw (0,-10) -- (0,10) ;
        draw (-6,0) -- (6,0) withcolor white ;
        draw (0,-6) -- (0,6) withcolor white  ;
        draw fullcircle scaled 12.5 ;
    ) ;
    setbounds p to fullsquare scaled 20 ;
    p
enddef ;

vardef crop_marks_cmykrgb =
    save p ; picture p ; p := image (
        fill ulcircle   scaled 15 withcolor (1,0,0) ;
        fill urcircle   scaled 15 withcolor (0,1,0) ;
        fill lrcircle   scaled 15 withcolor (0,0,1) ;
        fill llcircle   scaled 15 withcolor (.5,.5,.5) ;
        fill ulcircle   scaled 10 withcolor (1,0,0,0) ;
        fill urcircle   scaled 10 withcolor (0,1,0,0) ;
        fill lrcircle   scaled 10 withcolor (0,0,1,0) ;
        fill llcircle   scaled 10 withcolor (0,0,0,1) ;
        draw (-10,0) -- (10,0) ;
        draw (0,-10) -- (0,10) ;
        draw fullcircle scaled 10 ;
        draw fullcircle scaled 15 ;
    ) ;
    setbounds p to fullsquare scaled 20 ;
    p
enddef ;

vardef crop_color(expr c, h, w, dx, dy, ts) =
    image (
        save p ; path p ;
        for i=1 upto 6 :
            p := fullsquare
                xscaled w
                yscaled h
                shifted (dx,dy-i*h) ;
            fill p
                withcolor (crop_colors[i]*c) ;
            draw textext("\format{'@0.2f'," & decimal crop_colors[i] & "}")
                scaled ts
                shifted center p withcolor white ;
        endfor ;
    )
enddef ;

vardef crop_gray(expr c, h, w, dx, dy, ts) =
    image (
        save p ; path p ;
        for i=.05 step .05 until 1 :
                p := fullsquare
                xscaled w
                yscaled h
                shifted (20*(i-1)*w+dx,dy) ;
            fill p
                withcolor (i*c) ;
            draw textext("\format{'@0.2f'," & decimal i & "}")
                scaled ts
                shifted center p withcolor white ;
        endfor ;
    )
enddef ;

% draw crop_marks_cmyk shifted llcorner more ;
% draw crop_marks_cmyk shifted lrcorner more ;
% draw crop_marks_cmyk shifted ulcorner more ;
% draw crop_marks_cmyk shifted urcorner more ;

def page_marks_add_color(expr width, height, length, offset) = % todo: namespace

    path page ; page := fullsquare xscaled width yscaled height ;
    path more ; more := page enlarged (offset+length/2,offset+length/2) ;

    numeric crop_colors[] ;
    crop_colors[1] := 1 ;
    crop_colors[2] := 0.95 ;
    crop_colors[3] := 0.75 ;
    crop_colors[4] := 0.50 ;
    crop_colors[5] := 0.25 ;
    crop_colors[6] := 0.05 ;

    numeric h ; h := height / 20 ;
    numeric w ; w := width  / 20 ;
    numeric d ; d := offset + length/2 ;

    draw crop_color((1,0,0,0),h,length,xpart ulcorner page - d, 10h,length/20) ;
    draw crop_color((0,1,0,0),h,length,xpart ulcorner page - d,3.5h,length/20) ;
    draw crop_color((0,0,1,0),h,length,xpart ulcorner page - d, -3h,length/20) ;

    draw crop_color((0,1,1,0),h,length,xpart urcorner page + d, 10h,length/20) ;
    draw crop_color((1,0,1,0),h,length,xpart urcorner page + d,3.5h,length/20) ;
    draw crop_color((1,1,0,0),h,length,xpart urcorner page + d, -3h,length/20) ;

    draw crop_gray((0,0,0,1),length,  w,-xpart llcorner page,-ypart llcorner page + d            ,w/20) ;
    draw crop_gray((1,0,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d + 1length/3,w/20) ;
    draw crop_gray((0,1,0,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 0length/3,w/20) ;
    draw crop_gray((0,0,1,0),length/3,w,-xpart llcorner page, ypart llcorner page - d - 1length/3,w/20) ;

    setbounds currentpicture to page ;

enddef ;

def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace

    path page ; page := fullsquare xscaled width yscaled height ;
    path more ; more := page enlarged (offset+length/2,offset+length/2) ;

    draw crop_marks_gray shifted center(topboundary    more) shifted (0, offset+length);
    draw crop_marks_cmyk shifted center(bottomboundary more) shifted (0,-offset-length);

    setbounds currentpicture to page ;

enddef ;

def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace

    path page ; page := fullsquare xscaled width yscaled height ;
    path more ; more := page enlarged (offset+length/2,offset+length/2) ;

    draw crop_marks_lines(page,length,offset,nx,ny) ;

    setbounds currentpicture to page ;

enddef ;

def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace

    path page ; page := fullsquare xscaled width yscaled height ;
    path more ; more := page enlarged (offset+length/2,offset+length/2) ;

    for s=llcorner more, lrcorner more, ulcorner more, urcorner more :
        draw textext(decimal n) shifted s ;
    endfor ;

    setbounds currentpicture to page ;

enddef ;
