View | Details | Raw Unified | Return to bug 44328
Collapse All | Expand All

(-)test/layoutengine/standard-testcases/block_widows.xml (+143 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
  Licensed to the Apache Software Foundation (ASF) under one or more
4
  contributor license agreements.  See the NOTICE file distributed with
5
  this work for additional information regarding copyright ownership.
6
  The ASF licenses this file to You under the Apache License, Version 2.0
7
  (the "License"); you may not use this file except in compliance with
8
  the License.  You may obtain a copy of the License at
9
10
       http://www.apache.org/licenses/LICENSE-2.0
11
12
  Unless required by applicable law or agreed to in writing, software
13
  distributed under the License is distributed on an "AS IS" BASIS,
14
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
  See the License for the specific language governing permissions and
16
  limitations under the License.
17
-->
18
<!-- $Id$ -->
19
<testcase>
20
  <info>
21
    <p>
22
      This test checks the default behavior of the "widows" property.
23
    </p>
24
  </info>
25
  <fo>
26
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
27
      <fo:layout-master-set>
28
        <fo:simple-page-master master-name="normal" page-width="3in" page-height="2in">
29
          <fo:region-body />
30
        </fo:simple-page-master>
31
      </fo:layout-master-set>
32
      <fo:page-sequence master-reference="normal">
33
        <fo:flow flow-name="xsl-region-body">
34
          <fo:block id="block-1">
35
            <!-- Basic test: simple paragraph generating 11 lines.
36
                 2 last lines should be kept together due to initial 
37
                 value for widows
38
              -->
39
            Lorem ipsum dolor sit amet, consectetur
40
            adipiscing elit. Cras placerat, lectus vel
41
            iaculis euismod, ipsum enim dapibus
42
            urna, eu pellentesque velit dolor ac 
43
            purus. Maecenas vitae pulvinar turpis.
44
            Duis venenatis tincidunt velit, fringilla
45
            dignissim sapien faucibus vel. Quisque
46
            placerat ornare consectetur. Aenean
47
            dui tortor, tempor ut convallis in,
48
            fermentum tempor nunc. Class aptent 
49
            taciti sociosqu ad litora torquent per
50
          </fo:block>
51
          <fo:block id="block-2" break-before="page">
52
            <!-- Basic test: simple paragraph generating 11 lines, followed by
53
                 another block.
54
                 A break between lines 10 and 11 is allowed.
55
              -->
56
            Lorem ipsum dolor sit amet, consectetur
57
            adipiscing elit. Cras placerat, lectus vel
58
            iaculis euismod, ipsum enim dapibus
59
            urna, eu pellentesque velit dolor ac 
60
            purus. Maecenas vitae pulvinar turpis.
61
            Duis venenatis tincidunt velit, fringilla
62
            dignissim sapien faucibus vel. Quisque
63
            placerat ornare consectetur. Aenean
64
            dui tortor, tempor ut convallis in,
65
            fermentum tempor nunc. Class aptent 
66
            taciti sociosqu ad litora torquent per
67
            <fo:block>
68
            Lorem ipsum dolor sit amet, consectetur
69
            adipiscing elit. Cras placerat, lectus vel
70
            iaculis euismod, ipsum enim dapibus
71
            urna, eu pellentesque velit dolor ac
72
            </fo:block>
73
          </fo:block>
74
          <fo:block id="block-3" break-before="page">
75
            <!-- Basic test: 1 paragraph consisting of 11 single-line subparagraphs.
76
                 Last 2 lines of the main paragraph should be kept together due to 
77
                 initial value for widows.
78
              -->
79
            <fo:block>
80
              <fo:block>Lorem ipsum</fo:block>
81
              <fo:block>Lorem ipsum</fo:block>
82
              <fo:block>Lorem ipsum</fo:block>
83
              <fo:block>Lorem ipsum</fo:block>
84
              <fo:block>Lorem ipsum</fo:block>
85
              <fo:block>Lorem ipsum</fo:block>
86
              <fo:block>Lorem ipsum</fo:block>
87
              <fo:block>Lorem ipsum</fo:block>
88
              <fo:block>Lorem ipsum</fo:block>
89
              <fo:block>Lorem ipsum</fo:block>
90
              <fo:block>Lorem ipsum</fo:block>
91
            </fo:block>
92
          </fo:block>
93
          <fo:block id="block-4" break-before="page">
94
            <!-- Special case: linefeed-treatment="preserve" (see Bugzilla 44328) -->
95
            <fo:block linefeed-treatment="preserve">Lorem ipsum
96
            dolor sit amet,
97
            consectetur
98
            adipiscing elit.
99
            Cras placerat,
100
            lectus vel
101
            iaculis euismod,
102
            ipsum enim
103
            dapibus urna,
104
            eu pellentesque
105
            velit dolor</fo:block>
106
          </fo:block>
107
          <fo:block id="block-5" break-before="page">
108
            <!-- Special case: 1 paragraph with 10 lines, and 1 with 1.
109
                 Last 2 lines of the first paragraph should be kept
110
                 together with the only line of the second due to initial
111
                 value of widows on the outer block.
112
              -->
113
            <fo:block>
114
            Lorem ipsum dolor sit amet, consectetur
115
            adipiscing elit. Cras placerat, lectus vel
116
            iaculis euismod, ipsum enim dapibus
117
            urna, eu pellentesque velit dolor ac 
118
            purus. Maecenas vitae pulvinar turpis.
119
            Duis venenatis tincidunt velit, fringilla
120
            dignissim sapien faucibus vel. Quisque
121
            placerat ornare consectetur. Aenean
122
            dui tortor, tempor ut convallis in,
123
            fermentum tempor nunc. Class aptent 
124
            </fo:block>
125
            <fo:block>Lorem ipsum</fo:block>
126
          </fo:block>
127
        </fo:flow>
128
      </fo:page-sequence>
129
    </fo:root>
130
  </fo>
131
  <checks>
132
    <eval expected="9" xpath="count((//page)[1]//lineArea)" />
133
    <eval expected="2" xpath="count((//page)[2]//lineArea)" />
134
    <eval expected="10" xpath="count((//page)[3]//lineArea)" />
135
    <eval expected="5" xpath="count((//page)[4]//lineArea)" />
136
    <eval expected="9" xpath="count((//page)[5]//lineArea)" />
137
    <eval expected="2" xpath="count((//page)[6]//lineArea)" />
138
    <eval expected="9" xpath="count((//page)[7]//lineArea)" />
139
    <eval expected="2" xpath="count((//page)[8]//lineArea)" />
140
    <eval expected="8" xpath="count((//page)[9]//lineArea)" />
141
    <eval expected="3" xpath="count((//page)[10]//lineArea)" />
142
  </checks>
143
</testcase>
(-)test/layoutengine/standard-testcases/block_orphans.xml (+167 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
  Licensed to the Apache Software Foundation (ASF) under one or more
4
  contributor license agreements.  See the NOTICE file distributed with
5
  this work for additional information regarding copyright ownership.
6
  The ASF licenses this file to You under the Apache License, Version 2.0
7
  (the "License"); you may not use this file except in compliance with
8
  the License.  You may obtain a copy of the License at
9
10
       http://www.apache.org/licenses/LICENSE-2.0
11
12
  Unless required by applicable law or agreed to in writing, software
13
  distributed under the License is distributed on an "AS IS" BASIS,
14
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
  See the License for the specific language governing permissions and
16
  limitations under the License.
17
-->
18
<!-- $Id$ -->
19
<testcase>
20
  <info>
21
    <p>
22
      This test checks the default behavior of the "orphans" property.
23
    </p>
24
  </info>
25
  <fo>
26
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
27
      <fo:layout-master-set>
28
        <fo:simple-page-master master-name="normal" page-width="3in" page-height="2in">
29
          <fo:region-body />
30
        </fo:simple-page-master>
31
      </fo:layout-master-set>
32
      <fo:page-sequence master-reference="normal">
33
        <fo:flow flow-name="xsl-region-body">
34
          <fo:block id="block-1" break-before="page">
35
            <!-- Basic test: 1 paragraph with 9 lines and 1 with 4.
36
                 All 4 lines of the second paragraph should be kept 
37
                 together due to initial value for orphans.
38
              -->
39
            <fo:block>
40
            Lorem ipsum dolor sit amet, consectetur
41
            adipiscing elit. Cras placerat, lectus vel
42
            iaculis euismod, ipsum enim dapibus
43
            urna, eu pellentesque velit dolor ac 
44
            purus. Maecenas vitae pulvinar turpis.
45
            Duis venenatis tincidunt velit, fringilla
46
            dignissim sapien faucibus vel. Quisque
47
            placerat ornare consectetur. Aenean
48
            dui tortor, tempor ut convallis in,
49
            </fo:block>
50
            <fo:block>
51
            Lorem ipsum dolor sit amet, consectetur
52
            adipiscing elit. Cras placerat, lectus vel
53
            iaculis euismod, ipsum enim dapibus
54
            urna, eu pellentesque velit dolor ac
55
            </fo:block>
56
          </fo:block>
57
          <fo:block id="block-2" break-before="page">
58
            <!-- Basic test: 1 block with 9 lines and 1 paragraph with 4 lines.
59
                 A break after the first line of the second paragraph is allowed.
60
              -->
61
            <fo:block>
62
            Lorem ipsum dolor sit amet, consectetur
63
            adipiscing elit. Cras placerat, lectus vel
64
            iaculis euismod, ipsum enim dapibus
65
            urna, eu pellentesque velit dolor ac 
66
            purus. Maecenas vitae pulvinar turpis.
67
            Duis venenatis tincidunt velit, fringilla
68
            dignissim sapien faucibus vel. Quisque
69
            placerat ornare consectetur. Aenean
70
            dui tortor, tempor ut convallis in,
71
            </fo:block>
72
            Lorem ipsum dolor sit amet, consectetur
73
            adipiscing elit. Cras placerat, lectus vel
74
            iaculis euismod, ipsum enim dapibus
75
            urna, eu pellentesque velit dolor ac
76
          </fo:block>
77
          <fo:block id="block-3" break-before="page">
78
            <!-- Basic test: 1 regular paragraph of 9 lines followed by 1 consisting 
79
                 of 4 single-line subparagraphs.
80
                 All 4 lines of the second paragraph should be kept together due
81
                 to initial value for orphans.
82
              -->
83
            <fo:block id="block-3a">
84
            Lorem ipsum dolor sit amet, consectetur
85
            adipiscing elit. Cras placerat, lectus vel
86
            iaculis euismod, ipsum enim dapibus
87
            urna, eu pellentesque velit dolor ac 
88
            purus. Maecenas vitae pulvinar turpis.
89
            Duis venenatis tincidunt velit, fringilla
90
            dignissim sapien faucibus vel. Quisque
91
            placerat ornare consectetur. Aenean
92
            dui tortor, tempor ut convallis in,
93
            </fo:block>
94
            <fo:block id="block-3b">
95
              <fo:block>Lorem ipsum</fo:block>
96
              <fo:block>Lorem ipsum</fo:block>
97
              <fo:block>Lorem ipsum</fo:block>
98
              <fo:block>Lorem ipsum</fo:block>
99
            </fo:block>
100
          </fo:block>
101
          <fo:block id="block-4" break-before="page">
102
            <!-- Special case: linefeed-treatment="preserve" (see Bugzilla 44328) -->
103
            <fo:block>
104
            Lorem ipsum dolor sit amet, consectetur
105
            adipiscing elit. Cras placerat, lectus vel
106
            iaculis euismod, ipsum enim dapibus
107
            urna, eu pellentesque velit dolor ac 
108
            purus. Maecenas vitae pulvinar turpis.
109
            Duis venenatis tincidunt velit, fringilla
110
            dignissim sapien faucibus vel. Quisque
111
            placerat ornare consectetur. Aenean
112
            dui tortor, tempor ut convallis in,
113
            </fo:block>
114
            <fo:block linefeed-treatment="preserve">Lorem ipsum
115
            dolor sit amet,
116
            consectetur
117
            velit dolor</fo:block>
118
          </fo:block>
119
          <fo:block id="block-5" break-before="page" widows="1">
120
            <!-- Last but not least, demonstrate peculiar side-effect in case
121
                 of convoluted nesting...
122
                 Even though widows would allow a break before the last line,
123
                 all 10 last lines are moved to the next page due to stacked 
124
                 orphans constraints
125
              -->
126
            <fo:block id="level-1">Lorem ipsum
127
              <fo:block>Lorem ipsum</fo:block>
128
              <fo:block id="level-2">Lorem ipsum
129
                <fo:block id="level-3">Lorem ipsum
130
                  <fo:block id="level-4">Lorem ipsum
131
                    <fo:block id="level-5">Lorem ipsum
132
                      <fo:block id="level-6">Lorem ipsum
133
                        <fo:block id="level-7">Lorem ipsum
134
                          <fo:block id="level-8">Lorem ipsum
135
                            <fo:block id="level-9">Lorem ipsum
136
                              <fo:block id="level-10">Lorem ipsum
137
                                <fo:block id="level-11">
138
                                Lorem ipsum
139
                                </fo:block>
140
                              </fo:block>
141
                            </fo:block>
142
                          </fo:block>
143
                        </fo:block>
144
                      </fo:block>
145
                    </fo:block>
146
                  </fo:block>
147
                </fo:block>
148
              </fo:block>
149
            </fo:block>
150
          </fo:block>
151
        </fo:flow>
152
      </fo:page-sequence>
153
    </fo:root>
154
  </fo>
155
  <checks>
156
    <eval expected="9" xpath="count((//page)[1]//lineArea)" />
157
    <eval expected="4" xpath="count((//page)[2]//lineArea)" />
158
    <eval expected="10" xpath="count((//page)[3]//lineArea)" />
159
    <eval expected="3" xpath="count((//page)[4]//lineArea)" />
160
    <eval expected="9" xpath="count((//page)[5]//lineArea)" />
161
    <eval expected="4" xpath="count((//page)[6]//lineArea)" />
162
    <eval expected="9" xpath="count((//page)[7]//lineArea)" />
163
    <eval expected="4" xpath="count((//page)[8]//lineArea)" />
164
    <eval expected="2" xpath="count((//page)[9]//lineArea)" />
165
    <eval expected="10" xpath="count((//page)[10]//lineArea)" />
166
  </checks>
167
</testcase>
(-)src/java/org/apache/fop/layoutmgr/KnuthPenalty.java (+3 lines)
Lines 46-51 Link Here
46
    /** Dummy, zero-width penalty */
46
    /** Dummy, zero-width penalty */
47
    public static final KnuthPenalty DUMMY_ZERO_PENALTY
47
    public static final KnuthPenalty DUMMY_ZERO_PENALTY
48
            = new KnuthPenalty(0, 0, false, null, true);
48
            = new KnuthPenalty(0, 0, false, null, true);
49
    /** Dummy break inhibitor */
50
    public static final KnuthPenalty DUMMY_INFINITE_PENALTY
51
            = new KnuthPenalty(0, KnuthElement.INFINITE, false, null, true);
49
52
50
    private int penalty;
53
    private int penalty;
51
    private boolean penaltyFlagged;
54
    private boolean penaltyFlagged;
(-)src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (-7 / +90 lines)
Lines 66-71 Link Here
66
    private MinOptMax effSpaceBefore;
66
    private MinOptMax effSpaceBefore;
67
    private MinOptMax effSpaceAfter;
67
    private MinOptMax effSpaceAfter;
68
68
69
    private int orphans = 2;
70
    private int widows = 2;
71
69
    /**
72
    /**
70
     * Creates a new BlockLayoutManager.
73
     * Creates a new BlockLayoutManager.
71
     * @param inBlock the block FO object to create the layout manager for.
74
     * @param inBlock the block FO object to create the layout manager for.
Lines 97-102 Link Here
97
                                    .getOptimum(this).getLength().getValue(this);
100
                                    .getOptimum(this).getLength().getValue(this);
98
        adjustedSpaceAfter = fo.getCommonMarginBlock().spaceAfter.getSpace()
101
        adjustedSpaceAfter = fo.getCommonMarginBlock().spaceAfter.getSpace()
99
                                    .getOptimum(this).getLength().getValue(this);
102
                                    .getOptimum(this).getLength().getValue(this);
103
        orphans = fo.getOrphans();
104
        widows = fo.getWidows();
100
    }
105
    }
101
106
102
    /** {@inheritDoc} */
107
    /** {@inheritDoc} */
Lines 110-119 Link Here
110
    public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
115
    public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
111
            Position restartPosition, LayoutManager restartAtLM) {
116
            Position restartPosition, LayoutManager restartAtLM) {
112
        resetSpaces();
117
        resetSpaces();
113
        return super.getNextKnuthElements(
118
119
        List<ListElement> contentList = super.getNextKnuthElements(
114
                context, alignment, lmStack, restartPosition, restartAtLM);
120
                context, alignment, lmStack, restartPosition, restartAtLM);
115
    }
121
122
        if (!this.hasNextChildLM()) {
123
            // handle widows
124
            int boxCount = 0, index = contentList.size();
125
            ListElement current;
126
            for (ListIterator<ListElement> it = contentList.listIterator(contentList.size());
127
                    it.hasPrevious();) {
128
                current = it.previous();
129
                index--;
130
                if (current.isBox() && !((KnuthBox) current).isAuxiliary()) {
131
                    // non-auxiliary box => assume a 'line' and increase boxCount
132
                    boxCount++;
133
                    if (boxCount >= widows) {
134
                        break;
135
                    }
136
                }
137
            }
138
            if (index <= (contentList.size() - boxCount)) {
139
                ElementListUtils.removeLegalBreaks(
140
                        contentList.subList(index, contentList.size()));
141
            }
142
        }
116
143
144
        return contentList;
145
    }
