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

(-)src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (-15 / +31 lines)
Lines 22-27 Link Here
22
import org.apache.commons.logging.Log;
22
import org.apache.commons.logging.Log;
23
import org.apache.commons.logging.LogFactory;
23
import org.apache.commons.logging.LogFactory;
24
24
25
import org.apache.fop.fo.Constants;
25
import org.apache.fop.fo.FONode;
26
import org.apache.fop.fo.FONode;
26
27
27
/**
28
/**
Lines 156-165 Link Here
156
    private KnuthNode lastRecovered;
157
    private KnuthNode lastRecovered;
157
158
158
    /**
159
    /**
159
     * Create a new instance.
160
     * Create a new BreakingAlgorithm instance.
160
     * @param align alignment of the paragraph/page. One of EN_START, EN_JUSTIFY, etc. For
161
     *
161
     * pages EN_BEFORE, EN_AFTER are mapped to the corresponding inline properties
162
     * @param align alignment of the paragraph/page. One of {@link Constants#EN_START},
162
     * (EN_START, EN_END)
163
     * {@link Constants#EN_JUSTIFY}, etc. <i>Note: For pages, {@link Constants#EN_BEFORE}
164
     * and {@link Constants#EN_AFTER} are mapped to the corresponding inline properties
165
     * {@link Constants#EN_START} and {@link Constants#EN_END})
163
     * @param alignLast alignment of the paragraph's last line
166
     * @param alignLast alignment of the paragraph's last line
164
     * @param first for the text-indent property (indent the first line of a paragraph)
167
     * @param first for the text-indent property (indent the first line of a paragraph)
165
     * @param partOverflowRecovery true if too long elements should be moved to the next line/part
168
     * @param partOverflowRecovery true if too long elements should be moved to the next line/part
Lines 404-416 Link Here
404
        return findBreakingPoints(par, 0, threshold, force, allowedBreaks);
407
        return findBreakingPoints(par, 0, threshold, force, allowedBreaks);
405
    }
408
    }
406
    
409
    
407
    /** Finds an optimal set of breakpoints for the given paragraph.
410
    /**
411
     * Finds an optimal set of breakpoints for the given paragraph.
412
     *
408
     * @param par the paragraph to break
413
     * @param par               the paragraph to break
409
     * @param startIndex index of the Knuth element at which the breaking must start
414
     * @param startIndex        index of the {@link KnuthElement} at which
415
     *                          the breaking must start
410
     * @param threshold upper bound of the adjustment ratio
416
     * @param threshold         upper bound of the adjustment ratio
411
     * @param force true if a set of breakpoints must be found even if there are no
417
     * @param force             true if a set of breakpoints must be found
412
     * feasible ones
418
     *                          even if there are no feasible ones
413
     * @param allowedBreaks one of ONLY_FORCED_BREAKS, NO_FLAGGED_PENALTIES, ALL_BREAKS
419
     * @param allowedBreaks     one of {@link #ONLY_FORCED_BREAKS},
420
     *                          {@link #NO_FLAGGED_PENALTIES},
421
     *                          {@link #ALL_BREAKS}
422
     * @return the index of the optimal set of breakpoints
414
     */
423
     */
