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;
import org.apache.fop.traits.WritingMode;
import org.apache.fop.traits.WritingModeTraits;
-/**
- * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container">
- * <code>fo:inline-container</code></a> 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}
* <br>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);
}
}
- /** {@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;
+ }
+
}
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;
/** 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 */
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));
}
}
+++ /dev/null
-/*
- * 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;
- }
-
-}
--- /dev/null
+/*
+ * 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<ListElement> 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<KnuthSequence> 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<KnuthSequence> knuthElements = new ArrayList<KnuthSequence>(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<ListElement> getChildKnuthElements(LayoutContext layoutContext, int alignment) {
+ List<ListElement> allChildElements = new LinkedList<ListElement>();
+ LayoutManager childLM;
+ while ((childLM = getChildLM()) != null) {
+ LayoutContext childLC = LayoutContext.offspringOf(layoutContext); // TODO copyOf? newInstance?
+ childLC.setRefIPD(layoutContext.getRefIPD());
+ @SuppressWarnings("unchecked")
+ List<ListElement> 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");
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ Test for a basic implementation of fo:inline-container.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="320pt" page-width="420pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="80pt" height="50pt">
+ <fo:block>Text inside inline-container.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <!-- The inline-container’s area is there, at the right place -->
+ <eval expected="viewport" xpath="local-name(//flow/block/lineArea/*[position()=2])"/>
+ <!-- It has the right properties -->
+ <eval expected="true" xpath="//viewport/@is-viewport-area"/>
+ <eval expected="80000" xpath="//viewport/@ipd"/>
+ <eval expected="50000" xpath="//viewport/@bpd"/>
+ <eval expected="1" xpath="count(//viewport/*)"/>
+ <eval expected="container" xpath="local-name(//viewport/*)"/>
+ <!-- Its content is there too -->
+ <eval expected="1" xpath="count(//container/block)"/>
+ <eval expected="80000" xpath="//container/block/@ipd"/>
+ </checks>
+</testcase>