File size: 11,139 Bytes
07c3cdd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/box-inline-create {               % => 
  box-generic-inline-create

  dup /Lines [] put
  
  dup box-inline-setup-methods
  dup /box-inline add-type
} def                              % => Box

% Extends the existing line box to include the given child 
% OR starts new line box, if current child is to the left of the box right edge 
% (which should not happen white the line box is filled)
%
% @param $box child box which will be first in this line box
% @param $line_no number of line box
%
/box-inline-extend-line {          % => LineNo Box This
  dup box-inline-get-lines
  length                           % => LineNo Box This NumLines
  3 index le {                     % => LineNo Box This
% New line box started
    2 index
    2 index
    2 index
    box-inline-init-line           % => LineNo Box This
    2 index                        % => LineNo Box This LineNo
  } {                              % => LineNo Box This
    1 index get-left               % => LineNo Box This BoxLeft
    1 index box-inline-get-lines   % => LineNo Box This BoxLeft Lines
    4 index get                    % => LineNo Box This BoxLeft Line
    line-get-right                 % => LineNo Box This BoxLeft LineRight
    lt {                           % => LineNo Box This
      2 index 1 add                % => LineNo Box This LineNo'
      dup
      3 index
      3 index                      % => LineNo Box This LineNo' LineNo' Box This
      box-inline-init-line         % => LineNo Box This LineNo' 
    } {
      dup box-inline-get-lines     % => LineNo Box This Lines
      3 index get                  % => LineNo Box This Line
      2 index exch line-extend     % => LineNo Box This
      2 index                      % => LineNo Box This LineNo
    } ifelse                       % => 
  } ifelse                         % => LineNo Box This LineNo'

  exch pop
  exch pop
  exch pop
} def

/box-inline-get-extra-line-left {  % => This
  dup get-extra-left               % => This EL
  1 index get-parent /null ne {    % => This EL
    1 index get-parent
    /get-extra-line-left
    call-method                    % => This EL ParentEL
    add
  } if

  exch pop
} def

/box-inline-get-extra-line-right {
  dup get-extra-right              % => This EL
  1 index get-parent /null ne {    % => This EL
    1 index get-parent
    /get-extra-line-right
    call-method                    % => This EL ParentEL
    add
  } if

  exch pop
} def

/box-inline-get-lines {
  /Lines get
} def

% Initialize next line box inside this inline 
%
% Adds the next element to _lines array inside the current object and initializes it with the 
% $box parameters
% 
% @param $box child box which will be first in this line box
% @param $line_no number of line box
%
/box-inline-init-line {            % => LineNo Box This
  1 index
  line-create                      % => LinoNo Box This Line

  1 index box-inline-get-lines
  array-prepend
  1 index box-inline-put-lines     % => LineNo Box This
  
  pop pop pop
} def

/box-inline-merge-line {           % => LineNo Box This
  1 index box-inline-get-lines {   % => LineNo Box This Line
    1 index box-inline-get-lines   % => LineNo Box This Line Lines
    array-prepend                  % => LineNo Box This Lines'
    1 index box-inline-put-lines   % => LineNo Box This 
  } forall                         % => LineNo Box This

  exch pop
  exch pop
  box-inline-get-lines length      % => LineNo'
} def

/box-inline-offset {               % => DY DX This
  3 copy
  box-container-offset             % => DY DX This

  dup box-inline-get-lines {       % => DY DX This Line
    3 index exch
    3 index exch
    line-offset                    % => DY DX This
  } forall

  pop pop pop
} def

/box-inline-put-lines {            % => Value This
  exch /Lines exch put
} def

/box-inline-reflow {               % => Context Parent This
% Note that inline boxes (actually SPANS)
% are never added to the parent's line boxes

% Move current box to the parent's current coordinates
% Note that span box will start at the far left of the parent, NOT on its current X!
% Also, note that inline box can have margins, padding and borders!

  1 index get-left
  1 index put-left

  1 index get-top
  1 index get-extra-top sub
  1 index put-top                  % => Context Parent This

% first line of the SPAN will be offset to its parent current-x PLUS the left padding of current span!
  1 index get-current-x
  1 index get-extra-left
  add                              % => Context Parent This CX
  
  dup 3 index put-current-x        % => Context Parent This CX
  1 index put-current-x            % => Context Pareht This 

% Note that the same operation IS NOT applied to parent current-y!
% The padding space is just extended to the top possibly OVERLAPPING the above boxes.

  0 1 index put-width

% Reflow contents

  0                               % => Context Parent This LineNo
  1 index get-content {           % => Context Parent This LineNo Child
% Add current element into _parent_ line box and reflow it
    4 index
    4 index                       % => Context Parent This LineNo Child Context Parent
    2 index
    /reflow call-method           % => Context Parent This LineNo Child
    
% Track the real height of the inline box; it will be used by other functions 
% (say, functions calculating content height)
    dup get-bottom-margin         % => Context Parent This LineNo' Child BM
    3 index
    box-generic-extend-height     % => Context Parent This LineNo Child

    pop
  } forall                        % => Context Parent This LineNo 
  pop                             % => Context Parent This 
    
% Extend parent height to fit this inline box
% TODO: Is it really required? Seems that it will be accomplished by child reflow functions
%  dup get-bottom-margin           % => Context Parent This GBM
%  2 index
%  box-generic-extend-height       % => Context Parent This

% Apply right extra space value (padding + border + margin)
  1 index get-current-x
  1 index get-extra-right
  add
  2 index put-current-x

% After reflow_content we should have the top stack value replace by the value
% of last child bottom collapsed margin

  dup box-container-get-first-data /null ne {
    2 index context-pop-collapsed-margin
    0 3 index context-push-collapsed-margin
  } if

  pop pop pop
} def