415
    public int findBreakingPoints(KnuthSequence par, int startIndex,
424
    public int findBreakingPoints(KnuthSequence par, int startIndex,
416
                                  double threshold, boolean force,
425
                                  double threshold, boolean force,
Lines 477-487 Link Here
477
                // only if its penalty is not infinite;
486
                // only if its penalty is not infinite;
478
                // consider all penalties, non-flagged penalties or non-forcing penalties
487
                // consider all penalties, non-flagged penalties or non-forcing penalties
479
                // according to the value of allowedBreaks
488
                // according to the value of allowedBreaks
480
                if (((KnuthPenalty) thisElement).getP() < KnuthElement.INFINITE
489
                if ((thisElement).getP() < KnuthElement.INFINITE
481
                    && (!(allowedBreaks == NO_FLAGGED_PENALTIES) 
490
                    && (!(allowedBreaks == NO_FLAGGED_PENALTIES) 
482
                            || !(((KnuthPenalty) thisElement).isFlagged()))
491
                            || !(((KnuthPenalty) thisElement).isFlagged()))
483
                    && (!(allowedBreaks == ONLY_FORCED_BREAKS) 
492
                    && (!(allowedBreaks == ONLY_FORCED_BREAKS) 
484
                            || ((KnuthPenalty) thisElement).getP() == -KnuthElement.INFINITE)) {
493
                            || (thisElement).getP() == -KnuthElement.INFINITE)) {
485
                    considerLegalBreak(thisElement, i);
494
                    considerLegalBreak(thisElement, i);
486
                }
495
                }
487
                previousIsBox = false;
496
                previousIsBox = false;
Lines 586-592 Link Here
586
        Position pos = (el != null ? el.getPosition() : null);
595
        Position pos = (el != null ? el.getPosition() : null);
587
        LayoutManager lm = (pos != null ? pos.getLM() : null);
596
        LayoutManager lm = (pos != null ? pos.getLM() : null);
588
        while (pos instanceof NonLeafPosition) {
597
        while (pos instanceof NonLeafPosition) {
589
            pos = ((NonLeafPosition)pos).getPosition();
598
            pos = pos.getPosition();
590
            if (pos != null && pos.getLM() != null) {
599
            if (pos != null && pos.getLM() != null) {
591
                lm = pos.getLM();
600
                lm = pos.getLM();
592
            }
601
            }
Lines 1141-1144 Link Here
1141
        return this.alignmentLast;
1150
        return this.alignmentLast;
1142
    }
1151
    }
1143
1152
1144
}
1153
    public int getOverflowAmount() {
1154
        return (this.totalWidth - this.totalShrink) - this.lineWidth;
1155
    }
1156
    
1157
    public int getTotalWidth() {
1158
        return this.totalWidth;
1159
    }
1160
}
(-)src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java (+578 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 * 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 * 
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id:$ */
19
20
package org.apache.fop.layoutmgr.inline;
21
22
// Java
23
import java.util.LinkedList;
24
import java.util.List;
25
import java.util.ListIterator;
26
import java.awt.geom.Rectangle2D;
27
28
import org.apache.fop.area.Area;
29
import org.apache.fop.area.Block;
30
import org.apache.fop.area.Trait;
31
import org.apache.fop.area.CTM;
32
import org.apache.fop.area.inline.InlineArea;
33
import org.apache.fop.area.inline.InlineBlockParent;
34
import org.apache.fop.area.inline.Viewport;
35
import org.apache.fop.datatypes.FODimension;
36
import org.apache.fop.datatypes.Length;
37
import org.apache.fop.fo.flow.InlineContainer;
38
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
39
import org.apache.fop.fo.properties.SpaceProperty;
40
import org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager.StackingIter;
41
import org.apache.fop.layoutmgr.AbstractBreaker;
42
import org.apache.fop.layoutmgr.ElementListObserver;
43
import org.apache.fop.layoutmgr.InlineKnuthSequence;
44
import org.apache.fop.layoutmgr.KnuthSequence;
45
import org.apache.fop.layoutmgr.LayoutContext;
46
import org.apache.fop.layoutmgr.LayoutManager;
47
import org.apache.fop.layoutmgr.LeafPosition;
48
import org.apache.fop.layoutmgr.ListElement;
49
import org.apache.fop.layoutmgr.NonLeafPosition;
50
import org.apache.fop.layoutmgr.PageBreakingAlgorithm;
51
import org.apache.fop.layoutmgr.Position;
52
import org.apache.fop.layoutmgr.PositionIterator;
53
import org.apache.fop.layoutmgr.SpaceResolver;
54
import org.apache.fop.layoutmgr.TraitSetter;
55
import org.apache.fop.traits.MinOptMax;
56
/**
57
 * This creates a single inline container area after
58
 * laying out the child block areas. All footnotes, floats
59
 * and id areas are maintained for later retrieval.
60
 */
61
public class InlineContainerLayoutManager extends LeafNodeLayoutManager {
62
63
    Viewport currentViewport;
64
    InlineArea referenceArea;
65
    Block baseBlockArea;
66
    
67
    /** The Common Border, Padding and Background properties */
68
    private CommonBorderPaddingBackground borderProps = null;
69
    /** The alignment adjust property */
70
    private Length alignmentAdjust;
71
    /** The alignment baseline property */
72
    private int alignmentBaseline = EN_BASELINE;
73
    /** The baseline shift property */
74
    private Length baselineShift;
75
    /** The dominant baseline property */
76
    private int dominantBaseline;
77
    /** The line height property */
78
    private SpaceProperty lineHeight;
79
80
    private Length height;
81
    private Length width;
82
    private boolean autoHeight;
83
    private boolean autoWidth;
84
85
    private int contentAreaBPD;
86
    private int contentAreaIPD;
87
    private int viewportContentBPD;
88
    private int referenceIPD;
89
90
    private FODimension relDims;
91
    private CTM absoluteCTM;
92
93
    private LayoutManager lastChildLM = null;
94
    
95
96
    /**
97
     * Construct a new InlineContainerLayoutManager
98
     * for the the given {@link InlineContainer}
99
     *
100
     * @param node  the base {@link InlineContainer}
101
     */
102
    public InlineContainerLayoutManager(InlineContainer node) {
103
        super(node);
104
    }
105
    
106
    /** {@inheritDoc} */
107
    public void initialize() {
108
        InlineContainer node = (InlineContainer) fobj;
109
        
110
        borderProps = node.getCommonBorderPaddingBackground();
111
        
112
        alignmentAdjust = node.getAlignmentAdjust();
113
        alignmentBaseline = node.getAlignmentBaseline();
114
        baselineShift = node.getBaselineShift();
115
        dominantBaseline = node.getDominantBaseline();
116
        
117
        boolean rotated = (node.getReferenceOrientation() % 180 != 0);
118
        if (rotated) {
119
            height = node.getInlineProgressionDimension()
120
                            .getOptimum(this).getLength();
121
            width = node.getBlockProgressionDimension()
122
                            .getOptimum(this).getLength();
123
        } else {
124
            height = node.getBlockProgressionDimension()
125
                            .getOptimum(this).getLength();
126
            width = node.getInlineProgressionDimension()
127
                            .getOptimum(this).getLength();
128
        }
129
130
    }
131
    
132
    /** {@inheritDoc} */
133
    public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
134
135
        InlineContainer ic = (InlineContainer) fobj;
136
        boolean rotated = (ic.getReferenceOrientation() % 180 != 0);
137
        autoHeight = false;
138
        int maxbpd = context.getStackLimitBP().opt;
139
        int allocBPD;
140
        if (height.getEnum() == EN_AUTO
141
                || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
142
            //auto height when height="auto" or "if that dimension is not specified explicitly
143
            //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1)
144
            allocBPD = maxbpd;
145
            autoHeight = true;
146
        } else {
147
            allocBPD = height.getValue(this); //this is the content-height
148
            allocBPD += borderProps.getBPPaddingAndBorder(false, this);
149
        }
150
        if (width.getEnum() == EN_AUTO) {
151
            autoWidth = true;
152
        }
153
        viewportContentBPD = allocBPD - borderProps.getBPPaddingAndBorder(false, this);
154
155
        referenceIPD = context.getRefIPD();
156
157
        double contentRectOffsetX = 0;
158
        //contentRectOffsetX += ic.getCommonMarginInline().spaceStart.getLength().getValue(this);
159
        double contentRectOffsetY = 0;
160
        contentRectOffsetY += borderProps.getBorderBeforeWidth(false);
161
        contentRectOffsetY += borderProps.getPaddingBefore(false, this);
162
163
        updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight);
164
165
        if (getContentAreaIPD() > referenceIPD) {
166
            InlineLevelEventProducer eventProducer
167
                    = InlineLevelEventProducer.Provider.get(
168
                        ic.getUserAgent().getEventBroadcaster());
169
            eventProducer.lineOverflows(
170
                    this, 0,
171
                    (getContentAreaIPD() - referenceIPD), ic.getLocator());
172
        }
173
174
        LinkedList returnList = new LinkedList();
175
        KnuthSequence inlineSeq = new InlineKnuthSequence();
176
        
177
        addKnuthElementsForBorderPaddingStart(inlineSeq);
178
179
        MinOptMax refIPD;
180
        if (autoWidth) {
181
            refIPD = new MinOptMax(referenceIPD);
182
        } else {
183
            refIPD = new MinOptMax(width.getValue(this));
184
        }
185
        InlineContainerBreaker breaker = new InlineContainerBreaker(this, refIPD);
186
        breaker.doLayout(height.getValue(this), autoHeight);
187
188
        if (!breaker.isEmpty()) {
189
            if (autoHeight) {
190
                //Update content BPD now that it is known
191
                int newHeight = breaker.deferredAlg.getTotalWidth();
192
                if (rotated) {
193
                    setContentAreaIPD(newHeight);
194
                } else {
195
                    viewportContentBPD = newHeight;
196
                }
197
                updateRelDims(contentRectOffsetX, contentRectOffsetY, false);
198
            }
199
200
            Position icPosition = new InlineContainerPosition(this, breaker);
201
            inlineSeq.add(new KnuthInlineBox(refIPD.opt, makeAlignmentContext(context), notifyPos(icPosition), false));
202
        }
203
204
        addKnuthElementsForBorderPaddingEnd(inlineSeq);
205
206
        returnList.add(inlineSeq);
207
        
208
        setFinished(true);
209
        
210
        return returnList;
211
    }