146
117
    /**
147
    /**
118
     * Overridden to take into account that the childLM may be the block's
148
     * Overridden to take into account that the childLM may be the block's
119
     * {@link LineLayoutManager}.
149
     * {@link LineLayoutManager}.
Lines 132-156 Link Here
132
            // nop; will have been properly set by makeChildLayoutContext()
162
            // nop; will have been properly set by makeChildLayoutContext()
133
        }
163
        }
134
164
135
        if (childLM == this.childLMs.get(0)) {
165
        boolean isFirst = childLM == this.childLMs.get(0);
166
        if (isFirst) {
136
            childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
167
            childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
137
            //Handled already by the parent (break collapsing, see above)
168
            //Handled already by the parent (break collapsing, see above)
138
        }
169
        }
139
170
171
        List<ListElement> childElements;
140
        if (lmStack == null) {
172
        if (lmStack == null) {
141
            return childLM.getNextKnuthElements(childLC, alignment);
173
            childElements = childLM.getNextKnuthElements(childLC, alignment);
142
        } else {
174
        } else {
143
            if (childLM instanceof LineLayoutManager) {
175
            if (childLM instanceof LineLayoutManager) {
144
                assert (restartPosition instanceof LeafPosition);
176
                assert (restartPosition instanceof LeafPosition);
145
                return ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
177
                childElements = ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
146
                        (LeafPosition) restartPosition);
178
                        (LeafPosition) restartPosition);
147
            } else {
179
            } else {
148
                return childLM.getNextKnuthElements(childLC, alignment,
180
                childElements = childLM.getNextKnuthElements(childLC, alignment,
149
                        lmStack, restartPosition, restartAtLM);
181
                        lmStack, restartPosition, restartAtLM);
150
            }
182
            }
151
        }
183
        }
152
    }
184
185
        if (isFirst) {
186
            // handle orphans
187
            int boxCount = 0, endIndex = 0;
188
            ListElement current;
189
            for (ListIterator<ListElement> it = childElements.listIterator(); it.hasNext();) {
190
                current = it.next();
191
                endIndex++;
192
                if (current.isBox() && !((KnuthBox) current).isAuxiliary()) {
193
                    // non-auxiliary box => assume a 'line' and increase boxCount
194
                    boxCount++;
195
                    if (boxCount >= orphans) {
196
                        break;
197
                    }
198
                }
199
            }
200
            if (endIndex > boxCount) {
201
                ElementListUtils.removeLegalBreaks(childElements.subList(0, endIndex));
202
            }
203
        }
153
204
205
        return childElements;
206
    }
207
208
    /**
209
     * Overridden to deal with a special case for the "orphans" property.
210
     * {@inheritDoc}
211
     */
