From f8e822efe1de8bd8192dbb8ff035b9a79f876614 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Mon, 29 Jul 2013 21:45:20 +0000 Subject: Directly use FOP fonts to lay out SVG images for PDF, PS and AFP outputs. The metrics are now taken from FOP configured fonts and no longer from AWT equivalents. That avoids discrepancies in case AWT and FOP use slightly different fonts, or if the font is not installed on the system. That actually also avoids having to install the font on the system. FOP is also used for the primary layout of text (prior to SVG-specific transforms like translation or rotation) for consistency between SVG and XSL-FO. This is a joint work from Peter Hancock and myself. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_FopFontsForSVG@1508208 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fo/FOText.java | 94 +--------------------------------- 1 file changed, 2 insertions(+), 92 deletions(-) (limited to 'src/java/org/apache/fop/fo') diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java index 2fc998c63..0b7dde212 100644 --- a/src/java/org/apache/fop/fo/FOText.java +++ b/src/java/org/apache/fop/fo/FOText.java @@ -21,7 +21,6 @@ package org.apache.fop.fo; import java.awt.Color; import java.nio.CharBuffer; -import java.util.Map; import java.util.NoSuchElementException; import java.util.Stack; @@ -38,12 +37,13 @@ import org.apache.fop.fo.properties.CommonTextDecoration; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.fonts.TextFragment; import org.apache.fop.util.CharUtilities; /** * A text node (PCDATA) in the formatting object tree. */ -public class FOText extends FONode implements CharSequence { +public class FOText extends FONode implements CharSequence, TextFragment { /** the CharBuffer containing the text */ private CharBuffer charBuffer; @@ -93,9 +93,6 @@ public class FOText extends FONode implements CharSequence { /* bidi levels */ private int[] bidiLevels; - /* advanced script processing state */ - private Map/**/ mappings; - private static final int IS_WORD_CHAR_FALSE = 0; private static final int IS_WORD_CHAR_TRUE = 1; private static final int IS_WORD_CHAR_MAYBE = 2; @@ -804,93 +801,6 @@ public class FOText extends FONode implements CharSequence { } } - /** - * Add characters mapped by script substitution processing. - * @param start index in character buffer - * @param end index in character buffer - * @param mappedChars sequence of character codes denoting substituted characters - */ - public void addMapping(int start, int end, CharSequence mappedChars) { - if (mappings == null) { - mappings = new java.util.HashMap(); - } - mappings.put(new MapRange(start, end), mappedChars.toString()); - } - - /** - * Determine if characters over specific interval have a mapping. - * @param start index in character buffer - * @param end index in character buffer - * @return true if a mapping exist such that the mapping's interval is coincident to - * [start,end) - */ - public boolean hasMapping(int start, int end) { - return (mappings != null) && (mappings.containsKey(new MapRange(start, end))); - } - - /** - * Obtain mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return a string of characters representing the mapping over the interval - * [start,end) - */ - public String getMapping(int start, int end) { - if (mappings != null) { - return (String) mappings.get(new MapRange(start, end)); - } else { - return null; - } - } - - /** - * Obtain length of mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return the length of the mapping (if present) or zero - */ - public int getMappingLength(int start, int end) { - if (mappings != null) { - return ((String) mappings.get(new MapRange(start, end))) .length(); - } else { - return 0; - } - } - - /** - * Obtain bidirectional levels of mapping of characters over specific interval. - * @param start index in character buffer - * @param end index in character buffer - * @return a (possibly empty) array of bidi levels or null - * in case no bidi levels have been assigned - */ - public int[] getMappingBidiLevels(int start, int end) { - if (hasMapping(start, end)) { - int nc = end - start; - int nm = getMappingLength(start, end); - int[] la = getBidiLevels(start, end); - if (la == null) { - return null; - } else if (nm == nc) { // mapping is same length as mapped range - return la; - } else if (nm > nc) { // mapping is longer than mapped range - int[] ma = new int [ nm ]; - System.arraycopy(la, 0, ma, 0, la.length); - for (int i = la.length, - n = ma.length, l = (i > 0) ? la [ i - 1 ] : 0; i < n; i++) { - ma [ i ] = l; - } - return ma; - } else { // mapping is shorter than mapped range - int[] ma = new int [ nm ]; - System.arraycopy(la, 0, ma, 0, ma.length); - return ma; - } - } else { - return getBidiLevels(start, end); - } - } - @Override protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) { if (currentRange != null) { -- cgit v1.2.3 From bd45787c63fcae138d6cdb28a1250396ccebbda0 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Mon, 21 Oct 2013 13:24:55 +0000 Subject: First bits of support for fo:inline-container git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_InlineContainer@1534143 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/fo/flow/InlineContainer.java | 164 ++++++-------- .../apache/fop/layoutmgr/LayoutManagerMapping.java | 12 +- .../fop/layoutmgr/inline/ICLayoutManager.java | 54 ----- .../inline/InlineContainerLayoutManager.java | 237 +++++++++++++++++++++ .../standard-testcases/inline-container_basic.xml | 56 +++++ 5 files changed, 361 insertions(+), 162 deletions(-) delete mode 100644 src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java create mode 100644 test/layoutengine/standard-testcases/inline-container_basic.xml (limited to 'src/java/org/apache/fop/fo') diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index 748eb593a..d3a80eb3f 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -29,6 +29,7 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; @@ -37,78 +38,72 @@ import org.apache.fop.traits.Direction; import org.apache.fop.traits.WritingMode; import org.apache.fop.traits.WritingModeTraits; -/** - * Class modelling the - * fo:inline-container object. - */ public class InlineContainer extends FObj { - // The value of FO traits (refined properties) that apply to fo:inline-container. - private Length alignmentAdjust; - private int alignmentBaseline; - private Length baselineShift; + private LengthRangeProperty inlineProgressionDimension; private LengthRangeProperty blockProgressionDimension; + private int overflow; private CommonBorderPaddingBackground commonBorderPaddingBackground; private CommonMarginInline commonMarginInline; - private int clip; - private int dominantBaseline; - private LengthRangeProperty inlineProgressionDimension; + private Numeric referenceOrientation; + private int displayAlign; private KeepProperty keepTogether; + private KeepProperty keepWithNext; + private KeepProperty keepWithPrevious; private SpaceProperty lineHeight; - private int overflow; - private Numeric referenceOrientation; + private Length alignmentAdjust; + private int alignmentBaseline; + private Length baselineShift; + private int dominantBaseline; private WritingModeTraits writingModeTraits; - // Unused but valid items, commented out for performance: - // private CommonRelativePosition commonRelativePosition; - // private int displayAlign; - // private Length height; - // private KeepProperty keepWithNext; - // private KeepProperty keepWithPrevious; - // private Length width; - // End of FO trait values /** used for FO validation */ - private boolean blockItemFound = false; + private boolean blockItemFound; + private CommonFont commonFont; /** - * Base constructor + * Creates a new instance. * - * @param parent {@link FONode} that is the parent of this object + * @param parent the parent of this inline-container */ public InlineContainer(FONode parent) { super(parent); } - /** {@inheritDoc} */ + @Override public void bind(PropertyList pList) throws FOPException { super.bind(pList); + commonFont = pList.getFontProps(); // TODO get directly from parent? alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum(); baselineShift = pList.get(PR_BASELINE_SHIFT).getLength(); blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange(); commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps(); commonMarginInline = pList.getMarginInlineProps(); - clip = pList.get(PR_CLIP).getEnum(); + displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum(); dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum(); inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); + keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); + keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); overflow = pList.get(PR_OVERFLOW).getEnum(); referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric(); writingModeTraits = new WritingModeTraits( - WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum())); + WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum())); } /** * {@inheritDoc} *
XSL Content Model: marker* (%block;)+ */ + @Override protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { if (localName.equals("marker")) { if (blockItemFound) { - nodesOutOfOrderError(loc, "fo:marker", "(%block;)"); + nodesOutOfOrderError(loc, "fo:marker", "(%block;)+"); } } else if (!isBlockItem(nsURI, localName)) { invalidChildError(loc, nsURI, localName); @@ -118,142 +113,109 @@ public class InlineContainer extends FObj { } } - /** {@inheritDoc} */ + @Override public void endOfNode() throws FOPException { if (!blockItemFound) { missingChildElementError("marker* (%block;)+"); } } - /** @return the "alignment-adjust" FO trait */ - public Length getAlignmentAdjust() { - return alignmentAdjust; + /** {@inheritDoc} */ + public String getLocalName() { + return "inline-container"; } - /** @return the "alignment-baseline" FO trait */ - public int getAlignmentBaseline() { - return alignmentBaseline; + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} + */ + public int getNameId() { + return FO_INLINE_CONTAINER; } - /** @return the "baseline-shift" FO trait */ - public Length getBaselineShift() { - return baselineShift; + public LengthRangeProperty getInlineProgressionDimension() { + return inlineProgressionDimension; } - /** @return the "block-progression-dimension" FO trait */ public LengthRangeProperty getBlockProgressionDimension() { return blockProgressionDimension; } - /** @return the "clip" FO trait */ - public int getClip() { - return clip; + public int getOverflow() { + return overflow; } - /**@return Returns the {@link CommonBorderPaddingBackground} */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { return this.commonBorderPaddingBackground; } - /** @return Returns the {@link CommonMarginInline} */ public CommonMarginInline getCommonMarginInline() { return this.commonMarginInline; } - /** @return the "dominant-baseline" FO trait */ - public int getDominantBaseline() { - return dominantBaseline; + public int getReferenceOrientation() { + return referenceOrientation.getValue(); } - /** @return the "keep-together" FO trait */ - public KeepProperty getKeepTogether() { - return keepTogether; + public int getDisplayAlign() { + return this.displayAlign; } - /** @return the "inline-progression-dimension" FO trait */ - public LengthRangeProperty getInlineProgressionDimension() { - return inlineProgressionDimension; + public KeepProperty getKeepTogether() { + return keepTogether; } - /** @return the "line-height" FO trait */ public SpaceProperty getLineHeight() { return lineHeight; } - /** @return the "overflow" FO trait */ - public int getOverflow() { - return overflow; + public Length getAlignmentAdjust() { + return alignmentAdjust; } - /** @return the "reference-orientation" FO trait */ - public int getReferenceOrientation() { - return referenceOrientation.getValue(); + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + public Length getBaselineShift() { + return baselineShift; + } + + public int getDominantBaseline() { + return dominantBaseline; + } + + public WritingMode getWritingMode() { + return writingModeTraits.getWritingMode(); } - /** - * Obtain inline progression direction. - * @return the inline progression direction - */ public Direction getInlineProgressionDirection() { return writingModeTraits.getInlineProgressionDirection(); } - /** - * Obtain block progression direction. - * @return the block progression direction - */ public Direction getBlockProgressionDirection() { return writingModeTraits.getBlockProgressionDirection(); } - /** - * Obtain column progression direction. - * @return the column progression direction - */ public Direction getColumnProgressionDirection() { return writingModeTraits.getColumnProgressionDirection(); } - /** - * Obtain row progression direction. - * @return the row progression direction - */ public Direction getRowProgressionDirection() { return writingModeTraits.getRowProgressionDirection(); } - /** - * Obtain (baseline) shift direction. - * @return the (baseline) shift direction - */ public Direction getShiftDirection() { return writingModeTraits.getShiftDirection(); } - /** - * Obtain writing mode. - * @return the writing mode - */ - public WritingMode getWritingMode() { - return writingModeTraits.getWritingMode(); - } - - /** {@inheritDoc} */ - public String getLocalName() { - return "inline-container"; - } - - /** - * {@inheritDoc} - * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER} - */ - public int getNameId() { - return FO_INLINE_CONTAINER; - } - @Override public boolean isDelimitedTextRangeBoundary(int boundary) { return false; } + public CommonFont getCommonFont() { + return commonFont; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java index 292251a84..0e333d219 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java @@ -73,7 +73,7 @@ import org.apache.fop.layoutmgr.inline.CharacterLayoutManager; import org.apache.fop.layoutmgr.inline.ContentLayoutManager; import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager; import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager; -import org.apache.fop.layoutmgr.inline.ICLayoutManager; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM; import org.apache.fop.layoutmgr.inline.LeaderLayoutManager; @@ -257,9 +257,9 @@ public class LayoutManagerMapping implements LayoutManagerMaker { /** a layout manager maker */ public static class InlineLayoutManagerMaker extends Maker { /** {@inheritDoc} */ - public void make(FONode node, List lms) { - lms.add(new InlineLayoutManager((InlineLevel) node)); - } + public void make(FONode node, List lms) { + lms.add(new InlineLayoutManager((InlineLevel) node)); + } } /** a layout manager maker */ @@ -274,9 +274,7 @@ public class LayoutManagerMapping implements LayoutManagerMaker { public static class InlineContainerLayoutManagerMaker extends Maker { /** {@inheritDoc} */ public void make(FONode node, List lms) { - ArrayList childList = new ArrayList(); - super.make(node, childList); - lms.add(new ICLayoutManager((InlineContainer) node, childList)); + lms.add(new InlineContainerLayoutManager((InlineContainer) node)); } } diff --git a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java deleted file mode 100644 index 7fe90f63c..000000000 --- a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.layoutmgr.inline; - -// Java -import java.util.List; - -// FOP -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.fo.flow.InlineContainer; -/** - * This creates a single inline container area after - * laying out the child block areas. All footnotes, floats - * and id areas are maintained for later retrieval. - */ -public class ICLayoutManager extends LeafNodeLayoutManager { - private List childrenLM; - - /** - * Construct inline container layout manager. - * @param node inline container FO node - * @param childLM child layout manager - */ - public ICLayoutManager(InlineContainer node, List childLM) { - super(node); - childrenLM = childLM; - } - - /** - * @param index an integer - * @return an inline area or null - */ - public InlineArea get(int index) { - return null; - } - -} diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java new file mode 100644 index 000000000..548225ad7 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr.inline; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.Container; +import org.apache.fop.area.inline.InlineViewport; +import org.apache.fop.fo.flow.InlineContainer; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.LengthRangeProperty; +import org.apache.fop.fo.properties.Property; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.layoutmgr.AbstractLayoutManager; +import org.apache.fop.layoutmgr.InlineKnuthSequence; +import org.apache.fop.layoutmgr.KnuthPossPosIter; +import org.apache.fop.layoutmgr.KnuthSequence; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.ListElement; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.TraitSetter; + +/** + * This creates a single inline container area after + * laying out the child block areas. All footnotes, floats + * and id areas are maintained for later retrieval. + */ +public class InlineContainerLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager { + + private CommonBorderPaddingBackground borderProps; + private int alignmentBaseline = EN_BASELINE; + private int contentAreaIPD; + private int contentAreaBPD; + + private List childElements; + private InlineViewport currentViewport; + private Container referenceArea; + + public InlineContainerLayoutManager(InlineContainer node) { + super(node); + } + + @Override + public void initialize() { + InlineContainer node = (InlineContainer) fobj; + borderProps = node.getCommonBorderPaddingBackground(); + } + + @Override + public List getNextKnuthElements(LayoutContext context, int alignment) { + InlineContainer ic = (InlineContainer) fobj; + contentAreaIPD = getLength(ic.getInlineProgressionDimension()); + contentAreaBPD = getLength(ic.getBlockProgressionDimension()); + LayoutContext childLC = LayoutContext.offspringOf(context); // TODO copyOf? + childLC.setRefIPD(contentAreaIPD); + childElements = getChildKnuthElements(childLC, alignment); // TODO which alignment? + AlignmentContext alignmentContext = makeAlignmentContext(context); // TODO correct? + Position position = new Position(this, 0); + KnuthSequence knuthSequence = new InlineKnuthSequence(); + knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); + List knuthElements = new ArrayList(1); + knuthElements.add(knuthSequence); + setFinished(true); + return knuthElements; + } + + private int getLength(LengthRangeProperty property) { + Property optimum = property.getOptimum(this); // TODO percent base context + if (optimum.isAuto()) { + throw new UnsupportedOperationException("auto dimension not supported"); + } + return optimum.getLength().getValue(this); // TODO percent base context + } + + private List getChildKnuthElements(LayoutContext layoutContext, int alignment) { + List allChildElements = new LinkedList(); + LayoutManager childLM; + while ((childLM = getChildLM()) != null) { + LayoutContext childLC = LayoutContext.offspringOf(layoutContext); // TODO copyOf? newInstance? + childLC.setRefIPD(layoutContext.getRefIPD()); + @SuppressWarnings("unchecked") + List childElements = childLM.getNextKnuthElements(childLC, alignmentBaseline); + allChildElements.addAll(childElements); + // TODO breaks, keeps, empty content + } + SpaceResolver.resolveElementList(allChildElements); + // TODO break-before, break-after + return allChildElements; + } + + @Override + public void addAreas(PositionIterator posIter, LayoutContext context) { + Position inlineContainerPosition = null; + while (posIter.hasNext()) { + Position pos = posIter.next(); + if (pos.getLM() == this) { + inlineContainerPosition = pos; + } + } + addId(); +// addMarkersToPage( +// true, +// true, +// lastPos == null || isLast(lastPos)); + + if (inlineContainerPosition != null) { + LayoutManager childLM; + KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); + while ((childLM = childPosIter.getNextChildLM()) != null) { + LayoutContext childLC = LayoutContext.copyOf(context); // TODO correct? + childLM.addAreas(childPosIter, childLC); + } + } + +// addMarkersToPage( +// false, +// true, +// lastPos == null || isLast(lastPos)); + +// boolean isLast = (context.isLastArea() && prevLM == lastChildLM); +// context.setFlags(LayoutContext.LAST_AREA, isLast); + } + + @Override + public Area getParentArea(Area childArea) { + if (referenceArea == null) { + referenceArea = new Container(); + referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); + TraitSetter.setProducerID(referenceArea, fobj.getId()); + referenceArea.setIPD(contentAreaIPD); + currentViewport = new InlineViewport(referenceArea); + currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + currentViewport.setIPD(getContentAreaIPD()); + currentViewport.setBPD(getContentAreaBPD()); + TraitSetter.setProducerID(currentViewport, fobj.getId()); + TraitSetter.addBorders(currentViewport, + borderProps, + false, false, false, false, this); + TraitSetter.addPadding(currentViewport, + borderProps, + false, false, false, false, this); + TraitSetter.addBackground(currentViewport, + borderProps, + this); + currentViewport.setClip(needClip()); + currentViewport.setContentPosition( + new java.awt.geom.Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); + getParent().addChildArea(currentViewport); + } + return referenceArea; + } + + @Override + public int getContentAreaIPD() { + return contentAreaIPD; + } + + @Override + public int getContentAreaBPD() { + return contentAreaBPD; + } + + @Override + public void addChildArea(Area childArea) { + referenceArea.addBlock((Block) childArea); + } + + private boolean needClip() { + int overflow = ((InlineContainer) fobj).getOverflow(); + return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW); + } + + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + InlineContainer ic = (InlineContainer) fobj; + FontInfo fi = fobj.getFOEventHandler().getFontInfo(); + FontTriplet[] fontkeys = ic.getCommonFont().getFontState(fi); + Font fs = fi.getFontInstance(fontkeys[0], ic.getCommonFont().fontSize.getValue(this)); + return new AlignmentContext(fs, ic.getLineHeight().getOptimum(this).getLength().getValue(this), // TODO + context.getWritingMode()); + } + + public List addALetterSpaceTo(List oldList) { + throw new UnsupportedOperationException("Not implemented"); + } + + public List addALetterSpaceTo(List oldList, int depth) { + throw new UnsupportedOperationException("Not implemented"); + } + + public String getWordChars(Position pos) { + throw new UnsupportedOperationException("Not implemented"); + } + + public void hyphenate(Position pos, HyphContext hyphContext) { + throw new UnsupportedOperationException("Not implemented"); + } + + public boolean applyChanges(List oldList) { + throw new UnsupportedOperationException("Not implemented"); + } + + public boolean applyChanges(List oldList, int depth) { + throw new UnsupportedOperationException("Not implemented"); + } + + public List getChangedKnuthElements(List oldList, int alignment, int depth) { + throw new UnsupportedOperationException("Not implemented"); + } + +} diff --git a/test/layoutengine/standard-testcases/inline-container_basic.xml b/test/layoutengine/standard-testcases/inline-container_basic.xml new file mode 100644 index 000000000..b2dfcc6e5 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_basic.xml @@ -0,0 +1,56 @@ + + + + + +

+ Test for a basic implementation of fo:inline-container. +

+
+ + + + + + + + + + Before: + Text inside inline-container. + After. + + + + + + + + + + + + + + + + + + +
-- cgit v1.2.3 From 3e04d9245827bc5bcbd320728fb14ec6f7613290 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 6 Nov 2013 19:52:38 +0000 Subject: Added support for default alignment of inline-container areas with their parent areas git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_InlineContainer@1539441 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/fo/flow/InlineContainer.java | 8 +- .../fop/layoutmgr/AbstractLayoutManager.java | 28 ++++ .../fop/layoutmgr/BlockContainerLayoutManager.java | 62 ++------- .../apache/fop/layoutmgr/BlockLayoutManager.java | 62 ++------- .../org/apache/fop/layoutmgr/LayoutManager.java | 17 +++ .../SpacedBorderedPaddedBlockLayoutManager.java | 112 +++++++++++++++ .../fop/layoutmgr/inline/ContentLayoutManager.java | 9 ++ .../inline/InlineContainerLayoutManager.java | 22 +-- .../fop/layoutmgr/inline/LineLayoutManager.java | 22 ++- .../fop/layoutmgr/list/ListBlockLayoutManager.java | 65 ++------- .../fop/layoutmgr/list/ListItemLayoutManager.java | 84 ++++------- .../fop/layoutmgr/table/TableLayoutManager.java | 68 ++------- .../inline-container_alignment.xml | 154 +++++++++++++++++++++ 13 files changed, 417 insertions(+), 296 deletions(-) create mode 100644 src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java create mode 100644 test/layoutengine/standard-testcases/inline-container_alignment.xml (limited to 'src/java/org/apache/fop/fo') diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index d3a80eb3f..13ea9943a 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -29,7 +29,6 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; -import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; @@ -59,7 +58,6 @@ public class InlineContainer extends FObj { /** used for FO validation */ private boolean blockItemFound; - private CommonFont commonFont; /** * Creates a new instance. @@ -73,7 +71,6 @@ public class InlineContainer extends FObj { @Override public void bind(PropertyList pList) throws FOPException { super.bind(pList); - commonFont = pList.getFontProps(); // TODO get directly from parent? alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum(); baselineShift = pList.get(PR_BASELINE_SHIFT).getLength(); @@ -214,8 +211,9 @@ public class InlineContainer extends FObj { return false; } - public CommonFont getCommonFont() { - return commonFont; + @Override + public boolean generatesReferenceAreas() { + return true; } } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 0285a41e7..2dd18e4ee 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im && isFinished()); } + public boolean hasLineAreaDescendant() { + if (childLMs == null || childLMs.isEmpty()) { + return false; + } else { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return true; + } + } + } + return false; + } + + public int getBaselineOffset() { + if (childLMs != null) { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return childLM.getBaselineOffset(); + } + } + } + throw newNoLineAreaDescendantException(); + } + + protected IllegalStateException newNoLineAreaDescendantException() { + return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant"); + } + /** * Transfers foreign attributes from the formatting object to the area. * @param targetArea the area to set the attributes on diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index a23cd28f1..83990797b 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.properties.CommonAbsolutePosition; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block-container FO. */ -public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements - ConditionalElementListener, BreakOpportunity { +public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl private MinOptMax foBlockSpaceBefore; private MinOptMax foBlockSpaceAfter; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int horizontalOverflow; private double contentRectOffsetX = 0; private double contentRectOffsetY = 0; @@ -128,6 +122,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockContainerFO().getCommonBorderPaddingBackground(); + } + private void resetSpaces() { this.discardBorderBefore = false; this.discardBorderAfter = false; @@ -993,51 +992,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl return true; } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ public boolean handleOverflow(int milliPoints) { if (milliPoints > this.horizontalOverflow) { diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 0fb738aea..4129b65bd 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Block; import org.apache.fop.area.LineArea; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block FO. */ -public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(BlockLayoutManager.class); @@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co private int follow = 2000; //private int middleShift = 0; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Creates a new BlockLayoutManager. * @param inBlock the block FO object to create the layout manager for. @@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co .getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockFO().getCommonBorderPaddingBackground(); + } + /** {@inheritDoc} */ @Override public List getNextKnuthElements(LayoutContext context, int alignment) { @@ -456,51 +455,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co return true; } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ @Override public boolean isRestartable() { diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java index 985131bf1..107a252b0 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -177,6 +177,23 @@ public interface LayoutManager extends PercentBaseContext { */ List getChangedKnuthElements(List oldList, int alignment); + /** + * Whether the FO handled by this layout manager had a descendant (including itself) + * that will generate a line-area. + * + * @return {@code true} if a descendant line-area will be generated, {@code false} otherwise + */ + boolean hasLineAreaDescendant(); + + /** + * Returns the position of the dominant-baseline of this FO's first descendant + * line-area, if any. + * + * @return this FO's space-before plus the distance from the before-edge of its + * allocation-rectangle to the dominant-baseline of the first line-area descendant + */ + int getBaselineOffset(); + /** * Returns the IPD of the content area * @return the IPD of the content area diff --git a/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java new file mode 100644 index 000000000..2ac41e96a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.traits.MinOptMax; + +/** + * A block-stacking layout manager for an FO that supports spaces, border and padding. + */ +public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager + implements ConditionalElementListener { + + private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class); + + protected MinOptMax effSpaceBefore; + + protected MinOptMax effSpaceAfter; + + protected boolean discardBorderBefore; + protected boolean discardBorderAfter; + protected boolean discardPaddingBefore; + protected boolean discardPaddingAfter; + + public SpacedBorderedPaddedBlockLayoutManager(FObj node) { + super(node); + } + + public void notifySpace(RelSide side, MinOptMax effectiveLength) { + if (RelSide.BEFORE == side) { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceBefore + "-> " + effectiveLength); + } + this.effSpaceBefore = effectiveLength; + } else { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceAfter + "-> " + effectiveLength); + } + this.effSpaceAfter = effectiveLength; + } + } + + public void notifyBorder(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardBorderBefore = true; + } else { + this.discardBorderAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Border " + side + " -> " + effectiveLength); + } + } + + public void notifyPadding(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardPaddingBefore = true; + } else { + this.discardPaddingAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Padding " + side + " -> " + effectiveLength); + } + } + + @Override + public int getBaselineOffset() { + int baselineOffset = super.getBaselineOffset(); + if (effSpaceBefore != null) { + baselineOffset += effSpaceBefore.getOpt(); + } + if (!discardBorderBefore) { + baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false); + } + if (!discardPaddingBefore) { + baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this); + } + return baselineOffset; + } + + /** + * Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager. + */ + protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index b3c768987..c067b040f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -332,6 +332,15 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager return parentLM.getPSLM(); } + + public boolean hasLineAreaDescendant() { + return true; + } + + public int getBaselineOffset() { + return childLM.getBaselineOffset(); + } + // --------- Property Resolution related functions --------- // /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java index 75eb12d5b..9495e2c73 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -31,9 +31,6 @@ import org.apache.fop.fo.flow.InlineContainer; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.LengthRangeProperty; import org.apache.fop.fo.properties.Property; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; import org.apache.fop.layoutmgr.AbstractLayoutManager; import org.apache.fop.layoutmgr.AreaAdditionUtil; import org.apache.fop.layoutmgr.BlockLevelEventProducer; @@ -64,6 +61,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen private List childElements; private int ipdOverflow; + private AlignmentContext alignmentContext; private InlineViewport currentViewport; private Container referenceArea; @@ -84,7 +82,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen childLC.setRefIPD(contentAreaIPD); childElements = getChildKnuthElements(childLC, alignment); // TODO which alignment? determineBPD(); - AlignmentContext alignmentContext = makeAlignmentContext(context); // TODO correct? + alignmentContext = makeAlignmentContext(context); // TODO correct? Position position = new Position(this, 0); KnuthSequence knuthSequence = new InlineKnuthSequence(); knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); @@ -121,6 +119,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen handleIPDOverflow(); wrapPositions(allChildElements); SpaceResolver.resolveElementList(allChildElements); + SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1); // TODO break-before, break-after return allChildElements; } @@ -149,13 +148,13 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen protected AlignmentContext makeAlignmentContext(LayoutContext context) { InlineContainer ic = (InlineContainer) fobj; - FontInfo fi = fobj.getFOEventHandler().getFontInfo(); - FontTriplet[] fontkeys = ic.getCommonFont().getFontState(fi); - Font fs = fi.getFontInstance(fontkeys[0], ic.getCommonFont().fontSize.getValue(this)); - return new AlignmentContext(contentAreaBPD, + AlignmentContext ac = new AlignmentContext(contentAreaBPD, ic.getAlignmentAdjust(), ic.getAlignmentBaseline(), ic.getBaselineShift(), ic.getDominantBaseline(), context.getAlignmentContext()); + int baselineOffset = hasLineAreaDescendant() ? getBaselineOffset() : contentAreaBPD; + ac.resizeLine(contentAreaBPD, baselineOffset); + return ac; } private void handleIPDOverflow() { @@ -183,6 +182,11 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen return ((InlineContainer) fobj).getOverflow() != EN_ERROR_IF_OVERFLOW; } + @Override + public boolean getGeneratesReferenceArea() { + return true; + } + @Override public void addAreas(PositionIterator posIter, LayoutContext context) { Position inlineContainerPosition = null; @@ -196,7 +200,6 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen assert inlineContainerPosition.getLM() == this; } assert inlineContainerPosition != null; - SpaceResolver.performConditionalsNotification(childElements, 0, childElements.size() - 1, -1); KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); AreaAdditionUtil.addAreas(this, childPosIter, context); @@ -212,6 +215,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen TraitSetter.setProducerID(referenceArea, fobj.getId()); referenceArea.setIPD(contentAreaIPD); currentViewport = new InlineViewport(referenceArea); + currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); currentViewport.setIPD(getContentAreaIPD()); currentViewport.setBPD(getContentAreaBPD()); diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index b3987a075..25d8c0872 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -160,6 +160,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager private final int follow; private AlignmentContext alignmentContext; + private int baselineOffset = -1; + private List knuthParagraphs; private LineLayoutPossibilities lineLayouts; @@ -556,7 +558,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int constantLineHeight = 12000; - /** * Create a new Line Layout Manager. * This is used by the block layout manager to create @@ -939,7 +940,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager while (listIter.hasNext()) { ListElement tempElement; tempElement = (ListElement) listIter.next(); - if (tempElement.getLayoutManager() != this) { + LayoutManager lm = tempElement.getLayoutManager(); + if (baselineOffset < 0 && lm != null && lm.hasLineAreaDescendant()) { + baselineOffset = lm.getBaselineOffset(); + } + if (lm != this) { tempElement.setPosition(notifyPos(new NonLeafPosition(this, tempElement.getPosition()))); } @@ -987,6 +992,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager } startIndex = endIndex + 1; LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i); + if (baselineOffset < 0) { + baselineOffset = lbp.spaceBefore + lbp.baseline; + } returnList.add(new KnuthBlockBox( lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter, footnoteList, lbp, false)); @@ -1424,6 +1432,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } + @Override + public boolean hasLineAreaDescendant() { + return true; + } + + @Override + public int getBaselineOffset() { + return baselineOffset; + } + /** * Add the areas with the break points. * diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 61d8a891d..44a9720a4 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal; * A list block contains list items which are stacked within * the list block area.. */ -public class ListBlockLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener { +public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager { /** logging instance */ private static Log log = LogFactory.getLog(ListBlockLayoutManager.class); private Block curBlockArea; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Create a new list block layout manager. * @param node list-block to create the layout manager for @@ -70,6 +61,11 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager super(node); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListBlockFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -277,50 +273,5 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager return getListBlockFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 083e4ee1b..344f6722b 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,12 +32,11 @@ import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; import org.apache.fop.layoutmgr.BreakOpportunityHelper; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager; @@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import org.apache.fop.util.BreakUtil; @@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil; * LayoutManager for a list-item FO. * The list item contains a list item label and a list item body. */ -public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(ListItemLayoutManager.class); @@ -78,13 +76,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements private List labelList = null; private List bodyList = null; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private Keep keepWithNextPendingOnLabel; private Keep keepWithNextPendingOnBody; @@ -145,6 +136,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements setBody(node.getBody()); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListItemFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -475,6 +471,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return returnedList; } + + @Override + public boolean hasLineAreaDescendant() { + return label.hasLineAreaDescendant() || body.hasLineAreaDescendant(); + } + + @Override + public int getBaselineOffset() { + if (label.hasLineAreaDescendant()) { + return label.getBaselineOffset(); + } else if (body.hasLineAreaDescendant()) { + return body.getBaselineOffset(); + } else { + throw newNoLineAreaDescendantException(); + } + } + /** * Add the areas for the break points. * @@ -652,51 +665,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return getListItemFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ @Override public void reset() { diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 7f1754064..afb6547c0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers; import org.apache.fop.fo.flow.RetrieveTableMarker; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.layoutmgr.BlockLevelEventProducer; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.LayoutContext; @@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil; * The table then creates areas for the columns, bodies and rows * the render background. */ -public class TableLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener, BreakOpportunity { +public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -82,13 +81,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager private double tableUnit; private boolean autoLayout = true; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int halfBorderSeparationBPD; private int halfBorderSeparationIPD; @@ -132,6 +124,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager this.columns = new ColumnSetup(node); } + + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getTable().getCommonBorderPaddingBackground(); + } + + /** @return the table FO */ public Table getTable() { return (Table)this.fobj; @@ -521,51 +520,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager } } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ public void reset() { super.reset(); diff --git a/test/layoutengine/standard-testcases/inline-container_alignment.xml b/test/layoutengine/standard-testcases/inline-container_alignment.xml new file mode 100644 index 000000000..153d9a9c4 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment.xml @@ -0,0 +1,154 @@ + + + + + +

+ Checks that the inline-container is properly aligned with the parent area. +

+
+ + + + + + + + + + By default the alignment is with the baseline of the first descendant + line-area. + The line before. The line before. Before: + Inside the inline-container. + After the inline-container. + + + + + + The line before. The line before. Before: + + + Inside the + inline-container. + + + After the inline-container. + + + + + + This inline-container has no line-area descendant. The after edge of its + allocation rectangle should be aligned with the baseline. + The line before. The line before. Before: + + After the inline-container. + + + + + + The first line-area descendant is in fo:list-item-body. + The line before. The line before. Before: + + + + + + + + List item + + + + + After the inline-container. + + + + + + This inline-container contains a block that contains an inline that contains a + block. + The line before. The line before. Before: + inline + After the inline-container. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-- cgit v1.2.3 From 7a151fd401340c0c4578a4d865a3245551ff85c4 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Thu, 14 Nov 2013 09:45:39 +0000 Subject: Code clean-up and simplification git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_InlineContainer@1541863 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/fo/flow/InlineContainer.java | 8 ++++++ .../inline/InlineContainerLayoutManager.java | 32 ++++++---------------- 2 files changed, 17 insertions(+), 23 deletions(-) (limited to 'src/java/org/apache/fop/fo') diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index 13ea9943a..bcff3dc72 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -158,10 +158,18 @@ public class InlineContainer extends FObj { return this.displayAlign; } + public KeepProperty getKeepWithPrevious() { + return keepWithPrevious; + } + public KeepProperty getKeepTogether() { return keepTogether; } + public KeepProperty getKeepWithNext() { + return keepWithNext; + } + public SpaceProperty getLineHeight() { return lineHeight; } diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java index 5127794c0..771bda255 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -19,6 +19,7 @@ package org.apache.fop.layoutmgr.inline; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -86,11 +87,9 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen @Override public List getNextKnuthElements(LayoutContext context, int alignment) { determineIPD(context); - LayoutContext childLC = LayoutContext.offspringOf(context); // TODO copyOf? - childLC.setRefIPD(contentAreaIPD); - childElements = getChildKnuthElements(childLC, alignment); // TODO which alignment? + childElements = getChildKnuthElements(context, alignment); determineBPD(); - alignmentContext = makeAlignmentContext(context); // TODO correct? + alignmentContext = makeAlignmentContext(context); Position position = new Position(this, 0); KnuthSequence knuthSequence = new InlineKnuthSequence(); knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); @@ -117,18 +116,16 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen List allChildElements = new LinkedList(); LayoutManager childLM; while ((childLM = getChildLM()) != null) { - LayoutContext childLC = LayoutContext.offspringOf(layoutContext); // TODO copyOf? newInstance? - childLC.setRefIPD(layoutContext.getRefIPD()); + LayoutContext childLC = LayoutContext.offspringOf(layoutContext); + childLC.setRefIPD(contentAreaIPD); @SuppressWarnings("unchecked") List childElements = childLM.getNextKnuthElements(childLC, alignment); allChildElements.addAll(childElements); - // TODO breaks, keeps, empty content } handleIPDOverflow(); wrapPositions(allChildElements); SpaceResolver.resolveElementList(allChildElements); SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1); - // TODO break-before, break-after return allChildElements; } @@ -254,9 +251,6 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen assert inlineContainerPosition != null; KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); AreaAdditionUtil.addAreas(this, childPosIter, context); - -// boolean isLast = (context.isLastArea() && prevLM == lastChildLM); -// context.setFlags(LayoutContext.LAST_AREA, isLast); } @Override @@ -267,23 +261,15 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen TraitSetter.setProducerID(referenceArea, fobj.getId()); referenceArea.setIPD(contentAreaIPD); currentViewport = new InlineViewport(referenceArea); - currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + TraitSetter.setProducerID(currentViewport, fobj.getId()); + currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); currentViewport.setIPD(getContentAreaIPD()); currentViewport.setBPD(getContentAreaBPD()); - TraitSetter.setProducerID(currentViewport, fobj.getId()); - TraitSetter.addBorders(currentViewport, - borderProps, - false, false, false, false, this); - TraitSetter.addPadding(currentViewport, - borderProps, - false, false, false, false, this); - TraitSetter.addBackground(currentViewport, - borderProps, - this); + TraitSetter.addBackground(currentViewport, borderProps, this); currentViewport.setClip(needClip()); currentViewport.setContentPosition( - new java.awt.geom.Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); + new Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); getParent().addChildArea(currentViewport); } return referenceArea; -- cgit v1.2.3 From ce86f97648fbc8e168ec9ddb34c5cd340b4ff973 Mon Sep 17 00:00:00 2001 From: Robert Meyer Date: Mon, 17 Feb 2014 09:59:17 +0000 Subject: FOP-2341: Infinite loop when smaller used with a zero length font-size git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1568925 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/java/org/apache/fop/fo') diff --git a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java index 72884a177..fe9c64cb7 100644 --- a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java @@ -105,6 +105,9 @@ public class FontSizePropertyMaker // than the last caculated step lastStepFontSize = nextStepFontSize; nextStepFontSize = (int)Math.round(lastStepFontSize * scale); + if (nextStepFontSize == lastStepFontSize) { + break; + } } // baseFontSize is between last and next step font size // Return the step value closer to the baseFontSize -- cgit v1.2.3