212
213
    /** {@inheritDoc} */
214
    public void addChildArea(Area childArea) {
215
        baseBlockArea.addBlock((Block) childArea);
216
    }
217
218
    /** {@inheritDoc} */
219
    public void addAreas(PositionIterator posIter, LayoutContext context) {
220
221
        /* "Unwrap" the NonLeafPositions stored in parentIter and put
222
         * them in a new list.  Set lastLM to be the LayoutManager
223
         * which created the last Position: if the LAST_AREA flag is
224
         * set in the layout context, it must be also set in the
225
         * layout context given to lastLM, but must be cleared in the
226
         * layout context given to the other LMs. */
227
        LinkedList positionList = new LinkedList();
228
        Position pos;
229
        LayoutManager lastLM = null;// last child LM in this iterator
230
        Position lastPos = null;
231
        InlineContainerPosition icPos = null;
232
        while (posIter.hasNext()) {
233
            pos = (Position) posIter.next();
234
            if (pos instanceof InlineContainerPosition) {
235
                assert (icPos == null);
236
                icPos = (InlineContainerPosition)pos;
237
            }
238
            if (pos != null && pos.getPosition() != null) {
239
                positionList.add(pos.getPosition());
240
                lastLM = pos.getPosition().getLM();
241
                lastPos = pos;
242
            }
243
        }
244
245
        addId();
246
        addMarkersToPage(
247
                true, 
248
                true, 
249
                lastPos == null || isLast(lastPos));
250
251
        LayoutManager prevLM = null;
252
253
        if (icPos == null) {
254
            StackingIter childPosIter
255
                = new StackingIter(positionList.listIterator());
256
257
            LayoutManager childLM;
258
            while ((childLM = childPosIter.getNextChildLM()) != null) {
259
                context.setFlags(LayoutContext.LAST_AREA,
260
                                      context.isLastArea() && childLM == lastLM);
261
                childLM.addAreas(childPosIter, context);
262
                context.setLeadingSpace(context.getTrailingSpace());
263
                context.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
264
                prevLM = childLM;
265
            }
266
267
            currentViewport.setContent(referenceArea);
268
            parentLM.addChildArea(currentViewport);
269
        } else {
270
            icPos.breaker.addContainedAreas();
271
        }
272
273
        addMarkersToPage(
274
                false, 
275
                true, 
276
                lastPos == null || isLast(lastPos));
277
        
278
        boolean isLast = (context.isLastArea() && prevLM == lastChildLM);
279
        context.setFlags(LayoutContext.LAST_AREA, isLast);
280
    }
