Files
luos/gulliver/thirdparty/html2ps_pdf/postscript/box.container.ps

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