Spaces:
Sleeping
Sleeping
| /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 |