281
282
    /** {@inheritDoc} */
283
    public int getContentAreaIPD() {
284
        return width.getEnum() == EN_AUTO
285
                ? referenceIPD
286
                    : width.getValue(this);
287
    }
288
289
    /**
290
     * Sets the IPD of the content area
291
     * @param contentAreaIPD the IPD of the content area
292
     */
293
    private void setContentAreaIPD(int contentAreaIPD) {
294
        this.contentAreaIPD = contentAreaIPD;
295
    }
296
297
    /** {@inheritDoc} */
298
    public int getContentAreaBPD() {
299
        return height.getEnum() == EN_AUTO
300
                ? viewportContentBPD 
301
                    : height.getValue(this);
302
    }
303
    
304
    /**
305
     * Get the parent area for children of this inline-container.
306
     * This returns the current inline-container area
307
     * and creates it if required.
308
     *
309
     * {@inheritDoc}
310
     */
311
    public Area getParentArea(Area childArea) {
312
        if (referenceArea == null) {
313
            currentViewport = new Viewport(childArea);
314
            currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
315
            currentViewport.setIPD(getContentAreaIPD());
316
            currentViewport.setBPD(getContentAreaBPD());
317
            
318
            TraitSetter.setProducerID(currentViewport, fobj.getId());
319
            TraitSetter.addBorders(currentViewport, 
320
                    borderProps, 
321
                    false, false, false, false, this);
322
            TraitSetter.addPadding(currentViewport, 
323
                    borderProps, 
324
                    false, false, false, false, this);
325
            TraitSetter.addBackground(currentViewport, 
326
                    borderProps,
327
                    this);
328
329
            currentViewport.setCTM(absoluteCTM);
330
            currentViewport.setClip(needClip());
331
            currentViewport.setContentPosition(
332
                    new java.awt.geom.Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD()));
333
            referenceArea = new InlineBlockParent();
334
            referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
335
            TraitSetter.setProducerID(referenceArea, fobj.getId());
336
            // Set up dimensions
337
            // Must get dimensions from parent area
338
            parentLM.getParentArea(referenceArea);
339
            referenceArea.setIPD(referenceIPD);
340
            baseBlockArea = new Block();
341
            referenceArea.addChildArea(baseBlockArea);
342
            // Get reference IPD from parentArea
343
            setCurrentArea(currentViewport); // ??? for generic operations
344
        }
345
        return referenceArea;
346
    }
347
    
348
    private boolean needClip() {
349
        int overflow = ((InlineContainer) fobj).getOverflow();
350
        return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW);
351
    }
352
    
353
    /**
354
     * {@inheritDoc}
355
     */
356
    protected AlignmentContext makeAlignmentContext(LayoutContext context) {
357
        return new AlignmentContext(
358
                viewportContentBPD
359
                , alignmentAdjust
360
                , alignmentBaseline
361
                , baselineShift
362
                , dominantBaseline
363
                , context.getAlignmentContext()
364
            );
365
    }
366
367
    /**
368
     * Get the allocation ipd of the inline area.
369
     * This method may be overridden to handle percentage values.
370
     * @param refIPD the ipd of the parent reference area
371
     * @return the min/opt/max ipd of the inline area
372
     */
373
    protected MinOptMax getAllocationIPD(int refIPD) {
374
        return new MinOptMax(curArea.getIPD());
375
    }