212
    @Override
213
    protected void addInBetweenBreak(List<ListElement> contentList, LayoutContext parentLC, LayoutContext childLC) {
214
215
        if (this.childLMs.size() > 1 &&
216
                this.curChildLM == this.childLMs.get(1)) {
217
            // special case: second childLM; if the first childLM did not produce enough
218
            // lines to satisfy this LM's orphans constraint, avoid adding a break possibility
219
            int boxCount = 0;
220
            for (ListElement el : contentList) {
221
                if (el.isBox() && !((KnuthBox) el).isAuxiliary()) {
222
                    boxCount++;
223
                    if (boxCount >= orphans) {
224
                        break;
225
                    }
226
                }
227
            }
228
229
            if (boxCount < orphans) {
230
                return;
231
            }
232
        }
233
234
        super.addInBetweenBreak(contentList, parentLC, childLC);
235
    }
236
154
    private void resetSpaces() {
237
    private void resetSpaces() {
155
        this.discardBorderBefore = false;
238
        this.discardBorderBefore = false;
156
        this.discardBorderAfter = false;
239
        this.discardBorderAfter = false;
(-)src/java/org/apache/fop/layoutmgr/ElementListUtils.java (-1 / +57 lines)
Lines 133-138 Link Here
133
    }
133
    }
