1023 lines
37 KiB
PostScript
Executable File
1023 lines
37 KiB
PostScript
Executable File
/add-child {
|
|
1 index /add-child call-method
|
|
} def
|
|
|
|
/box-container-add-child { % => Child This
|
|
dup 2 index put-parent % => Child This
|
|
|
|
1 index
|
|
1 index get-content % => Child This Child Content
|
|
array-prepend % => Child This Content'
|
|
1 index put-content
|
|
|
|
pop pop
|
|
} def
|
|
|
|
/box-container-add-deferred-float {% => Float This
|
|
dup /DeferredFloats get % => Float This DeferredFloats
|
|
2 index exch array-prepend % => Float This Floats
|
|
1 index exch
|
|
/DeferredFloats exch
|
|
put % => Float This
|
|
pop pop
|
|
} def
|
|
|
|
/box-container-append-line { % => Child This
|
|
exch
|
|
1 index get-line % => Parent Child PLine
|
|
array-prepend
|
|
exch put-line
|
|
} def
|
|
|
|
/box-container-calculate-text-indent {
|
|
% => This
|
|
dup /text-indent get-css-value % => This TextIndent
|
|
|
|
dup /Percentage get {
|
|
/Value get
|
|
1 index /get-width call-method mul 100 div
|
|
} {
|
|
/Value get
|
|
} ifelse % => This Value
|
|
|
|
exch pop
|
|
} def
|
|
|
|
/box-container-clear-deferred-floats {
|
|
get-box-dict [] /DeferredFloats put
|
|
} def
|
|
|
|
/box-container-clear-line { % => Box
|
|
[] exch put-line
|
|
} def
|
|
|
|
/box-container-close-line { % => Context This
|
|
false 2 index 2 index
|
|
box-container-close-line-common % => Context This
|
|
pop pop
|
|
} def
|
|
|
|
/box-container-close-last-line { % => Context This
|
|
true 2 index 2 index
|
|
box-container-close-line-common % => Context This
|
|
pop pop
|
|
} def
|
|
|
|
/box-container-close-line-common { % => IsLastLine Context This
|
|
% Align line-box using 'text-align' property
|
|
|
|
% Note that text-align should not be applied to the block boxes!
|
|
% As block boxes will be alone in the line-box, we can check
|
|
% if the very first box in the line is inline; if not - no justification should be made
|
|
dup get-line dup length 0 gt { % => IsLastLine Context This Line
|
|
0 get is-inline { % => IsLastLine Context This
|
|
dup /text-align get-css-value
|
|
3 index exch % => IsLastLine Context This IsLastLine AlignFun
|
|
3 index exch % => IsLastLine Context This IsLastLine Context AlignFun
|
|
3 index exch % => IsLastLine Context This IsLastLine Context This AlignFun
|
|
cvx exec % => IsLastLine Context This
|
|
} { % => IsLastLine Context This
|
|
% Nevertheless, CENTER tag and P/DIV with ALIGN attribute set should affect the
|
|
% position of non-inline children.
|
|
dup /pseudo-align get-css-value
|
|
3 index exch % => IsLastLine Context This IsLastLine AlignFun
|
|
3 index exch % => IsLastLine Context This IsLastLine Context AlignFun
|
|
3 index exch % => IsLastLine Context This IsLastLine Context This AlignFun
|
|
cvx exec
|
|
} ifelse % => IsLastLine Context This
|
|
} {
|
|
pop
|
|
} ifelse % => IsLastLine Context This
|
|
|
|
% Apply vertical align to all of the line content
|
|
% first, we need to aling all baseline-aligned boxes to determine the basic line-box height, top and bottom edges
|
|
% then, SUP and SUP positioned boxes (as they can extend the top and bottom edges, but not affected themselves)
|
|
% then, MIDDLE, BOTTOM and TOP positioned boxes in the given order
|
|
|
|
0 0 % => IsLastLine Context This 0(Baseline) 0(Height)
|
|
2 index get-line { % => IsLastLine Context This 0(Baseline) 0(Height) Child
|
|
dup /vertical-align get-css-value
|
|
/baseline eq { % => IsLastLine Context This Baseline Height Child
|
|
dup get-default-baseline % => IsLastLine Context This Baseline Height Child DefaultDaseline
|
|
4 3 roll % => IsLastLine Context This Height Child DefaultDaseline Baseline
|
|
max % => IsLastLine Context This Height Child Baseline'
|
|
3 1 roll % => IsLastLine Context This Baseline' Height Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline' Height
|
|
|
|
2 index get-line { % => IsLastLine Context This Baseline' Height Child
|
|
dup /vertical-align get-css-value
|
|
/baseline eq { % => IsLastLine Context This Baseline Height Child
|
|
2 index 1 index put-baseline % => IsLastLine Context This Baseline Height Child
|
|
|
|
dup get-baseline-offset
|
|
1 index get-full-height add % => IsLastLine Context This Baseline Height Child H+BO
|
|
3 2 roll % => IsLastLine Context This Baseline Child Height H+BO
|
|
max % => IsLastLine Context This Baseline Child Height'
|
|
exch % => IsLastLine Context This Baseline Height' Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height
|
|
|
|
% SUB vertical align
|
|
2 index get-line { % => IsLastLine Context This Baseline' Height Child
|
|
dup /vertical-align get-css-value
|
|
/sub eq { % => IsLastLine Context This Baseline Height Child
|
|
2 index
|
|
1 index get-full-height
|
|
2 div % => IsLastLine Context This Baseline Height Child
|
|
add
|
|
1 index put-baseline
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height
|
|
|
|
% SUPER vertical align
|
|
2 index get-line { % => IsLastLine Context This Baseline' Height Child
|
|
dup /vertical-align get-css-value
|
|
/super eq { % => IsLastLine Context This Baseline Height Child
|
|
dup get-full-height 2 div % => IsLastLine Context This Baseline Height Child BL
|
|
1 index put-baseline
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height
|
|
|
|
% MIDDLE vertical align
|
|
0 % => IsLastLine Context This Baseline Height 0
|
|
3 index get-line { % => IsLastLine Context This Baseline Height Middle Child
|
|
dup /vertical-align get-css-value
|
|
/middle eq { % => IsLastLine Context This Baseline Height Middle Child
|
|
dup get-full-height 2 div % => IsLastLine Context This Baseline Height Middle Child Middle
|
|
3 2 roll % => IsLastLine Context This Baseline Height Child Middle Middle2
|
|
max % => IsLastLine Context This Baseline Height Child Middle'
|
|
exch % => IsLastLine Context This Baseline Height Middle Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Middle
|
|
|
|
dup 2 mul 2 index gt { % => IsLastLine Context This Baseline Height Middle
|
|
dup 2 index 2 div sub % => IsLastLine Context This Baseline Height Middle Delta
|
|
% offset already aligned items
|
|
4 index get-line { % => IsLastLine Context This Baseline Height Middle Delta Child
|
|
dup get-baseline
|
|
2 index add
|
|
1 index put-baseline
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Middle Delta
|
|
pop % => IsLastLine Context This Baseline Height Middle
|
|
2 mul exch pop
|
|
} {
|
|
pop
|
|
} ifelse % => IsLastLine Context This Baseline Height
|
|
|
|
2 index get-line { % => IsLastLine Context This Baseline Height Child
|
|
dup /vertical-align get-css-value
|
|
/middle eq { % => IsLastLine Context This Baseline Height Child
|
|
dup get-default-baseline
|
|
1 index get-full-height 2 div
|
|
sub
|
|
2 index 2 div
|
|
add
|
|
1 index put-baseline % => IsLastLine Context This Baseline Height Child
|
|
} if
|
|
pop
|
|
} forall
|
|
|
|
% BOTTOM vertical align
|
|
0 % => IsLastLine Context This Baseline Height 0
|
|
3 index get-line { % => IsLastLine Context This Baseline Height Bottom Child
|
|
dup /vertical-align get-css-value
|
|
/bottom eq { % => IsLastLine Context This Baseline Height Bottom Child
|
|
dup get-full-height % => IsLastLine Context This Baseline Height Bottom Child Bottom
|
|
3 2 roll % => IsLastLine Context This Baseline Height Child Bottom Bottom2
|
|
max % => IsLastLine Context This Baseline Height Child Bottom'
|
|
exch % => IsLastLine Context This Baseline Height Bottom Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Bottom
|
|
|
|
dup 2 index gt { % => IsLastLine Context This Baseline Height Bottom
|
|
dup 2 index sub % => IsLastLine Context This Baseline Height Bottom Delta
|
|
% offset already aligned items
|
|
4 index get-line { % => IsLastLine Context This Baseline Height Bottom Delta Child
|
|
dup get-baseline
|
|
2 index add
|
|
1 index put-baseline
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Bottom Delta
|
|
pop % => IsLastLine Context This Baseline Height Bottom
|
|
exch pop
|
|
} {
|
|
pop
|
|
} ifelse % => IsLastLine Context This Baseline Height
|
|
|
|
2 index get-line { % => IsLastLine Context This Baseline Height Child
|
|
dup /vertical-align get-css-value
|
|
/bottom eq { % => IsLastLine Context This Baseline Height Child
|
|
dup get-default-baseline
|
|
1 index get-full-height
|
|
sub
|
|
2 index
|
|
add
|
|
1 index put-baseline % => IsLastLine Context This Baseline Height Child
|
|
} if
|
|
pop
|
|
} forall
|
|
|
|
% TOP vertical align
|
|
0 % => IsLastLine Context This Baseline Height 0
|
|
3 index get-line { % => IsLastLine Context This Baseline Height Bottom Child
|
|
dup /vertical-align get-css-value
|
|
/top eq { % => IsLastLine Context This Baseline Height Bottom Child
|
|
dup get-full-height % => IsLastLine Context This Baseline Height Bottom Child Bottom
|
|
3 2 roll % => IsLastLine Context This Baseline Height Child Bottom Bottom2
|
|
max % => IsLastLine Context This Baseline Height Child Bottom'
|
|
exch % => IsLastLine Context This Baseline Height Bottom Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Bottom
|
|
|
|
dup 2 index gt { % => IsLastLine Context This Baseline Height Bottom
|
|
dup 2 index sub % => IsLastLine Context This Baseline Height Bottom Delta
|
|
% offset already aligned items
|
|
4 index get-line { % => IsLastLine Context This Baseline Height Bottom Delta Child
|
|
dup get-baseline
|
|
2 index add
|
|
1 index put-baseline
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height Bottom Delta
|
|
pop % => IsLastLine Context This Baseline Height Bottom
|
|
exch pop
|
|
} {
|
|
pop
|
|
} ifelse % => IsLastLine Context This Baseline Height
|
|
|
|
2 index get-line { % => IsLastLine Context This Baseline Height Child
|
|
dup /vertical-align get-css-value
|
|
/top eq { % => IsLastLine Context This Baseline Height Child
|
|
dup get-default-baseline
|
|
1 index put-baseline % => IsLastLine Context This Baseline Height Child
|
|
} if
|
|
pop
|
|
} forall % => IsLastLine Context This Baseline Height
|
|
|
|
pop pop % => IsLastLine Context This
|
|
|
|
% Calculate the bottom Y coordinate of last line box
|
|
|
|
dup get-current-y % => IsLastLine Context This BY
|
|
1 index get-line { % => IsLastLine Context This BY Child
|
|
% This line is required; say, we have sequence of text and image inside the container,
|
|
% AND image have greater baseline than text; in out case, text will be offset to the bottom
|
|
% of the page and we lose the gap between text and container bottom edge, unless we'll re-extend
|
|
% containier height
|
|
|
|
% Note that we're using the colapsed margin value to get the Y coordinate to extend height to,
|
|
% as bottom margin may be collapsed with parent
|
|
|
|
dup get-bottom-margin
|
|
4 index context-get-collapsed-margin add
|
|
3 index box-generic-extend-height
|
|
|
|
get-bottom-margin % => IsLastLine Context This BY BM
|
|
min % => IsLastLine Context This BY'
|
|
} forall
|
|
|
|
% Clear the line box
|
|
1 index box-container-clear-line
|
|
|
|
% Reset current X coordinate to the far left
|
|
1 index get-left
|
|
2 index put-current-x
|
|
|
|
% Extend Y coordinate
|
|
1 index put-current-y % => IsLastLine Context This
|
|
|
|
% Render the deferred floats
|
|
dup box-container-get-deferred-floats {
|
|
% => IsLastLine Context This Float
|
|
3 copy % => IsLastLine Context This Float Context This Float
|
|
box-container-reflow-static-float
|
|
pop
|
|
} forall % => IsLastLine Context This
|
|
dup box-container-clear-deferred-floats
|
|
|
|
% modify the current-x value, so that next inline box will not intersect any floating boxes
|
|
dup get-current-y
|
|
1 index get-current-x % => IsLastLine Context This Y X
|
|
3 index context-float-left-x % => IsLastLine Context This X
|
|
|
|
1 index put-current-x % => IsLastLine Context This
|
|
|
|
% clear the stack
|
|
pop pop pop
|
|
} def
|
|
|
|
/box-container-create { % =>
|
|
box-generic-create
|
|
|
|
dup /Content [] put
|
|
dup /Line [] put
|
|
|
|
dup box-container-setup-methods
|
|
dup /box-container add-type
|
|
} def
|
|
|
|
% Calculate the available widths - e.g. content width minus space occupied by floats;
|
|
% as floats may not fill the whole height of this box, this value depends on Y-coordinate.
|
|
% We use current_Y in calculations
|
|
%
|
|
/box-container-get-available-width { % => Context Box
|
|
dup get-current-y
|
|
1 index get-left
|
|
3 index context-float-left-x % => Context Box FL
|
|
1 index get-left sub % => Context Box FloatLeftWidth
|
|
|
|
1 index get-right
|
|
2 index get-current-y
|
|
3 index get-right
|
|
5 index context-float-right-x
|
|
sub % => Context Box FloatLeftWidth FloatRightWidth
|
|
|
|
2 index /get-width call-method
|
|
exch sub
|
|
exch sub
|
|
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
% Get a list of floating boxes which shold be rendered
|
|
% at the end of current line box
|
|
%
|
|
/box-container-get-deferred-floats {
|
|
get-box-dict /DeferredFloats get
|
|
} def
|
|
|
|
% Get first child of current box which actually will be drawn
|
|
% on the page. So, whitespace and null boxes will be ignored
|
|
%
|
|
% See description of is_null for null box definition.
|
|
% (not only NullBoxPDF is treated as null box)
|
|
%
|
|
% @return reference to the first visible child of current box
|
|
/box-container-get-first { % => This
|
|
/null
|
|
1 index get-content { % => This /null Child
|
|
dup /is-whitespace call-method not
|
|
1 index /is-null call-method not
|
|
and { % => This FC Child
|
|
exch pop % => This Child
|
|
exit
|
|
} if % => This FC Child
|
|
pop
|
|
} forall % => This FC
|
|
|
|
exch pop % => FC
|
|
} def
|
|
|
|
% Get first text or image child of current box which actually will be drawn
|
|
% on the page. So, whitespace and null boxes will be ignored
|
|
%
|
|
% See description of is_null for null box definition.
|
|
% (not only NullBoxPDF is treated as null box)
|
|
%
|
|
% @return reference to the first visible child of current box
|
|
/box-container-get-first-data { % => This
|
|
/null
|
|
1 index get-content { % => This /null Child
|
|
dup /is-whitespace call-method not
|
|
1 index /is-null call-method not
|
|
and { % => This FC Child
|
|
dup is-container {
|
|
box-container-get-first-data
|
|
dup /null ne {
|
|
exch pop exit
|
|
} if
|
|
} {
|
|
exch pop exit
|
|
} ifelse % => This FC Child
|
|
} if % => This FC Child
|
|
pop
|
|
} forall % => This FC
|
|
|
|
exch pop % => FC
|
|
} def
|
|
|
|
% Get last child of current box which actually will be drawn
|
|
% on the page. So, whitespace and null boxes will be ignored
|
|
%
|
|
% See description of is_null for null box definition.
|
|
% (not only NullBoxPDF is treated as null box)
|
|
%
|
|
% @return reference to the first visible child of current box
|
|
/box-container-get-last { % => This
|
|
/null
|
|
1 index get-content % => This /null Content
|
|
dup length 1 sub -1 0 { % => This /null Content I
|
|
2 copy get % => This /null Context I Element
|
|
|
|
dup /is-whitespace call-method not
|
|
1 index /is-null call-method not
|
|
and
|
|
{
|
|
4 3 roll pop 3 1 roll % => This /null Context I
|
|
pop
|
|
exit
|
|
} {
|
|
pop
|
|
} ifelse % => This /null Context I
|
|
pop
|
|
} for % => This Last Content
|
|
pop exch pop
|
|
} def
|
|
|
|
|
|
/box-container-get-max-width { % => Context This
|
|
0 % => Context This MaxW
|
|
|
|
% We need to add text indent to the max width
|
|
1 index
|
|
box-generic-calc-text-indent % => Context This MaxW CMaxW
|
|
|
|
2 index get-content { % => Context This MaxW CMaxW Item
|
|
dup is-inline
|
|
1 index /float get-css-value
|
|
/none ne or { % => Context This MaxW CMaxW Item
|
|
4 index
|
|
1 index
|
|
/get-max-width call-method % => Context This MaxW CMaxW Item W
|
|
3 2 roll add exch % => Context This MaxW CMaxW' Item
|
|
} { % => Context This MaxW CMaxW Item
|
|
2 index 2 index max % => Context This MaxW CMaxW Item MaxW'
|
|
4 3 roll pop % => Context This CMaxW Item MaxW'
|
|
3 1 roll % => Context This MaxW CMaxW Item
|
|
|
|
4 index
|
|
1 index /get-max-width
|
|
call-method % => Context This MaxW CMaxW Item CMaxW'
|
|
3 2 roll pop exch % => Context This MaxW CMaxW' Item
|
|
|
|
% Process special case with percentage constrained table
|
|
|
|
dup get-width-constraint % => Context This MaxW CMaxW Item WC
|
|
|
|
1 index /box-table is-a
|
|
1 index /type get
|
|
/fraction eq and { % => Context This MaxW CMaxW Item WC
|
|
4 index
|
|
box-generic-get-expandable-width % => Context This MaxW CMaxW Item WC ExpandableWidth
|
|
|
|
5 index
|
|
/get-width call-method % => Context This MaxW CMaxW Item WC ExpandableWidth Width
|
|
|
|
2 index
|
|
dup /apply get exec % => Context This MaxW CMaxW Item WC CWidth
|
|
|
|
3 index max % => Context This MaxW CMaxW Item WC CMaxW'
|
|
|
|
4 3 roll pop 3 1 roll % => Context This MaxW CMaxW' Item WC
|
|
} if % => Context This MaxW CMaxW Item WC
|
|
pop % => Context This MaxW CMaxW Item
|
|
} ifelse % => Context This MaxW CMaxW Item
|
|
|
|
pop
|
|
} forall % => Context This MaxW CMaxW
|
|
|
|
% Check if last line have maximal width
|
|
|
|
max % => Context This MaxW
|
|
|
|
% Note that max width cannot differ drom constrained width,
|
|
% if any width constraints apply
|
|
|
|
1 index get-width-constraint % => Context This MaxW WC
|
|
dup /type get /none ne {
|
|
2 index get-parent
|
|
/get-width call-method % => Context This MaxW WC PWidth
|
|
2 index % => Context This MaxW WC PWidth MaxW
|
|
2 index dup /apply get exec % => Context This MaxW WC MaxW'
|
|
exch pop % => Context This MaxW MaxW'
|
|
exch pop
|
|
} {
|
|
pop
|
|
} ifelse % => Context This MaxW
|
|
|
|
1 index get-hor-extra
|
|
add
|
|
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
/box-container-get-min-nowrap-width { % => Context This
|
|
0 % => Context This MaxW
|
|
|
|
% We need to add text indent to the width
|
|
|
|
1 index
|
|
box-generic-calc-text-indent % => Context This MaxW CMaxW
|
|
|
|
2 index get-content { % => Context This MaxW CMaxW Child
|
|
dup is-inline {
|
|
% Inline boxes content will not be wrapped, so we may calculate its max width
|
|
4 index exch
|
|
/get-max-width call-method % => Context This MaxW CMaxW CMW
|
|
add % => Context This MaxW CMaxW
|
|
} { % => Context This MaxW CMaxW Child
|
|
3 1 roll % => Context This Child MaxW CMaxW
|
|
max % => Context This Child MaxW'
|
|
exch % => Context This MaxW' Child
|
|
3 index exch % => Context This MaxW' Context Child
|
|
/get-min-width call-method % => Context This MaxW' CMaxW'
|
|
} ifelse % => Context This MaxW CMaxW
|
|
} forall % => Context This MaxW CMaxW
|
|
|
|
% Check if last line have maximal width
|
|
max % => Context This MaxW
|
|
|
|
% Apply width constraint to min width. Return maximal value
|
|
1 index get-parent
|
|
/get-width call-method % => Context This MaxW ParentW
|
|
1 index % => Context This MaxW ParentW W
|
|
3 index get-width-constraint % => Context This MaxW ParentW W WC
|
|
dup /apply get exec % => Context This MaxW MaxW'
|
|
max % => Context This MaxW
|
|
|
|
1 index get-hor-extra add % => Context This MaxW
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
/box-container-get-min-width { % => Context This
|
|
% If box does not have any context, its minimal width is determined by extra horizontal space
|
|
dup get-content length 0 eq { % => Context This
|
|
dup get-hor-extra
|
|
} { % => Context This
|
|
% If we're in 'nowrap' mode, minimal and maximal width will be equal
|
|
dup /white-space get-css-value /nowrap eq
|
|
1 index
|
|
/pseudo-nowrap get-css-value
|
|
/nowrap eq or { % => Context This
|
|
2 copy box-container-get-min-nowrap-width
|
|
} { % => Context This
|
|
% We need to add text indent size to the with of the first item
|
|
dup
|
|
box-generic-calc-text-indent % => Context This TI
|
|
2 index
|
|
2 index % => Context This TI Context This
|
|
get-content 0 get
|
|
% box-container-get-first-data % => Context This TI Context First
|
|
/get-min-width call-method % => Context This TI WFirst
|
|
add % => Context This MinW
|
|
|
|
1 index get-content { % => Context This MinW Child
|
|
3 index exch
|
|
/get-min-width call-method % => Context This MinW CMinW
|
|
max % => Context This MinW
|
|
} forall % => Context This MinW
|
|
|
|
1 index get-parent
|
|
/get-width call-method % => Context This MinW ParentW
|
|
1 index % => Context This MinW ParentW MinW
|
|
3 index get-width-constraint % => Context This MinW ParentW MinW WC
|
|
dup /apply get exec % => Context This MinW MinW'
|
|
max
|
|
|
|
1 index get-hor-extra add % => Context This MinW'
|
|
} ifelse % => Context This Width
|
|
} ifelse % => Context This Width
|
|
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
% Get total height of this box content (including floats, if any)
|
|
% Note that floats can be contained inside children, so we'll need to use
|
|
% this function recusively
|
|
/box-container-get-real-full-height { % => This
|
|
% Treat items with overflow: hidden specifically,
|
|
% as floats flown out of this boxes will not be visible
|
|
dup /overflow get-css-value
|
|
/hidden eq { % => This
|
|
dup get-full-height % => This Height
|
|
} { % => This
|
|
% Check if this cell is totally empty
|
|
dup get-content length 0 eq {
|
|
0 % => This Height
|
|
} { % => This
|
|
% Initialize the vertical extent taken by content using the
|
|
% very first child
|
|
dup get-content 0 get
|
|
dup get-top-margin % => This C0 Top
|
|
1 index get-bottom-margin % => This C0 Top Bottom
|
|
3 2 roll pop % => This Top Bottom
|
|
|
|
2 index get-content { % => This Top Bottom Child
|
|
% Check if top margin of current child is to the up
|
|
% of vertical extent top margin
|
|
dup get-top-margin % => This Top Bottom Child ChildTop
|
|
4 3 roll max 3 1 roll % => This Top' Bottom Child
|
|
|
|
% Check if current child bottom margin will extend
|
|
% the vertical space OR if it contains floats extending
|
|
% this, unless this child have overflow: hidden, because this
|
|
% will prevent additional content to be visible
|
|
dup /overflow get-css-value
|
|
/hidden eq {
|
|
dup get-bottom-margin
|
|
3 2 roll min
|
|
exch % => This Top Bottom Child
|
|
} {
|
|
dup get-bottom-margin
|
|
1 index get-top-margin
|
|
2 index /get-real-full-height call-method
|
|
sub
|
|
min % => This Top Bottom Child ChildBM
|
|
3 2 roll min exch % => This Top Bottom' Child
|
|
} ifelse % => This Top Bottom Child
|
|
pop
|
|
} forall % => This Top Bottom
|
|
sub 0 max % => This RH
|
|
1 index get-vert-extra add % => This Height
|
|
} ifelse
|
|
} ifelse % => This Height
|
|
exch pop
|
|
} def
|
|
|
|
/box-container-is-first { % => Box This
|
|
dup box-container-get-first % => Box This First
|
|
dup /null eq {
|
|
pop false
|
|
} {
|
|
get-uid
|
|
2 index get-uid
|
|
eq
|
|
} ifelse
|
|
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
% Line box should be treated as empty in following cases:
|
|
% 1. It is really empty (so, it contains 0 boxes)
|
|
% 2. It contains only whitespace boxes
|
|
%
|
|
/box-container-line-box-empty { % => This
|
|
dup get-line length 0 eq {
|
|
pop true % => true
|
|
} {
|
|
true 1 index get-line % => This true Line
|
|
{ % => This Flag Child
|
|
/is-whitespace call-method
|
|
and
|
|
} forall
|
|
|
|
exch pop
|
|
} ifelse
|
|
} def
|
|
|
|
/box-container-offset { % => DY DX This
|
|
3 copy box-generic-offset
|
|
|
|
dup get-current-x
|
|
2 index add
|
|
1 index put-current-x
|
|
|
|
dup get-current-y
|
|
3 index add
|
|
1 index put-current-y
|
|
|
|
dup get-content {
|
|
3 index exch
|
|
3 index exch
|
|
/offset call-method
|
|
} forall
|
|
|
|
pop pop pop
|
|
} def
|
|
|
|
/box-container-offset-if-first { % => DY DX Box This
|
|
2 copy box-container-is-first {
|
|
dup get-parent /null ne {
|
|
3 index
|
|
3 index
|
|
3 index
|
|
3 index get-parent % => DY DX Box This DY DX Box Parent
|
|
|
|
box-container-offset-if-first
|
|
% => DY DX Box This ParentResult
|
|
|
|
not {
|
|
3 index
|
|
3 index
|
|
2 index /offset call-method % => DY DX Box This
|
|
true
|
|
} { false } ifelse
|
|
} { false } ifelse
|
|
} { false }ifelse
|
|
|
|
exch pop
|
|
exch pop
|
|
exch pop
|
|
exch pop
|
|
} def
|
|
|
|
/box-container-pre-reflow-images { % => This
|
|
dup get-content {
|
|
/pre-reflow-images call-method
|
|
} forall
|
|
pop
|
|
} def
|
|
|
|
/box-container-setup-methods { % => Box
|
|
dup get-box-dict /Methods get % => Box Methods
|
|
dup /add-child { box-container-add-child } put
|
|
dup /get-max-width { box-container-get-max-width } put
|
|
dup /get-min-width { box-container-get-min-width } put
|
|
dup /get-real-full-height { box-container-get-real-full-height } put
|
|
dup /offset { box-container-offset } put
|
|
dup /pre-reflow-images { box-container-pre-reflow-images } put
|
|
dup /reflow-anchors { box-container-reflow-anchors } put
|
|
dup /reflow-content { box-container-reflow-content } put
|
|
dup /reflow-inline { box-container-reflow-inline } put
|
|
dup /reflow-static-float { box-container-reflow-static-float } put
|
|
dup /show { box-container-show } put
|
|
pop pop
|
|
} def
|
|
|
|
/box-container-show { % => Viewport Box
|
|
2 copy box-generic-show % => Viewport Box
|
|
|
|
% Setup clipping path for non 'overflow: visible' boxes
|
|
dup /overflow get-css-value
|
|
/visible ne {
|
|
% Save clipping area state (of course, BEFORE the clipping area will be set)
|
|
gsave
|
|
|
|
newpath
|
|
dup get-left-border
|
|
1 index get-bottom-border % => Viewport Box X Y
|
|
2 index get-right-border
|
|
3 index get-left-border sub % => Viewport Box X Y W
|
|
3 index get-top-border
|
|
4 index get-bottom-border sub % => Viewport Box X Y W H
|
|
rectclip
|
|
|
|
} if
|
|
|
|
% draw content
|
|
dup get-content { % => Viewport Box ContentElement
|
|
% We'll check the visibility property here
|
|
% Reason: all boxes (except the top-level one) are contained in some other box,
|
|
% so every box will pass this check. The alternative is to add this check into every
|
|
% box class show member.
|
|
|
|
% The only exception of absolute positioned block boxes which are drawn separately;
|
|
% their show method is called explicitly; the similar check should be performed there
|
|
|
|
dup /visibility get-css-value /visible eq {
|
|
2 index
|
|
1 index
|
|
/show call-method
|
|
} if % => Viewport Box ContentElement
|
|
pop
|
|
} forall % => Viewport Box
|
|
|
|
dup /overflow get-css-value /visible ne {
|
|
% restore previous clipping path
|
|
grestore
|
|
} if
|
|
|
|
pop pop
|
|
} def % =>
|
|
|
|
/box-container-reflow-anchors { % => List Viewport Box
|
|
3 copy box-generic-reflow-anchors
|
|
|
|
dup get-content { % => List Viewport Box Child
|
|
3 index exch
|
|
3 index exch % => List Viewport Box List Viewport Child
|
|
/reflow-anchors call-method % => List' Viewport Box
|
|
} forall
|
|
|
|
pop pop pop
|
|
} def
|
|
|
|
/box-container-reflow-content { % => Context This
|
|
2 copy box-container-close-line % => Context This
|
|
|
|
% If first child is inline - apply text-indent
|
|
dup box-container-get-first
|
|
dup /null ne {
|
|
dup is-inline { % => Context This First
|
|
pop
|
|
dup box-container-calculate-text-indent
|
|
1 index get-additional-text-indent
|
|
add
|
|
1 index get-current-x
|
|
add
|
|
1 index put-current-x % => Context This
|
|
} {
|
|
pop
|
|
} ifelse
|
|
} {
|
|
pop
|
|
} ifelse
|
|
|
|
0 1 index put-height
|
|
|
|
% reset current Y value
|
|
dup get-top
|
|
1 index put-current-y
|
|
|
|
dup get-content { % => Context This Child
|
|
2 index exch % => Context This Context Child
|
|
2 index exch % => Context This Context This Child
|
|
/reflow call-method % => Context This
|
|
} forall % => Context This
|
|
|
|
1 index 1 index
|
|
box-container-close-last-line % => Context This
|
|
|
|
pop pop % =>
|
|
} def
|
|
|
|
/box-container-reflow-inline { % => This
|
|
dup get-content { % => This Child
|
|
/reflow-inline call-method % => This
|
|
} forall
|
|
pop
|
|
} def
|
|
|
|
/box-container-reflow-static-float { % => Context Parent Box
|
|
% Defer the float rendering till the next line box
|
|
1 index get-line length 0 gt {
|
|
dup 2 index box-container-add-deferred-float
|
|
} {
|
|
|
|
% Calculate margin values if they have been set as a percentage
|
|
|
|
2 copy
|
|
box-generic-calc-percentage-margins
|
|
|
|
% Calculate width value if it have been set as a percentage
|
|
|
|
3 copy
|
|
box-generic-calc-percentage-width
|
|
|
|
% Calculate margins and/or width is 'auto' values have been specified
|
|
|
|
2 copy
|
|
box-generic-calc-auto-width-margins
|
|
|
|
% Determine the actual width of the floating box
|
|
% Note that get_max_width returns both content and extra width
|
|
|
|
2 index 1 index /get-max-width call-method
|
|
1 index put-full-width
|
|
|
|
% We need to call this function before determining the horizontal coordinate
|
|
% as after vertical offset the additional space to the left may apperar
|
|
% => Context Parent Box
|
|
2 index
|
|
2 index get-current-y
|
|
2 index
|
|
box-generic-apply-clear % => Context Parent Box Y
|
|
|
|
% determine the position of top-left floating box corner
|
|
1 index /float get-css-value
|
|
/right eq {
|
|
2 index
|
|
2 index get-full-width
|
|
2 index % => Context Parent Box Y Parent Width Y
|
|
6 index
|
|
context-float-right-xy % => Context Parent Box Y X' Y'
|
|
|
|
exch
|
|
3 index get-full-width sub
|
|
exch
|
|
} {
|
|
2 index
|
|
2 index get-full-width
|
|
2 index % => Context Parent Box Y Parent Width Y
|
|
6 index
|
|
context-float-left-xy % => Context Parent Box Y X' Y'
|
|
} ifelse % => Context Parent Box Y X' Y'
|
|
|
|
3 index get-extra-top sub
|
|
exch
|
|
3 index get-extra-left add
|
|
3 index box-generic-move-to % => Context Parent Box Y
|
|
pop % => Context Parent Box
|
|
|
|
% Reflow contents.
|
|
% Note that floating box creates a new float flow context for it children.
|
|
|
|
2 index context-push-floats
|
|
|
|
% Floating box create a separate margin collapsing context
|
|
|
|
0 3 index context-push-collapsed-margin
|
|
|
|
2 index 1 index /reflow-content call-method
|
|
|
|
2 index context-pop-collapsed-margin
|
|
|
|
% Float should completely enclose its child floats
|
|
|
|
2 index context-float-bottom % => Context Parent Box FB
|
|
dup /null ne {
|
|
1 index box-generic-extend-height
|
|
} {
|
|
pop
|
|
} ifelse
|
|
|
|
2 index context-float-right % => Context Parent Box FR
|
|
dup /null ne {
|
|
1 index box-generic-extend-width
|
|
} {
|
|
pop
|
|
} ifelse
|
|
|
|
% restore old float flow context
|
|
|
|
2 index context-pop-floats
|
|
|
|
% Add this box to the list of floats in current context
|
|
|
|
dup 3 index context-add-float % => Context Parent Box
|
|
|
|
% Now fix the value of _current_x for the parent box; it is required
|
|
% in the following case:
|
|
% <body><img align="left">some text
|
|
% in such situation floating image is flown immediately, but it the close_line call have been made before,
|
|
% so _current_x value of container box will be still equal to ots left content edge; by calling float_left_x again,
|
|
% we'll force "some text" to be offset to the right
|
|
|
|
1 index get-current-y
|
|
2 index get-current-x
|
|
4 index
|
|
context-float-left-x
|
|
2 index put-current-x
|
|
|
|
} ifelse % => Context Parent Box
|
|
pop pop pop
|
|
} def
|
|
|
|
/get-content {
|
|
/Content get
|
|
} def
|
|
|
|
/get-line {
|
|
/Line get
|
|
} def
|
|
|
|
/line-length { % => Box
|
|
dup get-line 0 exch % => Box 0(CurrentLength) Line
|
|
{ % => Box CurrentLength LineElement
|
|
% Note that the line length should include the inline boxes margin/padding
|
|
% as inline boxes are not directly included to the parent line box,
|
|
% we'll need to check the parent of current line box element,
|
|
% and, if it is an inline box, AND this element is last or first contained element
|
|
% add correcponsing padding value
|
|
dup get-full-width % => Box CurrentLength LineElement EWidth
|
|
3 2 roll add exch % => Box CurrentLength LineElement
|
|
|
|
dup get-parent % => Box CurrentLength LineElement EParent
|
|
dup /null ne {
|
|
dup box-container-get-first % => Box CurrentLength LineElement EParent First
|
|
1 index
|
|
box-container-get-last % => Box CurrentLength LineElement EParent First Last
|
|
|
|
1 index /null ne {
|
|
1 index get-uid
|
|
4 index get-uid eq {
|
|
2 index
|
|
/get-extra-line-left
|
|
call-method % => Box CurrentLength LineElement EParent First Last ELeft
|
|
6 5 roll add 5 1 roll % => Box CurrentLength' LineElement EParent First Last
|
|
} if
|
|
} if
|
|
|
|
dup /null ne {
|
|
dup get-uid
|
|
4 index get-uid eq {
|
|
2 index
|
|
/get-extra-line-right
|
|
call-method % => Box CurrentLength LineElement EParent First Last ELeft
|
|
6 5 roll add 5 1 roll % => Box CurrentLength' LineElement EParent First Last
|
|
} if
|
|
} if
|
|
|
|
pop pop % => Box CurrentLength LineELement EParent
|
|
} if % => Box CurrentLength LineElement EParent
|
|
pop pop
|
|
} forall % => Box CurrentLength
|
|
exch pop % => Length
|
|
} def
|
|
|
|
/put-line {
|
|
exch /Line exch put
|
|
} def |