376
377
    /**
378
     * "wrap" the Position inside each element moving the elements from
379
     * SourceList to targetList
380
     * @param sourceList source list
381
     * @param targetList target list receiving the wrapped position elements
382
     */
383
    protected void wrapPositionElements(List sourceList, List targetList) {
384
        wrapPositionElements(sourceList, targetList, false);
385
    }
386
387
    /**
388
     * "wrap" the Position inside each element moving the elements from
389
     * SourceList to targetList
390
     * @param sourceList source list
391
     * @param targetList target list receiving the wrapped position elements
392
     * @param force if true, every Position is wrapped regardless of its LM of origin
393
     */
394
    protected void wrapPositionElements(List sourceList, List targetList, boolean force) {
395
396
        ListIterator listIter = sourceList.listIterator();
397
        Object tempElement;
398
        while (listIter.hasNext()) {
399
            tempElement = listIter.next();
400
            if (tempElement instanceof ListElement) {
401
                wrapPositionElement(
402
                        (ListElement) tempElement,
403
                        targetList,
404
                        force);
405
            } else if (tempElement instanceof List) {
406
                wrapPositionElements(
407
                        (List) tempElement,
408
                        targetList,
409
                        force);
410
            }
411
        }
412
    }
413
414
    /**
415
     * "wrap" the Position inside the given element and add it to the target list.
416
     * @param el the list element
417
     * @param targetList target list receiving the wrapped position elements
418
     * @param force if true, every Position is wrapped regardless of its LM of origin
419
     */
420
    protected void wrapPositionElement(ListElement el, List targetList, boolean force) {
421
        if (force || el.getLayoutManager() != this) {
422
            el.setPosition(notifyPos(new NonLeafPosition(this,
423
                    el.getPosition())));
424
        }
425
        targetList.add(el);
426
    }
427
428
    private void updateRelDims(double xOffset, double yOffset, boolean skipAutoHeight) {
429
        Rectangle2D rect = new Rectangle2D.Double(
430
                xOffset, yOffset,
431
                getContentAreaIPD(),
432
                this.viewportContentBPD);
433
        relDims = new FODimension(0, 0);
434
        absoluteCTM = CTM.getCTMandRelDims(
435
                ((InlineContainer) fobj).getReferenceOrientation(),
436
                ((InlineContainer) fobj).getWritingMode(),
437
                rect, relDims);
438
    }
439
440
    private class InlineContainerPosition extends LeafPosition {
441
442
        private InlineContainerBreaker breaker;
443
444
        public InlineContainerPosition(LayoutManager lm, InlineContainerBreaker breaker) {
445
            super(lm, 0);
446
            this.breaker = breaker;
447
        }
448
449
        public InlineContainerBreaker getBreaker() {
450
            return this.breaker;
451
        }
452
453
    }
454
455
    private class InlineContainerBreaker extends AbstractBreaker {
456
457
        private InlineContainerLayoutManager iclm;
458
        private MinOptMax ipd;
459
460
        //Info for deferred adding of areas
461
        private PageBreakingAlgorithm deferredAlg;
462
        private BlockSequence deferredOriginalList;
463
        private BlockSequence deferredEffectiveList;
464
465
        public InlineContainerBreaker(InlineContainerLayoutManager iclm, MinOptMax ipd) {
466
            this.iclm = iclm;
467
            this.ipd = ipd;
468
        }
469
470
        /** {@inheritDoc} */
471
        protected void observeElementList(List elementList) {
472
            ElementListObserver.observe(
473
                    elementList,
474
                    "inline-container",
475
                    iclm.fobj.getId());
476
        }
477
478
        /** {@inheritDoc} */
479
        protected boolean isPartOverflowRecoveryActivated() {
480
            return false;
481
        }
482
483
        /** {@inheritDoc} */
484
        protected boolean isSinglePartFavored() {
485
            return true;
486
        }
487
488
        int getDifferenceOfFirstPart() {
489
            PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst();
490
            return pbp.getDifference();
491
        }
492
493
        boolean isOverflow() {
494
            return !isEmpty()
495
                    && ((deferredAlg.getPageBreaks().size() > 1)
496
                        || (deferredAlg.getOverflowAmount() > 0));
497
        }
498
499
        int getOverflowAmount() {
500
            return deferredAlg.getOverflowAmount();
501
        }
502
503
        protected LayoutManager getTopLevelLM() {
504
            return iclm;
505
        }
506
507
        protected LayoutContext createLayoutContext() {
508
            LayoutContext lc = super.createLayoutContext();
509
            lc.setRefIPD(ipd.opt);
510
            lc.setWritingMode(((InlineContainer) fobj).getWritingMode());
511
            return lc;
512
        }
513
514
        protected LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
515
            LayoutManager curLM; // currently active LM
516
            LinkedList returnList = new LinkedList();
517
518
            while ((curLM = getChildLM()) != null) {
519
                LayoutContext childLC = new LayoutContext(0);
520
                childLC.setStackLimitBP(context.getStackLimitBP());
521
                childLC.setRefIPD(context.getRefIPD());
522
                childLC.setWritingMode(((InlineContainer)fobj).getWritingMode());
523
524
                LinkedList returnedList = null;
525
                if (!curLM.isFinished()) {
526
                    returnedList = curLM.getNextKnuthElements(childLC, alignment);
527
                }
528
                if (returnedList != null) {
529
                    iclm.wrapPositionElements(returnedList, returnList);
530
                }
531
            }
532
            SpaceResolver.resolveElementList(returnList);
533
            setFinished(true);
534
            return returnList;
535
        }