134
134
135
    /**
135
    /**
136
     * Removes all legal break points from the given {@code List<ListElement>}.
137
     * That is, this method:<br/>
138
     * <ul>
139
     *   <li>removes penalties in between two boxes</li>
140
     *   <li>converts other penalties to inhibit breaks</li>
141
     *   <li>converts glues following a box into auxiliary boxes
142
     *       or penalty-glue sequences</li>
143
     * </ul>
144
     *
145
     * @param elements  the element list from which the breaks will be removed
146
     */
147
    public static void removeLegalBreaks(List<ListElement> elements) {
148
149
        ListElement current;
150
        boolean previousIsBox = false;
151
152
        for (ListIterator<ListElement> it = elements.listIterator(); it.hasNext();) {
153
154
            current = it.next();
155
156
            if (current.isBox()) {
157
                previousIsBox = true;
158
                continue;
159
            } else if (current.isGlue() && previousIsBox) {
160
                KnuthGlue glue = (KnuthGlue)current;
161
                if (glue.getStretch() == 0 && glue.getShrink() == 0) {
162
                    // non-stretchable glue => replace with a box of the same width
163
                    it.set(new KnuthBox(glue.getWidth(), glue.getPosition(), true));
164
                } else {
165
                    // stretchable glue => add break-inhibitor
166
                    it.previous();
167
                    it.add(KnuthPenalty.DUMMY_INFINITE_PENALTY);
168
                    it.next();
169
                }
170
            } else if (current.isPenalty() || current instanceof BreakElement
171
                        && !current.isForcedBreak()) {
172
                boolean nextIsBox = (it.hasNext() && it.next().isBox());
173
                it.previous();
174
                if (previousIsBox && nextIsBox) {
175
                    // penalty or BreakElement in between boxes => remove
176
                    it.previous();
177
                    it.remove();
178
                } else {
179
                    if (current.isPenalty()) {
180
                        ((KnuthPenalty)current).setPenalty(KnuthElement.INFINITE);
181
                    } else {
182
                        ((BreakElement)current).setPenaltyValue(KnuthElement.INFINITE);
183
                    }
184
                }
185
            }
186
            previousIsBox = false;
187
        }
188
    }