/box-inline-reflow-inline {        % => This
  0                                % => This LineNo
  1 index get-content {            % => This LineNo Child
    dup /reflow-inline call-method
      
    dup /box-inline is-a {
      1 index                      % => This LineNo Child LineNo
      1 index                      % => This LineNo Child LineNo Child
      4 index                      % => This LineNo Child LineNo Child This
      box-inline-merge-line        % => This LineNo Child LineNo'

      3 2 roll                     % => This Child LineNo' LineNo
      pop
      exch                         % => This LineNo' Child 
    } {
      1 index                      % => This LineNo Child LineNo
      1 index                      % => This LineNo Child LineNo Child
      4 index                      % => This LineNo Child LineNo Child This
      box-inline-extend-line       % => This LineNo Child LineNo'
      3 2 roll                     % => This Child LineNo' LineNo
      pop
      exch                         % => This LineNo' Child 
    } ifelse                       % => This LineNo' Child

    pop
  } forall

  pop pop
} def

/box-inline-setup-methods {        % => Box
  dup get-box-dict /Methods get    % => Box Methods
  dup /get-extra-line-left  {box-inline-get-extra-line-left} put  
  dup /get-extra-line-right {box-inline-get-extra-line-right} put  
  dup /offset               {box-inline-offset} put  
  dup /reflow               {box-inline-reflow} put
  dup /reflow-inline        {box-inline-reflow-inline} put
  dup /show                 {box-inline-show} put
  pop pop
} def

/box-inline-show {                 % => Viewport This
% Show line boxes background and borders
  dup box-inline-get-lines {       % => Viewport This Line
    1 index 1 index line-fake-box  % => Viewport This Line FakeBox
    
    dup
    4 index                        % => Viewport This Line FakeBox FakeBox Viewport
    4 index get-background
    background-show                % => Viewport This Line FakeBox

    dup
    4 index
    4 index get-border
    border-show                    % => Viewport This Line FakeBox

    pop pop
  } forall

% Show content
  dup get-content {                % => Viewport This Child
    2 index exch
    /show call-method              % => Viewport This
  } forall

  pop pop
} def

/line-create {                     % => Box
  << >>
  dup /right  3 index get-right  put
  dup /left   3 index get-left   put
  dup /top    3 index get-top    put
  dup /bottom 3 index get-bottom put
  exch pop
} def

/line-extend {                     % => Box This
  dup /top get                     % => Box This V1
  2 index get-top                  % => Box This V1 V2
  max
  1 index exch /top exch put
  
  dup /right get                   % => Box This V1
  2 index get-right                % => Box This V1 V2
  max
  1 index exch /right exch put

  dup /bottom get                  % => Box This V1
  2 index get-bottom               % => Box This V1 V2
  min
  1 index exch /bottom exch put

% Left edge of the line box should never be modified

  pop pop
} def

/line-get-right {
  /right get
} def

/line-fake-box {                   % => Box This
% Create the fake box object
  box-block-create                 % => Box This FakeBox
  
% Setup fake box size
  1 index /left get
  1 index put-left

  1 index /right get
  2 index /left get sub
  1 index put-width

  1 index /top get
  1 index get-baseline sub
  1 index put-top

  1 index /top get
  2 index /bottom get sub
  1 index put-height

% Setup padding value
  2 index get-padding
  1 index put-padding

% Setup fake box border and background
  2 index get-background
  1 index put-background

  2 index get-border
  1 index put-border

  exch pop
  exch pop
} def

/line-offset {                     % => DY DX This
  dup /top get                     % => DY DX This Top
  3 index add                      % => DY DX This Top'
  1 index exch                     % => DY DX This This Top' 
  /top exch put                    % => DY DX This 

  dup /bottom get                  % => DY DX This Bottom
  3 index add                      % => DY DX This Bottom'
  1 index exch                     % => DY DX This This Bottom' 
  /bottom exch put                 % => DY DX This 

  dup /left get                    % => DY DX This Left
  2 index add                      % => DY DX This Left'
  1 index exch                     % => DY DX This This Left' 
  /left exch put                   % => DY DX This 

  dup /right get                   % => DY DX This Right
  2 index add                      % => DY DX This Right'
  1 index exch                     % => DY DX This This Right' 
  /right exch put                  % => DY DX This

  pop pop pop
} def