536
537
        protected int getCurrentDisplayAlign() {
538
            return ((InlineContainer)fobj).getDisplayAlign();
539
        }
540
541
        protected boolean hasMoreContent() {
542
            return !isFinished();
543
        }
544
545
        protected void addAreas(PositionIterator posIter, LayoutContext context) {
546
            iclm.addAreas(posIter, context);
547
        }
548
549
        protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
550
                BlockSequence originalList, BlockSequence effectiveList) {
551
            //Defer adding of areas until addAreas is called by the parent LM
552
            this.deferredAlg = alg;
553
            this.deferredOriginalList = originalList;
554
            this.deferredEffectiveList = effectiveList;
555
        }
556
557
        protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
558
            //nop for bclm
559
        }
560
561
        protected LayoutManager getCurrentChildLM() {
562
            return curChildLM;
563
        }
564
565
        public void addContainedAreas() {
566
            if (isEmpty()) {
567
                return;
568
            }
569
            //Rendering all parts (not just the first) at once for the case where the parts that
570
            //overflow should be visible.
571
            this.deferredAlg.removeAllPageBreaks();
572
            this.addAreas(this.deferredAlg,
573
                          this.deferredAlg.getPageBreaks().size(),
574
                          this.deferredOriginalList, this.deferredEffectiveList);
575
        }
576
577
    }
578
}
(-)src/java/org/apache/fop/fo/flow/InlineContainer.java (-1 / +7 lines)
Lines 48-53 Link Here
48
    private CommonBorderPaddingBackground commonBorderPaddingBackground;
48
    private CommonBorderPaddingBackground commonBorderPaddingBackground;
49
    private CommonMarginInline commonMarginInline;
49
    private CommonMarginInline commonMarginInline;
50
    private int clip;
50
    private int clip;
51
    private int displayAlign;
51
    private int dominantBaseline;
52
    private int dominantBaseline;
52
    private LengthRangeProperty inlineProgressionDimension;
53
    private LengthRangeProperty inlineProgressionDimension;
53
    private KeepProperty keepTogether;
54
    private KeepProperty keepTogether;
Lines 57-63 Link Here
57
    private int writingMode;
58
    private int writingMode;
58
    // Unused but valid items, commented out for performance:
59
    // Unused but valid items, commented out for performance:
59
    //     private CommonRelativePosition commonRelativePosition;
60
    //     private CommonRelativePosition commonRelativePosition;
60
    //     private int displayAlign;
61
    //     private Length height;
61
    //     private Length height;
62
    //     private KeepProperty keepWithNext;
62
    //     private KeepProperty keepWithNext;
63
    //     private KeepProperty keepWithPrevious;
63
    //     private KeepProperty keepWithPrevious;
Lines 86-91 Link Here
86
        commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
86
        commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
87
        commonMarginInline = pList.getMarginInlineProps();
87
        commonMarginInline = pList.getMarginInlineProps();
88
        clip = pList.get(PR_CLIP).getEnum();
88
        clip = pList.get(PR_CLIP).getEnum();
89
        displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
89
        dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
90
        dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
90
        inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
91
        inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
91
        keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
92
        keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
Lines 156-161 Link Here
156
        return this.commonMarginInline;
157
        return this.commonMarginInline;
157
    }
158
    }
158
159
160
    /** @return the value of the <code>display-align</code> property */
161
    public int getDisplayAlign() {
162
        return this.displayAlign;
163
    }
164
159
    /** @return the "dominant-baseline" property */
165
    /** @return the "dominant-baseline" property */
160
    public int getDominantBaseline() {
166
    public int getDominantBaseline() {
161
        return dominantBaseline;
167
        return dominantBaseline;
(-)src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (-12 / +16 lines)
Lines 56-62 Link Here
56
            footnoteLastListIndex = flli;
56
            footnoteLastListIndex = flli;
57
            footnoteLastElementIndex = flei;
57
            footnoteLastElementIndex = flei;
58
        }
58
        }
59
    }
59
60
        /**
61
         * Accessor for the difference member
62
         *
63
         * @return the difference
64
         */
65
        public int getDifference() {
66
            return difference;
67
        }
68
    }