189
190
    /**
136
     * Calculates the content length of the given element list. Warning: It doesn't take any
191
     * Calculates the content length of the given element list. Warning: It doesn't take any
137
     * stretch and shrink possibilities into account.
192
     * stretch and shrink possibilities into account.
138
     * @param elems the element list
193
     * @param elems the element list
Lines 218-224 Link Here
218
        int prevBreak = startIndex - 1;
273
        int prevBreak = startIndex - 1;
219
        while (prevBreak >= 0) {
274
        while (prevBreak >= 0) {
220
            KnuthElement el = (KnuthElement)elems.get(prevBreak);
275
            KnuthElement el = (KnuthElement)elems.get(prevBreak);
221
            if (el.isPenalty() && el.getPenalty() < KnuthElement.INFINITE) {
276
            if (el.isPenalty()
277
                    && ((KnuthElement)el).getPenalty() < KnuthElement.INFINITE) {
222
                break;
278
                break;
223
            }
279
            }
224
            prevBreak--;
280
            prevBreak--;
(-)src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (-4 / +1 lines)
Lines 918-927 Link Here
918
                for (int i = 0;
918
                for (int i = 0;
919
                        i < llPoss.getChosenLineCount();
919
                        i < llPoss.getChosenLineCount();
920
                        i++) {
920
                        i++) {
921
                    if (returnList.size() > 0
921
                    if (returnList.size() > 0 && i > 0) {
922
                            && i > 0 //if i==0 break generated above already
923
                            && i >= fobj.getOrphans()
924
                            && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
925
                        // penalty allowing a page break between lines
922
                        // penalty allowing a page break between lines
926
                        Keep keep = getKeepTogether();
923
                        Keep keep = getKeepTogether();
927
                        returnList.add(new BreakElement(
924
                        returnList.add(new BreakElement(

Return to bug 44328