mp-page.mpxl /size: 12 Kb    last modification: 2023-12-21 09:43
1%D \module
2%D   [       file=mp-page.mpiv,
3%D        version=1999.03.10,
4%D          title=\CONTEXT\ \METAPOST\ graphics,
5%D       subtitle=page enhancements,
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%D This module is rather preliminary and subjected to changes.In the process of
15%D moving to \METAFUN2\ this might change.
16
17if known metafun_loaded_page : endinput ; fi ;
18
19newinternal boolean metafun_loaded_page ; metafun_loaded_page := true ; immutable metafun_loaded_page ;
20
21def LoadPageState = enddef ; % just in case some old style uses it
22
23% Next we implement the the page area model. First some constants. We use a
24% matrix approach as we do at the TeX end but we could have gone for a period
25% separated variant. Too late.
26
27LeftEdge             :=  -4 ; Top             := -40 ;
28LeftEdgeSeparator    :=  -3 ; TopSeparator    := -30 ;
29LeftMargin           :=  -2 ; Header          := -20 ;
30LeftMarginSeparator  :=  -1 ; HeaderSeparator := -10 ;
31Text                 :=   0 ; Text            :=   0 ;
32RightMarginSeparator :=  +1 ; FooterSeparator := +10 ;
33RightMargin          :=  +2 ; Footer          := +20 ;
34RightEdgeSeparator   :=  +3 ; BottomSeparator := +30 ;
35RightEdge            :=  +4 ; Bottom          := +40 ;
36
37numeric HorPos ; HorPos := 0 ;
38numeric VerPos ; VerPos := 0 ;
39
40immutable % permanent
41    Text, HorPos, VerPos,
42    LeftEdge, LeftEdgeSeparator, LeftMargin, LeftMarginSeparator,
43    RightMarginSeparator, RightMargin, RightEdgeSeparator, RightEdge,
44    Top, TopSeparator, Header, HeaderSeparator,
45    FooterSeparator, Footer, BottomSeparator, Bottom ;
46
47% Because metapost > 1.50 has dynamic memory management and is less efficient than
48% before we now delay calculations ... (on a document with 150 pages the time spent
49% in mp was close to 5 seconds which was only due to initialising the page related
50% areas, something that was hardly noticeable before. At least now we're back to
51% half a second for such a case.
52
53% We could go for just setting them (:=):
54
55path    mfun_page_area    [][][] ;
56pair    mfun_page_location[][][] ;
57path    mfun_page_field   [][][] ;
58numeric mfun_page_vsize   [][] ;
59numeric mfun_page_hsize   [][] ;
60numeric mfun_page_vstep   [][] ;
61numeric mfun_page_hstep   [][] ;
62
63numeric mfun_page_odd ; mfun_page_odd := 1 ;
64
65def mfun_page_check_vsize =
66    mfun_page_vsize[mfun_page_odd][Top]             := TopHeight ;
67    mfun_page_vsize[mfun_page_odd][TopSeparator]    := TopDistance ;
68    mfun_page_vsize[mfun_page_odd][Header]          := HeaderHeight ;
69    mfun_page_vsize[mfun_page_odd][HeaderSeparator] := HeaderDistance ;
70    mfun_page_vsize[mfun_page_odd][Text]            := TextHeight ;
71    mfun_page_vsize[mfun_page_odd][FooterSeparator] := FooterDistance ;
72    mfun_page_vsize[mfun_page_odd][Footer]          := FooterHeight ;
73    mfun_page_vsize[mfun_page_odd][BottomSeparator] := BottomDistance ;
74    mfun_page_vsize[mfun_page_odd][Bottom]          := BottomHeight ;
75enddef ;
76
77def mfun_page_check_hsize =
78    mfun_page_hsize[mfun_page_odd][LeftEdge]             := LeftEdgeWidth ;
79    mfun_page_hsize[mfun_page_odd][LeftEdgeSeparator]    := LeftEdgeDistance ;
80    mfun_page_hsize[mfun_page_odd][LeftMargin]           := LeftMarginWidth ;
81    mfun_page_hsize[mfun_page_odd][LeftMarginSeparator]  := LeftMarginDistance ;
82    mfun_page_hsize[mfun_page_odd][Text]                 := MakeupWidth ;
83    mfun_page_hsize[mfun_page_odd][RightMarginSeparator] := RightMarginDistance ;
84    mfun_page_hsize[mfun_page_odd][RightMargin]          := RightMarginWidth ;
85    mfun_page_hsize[mfun_page_odd][RightEdgeSeparator]   := RightEdgeDistance ;
86    mfun_page_hsize[mfun_page_odd][RightEdge]            := RightEdgeWidth ;
87enddef ;
88
89def mfun_page_check_vstep =
90    mfun_page_vstep[mfun_page_odd][TopSeparator]    := PaperHeight-TopSpace ;
91    mfun_page_vstep[mfun_page_odd][Top]             := mfun_page_vstep[mfun_page_odd][TopSeparator]   +mfun_page_vsize[mfun_page_odd][TopSeparator] ;
92    mfun_page_vstep[mfun_page_odd][Header]          := mfun_page_vstep[mfun_page_odd][TopSeparator]   -mfun_page_vsize[mfun_page_odd][Header] ;
93    mfun_page_vstep[mfun_page_odd][HeaderSeparator] := mfun_page_vstep[mfun_page_odd][Header]         -mfun_page_vsize[mfun_page_odd][HeaderSeparator] ;
94    mfun_page_vstep[mfun_page_odd][Text]            := mfun_page_vstep[mfun_page_odd][HeaderSeparator]-mfun_page_vsize[mfun_page_odd][Text] ;
95    mfun_page_vstep[mfun_page_odd][FooterSeparator] := mfun_page_vstep[mfun_page_odd][Text]           -mfun_page_vsize[mfun_page_odd][FooterSeparator] ;
96    mfun_page_vstep[mfun_page_odd][Footer]          := mfun_page_vstep[mfun_page_odd][FooterSeparator]-mfun_page_vsize[mfun_page_odd][Footer] ;
97    mfun_page_vstep[mfun_page_odd][BottomSeparator] := mfun_page_vstep[mfun_page_odd][Footer]         -mfun_page_vsize[mfun_page_odd][BottomSeparator] ;
98    mfun_page_vstep[mfun_page_odd][Bottom]          := mfun_page_vstep[mfun_page_odd][BottomSeparator]-mfun_page_vsize[mfun_page_odd][Bottom] ;
99enddef ;
100
101def mfun_page_check_hstep =
102    mfun_page_hstep[mfun_page_odd][Text]                 := BackSpace ;
103    mfun_page_hstep[mfun_page_odd][LeftMarginSeparator]  := mfun_page_hstep[mfun_page_odd][Text]                -mfun_page_hsize[mfun_page_odd][LeftMarginSeparator] ;
104    mfun_page_hstep[mfun_page_odd][RightMarginSeparator] := mfun_page_hstep[mfun_page_odd][Text]                +mfun_page_hsize[mfun_page_odd][Text] ;
105    mfun_page_hstep[mfun_page_odd][LeftMargin]           := mfun_page_hstep[mfun_page_odd][LeftMarginSeparator] -mfun_page_hsize[mfun_page_odd][LeftMargin] ;
106    mfun_page_hstep[mfun_page_odd][RightMargin]          := mfun_page_hstep[mfun_page_odd][RightMarginSeparator]+mfun_page_hsize[mfun_page_odd][RightMarginSeparator] ;
107    mfun_page_hstep[mfun_page_odd][LeftEdgeSeparator]    := mfun_page_hstep[mfun_page_odd][LeftMargin]          -mfun_page_hsize[mfun_page_odd][LeftEdgeSeparator] ;
108    mfun_page_hstep[mfun_page_odd][LeftEdge]             := mfun_page_hstep[mfun_page_odd][LeftEdgeSeparator]   -mfun_page_hsize[mfun_page_odd][LeftEdge] ;
109    mfun_page_hstep[mfun_page_odd][RightEdgeSeparator]   := mfun_page_hstep[mfun_page_odd][RightMargin]         +mfun_page_hsize[mfun_page_odd][RightMargin] ;
110    mfun_page_hstep[mfun_page_odd][RightEdge]            := mfun_page_hstep[mfun_page_odd][RightEdgeSeparator]  +mfun_page_hsize[mfun_page_odd][RightEdgeSeparator] ;
111enddef ;
112
113numeric mfun_last_changed_page ; mfun_last_changed_page := -1 ;
114boolean mfun_page_done_odd     ; mfun_page_done_odd     := false ;
115boolean mfun_page_done_even    ; mfun_page_done_even    := false ;
116
117def mfun_check_page_dimensions_indeed =
118    mfun_page_check_vsize ;
119    mfun_page_check_hsize ;
120    mfun_page_check_vstep ;
121    mfun_page_check_hstep ;
122enddef ;
123
124def mfun_check_page_dimensions =
125    begingroup ;
126    save n ; n := LastChangedLayoutPage ;
127    SwapMarginDimensions ; % always
128    if mfun_last_changed_page <> n :
129        report("page", "layout changed") ;
130        mfun_page_done_odd := false ;
131        mfun_page_done_even := false ;
132        mfun_last_changed_page := n ;
133    fi ;
134    if odd RealPageNumber :
135        mfun_page_odd := 1 ;
136        if not mfun_page_done_odd :
137            report("page", "checking odd") ;
138            mfun_check_page_dimensions_indeed ;
139            mfun_page_done_odd := true ;
140        fi ;
141    else :
142        mfun_page_odd := 2 ;
143        if not mfun_page_done_even :
144            report("page", "checking even") ;
145            mfun_check_page_dimensions_indeed ;
146            mfun_page_done_even := true ;
147        fi ;
148    fi ;
149    endgroup ;
150enddef;
151
152def mfun_check_page_area =
153    mfun_check_page_dimensions ;
154    for VerPos=Top step 10 until Bottom:
155        for HorPos=LeftEdge step 1 until RightEdge:
156            mfun_page_area[mfun_page_odd][HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[mfun_page_odd][HorPos] yscaled mfun_page_vsize[where][VerPos] ;
157            mfun_page_area[mfun_page_odd][VerPos][HorPos] := mfun_page_area[mfun_page_odd][HorPos][VerPos] ;
158        endfor ;
159    endfor ;
160enddef ;
161
162def mfun_check_page_location =
163    mfun_check_page_dimensions ;
164    for VerPos=Top step 10 until Bottom:
165        for HorPos=LeftEdge step 1 until RightEdge:
166            mfun_page_location[mfun_page_odd][HorPos][VerPos] := (mfun_page_hstep[mfun_page_odd][HorPos],mfun_page_vstep[mfun_page_odd][VerPos]) ;
167            mfun_page_location[mfun_page_odd][VerPos][HorPos] := mfun_page_location[mfun_page_odd][HorPos][VerPos] ;
168        endfor ;
169    endfor ;
170enddef ;
171
172def mfun_check_page_field =
173    mfun_check_page_dimensions ;
174    for VerPos=Top step 10 until Bottom:
175        for HorPos=LeftEdge step 1 until RightEdge:
176            mfun_page_field[mfun_page_odd][HorPos][VerPos] := unitsquare xscaled mfun_page_hsize[mfun_page_odd][HorPos] yscaled mfun_page_vsize[mfun_page_odd][VerPos] shifted (mfun_page_hstep[mfun_page_odd][HorPos],mfun_page_vstep[mfun_page_odd][VerPos]) ;
177            mfun_page_field[mfun_page_odd][VerPos][HorPos] := mfun_page_field[mfun_page_odd][HorPos][VerPos] ;
178        endfor ;
179    endfor ;
180enddef ;
181
182def Area     = hide(mfun_check_page_area       ;) mfun_page_area    [mfun_page_odd] enddef ;
183def Location = hide(mfun_check_page_location   ;) mfun_page_location[mfun_page_odd] enddef ;
184def Field    = hide(mfun_check_page_field      ;) mfun_page_field   [mfun_page_odd] enddef ;
185def Vsize    = hide(mfun_check_page_dimensions ;) mfun_page_vsize   [mfun_page_odd] enddef ;
186def Hsize    = hide(mfun_check_page_dimensions ;) mfun_page_hsize   [mfun_page_odd] enddef ;
187def Vstep    = hide(mfun_check_page_dimensions ;) mfun_page_vstep   [mfun_page_odd] enddef ;
188def Hstep    = hide(mfun_check_page_dimensions ;) mfun_page_hstep   [mfun_page_odd] enddef ;
189
190immutable % permanent
191    Area, Location, Field, Vsize, Hsize, Vstep, Hstep ;
192
193vardef FrontPageWidth  = PaperWidth enddef ;
194vardef BackPageWidth   = PaperWidth enddef ;
195vardef CoverWidth      = 2 * PaperWidth + SpineWidth enddef ;
196vardef CoverHeight     = PaperHeight enddef ;
197
198vardef FrontPageHeight = PaperHeight enddef ;
199vardef BackPageHeight  = PaperHeight enddef ;
200vardef SpineHeight     = PaperHeight enddef ;
201
202path mfun_page_page, mfun_page_cover, mfun_page_spine, mfun_page_back, mfun_page_front ;
203
204def mfun_check_page  = mfun_page_page  := unitsquare xscaled PaperWidth     yscaled PaperHeight ; enddef ;
205def mfun_check_cover = mfun_page_cover := unitsquare xscaled CoverWidth     yscaled CoverHeight ; enddef ;
206def mfun_check_spine = mfun_page_spine := unitsquare xscaled SpineWidth     yscaled CoverHeight shifted (BackPageWidth,0) ; enddef ;
207def mfun_check_back  = mfun_page_back  := unitsquare xscaled BackPageWidth  yscaled CoverHeight ; enddef ;
208def mfun_check_front = mfun_page_front := unitsquare xscaled FrontPageWidth yscaled CoverHeight shifted (BackPageWidth+SpineWidth,0) ; enddef ;
209
210def Page      = hide(mfun_check_page  ;) mfun_page_page  enddef ;
211def CoverPage = hide(mfun_check_cover ;) mfun_page_cover enddef ;
212def Spine     = hide(mfun_check_spine ;) mfun_page_spine enddef ;
213def BackPage  = hide(mfun_check_back  ;) mfun_page_back  enddef ;
214def FrontPage = hide(mfun_check_front ;) mfun_page_front enddef ;
215
216% pages
217
218def StartPage =
219    begingroup ;
220    setbounds currentpicture to Page ;
221enddef ;
222
223def StopPage =
224    setbounds currentpicture to Page ;
225    endgroup ;
226enddef ;
227
228% cover pages
229
230def StartCover =
231    begingroup ;
232    setbounds currentpicture to CoverPage enlarged PaperBleed ;
233enddef ;
234
235def StopCover =
236    setbounds currentpicture to CoverPage enlarged PaperBleed ;
237    endgroup ;
238enddef ;
239
240immutable % permanent
241    FrontPageWidth, BackPageWidth, CoverWidth, FrontPageHeight, BackPageHeight, CoverHeight,
242    SpineHeight, Page, CoverPage, Spine, BackPage, FrontPage,
243    StartPage, StopPage, StartCover, StopCover ;
244
245% overlays:
246
247def OverlayBox =
248    (unitsquare xyscaled (OverlayWidth,OverlayHeight))
249enddef ;
250
251def BoundToOverlayBox =
252    setbounds currentpicture to OverlayBox;
253enddef ;
254
255immutable % permanent
256    OverlayBox ;
257
258permanent
259    BoundToOverlayBox ;
260
261% handy
262
263def innerenlarged =
264    if OnRightPage : leftenlarged  else : rightenlarged fi
265enddef ;
266
267def outerenlarged =
268    if OnRightPage : rightenlarged else : leftenlarged  fi
269enddef ;
270
271permanent
272    innerenlarged, outerenlarged ;
273
274% obsolete
275
276% def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ;
277% def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ;
278% def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ;
279% def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ;
280
281% def Enlarged (expr p, d) =
282%     (
283%         llEnlarged (p,d) --
284%         lrEnlarged (p,d) --
285%         urEnlarged (p,d) --
286%         ulEnlarged (p,d) --
287%         cycle
288%     )
289% enddef ;
290