60
69
61
    public class BlockSequence extends BlockKnuthSequence {
70
    public class BlockSequence extends BlockKnuthSequence {
62
71
Lines 445-452 Link Here
445
                    .listIterator(startElementIndex);
454
                    .listIterator(startElementIndex);
446
            KnuthElement firstElement;
455
            KnuthElement firstElement;
447
            while (effectiveListIterator.hasNext()
456
            while (effectiveListIterator.hasNext()
448
                    && !(firstElement = (KnuthElement) effectiveListIterator.next())
457
                    && !(((KnuthElement)effectiveListIterator.next()).isBox())) {
449
                            .isBox()) {
450
                /*
458
                /*
451
                if (firstElement.isGlue() && firstElement.getLayoutManager() != null) {
459
                if (firstElement.isGlue() && firstElement.getLayoutManager() != null) {
452
                    // discard the space representd by the glue element
460
                    // discard the space representd by the glue element
Lines 633-639 Link Here
633
        }
641
        }
634
        int averageLineLength = 0;
642
        int averageLineLength = 0;
635
        if (accumulatedLineLength > 0 && boxCount > 0) {
643
        if (accumulatedLineLength > 0 && boxCount > 0) {
636
            averageLineLength = (int) (accumulatedLineLength / boxCount);
644
            averageLineLength = (accumulatedLineLength / boxCount);
637
            log.debug("Average line length = " + averageLineLength);
645
            log.debug("Average line length = " + averageLineLength);
638
            if (averageLineLength < greatestMinimumLength) {
646
            if (averageLineLength < greatestMinimumLength) {
639
                averageLineLength = greatestMinimumLength;
647
                averageLineLength = greatestMinimumLength;
Lines 727-736 Link Here
727
                        break;
735
                        break;
728
                    case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT:
736
                    case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT:
729
                        // potential line number adjustment
737
                        // potential line number adjustment
730
                        lineNumberMaxAdjustment.max += ((KnuthGlue) thisElement)
738
                        lineNumberMaxAdjustment.max += thisElement.getY();
731
                                .getY();
739
                        lineNumberMaxAdjustment.min -= thisElement.getZ();
732
                        lineNumberMaxAdjustment.min -= ((KnuthGlue) thisElement)
733
                                .getZ();
734
                        adjustableLinesList.add(thisElement);
740
                        adjustableLinesList.add(thisElement);
735
                        break;
741
                        break;
736
                    case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT:
742
                    case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT:
Lines 751-760 Link Here
751
                        while (unconfirmedList.size() > 0) {
757
                        while (unconfirmedList.size() > 0) {
752
                            KnuthGlue blockSpace = (KnuthGlue) unconfirmedList
758
                            KnuthGlue blockSpace = (KnuthGlue) unconfirmedList
753
                                    .removeFirst();
759
                                    .removeFirst();
754
                            spaceMaxAdjustment.max += ((KnuthGlue) blockSpace)
760
                            spaceMaxAdjustment.max += blockSpace.getY();
755
                                    .getY();
761
                            spaceMaxAdjustment.min -= blockSpace.getZ();
756
                            spaceMaxAdjustment.min -= ((KnuthGlue) blockSpace)
757
                                    .getZ();
758
                            blockSpacesList.add(blockSpace);
762
                            blockSpacesList.add(blockSpace);
759
                        }
763
                        }
760
                    }
764
                    }
(-)src/java/org/apache/fop/render/AbstractRenderer.java (-2 / +3 lines)
Lines 398-404 Link Here
398
        for (int count = 0; count < spans.size(); count++) {
398
        for (int count = 0; count < spans.size(); count++) {
399
            span = (Span) spans.get(count);
399
            span = (Span) spans.get(count);
400
            for (int c = 0; c < span.getColumnCount(); c++) {
400
            for (int c = 0; c < span.getColumnCount(); c++) {
401
                NormalFlow flow = (NormalFlow) span.getNormalFlow(c);
401
                NormalFlow flow = span.getNormalFlow(c);
402
402
403
                if (flow != null) {
403
                if (flow != null) {
404
                    currentBPPosition = saveSpanBPPos;
404
                    currentBPPosition = saveSpanBPPos;
Lines 718-724 Link Here
718
        currentIPPosition += ibp.getBorderAndPaddingWidthStart();
718
        currentIPPosition += ibp.getBorderAndPaddingWidthStart();
719
        // For inline content the BP position is updated by the enclosing line area
719
        // For inline content the BP position is updated by the enclosing line area
720
        int saveBP = currentBPPosition;
720
        int saveBP = currentBPPosition;
721
        currentBPPosition += ibp.getOffset();
722
        renderBlock(ibp.getChildArea());
721
        renderBlock(ibp.getChildArea());
723
        currentBPPosition = saveBP;
722
        currentBPPosition = saveBP;
724
    }
723
    }
Lines 738-743 Link Here
738
            renderContainer((Container) content);
737
            renderContainer((Container) content);
739
        } else if (content instanceof ForeignObject) {
738
        } else if (content instanceof ForeignObject) {
740
            renderForeignObject((ForeignObject) content, contpos);
739
            renderForeignObject((ForeignObject) content, contpos);
740
        } else if (content instanceof InlineBlockParent) {
741
            renderInlineBlockParent((InlineBlockParent) content);
741
        }
742
        }
742
        currentIPPosition += viewport.getAllocIPD();
743
        currentIPPosition += viewport.getAllocIPD();
743
        currentBPPosition = saveBP;
744
        currentBPPosition = saveBP;
(-)src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (-5 / +2 lines)
Lines 72-78 Link Here
72
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
72
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
73
import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
73
import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
74
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
74
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
75
import org.apache.fop.layoutmgr.inline.ICLayoutManager;
75
import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
76
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
76
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
77
import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
77
import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
78
import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM;
78
import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM;
Lines 218-224 Link Here
218
    public static class Maker {
218
    public static class Maker {
219
        public void make(FONode node, List lms) {
219
        public void make(FONode node, List lms) {
220
            // no layout manager
220
            // no layout manager
221
            return;
222
        }
221
        }
223
    }
222
    }
224
223
Lines 283-291 Link Here
283
282
284
    public static class InlineContainerLayoutManagerMaker extends Maker {
283
    public static class InlineContainerLayoutManagerMaker extends Maker {
285
        public void make(FONode node, List lms) {
284
        public void make(FONode node, List lms) {
286
            ArrayList childList = new ArrayList();
285
            lms.add(new InlineContainerLayoutManager((InlineContainer) node));
287
            super.make(node, childList);
288
            lms.add(new ICLayoutManager((InlineContainer) node, childList));
289
        }
286
        }
290
    }
287
    }
291
288
(-)src/java/org/apache/fop/area/inline/Viewport.java (+24 lines)
Lines 20-25 Link Here
20
package org.apache.fop.area.inline;
20
package org.apache.fop.area.inline;
21
21
22
import org.apache.fop.area.Area;
22
import org.apache.fop.area.Area;
23
import org.apache.fop.area.CTM;
23
24
24
import java.io.IOException;
25
import java.io.IOException;
25
import java.awt.geom.Rectangle2D;
26
import java.awt.geom.Rectangle2D;
Lines 38-43 Link Here
38
    private boolean clip = false;
39
    private boolean clip = false;
39
    // position of the child area relative to this area
40
    // position of the child area relative to this area
40
    private Rectangle2D contentPosition;
41
    private Rectangle2D contentPosition;
42
    // transform if rotated
43
    private CTM viewportCTM;
41
44
42
    /**
45
    /**
43
     * Create a new viewport area with the content area.
46
     * Create a new viewport area with the content area.
Lines 67-72 Link Here
67
    }
70
    }
68
71
69
    /**
72
    /**
73
     * Set the transform of this viewport.
74
     * If the viewport is rotated, this transform will do the work.
75
     *
76
     * @param ctm the transformation
77
     */
78
    public void setCTM(CTM ctm) {
79
        viewportCTM = ctm;
80
    }
81
82
    /**
83
     * Get the transform of this viewport.
84
     *
85
     * @return the transformation of this viewport
86
     *         or null if normally stacked without rotation
87
     */
88
    public CTM getCTM() {
89
        return viewportCTM;
90
    }
91
92
93
    /**
70
     * Set the position and size of the content of this viewport.
94
     * Set the position and size of the content of this viewport.
71
     *
95
     *
72
     * @param cp the position and size to place the content
96
     * @param cp the position and size to place the content
(-)src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (-2 / +2 lines)
Lines 31-37 Link Here
31
import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
31
import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
32
import org.apache.fop.traits.MinOptMax;
32
import org.apache.fop.traits.MinOptMax;
33
33
34
class PageBreakingAlgorithm extends BreakingAlgorithm {
34
public class PageBreakingAlgorithm extends BreakingAlgorithm {
35
35
36
    /** the logger for the class */
36
    /** the logger for the class */
37
    private static Log log = LogFactory.getLog(PageBreakingAlgorithm.class);
37
    private static Log log = LogFactory.getLog(PageBreakingAlgorithm.class);
Lines 313-319 Link Here
313
                                    int elementIndex) {
313
                                    int elementIndex) {
314
        KnuthPageNode pageNode = (KnuthPageNode) activeNode;
314
        KnuthPageNode pageNode = (KnuthPageNode) activeNode;
315
        int actualWidth = totalWidth - pageNode.totalWidth;
315
        int actualWidth = totalWidth - pageNode.totalWidth;
316
        int footnoteSplit;
316
        int footnoteSplit = 0;
317
        boolean canDeferOldFootnotes;
317
        boolean canDeferOldFootnotes;
318
        if (element.isPenalty()) {
318
        if (element.isPenalty()) {
319
            actualWidth += element.getW();
319
            actualWidth += element.getW();

Return to bug 44885