From 2ae0a968ee9de3880e0cf03a1c505e2f296108a5 Mon Sep 17 00:00:00 2001 From: Manuel Mall Date: Fri, 7 Oct 2005 08:55:22 +0000 Subject: [PATCH] Update to support border and padding and alignments on inline fos git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@307055 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/area/Area.java | 64 +- src/java/org/apache/fop/area/Block.java | 2 +- .../fop/area/inline/AbstractTextArea.java | 60 +- .../apache/fop/area/inline/FilledArea.java | 2 + .../apache/fop/area/inline/InlineArea.java | 24 +- .../org/apache/fop/datatypes/LengthBase.java | 29 +- .../org/apache/fop/fo/FOPropertyMapping.java | 18 +- .../org/apache/fop/fo/StaticPropertyList.java | 3 + .../apache/fop/fo/flow/AbstractGraphics.java | 44 +- .../org/apache/fop/fo/flow/BidiOverride.java | 25 +- src/java/org/apache/fop/fo/flow/Block.java | 3 +- .../org/apache/fop/fo/flow/Character.java | 49 +- .../fop/fo/flow/InitialPropertySet.java | 11 +- src/java/org/apache/fop/fo/flow/Inline.java | 31 +- .../apache/fop/fo/flow/InlineContainer.java | 41 +- .../org/apache/fop/fo/flow/InlineLevel.java | 13 +- src/java/org/apache/fop/fo/flow/Leader.java | 31 +- .../org/apache/fop/fo/flow/PageNumber.java | 41 +- .../fop/fo/flow/PageNumberCitation.java | 44 +- .../VerticalAlignShorthandParser.java | 142 +++++ .../layoutmgr/AbstractBaseLayoutManager.java | 7 +- .../fop/layoutmgr/AbstractLayoutManager.java | 88 ++- .../BlockContainerLayoutManager.java | 5 +- .../fop/layoutmgr/BlockLayoutManager.java | 2 +- .../layoutmgr/BlockStackingLayoutManager.java | 56 +- .../fop/layoutmgr/FlowLayoutManager.java | 3 +- .../apache/fop/layoutmgr/LayoutContext.java | 168 +++-- .../layoutmgr/StaticContentLayoutManager.java | 1 + .../inline/AbstractGraphicsLayoutManager.java | 59 +- .../layoutmgr/inline/AlignmentContext.java | 582 ++++++++++++++++++ .../inline/BasicScaledBaselineTable.java | 192 ++++++ .../inline/CharacterLayoutManager.java | 152 ++--- .../inline/ContentLayoutManager.java | 18 +- .../inline/FootnoteLayoutManager.java | 2 +- .../layoutmgr/inline/InlineLayoutManager.java | 357 +++++------ .../inline/InlineStackingLayoutManager.java | 115 +++- .../fop/layoutmgr/inline/KnuthInlineBox.java | 38 +- .../layoutmgr/inline/LeaderLayoutManager.java | 172 ++---- .../inline/LeafNodeLayoutManager.java | 200 +++--- .../layoutmgr/inline/LineLayoutManager.java | 232 ++++--- .../PageNumberCitationLayoutManager.java | 34 +- .../inline/PageNumberLayoutManager.java | 30 +- .../layoutmgr/inline/ScaledBaselineTable.java | 70 +++ .../inline/ScaledBaselineTableFactory.java | 74 +++ .../layoutmgr/inline/TextLayoutManager.java | 467 ++++++++++---- .../render/AbstractPathOrientedRenderer.java | 48 +- .../apache/fop/render/AbstractRenderer.java | 40 +- .../fop/render/java2d/Java2DRenderer.java | 4 +- .../apache/fop/render/pdf/PDFRenderer.java | 34 +- .../org/apache/fop/render/ps/PSRenderer.java | 9 +- .../apache/fop/render/svg/SVGRenderer.java | 6 +- .../apache/fop/render/xml/XMLRenderer.java | 16 +- test/layoutengine/disabled-testcases.txt | 5 +- .../testcases/basic-link_background-image.xml | 4 +- test/layoutengine/testcases/block_basic_2.xml | 30 +- .../testcases/block_line-height.xml | 79 ++- .../testcases/character_background-color.xml | 43 ++ .../testcases/character_background-image.xml | 9 +- .../testcases/character_border_padding.xml | 98 +++ .../testcases/character_vertical-align.xml | 59 ++ .../external-graphic_border_padding.xml | 4 +- .../layoutengine/testcases/footnote_basic.xml | 2 +- .../testcases/footnote_footnote-separator.xml | 10 +- .../testcases/inline_alignment-adjust_1.xml | 107 ++++ .../testcases/inline_alignment-adjust_2.xml | 98 +++ .../testcases/inline_alignment-baseline_1.xml | 107 ++++ .../testcases/inline_alignment-baseline_2.xml | 140 +++++ .../testcases/inline_alignment-baseline_3.xml | 107 ++++ .../testcases/inline_alignment-baseline_4.xml | 231 +++++++ .../testcases/inline_background-color.xml | 132 ++++ .../testcases/inline_background-image.xml | 4 +- .../testcases/inline_baseline-shift_1.xml | 164 +++++ .../testcases/inline_baseline-shift_2.xml | 171 +++++ .../testcases/inline_baseline-shift_3.xml | 210 +++++++ .../testcases/inline_baseline-shift_4.xml | 184 ++++++ .../testcases/inline_border_padding.xml | 108 +++- .../inline_border_padding_block_nested.xml | 146 +++++ ...inline_border_padding_conditionality_1.xml | 398 ++++++++++++ ...inline_border_padding_conditionality_2.xml | 311 ++++++++++ .../inline_border_padding_hyphenate.xml | 399 ++++++++++++ .../inline_border_padding_hyphenate_de.xml | 399 ++++++++++++ .../testcases/inline_dominant-baseline_1.xml | 128 ++++ .../testcases/inline_dominant-baseline_2.xml | 128 ++++ .../testcases/inline_dominant-baseline_3.xml | 115 ++++ .../testcases/inline_vertical-align_1.xml | 148 +++++ .../testcases/inline_vertical-align_2.xml | 121 ++++ ...instream-foreign-object_border_padding.xml | 4 +- .../testcases/leader_alignment-baseline.xml | 170 +++++ .../testcases/leader_background-color.xml | 81 +++ .../testcases/leader_border_padding.xml | 256 ++++++++ .../testcases/leader_leader-pattern_dots.xml | 22 +- .../testcases/leader_leader-pattern_rule.xml | 133 ++-- .../testcases/leader_leader-pattern_space.xml | 6 +- .../leader_leader-pattern_use-content.xml | 20 +- test/layoutengine/testcases/leader_toc.xml | 153 +++++ .../page-number-citation_background-color.xml | 43 ++ .../page-number-citation_background-image.xml | 49 ++ .../page-number-citation_border_padding.xml | 98 +++ .../page-number-citation_vertical-align.xml | 59 ++ .../page-number_background-color.xml | 43 ++ .../page-number_background-image.xml | 48 ++ .../testcases/page-number_border_padding.xml | 98 +++ .../testcases/page-number_vertical-align.xml | 59 ++ .../testcases/table-cell_background-image.xml | 260 ++++---- 104 files changed, 8592 insertions(+), 1367 deletions(-) create mode 100644 src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java create mode 100644 src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java create mode 100644 src/java/org/apache/fop/layoutmgr/inline/BasicScaledBaselineTable.java create mode 100644 src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTable.java create mode 100644 src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTableFactory.java create mode 100755 test/layoutengine/testcases/character_background-color.xml create mode 100755 test/layoutengine/testcases/character_border_padding.xml create mode 100755 test/layoutengine/testcases/character_vertical-align.xml create mode 100755 test/layoutengine/testcases/inline_alignment-adjust_1.xml create mode 100755 test/layoutengine/testcases/inline_alignment-adjust_2.xml create mode 100755 test/layoutengine/testcases/inline_alignment-baseline_1.xml create mode 100755 test/layoutengine/testcases/inline_alignment-baseline_2.xml create mode 100755 test/layoutengine/testcases/inline_alignment-baseline_3.xml create mode 100755 test/layoutengine/testcases/inline_alignment-baseline_4.xml create mode 100755 test/layoutengine/testcases/inline_background-color.xml create mode 100755 test/layoutengine/testcases/inline_baseline-shift_1.xml create mode 100755 test/layoutengine/testcases/inline_baseline-shift_2.xml create mode 100755 test/layoutengine/testcases/inline_baseline-shift_3.xml create mode 100755 test/layoutengine/testcases/inline_baseline-shift_4.xml create mode 100755 test/layoutengine/testcases/inline_border_padding_block_nested.xml create mode 100755 test/layoutengine/testcases/inline_border_padding_conditionality_1.xml create mode 100755 test/layoutengine/testcases/inline_border_padding_conditionality_2.xml create mode 100755 test/layoutengine/testcases/inline_border_padding_hyphenate.xml create mode 100755 test/layoutengine/testcases/inline_border_padding_hyphenate_de.xml create mode 100755 test/layoutengine/testcases/inline_dominant-baseline_1.xml create mode 100755 test/layoutengine/testcases/inline_dominant-baseline_2.xml create mode 100755 test/layoutengine/testcases/inline_dominant-baseline_3.xml create mode 100755 test/layoutengine/testcases/inline_vertical-align_1.xml create mode 100755 test/layoutengine/testcases/inline_vertical-align_2.xml create mode 100755 test/layoutengine/testcases/leader_alignment-baseline.xml create mode 100755 test/layoutengine/testcases/leader_background-color.xml create mode 100755 test/layoutengine/testcases/leader_border_padding.xml create mode 100755 test/layoutengine/testcases/leader_toc.xml create mode 100755 test/layoutengine/testcases/page-number-citation_background-color.xml create mode 100755 test/layoutengine/testcases/page-number-citation_background-image.xml create mode 100755 test/layoutengine/testcases/page-number-citation_border_padding.xml create mode 100755 test/layoutengine/testcases/page-number-citation_vertical-align.xml create mode 100755 test/layoutengine/testcases/page-number_background-color.xml create mode 100755 test/layoutengine/testcases/page-number_background-image.xml create mode 100755 test/layoutengine/testcases/page-number_border_padding.xml create mode 100755 test/layoutengine/testcases/page-number_vertical-align.xml diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java index 5ce94de92..df0292bec 100644 --- a/src/java/org/apache/fop/area/Area.java +++ b/src/java/org/apache/fop/area/Area.java @@ -211,13 +211,14 @@ public class Area implements Serializable { /** * Get the allocation block progression dimension of this area. - * This adds the content, borders and the padding to find the + * This adds the content, borders, padding and spaces to find the * total allocated BPD. * - * @return the total IPD allocation for this area + * @return the total BPD allocation for this area */ public int getAllocBPD() { - return getBorderAndPaddingWidthBefore() + getBPD() + getBorderAndPaddingWidthAfter(); + return getSpaceBefore() + getBorderAndPaddingWidthBefore() + getBPD() + + getBorderAndPaddingWidthAfter() + getSpaceAfter(); } /** @@ -300,6 +301,63 @@ public class Area implements Serializable { return margin; } + + /** + * Returns the space before + * + * @return width in millipoints + */ + public int getSpaceBefore() { + int margin = 0; + Integer space = (Integer) getTrait(Trait.SPACE_BEFORE); + if (space != null) { + margin = space.intValue(); + } + return margin; + } + + /** + * Returns the space after + * + * @return width in millipoints + */ + public int getSpaceAfter() { + int margin = 0; + Integer space = (Integer) getTrait(Trait.SPACE_AFTER); + if (space != null) { + margin = space.intValue(); + } + return margin; + } + + /** + * Returns the space start + * + * @return width in millipoints + */ + public int getSpaceStart() { + int margin = 0; + Integer space = (Integer) getTrait(Trait.SPACE_START); + if (space != null) { + margin = space.intValue(); + } + return margin; + } + + /** + * Returns the space end + * + * @return width in millipoints + */ + public int getSpaceEnd() { + int margin = 0; + Integer space = (Integer) getTrait(Trait.SPACE_END); + if (space != null) { + margin = space.intValue(); + } + return margin; + } + /** * Add a child to this area. * The default is to do nothing. Subclasses must override diff --git a/src/java/org/apache/fop/area/Block.java b/src/java/org/apache/fop/area/Block.java index 881c2704b..700334e77 100644 --- a/src/java/org/apache/fop/area/Block.java +++ b/src/java/org/apache/fop/area/Block.java @@ -95,7 +95,7 @@ public class Block extends BlockParent { if (children == null) { children = new ArrayList(); } - bpd += line.getBPD(); + bpd += line.getAllocBPD(); children.add(line); } diff --git a/src/java/org/apache/fop/area/inline/AbstractTextArea.java b/src/java/org/apache/fop/area/inline/AbstractTextArea.java index 6e8f9d418..a50500979 100644 --- a/src/java/org/apache/fop/area/inline/AbstractTextArea.java +++ b/src/java/org/apache/fop/area/inline/AbstractTextArea.java @@ -30,9 +30,10 @@ public abstract class AbstractTextArea extends InlineArea { */ protected class TextAdjustingInfo extends InlineAdjustingInfo { - // difference between the optimal width of a space - // and the default width of a space according to the font - // (this is equivalent to the property word-spacing.optimum) + /** difference between the optimal width of a space + * and the default width of a space according to the font + * (this is equivalent to the property word-spacing.optimum) + */ protected int spaceDifference = 0; /** @@ -47,9 +48,10 @@ public abstract class AbstractTextArea extends InlineArea { } } - private int iTextWordSpaceAdjust = 0; - private int iTextLetterSpaceAdjust = 0; + private int textWordSpaceAdjust = 0; + private int textLetterSpaceAdjust = 0; private TextAdjustingInfo adjustingInfo = null; + private int baselineOffset = 0; /** * Default constructor @@ -74,33 +76,34 @@ public abstract class AbstractTextArea extends InlineArea { * @return the text word space adjustment */ public int getTextWordSpaceAdjust() { - return iTextWordSpaceAdjust; + return textWordSpaceAdjust; } /** * Set text word space adjust. * - * @param iTWSadjust the text word space adjustment + * @param textWordSpaceAdjust the text word space adjustment */ - public void setTextWordSpaceAdjust(int iTWSadjust) { - iTextWordSpaceAdjust = iTWSadjust; + public void setTextWordSpaceAdjust(int textWordSpaceAdjust) { + this.textWordSpaceAdjust = textWordSpaceAdjust; } + /** * Get text letter space adjust. * * @return the text letter space adjustment */ public int getTextLetterSpaceAdjust() { - return iTextLetterSpaceAdjust; + return textLetterSpaceAdjust; } /** * Set text letter space adjust. * - * @param iTLSadjust the text letter space adjustment + * @param textLetterSpaceAdjust the text letter space adjustment */ - public void setTextLetterSpaceAdjust(int iTLSadjust) { - iTextLetterSpaceAdjust = iTLSadjust; + public void setTextLetterSpaceAdjust(int textLetterSpaceAdjust) { + this.textLetterSpaceAdjust = textLetterSpaceAdjust; } /** @@ -133,20 +136,22 @@ public abstract class AbstractTextArea extends InlineArea { // balancing factor double balancingFactor = 1.0; if (variationFactor < 0) { - if (iTextWordSpaceAdjust < 0) { + if (textWordSpaceAdjust < 0) { // from a negative adjustment to a positive one - balancingFactor = ((double) adjustingInfo.availableStretch / adjustingInfo.availableShrink) + balancingFactor + = ((double) adjustingInfo.availableStretch / adjustingInfo.availableShrink) * ((double) lineShrink / lineStretch); } else { // from a positive adjustment to a negative one - balancingFactor = ((double) adjustingInfo.availableShrink / adjustingInfo.availableStretch) + balancingFactor + = ((double) adjustingInfo.availableShrink / adjustingInfo.availableStretch) * ((double) lineStretch / lineShrink); } } - iTextWordSpaceAdjust = (int) ((iTextWordSpaceAdjust - adjustingInfo.spaceDifference) + textWordSpaceAdjust = (int) ((textWordSpaceAdjust - adjustingInfo.spaceDifference) * variationFactor * balancingFactor) + adjustingInfo.spaceDifference; - iTextLetterSpaceAdjust *= variationFactor; + textLetterSpaceAdjust *= variationFactor; // update the ipd of the area int oldAdjustment = adjustingInfo.adjustment; adjustingInfo.adjustment *= balancingFactor * variationFactor; @@ -154,4 +159,23 @@ public abstract class AbstractTextArea extends InlineArea { } return false; } + + /** + * Get baseline offset, i.e. the distance from the before edge + * of this area to the nominal baseline. + * + * @return the baseline offset + */ + public int getBaselineOffset() { + return baselineOffset; + } + + /** + * Set the baseline offset. + * + * @param baselineOffset the baseline offset + */ + public void setBaselineOffset(int baselineOffset) { + this.baselineOffset = baselineOffset; + } } diff --git a/src/java/org/apache/fop/area/inline/FilledArea.java b/src/java/org/apache/fop/area/inline/FilledArea.java index 84e905536..febc5ac98 100644 --- a/src/java/org/apache/fop/area/inline/FilledArea.java +++ b/src/java/org/apache/fop/area/inline/FilledArea.java @@ -46,9 +46,11 @@ public class FilledArea extends InlineParent { * * @param v the offset */ + /* public void setOffset(int v) { setChildOffset(inlines.listIterator(), v); } + */ private void setChildOffset(ListIterator childrenIterator, int v) { while (childrenIterator.hasNext()) { diff --git a/src/java/org/apache/fop/area/inline/InlineArea.java b/src/java/org/apache/fop/area/inline/InlineArea.java index e448a4516..2f326823b 100644 --- a/src/java/org/apache/fop/area/inline/InlineArea.java +++ b/src/java/org/apache/fop/area/inline/InlineArea.java @@ -35,11 +35,11 @@ public class InlineArea extends Area { * page-number or a page-number-citation is resolved */ protected class InlineAdjustingInfo { - // stretch of the inline area + /** stretch of the inline area */ protected int availableStretch; - // shrink of the inline area + /** shrink of the inline area */ protected int availableShrink; - // total adjustment (= ipd - width of fixed elements) + /** total adjustment (= ipd - width of fixed elements) */ protected int adjustment; /** @@ -57,9 +57,9 @@ public class InlineArea extends Area { } /** - * offset position from top of parent area + * offset position from before edge of parent area */ - protected int verticalPosition = 0; + protected int offset = 0; /** * parent area @@ -88,25 +88,23 @@ public class InlineArea extends Area { /** * Set the offset of this inline area. * This is used to set the offset of the inline area - * which is normally relative to the top of the line - * or the baseline. + * which is relative to the before edge of the parent area. * - * @param v the offset + * @param offset the offset */ - public void setOffset(int v) { - verticalPosition = v; + public void setOffset(int offset) { + this.offset = offset; } /** * Get the offset of this inline area. * This returns the offset of the inline area - * which is normally relative to the top of the line - * or the baseline. + * which is relative to the before edge of the parent area. * * @return the offset */ public int getOffset() { - return verticalPosition; + return offset; } /** diff --git a/src/java/org/apache/fop/datatypes/LengthBase.java b/src/java/org/apache/fop/datatypes/LengthBase.java index 7c14d213f..00f03c450 100644 --- a/src/java/org/apache/fop/datatypes/LengthBase.java +++ b/src/java/org/apache/fop/datatypes/LengthBase.java @@ -22,6 +22,9 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.InstreamForeignObject; /** * Models a length which can be used as a factor in a percentage length @@ -53,15 +56,8 @@ public class LengthBase implements PercentBase { public static final int IMAGE_BACKGROUND_POSITION_VERTICAL = 10; /** constant for a table-unit-based length */ public static final int TABLE_UNITS = 11; - - /** array of valid percent-based length types */ - public static final int[] PERCENT_BASED_LENGTH_TYPES - = {CUSTOM_BASE, FONTSIZE, INH_FONTSIZE, PARENT_AREA_WIDTH, - CONTAINING_REFAREA_WIDTH, - IMAGE_INTRINSIC_WIDTH, IMAGE_INTRINSIC_HEIGHT, - IMAGE_BACKGROUND_POSITION_HORIZONTAL, IMAGE_BACKGROUND_POSITION_VERTICAL, - TABLE_UNITS - }; + /** constant for a alignment adjust percent-based length */ + public static final int ALIGNMENT_ADJUST = 12; /** * The FO for which this property is to be calculated. @@ -73,7 +69,8 @@ public class LengthBase implements PercentBase { */ private /* final */ int iBaseType; - private Length fontSize; + /** For percentages based on other length properties */ + private Length baseLength; /** * Constructor @@ -87,10 +84,10 @@ public class LengthBase implements PercentBase { this.iBaseType = iBaseType; switch (iBaseType) { case FONTSIZE: - this.fontSize = plist.get(Constants.PR_FONT_SIZE).getLength(); + this.baseLength = plist.get(Constants.PR_FONT_SIZE).getLength(); break; case INH_FONTSIZE: - this.fontSize = plist.getInherited(Constants.PR_FONT_SIZE).getLength(); + this.baseLength = plist.getInherited(Constants.PR_FONT_SIZE).getLength(); break; default: // TODO: pacify CheckStyle @@ -117,16 +114,16 @@ public class LengthBase implements PercentBase { * @see org.apache.fop.datatypes.PercentBase#getBaseLength(PercentBaseContext) */ public int getBaseLength(PercentBaseContext context) throws PropertyException { - int baseLength = 0; + int baseLen = 0; if (context != null) { if (iBaseType == FONTSIZE || iBaseType == INH_FONTSIZE) { - return fontSize.getValue(context); + return baseLength.getValue(context); } - baseLength = context.getBaseLength(iBaseType, fobj); + baseLen = context.getBaseLength(iBaseType, fobj); } else { fobj.getLogger().error("getBaseLength called without context"); } - return baseLength; + return baseLen; } } diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index f60bbafbb..a41672bb0 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -55,6 +55,7 @@ import org.apache.fop.fo.properties.StringProperty; import org.apache.fop.fo.properties.TableBorderPrecedence; import org.apache.fop.fo.properties.TextDecorationProperty; import org.apache.fop.fo.properties.ToBeImplementedProperty; +import org.apache.fop.fo.properties.VerticalAlignShorthandParser; /** * This class creates and returns an array of Property.Maker instances @@ -1349,6 +1350,8 @@ public class FOPropertyMapping implements Constants { m.addEnum("text-top", getEnumProperty(EN_TEXT_TOP, "TEXT_TOP")); m.addEnum("text-bottom", getEnumProperty(EN_TEXT_BOTTOM, "TEXT_BOTTOM")); m.setDefault("auto"); + m.setPercentBase(LengthBase.ALIGNMENT_ADJUST); + m.addShorthand(s_generics[PR_VERTICAL_ALIGN]); addPropertyMaker("alignment-adjust", m); // alignment-baseline @@ -1366,7 +1369,12 @@ public class FOPropertyMapping implements Constants { m.addEnum("alphabetic", getEnumProperty(EN_ALPHABETIC, "ALPHABETIC")); m.addEnum("hanging", getEnumProperty(EN_HANGING, "HANGING")); m.addEnum("mathematical", getEnumProperty(EN_MATHEMATICAL, "MATHEMATICAL")); + m.addEnum("top", getEnumProperty(EN_TOP, "TOP")); + m.addEnum("bottom", getEnumProperty(EN_BOTTOM, "BOTTOM")); + m.addEnum("text-top", getEnumProperty(EN_TEXT_TOP, "TEXT_TOP")); + m.addEnum("text-bottom", getEnumProperty(EN_TEXT_BOTTOM, "TEXT_BOTTOM")); m.setDefault("auto"); + m.addShorthand(s_generics[PR_VERTICAL_ALIGN]); addPropertyMaker("alignment-baseline", m); // baseline-shift @@ -1376,6 +1384,8 @@ public class FOPropertyMapping implements Constants { m.addEnum("sub", getEnumProperty(EN_SUB, "SUB")); m.addEnum("super", getEnumProperty(EN_SUPER, "SUPER")); m.setDefault("baseline"); + m.addShorthand(s_generics[PR_VERTICAL_ALIGN]); + m.setPercentBase(LengthBase.CUSTOM_BASE); addPropertyMaker("baseline-shift", m); // display-align @@ -1406,6 +1416,7 @@ public class FOPropertyMapping implements Constants { m.addEnum("text-after-edge", getEnumProperty(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE" )); m.addEnum("text-before-edge", getEnumProperty(EN_TEXT_BEFORE_EDGE, "TEXT_BEFORE_EDGE")); m.setDefault("auto"); + m.addShorthand(s_generics[PR_VERTICAL_ALIGN]); addPropertyMaker("dominant-baseline", m); // relative-align @@ -2488,6 +2499,7 @@ public class FOPropertyMapping implements Constants { m.setInherited(false); m.addEnum("use-font-metrics", getEnumProperty(EN_USE_FONT_METRICS, "USE_FONT_METRICS")); m.setDefault("use-font-metrics"); + m.setPercentBase(LengthBase.FONTSIZE); addPropertyMaker("text-altitude", m); // text-depth @@ -2495,6 +2507,7 @@ public class FOPropertyMapping implements Constants { m.setInherited(false); m.addEnum("use-font-metrics", getEnumProperty(EN_USE_FONT_METRICS, "USE_FONT_METRICS")); m.setDefault("use-font-metrics"); + m.setPercentBase(LengthBase.FONTSIZE); addPropertyMaker("text-depth", m); // unicode-bidi @@ -2720,8 +2733,8 @@ public class FOPropertyMapping implements Constants { m.setDefault("auto"); addPropertyMaker("size", m); - // vertical-align TODO: Should be a LengthProperty. - m = new EnumProperty.Maker(PR_VERTICAL_ALIGN); + // vertical-align + m = new LengthProperty.Maker(PR_VERTICAL_ALIGN); m.setInherited(false); m.addEnum("baseline", getEnumProperty(EN_BASELINE, "BASELINE")); m.addEnum("middle", getEnumProperty(EN_MIDDLE, "MIDDLE")); @@ -2731,6 +2744,7 @@ public class FOPropertyMapping implements Constants { m.addEnum("text-bottom", getEnumProperty(EN_TEXT_BOTTOM, "TEXT_BOTTOM")); m.addEnum("top", getEnumProperty(EN_TOP, "TOP")); m.addEnum("bottom", getEnumProperty(EN_BOTTOM, "BOTTOM")); + m.setDatatypeParser(new VerticalAlignShorthandParser()); m.setDefault("baseline"); addPropertyMaker("vertical-align", m); diff --git a/src/java/org/apache/fop/fo/StaticPropertyList.java b/src/java/org/apache/fop/fo/StaticPropertyList.java index 37699847a..0ffa1e7ca 100755 --- a/src/java/org/apache/fop/fo/StaticPropertyList.java +++ b/src/java/org/apache/fop/fo/StaticPropertyList.java @@ -65,6 +65,9 @@ public class StaticPropertyList extends PropertyList { { Property p = values[propId]; if (p == null) { + if (propId == 94) { + propId = propId; + } p = values[propId] = super.get(propId, bTryInherit, bTryDefault); } return p; diff --git a/src/java/org/apache/fop/fo/flow/AbstractGraphics.java b/src/java/org/apache/fop/fo/flow/AbstractGraphics.java index b9f360c2c..493738b12 100644 --- a/src/java/org/apache/fop/fo/flow/AbstractGraphics.java +++ b/src/java/org/apache/fop/fo/flow/AbstractGraphics.java @@ -30,6 +30,7 @@ import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.CommonRelativePosition; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; +import org.apache.fop.fo.properties.SpaceProperty; /** * Common base class for instream-foreign-object and external-graphics @@ -59,12 +60,11 @@ public abstract class AbstractGraphics extends FObj { private LengthRangeProperty inlineProgressionDimension; private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; - private Length lineHeight; + private SpaceProperty lineHeight; private int overflow; private int scaling; private int scalingMethod; private int textAlign; - private int verticalAlign; // shorthand!!! private Length width; // End of property values @@ -101,12 +101,11 @@ public abstract class AbstractGraphics extends FObj { inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); overflow = pList.get(PR_OVERFLOW).getEnum(); scaling = pList.get(PR_SCALING).getEnum(); scalingMethod = pList.get(PR_SCALING_METHOD).getEnum(); textAlign = pList.get(PR_TEXT_ALIGN).getEnum(); - verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum(); width = pList.get(PR_WIDTH).getLength(); } @@ -177,7 +176,7 @@ public abstract class AbstractGraphics extends FObj { /** * @return the "line-height" property. */ - public Length getLineHeight() { + public SpaceProperty getLineHeight() { return lineHeight; } @@ -230,13 +229,6 @@ public abstract class AbstractGraphics extends FObj { return scaling; } - /** - * @return the "vertical-align" property. - */ - public int getVerticalAlign() { - return verticalAlign; - } - /** * @return the "overflow" property. */ @@ -244,6 +236,34 @@ public abstract class AbstractGraphics extends FObj { return overflow; } + /** + * @return the "alignment-adjust" property + */ + public Length getAlignmentAdjust() { + return alignmentAdjust; + } + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + /** * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicWidth() */ diff --git a/src/java/org/apache/fop/fo/flow/BidiOverride.java b/src/java/org/apache/fop/fo/flow/BidiOverride.java index f8c28d4e0..3865c260b 100644 --- a/src/java/org/apache/fop/fo/flow/BidiOverride.java +++ b/src/java/org/apache/fop/fo/flow/BidiOverride.java @@ -48,7 +48,7 @@ public class BidiOverride extends FObjMixed { private ColorTypeProperty prColor; // private ToBeImplementedProperty prDirection; // private ToBeImplementedProperty prLetterSpacing; - private Length prLineHeight; + private SpaceProperty lineHeight; // private ToBeImplementedProperty prScoreSpaces; // private ToBeImplementedProperty prUnicodeBidi; private SpaceProperty prWordSpacing; @@ -69,13 +69,11 @@ public class BidiOverride extends FObjMixed { int lvlFootnote = findAncestor(FO_FOOTNOTE); if (lvlLeader > 0) { - if (lvlInCntr < 0 || - (lvlInCntr > 0 && lvlInCntr > lvlLeader)) { + if (lvlInCntr < 0 || (lvlInCntr > 0 && lvlInCntr > lvlLeader)) { canHaveBlockLevelChildren = false; } } else if (lvlInline > 0 && lvlFootnote == (lvlInline + 1)) { - if (lvlInCntr < 0 || - (lvlInCntr > 0 && lvlInCntr > lvlInline)) { + if (lvlInCntr < 0 || (lvlInCntr > 0 && lvlInCntr > lvlInline)) { canHaveBlockLevelChildren = false; } } @@ -92,7 +90,7 @@ public class BidiOverride extends FObjMixed { prColor = pList.get(PR_COLOR).getColorType(); // prDirection = pList.get(PR_DIRECTION); // prLetterSpacing = pList.get(PR_LETTER_SPACING); - prLineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); // prScoreSpaces = pList.get(PR_SCORE_SPACES); // prUnicodeBidi = pList.get(PR_UNICODE_BIDI); prWordSpacing = pList.get(PR_WORD_SPACING).getSpace(); @@ -116,16 +114,23 @@ public class BidiOverride extends FObjMixed { } else if (!isBlockOrInlineItem(nsURI, localName)) { invalidChildError(loc, nsURI, localName); } else if (!canHaveBlockLevelChildren && isBlockItem(nsURI, localName)) { - String ruleViolated = "An fo:bidi-override" + - " that is a descendant of an fo:leader or of the fo:inline child" + - " of an fo:footnote may not have block-level children, unless it" + - " has a nearer ancestor that is an fo:inline-container."; + String ruleViolated = "An fo:bidi-override" + + " that is a descendant of an fo:leader or of the fo:inline child" + + " of an fo:footnote may not have block-level children, unless it" + + " has a nearer ancestor that is an fo:inline-container."; invalidChildError(loc, nsURI, localName, ruleViolated); } else { blockOrInlineItemFound = true; } } + /** + * @return the "line-height" property. + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + /** * @see org.apache.fop.fo.FObj#getName() */ diff --git a/src/java/org/apache/fop/fo/flow/Block.java b/src/java/org/apache/fop/fo/flow/Block.java index 45f8cc959..d6600f963 100644 --- a/src/java/org/apache/fop/fo/flow/Block.java +++ b/src/java/org/apache/fop/fo/flow/Block.java @@ -18,6 +18,7 @@ package org.apache.fop.fo.flow; +import java.util.Iterator; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; @@ -378,7 +379,7 @@ public class Block extends FObjMixed { boolean bInWS = false; boolean bPrevWasLF = false; - /* bSeenNonWSYet is an indicator used for trimming all leading + /* seenNonWSYet is an indicator used for trimming all leading whitespace for the first inline child of the block */ boolean bSeenNonWSYet = false; diff --git a/src/java/org/apache/fop/fo/flow/Character.java b/src/java/org/apache/fop/fo/flow/Character.java index 04c289735..267bf47af 100644 --- a/src/java/org/apache/fop/fo/flow/Character.java +++ b/src/java/org/apache/fop/fo/flow/Character.java @@ -38,6 +38,7 @@ import org.apache.fop.fo.properties.CommonRelativePosition; 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; /** * This class represents the flow object 'fo:character'. Its use is defined by @@ -75,14 +76,13 @@ public class Character extends FObj { private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; private Property letterSpacing; - private Length lineHeight; + private SpaceProperty lineHeight; private int scoreSpaces; private int suppressAtLineBreak; /** Holds the text decoration values. May be null */ private CommonTextDecoration textDecoration; // private ToBeImplementedProperty textShadow; private int textTransform; - private int verticalAlign; private int visibility; private Property wordSpacing; // End of property values @@ -125,13 +125,12 @@ public class Character extends FObj { keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); letterSpacing = pList.get(PR_LETTER_SPACING); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); scoreSpaces = pList.get(PR_SCORE_SPACES).getEnum(); suppressAtLineBreak = pList.get(PR_SUPPRESS_AT_LINE_BREAK).getEnum(); textDecoration = pList.getTextDecorationProps(); // textShadow = pList.get(PR_TEXT_SHADOW); textTransform = pList.get(PR_TEXT_TRANSFORM).getEnum(); - verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum(); visibility = pList.get(PR_VISIBILITY).getEnum(); wordSpacing = pList.get(PR_WORD_SPACING); } @@ -196,6 +195,34 @@ public class Character extends FObj { return color; } + /** + * @return the "alignment-adjust" property + */ + public Length getAlignmentAdjust() { + return alignmentAdjust; + } + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + /** * @return the "id" property. */ @@ -210,6 +237,13 @@ public class Character extends FObj { return letterSpacing; } + /** + * @return the "line-height" property. + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + /** @return the "text-decoration" property. */ public CommonTextDecoration getTextDecoration() { return textDecoration; @@ -222,13 +256,6 @@ public class Character extends FObj { return wordSpacing; } - /** - * @return the "vertical-align" property. - */ - public int getVerticalAlign() { - return verticalAlign; - } - /** * @see org.apache.fop.fo.FObj#getName() */ diff --git a/src/java/org/apache/fop/fo/flow/InitialPropertySet.java b/src/java/org/apache/fop/fo/flow/InitialPropertySet.java index fd3facd81..664c5972c 100644 --- a/src/java/org/apache/fop/fo/flow/InitialPropertySet.java +++ b/src/java/org/apache/fop/fo/flow/InitialPropertySet.java @@ -48,7 +48,7 @@ public class InitialPropertySet extends FObj { private ColorTypeProperty color; private String id; // private ToBeImplementedProperty letterSpacing; - private Length lineHeight; + private SpaceProperty lineHeight; private int scoreSpaces; private int textDecoration; // private ToBeImplementedProperty textShadow; @@ -75,7 +75,7 @@ public class InitialPropertySet extends FObj { color = pList.get(PR_COLOR).getColorType(); id = pList.get(PR_ID).getString(); // letterSpacing = pList.get(PR_LETTER_SPACING); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); scoreSpaces = pList.get(PR_SCORE_SPACES).getEnum(); textDecoration = pList.get(PR_TEXT_DECORATION).getEnum(); // textShadow = pList.get(PR_TEXT_SHADOW); @@ -99,6 +99,13 @@ public class InitialPropertySet extends FObj { invalidChildError(loc, nsURI, localName); } + /** + * @return the "line-height" property. + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + /** * @see org.apache.fop.fo.FObj#getName() */ diff --git a/src/java/org/apache/fop/fo/flow/Inline.java b/src/java/org/apache/fop/fo/flow/Inline.java index f6e6e7176..0070187d6 100644 --- a/src/java/org/apache/fop/fo/flow/Inline.java +++ b/src/java/org/apache/fop/fo/flow/Inline.java @@ -49,7 +49,6 @@ public class Inline extends InlineLevel { private KeepProperty keepTogether; private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; - private int verticalAlign; private Length width; private int wrapOption; // End of property values @@ -82,7 +81,6 @@ public class Inline extends InlineLevel { keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); - verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum(); width = pList.get(PR_WIDTH).getLength(); wrapOption = pList.get(PR_WRAP_OPTION).getEnum(); } @@ -157,12 +155,33 @@ public class Inline extends InlineLevel { } /** - * Return the "vertical-align" property. + * @return the "alignment-adjust" property */ - public int getVerticalAlign() { - return verticalAlign; + public Length getAlignmentAdjust() { + return alignmentAdjust; } - + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + /** * @see org.apache.fop.fo.FObjMixed#charIterator */ diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index 380ff8b7d..1e100508f 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -32,6 +32,7 @@ import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.CommonRelativePosition; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; +import org.apache.fop.fo.properties.SpaceProperty; /** * Class modelling the fo:inline-container object. @@ -55,7 +56,7 @@ public class InlineContainer extends FObj { private KeepProperty keepTogether; private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; - private Length lineHeight; + private SpaceProperty lineHeight; private int overflow; private Numeric referenceOrientation; private Length width; @@ -92,7 +93,7 @@ public class InlineContainer extends FObj { 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).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); overflow = pList.get(PR_OVERFLOW).getEnum(); referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric(); width = pList.get(PR_WIDTH).getLength(); @@ -132,6 +133,41 @@ public class InlineContainer extends FObj { } } + /** + * @return the "alignment-adjust" property + */ + public Length getAlignmentAdjust() { + return alignmentAdjust; + } + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + + /** + * @return the "line-height" property. + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + /** * @return the "id" property. */ @@ -152,4 +188,5 @@ public class InlineContainer extends FObj { public int getNameId() { return FO_INLINE_CONTAINER; } + } diff --git a/src/java/org/apache/fop/fo/flow/InlineLevel.java b/src/java/org/apache/fop/fo/flow/InlineLevel.java index 096eac768..5c0d264fb 100644 --- a/src/java/org/apache/fop/fo/flow/InlineLevel.java +++ b/src/java/org/apache/fop/fo/flow/InlineLevel.java @@ -29,6 +29,7 @@ import org.apache.fop.fo.properties.CommonAural; 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.SpaceProperty; /** * Class modelling the commonalities of several inline-level @@ -43,7 +44,7 @@ public abstract class InlineLevel extends FObjMixed { protected CommonAural commonAural; protected CommonFont commonFont; protected ColorType color; - protected Length lineHeight; + protected SpaceProperty lineHeight; protected int visibility; // End of property values @@ -64,7 +65,7 @@ public abstract class InlineLevel extends FObjMixed { commonAural = pList.getAuralProps(); commonFont = pList.getFontProps(); color = pList.get(PR_COLOR).getColorType(); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); visibility = pList.get(PR_VISIBILITY).getEnum(); } @@ -95,5 +96,13 @@ public abstract class InlineLevel extends FObjMixed { public ColorType getColor() { return color; } + + /** + * @return the "line-height" property + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + } diff --git a/src/java/org/apache/fop/fo/flow/Leader.java b/src/java/org/apache/fop/fo/flow/Leader.java index f8e67130f..c542a8c25 100644 --- a/src/java/org/apache/fop/fo/flow/Leader.java +++ b/src/java/org/apache/fop/fo/flow/Leader.java @@ -39,7 +39,6 @@ public class Leader extends InlineLevel { private CommonRelativePosition commonRelativePosition; private Length alignmentAdjust; private int alignmentBaseline; - private int verticalAlign; private Length baselineShift; private int dominantBaseline; private Length textDepth; @@ -73,7 +72,6 @@ public class Leader extends InlineLevel { commonRelativePosition = pList.getRelativePositionProps(); alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum(); - verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum(); baselineShift = pList.get(PR_BASELINE_SHIFT).getLength(); dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum(); textDepth = pList.get(PR_TEXT_DEPTH).getLength(); @@ -167,12 +165,33 @@ public class Leader extends InlineLevel { } /** - * @return the "vertical-align" property. + * @return the "alignment-adjust" property */ - public int getVerticalAlign() { - return verticalAlign; + public Length getAlignmentAdjust() { + return alignmentAdjust; } - + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + /** * @see org.apache.fop.fo.FObj#getName() */ diff --git a/src/java/org/apache/fop/fo/flow/PageNumber.java b/src/java/org/apache/fop/fo/flow/PageNumber.java index e3afb7ab4..85cca2807 100644 --- a/src/java/org/apache/fop/fo/flow/PageNumber.java +++ b/src/java/org/apache/fop/fo/flow/PageNumber.java @@ -57,7 +57,7 @@ public class PageNumber extends FObj { private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; // private ToBeImplementedProperty letterSpacing; - private Length lineHeight; + private SpaceProperty lineHeight; private int scoreSpaces; private Length textAltitude; /** Holds the text decoration values. May be null */ @@ -98,7 +98,7 @@ public class PageNumber extends FObj { keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); // letterSpacing = pList.get(PR_LETTER_SPACING); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); scoreSpaces = pList.get(PR_SCORE_SPACES).getEnum(); textAltitude = pList.get(PR_TEXT_ALTITUDE).getLength(); textDecoration = pList.getTextDecorationProps(); @@ -162,7 +162,42 @@ public class PageNumber extends FObj { return textDecoration; } - /** @see org.apache.fop.fo.FONode#getName() */ + /** + * @return the "alignment-adjust" property + */ + public Length getAlignmentAdjust() { + return alignmentAdjust; + } + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + + /** + * @return the "line-height" property + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + + /** @see org.apache.fop.fo.FONode#getName() */ public String getName() { return "fo:page-number"; } diff --git a/src/java/org/apache/fop/fo/flow/PageNumberCitation.java b/src/java/org/apache/fop/fo/flow/PageNumberCitation.java index 775479b43..a67a716f5 100644 --- a/src/java/org/apache/fop/fo/flow/PageNumberCitation.java +++ b/src/java/org/apache/fop/fo/flow/PageNumberCitation.java @@ -60,7 +60,7 @@ public class PageNumberCitation extends FObj { private KeepProperty keepWithNext; private KeepProperty keepWithPrevious; // private ToBeImplementedProperty letterSpacing; - private Length lineHeight; + private SpaceProperty lineHeight; private String refId; private int scoreSpaces; private Length textAltitude; @@ -102,7 +102,7 @@ public class PageNumberCitation extends FObj { keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); // letterSpacing = pList.get(PR_LETTER_SPACING); - lineHeight = pList.get(PR_LINE_HEIGHT).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); refId = pList.get(PR_REF_ID).getString(); scoreSpaces = pList.get(PR_SCORE_SPACES).getEnum(); textAltitude = pList.get(PR_TEXT_ALTITUDE).getLength(); @@ -152,6 +152,46 @@ public class PageNumberCitation extends FObj { return textDecoration; } + /** + * @return the "alignment-adjust" property + */ + public Length getAlignmentAdjust() { + return alignmentAdjust; + } + + /** + * @return the "alignment-baseline" property + */ + public int getAlignmentBaseline() { + return alignmentBaseline; + } + + /** + * @return the "baseline-shift" property + */ + public Length getBaselineShift() { + return baselineShift; + } + + /** + * @return the "dominant-baseline" property + */ + public int getDominantBaseline() { + return dominantBaseline; + } + + /** @return the Common Border, Padding, and Background Properties. */ + public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return commonBorderPaddingBackground; + } + + /** + * @return the "line-height" property + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + /** @return the "id" property. */ public String getId() { return id; diff --git a/src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java b/src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java new file mode 100644 index 000000000..60b22d753 --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java @@ -0,0 +1,142 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.fo.properties; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.PropertyList; + +/** + * A shorthand parser for the vertical-align shorthand. It is used to set + * values for alignment-baseline, alignment-adjust, baseline-shift + * and dominant-baseline. + */ +public class VerticalAlignShorthandParser implements ShorthandParser, Constants { + + /** + * @see ShorthandParser#getValueForProperty(int, Property, PropertyMaker, PropertyList) + */ + public Property getValueForProperty(int propId, + Property property, + PropertyMaker maker, + PropertyList propertyList) { + int propVal = property.getEnum(); + switch (propVal) { + case EN_BASELINE: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_BASELINE, "BASELINE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_TOP: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_BEFORE_EDGE, "BEFORE_EDGE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_TEXT_TOP: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_TEXT_BEFORE_EDGE, "TEXT_BEFORE_EDGE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_MIDDLE: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_MIDDLE, "MIDDLE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_BOTTOM: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_AFTER_EDGE, "AFTER_EDGE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_TEXT_BOTTOM: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_SUB: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_BASELINE, "BASELINE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_SUB, "SUB")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + case EN_SUPER: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_BASELINE, "BASELINE"); + case PR_ALIGNMENT_ADJUST: + return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_SUPER, "SUPER")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + default: + switch (propId) { + case PR_ALIGNMENT_BASELINE: + return new EnumProperty(EN_BASELINE, "BASELINE"); + case PR_ALIGNMENT_ADJUST: + return property; + case PR_BASELINE_SHIFT: + return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + case PR_DOMINANT_BASELINE: + return new EnumProperty(EN_AUTO, "AUTO"); + } + } + return null; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java index ea8dab3e7..cec2c5425 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java @@ -33,9 +33,11 @@ import org.apache.fop.fo.FObj; public abstract class AbstractBaseLayoutManager implements LayoutManager, PercentBaseContext { + /** Indicator if this LM generates reference areas */ protected boolean generatesReferenceArea = false; + /** Indicator if this LM generates block areas */ protected boolean generatesBlockArea = false; - + /** The formatting object for this LM */ protected FObj fobj = null; /** @@ -258,6 +260,9 @@ public abstract class AbstractBaseLayoutManager return false; } + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getFObj + */ public FObj getFObj() { return fobj; } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index e25cdc5a4..80b49aafb 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -36,18 +36,27 @@ import java.util.Map; */ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager implements Constants { + + /** Parent LayoutManager for this LayoutManager */ protected LayoutManager parentLM = null; + /** List of child LayoutManagers */ protected List childLMs = null; + /** Iterator for child LayoutManagers */ protected ListIterator fobjIter = null; + /** Marker map for markers related to this LayoutManager */ protected Map markers = null; /** True if this LayoutManager has handled all of its content. */ private boolean bFinished = false; - /** child LM and child LM iterator during getNextBreakPoss phase */ + /** child LM and child LM iterator during getNextKnuthElement phase */ protected LayoutManager curChildLM = null; + /** child LM and child LM iterator during getNextKnuthElement phase */ protected ListIterator childLMiter = null; + private int lastGeneratedPosition = -1; + private int smallestPosNumberChecked = Integer.MAX_VALUE; + /** * Abstract layout manager. */ @@ -69,14 +78,17 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager childLMiter = new LMiter(this); } + /** @see LayoutManager#setParent(LayoutManager) */ public void setParent(LayoutManager lm) { this.parentLM = lm; } + /** @see LayoutManager#getParent */ public LayoutManager getParent() { return this.parentLM; } + /** @see LayoutManager#initialize */ public void initialize() { // Empty } @@ -86,6 +98,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * all children have finished layout. * Note: child must implement LayoutManager! If it doesn't, skip it * and print a warning. + * @return the current child LayoutManager */ protected LayoutManager getChildLM() { if (curChildLM != null && !curChildLM.isFinished()) { @@ -99,6 +112,14 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return null; } + /** + * Return indication if getChildLM will return another LM. + * @return true if another child LM is still available + */ + protected boolean hasNextChildLM() { + return childLMiter.hasNext(); + } + /** * Reset the layoutmanager "iterator" so that it will start * with the passed Position's generating LM @@ -131,6 +152,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager } } + /** @see LayoutManager#resetPosition(Position) */ public void resetPosition(Position resetPos) { // if (resetPos == null) { // reset(null); @@ -146,12 +168,18 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return bFinished; } + /** + * Set the flag indicating the LayoutManager has handled all of its content. + * @param fin the flag value to be set + */ public void setFinished(boolean fin) { bFinished = fin; } /** - * @see org.apache.fop.layoutmgr.LayoutManager#addAreas(org.apache.fop.layoutmgr.PositionIterator, org.apache.fop.layoutmgr.LayoutContext) + * @see org.apache.fop.layoutmgr.LayoutManager#addAreas( + * org.apache.fop.layoutmgr.PositionIterator + * , org.apache.fop.layoutmgr.LayoutContext) */ public void addAreas(PositionIterator posIter, LayoutContext context) { } @@ -166,8 +194,10 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return null; } + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) + */ public LinkedList getChangedKnuthElements(List oldList, - /*int flaggedPenalty,*/ int alignment) { log.warn("null implementation of getChangeKnuthElement() called!"); return null; @@ -182,6 +212,8 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * Finally, based on the dimensions of the parent area, it initializes * its own area. This includes setting the content IPD and the maximum * BPD. + * @param childArea the child area for which the parent area is wanted + * @return the parent area for the given child */ public Area getParentArea(Area childArea) { return null; @@ -191,6 +223,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * Add a child area to the current area. If this causes the maximum * dimension of the current area to be exceeded, the parent LM is called * to add it. + * @param childArea the child area to be added */ public void addChildArea(Area childArea) { } @@ -286,4 +319,53 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager } } + /** + * Adds a Position to the Position participating in the first|last determination by assigning + * it a unique position index. + * @param pos the Position + * @return the same Position but with a position index + */ + protected Position notifyPos(Position pos) { + if (pos.getIndex() >= 0) { + throw new IllegalStateException("Position already got its index"); + } + lastGeneratedPosition++; + pos.setIndex(lastGeneratedPosition); + return pos; + } + + /** + * Indicates whether the given Position is the first area-generating Position of this LM. + * @param pos the Position (must be one with a position index) + * @return True if it is the first Position + */ + public boolean isFirst(Position pos) { + //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos); + if (pos.getIndex() < 0) { + throw new IllegalArgumentException("Only Positions with an index can be checked"); + } + if (pos.getIndex() == this.smallestPosNumberChecked) { + return true; + } else if (pos.getIndex() < this.smallestPosNumberChecked) { + this.smallestPosNumberChecked = pos.getIndex(); + return true; + } else { + return false; + } + } + + /** + * Indicates whether the given Position is the last area-generating Position of this LM. + * @param pos the Position (must be one with a position index) + * @return True if it is the last Position + */ + public boolean isLast(Position pos) { + //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos); + if (pos.getIndex() < 0) { + throw new IllegalArgumentException("Only Positions with an index can be checked"); + } + return (pos.getIndex() == this.lastGeneratedPosition + && isFinished()); + } + } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index 2fe1c2d38..55dd12dde 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -225,6 +225,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager { childLC.setStackLimit(MinOptMax.subtract(context .getStackLimit(), stackLimit)); childLC.setRefIPD(relDims.ipd); + childLC.setWritingMode(getBlockContainerFO().getWritingMode()); // get elements from curLM returnedList = curLM.getNextKnuthElements(childLC, alignment); @@ -523,6 +524,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager { protected LayoutContext createLayoutContext() { LayoutContext lc = super.createLayoutContext(); lc.setRefIPD(ipd.opt); + lc.setWritingMode(getBlockContainerFO().getWritingMode()); return lc; } @@ -534,7 +536,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager { LayoutContext childLC = new LayoutContext(0); childLC.setStackLimit(context.getStackLimit()); childLC.setRefIPD(context.getRefIPD()); - + childLC.setWritingMode(getBlockContainerFO().getWritingMode()); + LinkedList returnedList = null; if (!curLM.isFinished()) { returnedList = curLM.getNextKnuthElements(childLC, alignment); diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 0b9b2cd6c..d353727e4 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -152,7 +152,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { */ private LineLayoutManager createLineManager(LayoutManager firstlm) { LineLayoutManager llm; - llm = new LineLayoutManager(getBlockFO(), lineHeight, lead, follow, middleShift); + llm = new LineLayoutManager(getBlockFO(), lineHeight, lead, follow); List inlines = new java.util.ArrayList(); inlines.add(firstlm); while (proxyLMiter.hasNext()) { diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index b01e9d075..084101ce4 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -74,9 +74,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager /** see foSpaceBefore */ protected MinOptMax foSpaceAfter = null; - private int lastGeneratedPosition = -1; - private int smallestPosNumberChecked = Integer.MAX_VALUE; - private Position auxiliaryPosition; private int contentAreaIPD = 0; @@ -183,55 +180,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } } - /** - * Adds a Position to the Position participating in the first|last determination by assigning - * it a unique position index. - * @param pos the Position - * @return the same Position but with a position index - */ - protected Position notifyPos(Position pos) { - if (pos.getIndex() >= 0) { - throw new IllegalStateException("Position already got its index"); - } - lastGeneratedPosition++; - pos.setIndex(lastGeneratedPosition); - return pos; - } - - /** - * Indicates whether the given Position is the first area-generating Position of this LM. - * @param pos the Position (must be one with a position index) - * @return True if it is the first Position - */ - public boolean isFirst(Position pos) { - //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos); - if (pos.getIndex() < 0) { - throw new IllegalArgumentException("Only Positions with an index can be checked"); - } - if (pos.getIndex() == this.smallestPosNumberChecked) { - return true; - } else if (pos.getIndex() < this.smallestPosNumberChecked) { - this.smallestPosNumberChecked = pos.getIndex(); - return true; - } else { - return false; - } - } - - /** - * Indicates whether the given Position is the last area-generating Position of this LM. - * @param pos the Position (must be one with a position index) - * @return True if it is the last Position - */ - public boolean isLast(Position pos) { - //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos); - if (pos.getIndex() < 0) { - throw new IllegalArgumentException("Only Positions with an index can be checked"); - } - return (pos.getIndex() == this.lastGeneratedPosition - && isFinished()); - } - /** @return a cached auxiliary Position instance used for things like spaces. */ protected Position getAuxiliaryPosition() { if (this.auxiliaryPosition == null) { @@ -1400,6 +1348,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager return contentAreaIPD; } + /** + * Sets the IPD of the content area + * @param contentAreaIPD the IPD of the content area + */ protected void setContentAreaIPD(int contentAreaIPD) { this.contentAreaIPD = contentAreaIPD; } diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index 427bf39b5..37e852cb6 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -93,7 +93,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager LayoutContext childLC = new LayoutContext(0); childLC.setStackLimit(context.getStackLimit()); childLC.setRefIPD(context.getRefIPD()); - + childLC.setWritingMode(getCurrentPV().getSPM().getWritingMode()); + // get elements from curLM returnedList = curLM.getNextKnuthElements(childLC, alignment); //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size()); diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java index f63f23ccf..45ce1889b 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java @@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr; import org.apache.fop.fo.Constants; import org.apache.fop.layoutmgr.inline.HyphContext; import org.apache.fop.traits.MinOptMax; +import org.apache.fop.layoutmgr.inline.AlignmentContext; /** @@ -82,6 +83,9 @@ public class LayoutContext { /** inline-progression-dimension of nearest ancestor reference area */ int refIPD; + /** the writing mode established by the nearest ancestor reference area */ + private int writingMode = Constants.EN_LR_TB; + /** Current pending space-after or space-end from preceding area */ SpaceSpecifier trailingSpace; @@ -100,17 +104,23 @@ public class LayoutContext { /** Stretch or shrink value when adding spaces. */ private double dSpaceAdjust = 0.0; - private int iLineHeight; - private int iBaseline; - private int iMiddleShift; - private int iTopShift; /*LF*/ - private int iBottomShift; /*LF*/ - private int iSpaceBefore; /*LF*/ - private int iSpaceAfter; /*LF*/ + private AlignmentContext alignmentContext = null; + + /** Amount of space before / start */ + private int spaceBefore = 0; + + /** Amount of space after / end */ + private int spaceAfter = 0; + + /** Amount of space to reserve at the beginning of each line */ + private int lineStartBorderAndPaddingWidth = 0; + /** Amount of space to reserve at the end of each line */ + private int lineEndBorderAndPaddingWidth = 0; public LayoutContext(LayoutContext parentLC) { this.flags = parentLC.flags; this.refIPD = parentLC.refIPD; + this.writingMode = parentLC.writingMode; this.stackLimit = null; // Don't reference parent MinOptMax! this.leadingSpace = parentLC.leadingSpace; //??? this.trailingSpace = parentLC.trailingSpace; //??? @@ -118,13 +128,9 @@ public class LayoutContext { this.bpAlignment = parentLC.bpAlignment; this.dSpaceAdjust = parentLC.dSpaceAdjust; this.ipdAdjust = parentLC.ipdAdjust; - this.iLineHeight = parentLC.iLineHeight; - this.iBaseline = parentLC.iBaseline; - this.iMiddleShift = parentLC.iMiddleShift; -/*LF*/ this.iTopShift = parentLC.iTopShift; -/*LF*/ this.iBottomShift = parentLC.iBottomShift; -/*LF*/ this.iSpaceBefore = parentLC.iSpaceBefore; -/*LF*/ this.iSpaceAfter = parentLC.iSpaceAfter; + this.alignmentContext = parentLC.alignmentContext; + this.lineStartBorderAndPaddingWidth = parentLC.lineStartBorderAndPaddingWidth; + this.lineEndBorderAndPaddingWidth = parentLC.lineEndBorderAndPaddingWidth; // Copy other fields as necessary. Use clone??? } @@ -257,60 +263,50 @@ public class LayoutContext { return ipdAdjust; } - public void setLineHeight(int lh) { - iLineHeight = lh; - } - - public int getLineHeight() { - return iLineHeight; - } - - public void setBaseline(int bl) { - iBaseline = bl; - } - - public int getBaseline() { - return iBaseline; + public void setAlignmentContext(AlignmentContext alignmentContext) { + this.alignmentContext = alignmentContext; } - public void setMiddleShift(int ms) { - iMiddleShift = ms; + public AlignmentContext getAlignmentContext() { + return this.alignmentContext; } - public int getMiddleBaseline() { - return iBaseline + iMiddleShift; + public void resetAlignmentContext() { + if (this.alignmentContext != null) { + this.alignmentContext = this.alignmentContext.getParentAlignmentContext(); + } } - public void setTopShift(int ts) { - iTopShift = ts; - } - - public int getTopBaseline() { - return iBaseline + iTopShift; - } - - public void setBottomShift(int bs) { - iBottomShift = bs; - } - - public int getBottomBaseline() { - return iBaseline + iBottomShift; - } - - public int getSpaceBefore() { - return iSpaceBefore; + /** + * Get the width to be reserved for border and padding at the start of the line. + * @return the width to be reserved + */ + public int getLineStartBorderAndPaddingWidth() { + return lineStartBorderAndPaddingWidth; } - public void setSpaceBefore(int sp) { - iSpaceBefore = sp; + /** + * Set the width to be reserved for border and padding at the start of the line. + * @param lineStartBorderAndPaddingWidth the width to be reserved + */ + public void setLineStartBorderAndPaddingWidth(int lineStartBorderAndPaddingWidth) { + this.lineStartBorderAndPaddingWidth = lineStartBorderAndPaddingWidth; } - - public int getSpaceAfter() { - return iSpaceAfter; + + /** + * Get the width to be reserved for border and padding at the end of the line. + * @return the width to be reserved + */ + public int getLineEndBorderAndPaddingWidth() { + return lineEndBorderAndPaddingWidth; } - - public void setSpaceAfter(int sp) { - iSpaceAfter = sp; + + /** + * Set the width to be reserved for border and padding at the end of the line. + * @param lineEndBorderAndPaddingWidth the width to be reserved + */ + public void setLineEndBorderAndPaddingWidth(int lineEndBorderAndPaddingWidth) { + this.lineEndBorderAndPaddingWidth = lineEndBorderAndPaddingWidth; } /** @@ -335,6 +331,54 @@ public class LayoutContext { } } + /** + * Get the writing mode of the relevant reference area. + * @return the applicable writing mode + */ + public int getWritingMode() { + return writingMode; + } + + /** + * Set the writing mode. + * @param writingMode the writing mode + */ + public void setWritingMode(int writingMode) { + this.writingMode = writingMode; + } + + /** + * Get the current amount of space before / start + * @return the space before / start amount + */ + public int getSpaceBefore() { + return spaceBefore; + } + + /** + * Set the amount of space before / start + * @param spaceBefore the amount of space before / start + */ + public void setSpaceBefore(int spaceBefore) { + this.spaceBefore = spaceBefore; + } + + /** + * Get the current amount of space after / end + * @return the space after / end amount + */ + public int getSpaceAfter() { + return spaceAfter; + } + + /** + * Set the amount of space after / end + * @param spaceAfter the amount of space after / end + */ + public void setSpaceAfter(int spaceAfter) { + this.spaceAfter = spaceAfter; + } + /** @see java.lang.Object#toString() */ public String toString() { return "Layout Context:" + @@ -344,17 +388,15 @@ public class LayoutContext { "\nReference IPD: \t" + getRefIPD() + "\nSpace Adjust: \t" + getSpaceAdjust() + "\nIPD Adjust: \t" + getIPDAdjust() + - "\nLine Height: \t" + getLineHeight() + - "\nBaseline: \t" + getBaseline() + - "\nMiddle Baseline: \t" + getMiddleBaseline() + "\nResolve Leading Space: \t" + resolveLeadingSpace() + "\nSuppress Leading Space: \t" + suppressLeadingSpace() + "\nIs First Area: \t" + isFirstArea() + "\nStarts New Area: \t" + startsNewArea() + "\nIs Last Area: \t" + isLastArea() + "\nTry Hyphenate: \t" + tryHyphenate() + - "\nKeeps: \t[" + (isKeepWithNextPending()?"keep-with-next":"") + "][" - + (isKeepWithPreviousPending()?"keep-with-previous":"") + "] pending"; + "\nKeeps: \t[" + (isKeepWithNextPending() ? "keep-with-next" : "") + "][" + + (isKeepWithPreviousPending() ? "keep-with-previous" : "") + "] pending"; } + } diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java index 324234482..949594beb 100644 --- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java @@ -279,6 +279,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager { LayoutContext childLC = new LayoutContext(0); childLC.setStackLimit(context.getStackLimit()); childLC.setRefIPD(context.getRefIPD()); + childLC.setWritingMode(context.getWritingMode()); LinkedList returnedList = null; if (!curLM.isFinished()) { diff --git a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java index 7bf854715..8ebe812fd 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java @@ -39,6 +39,7 @@ import org.apache.fop.layoutmgr.TraitSetter; */ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManager { + /** The graphics object this LM deals with */ protected AbstractGraphics fobj; /** @@ -72,7 +73,7 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage int ipd = -1; boolean bpdauto = false; if (hasLH) { - bpd = fobj.getLineHeight().getValue(this); + bpd = fobj.getLineHeight().getOptimum(this).getLength().getValue(this); } else { // this property does not apply when the line-height applies // isn't the block-progression-dimension always in the same @@ -183,11 +184,11 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage //Determine extra IPD from borders etc. int startIPD = borderProps.getPadding(CommonBorderPaddingBackground.START, - false/*bNotFirst*/, this); + false, this); startIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, - false/*bNotFirst*/); - int endIPD = borderProps.getPadding(CommonBorderPaddingBackground.END, false/*bNotLast*/, this); - endIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, false/*bNotLast*/); + false); + int endIPD = borderProps.getPadding(CommonBorderPaddingBackground.END, false, this); + endIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, false); xoffset += startIPD; //ipd += startIPD; @@ -220,48 +221,28 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage int alignment) { Viewport areaCurrent = getInlineArea(); setCurrentArea(areaCurrent); - setAlignment(fobj.getVerticalAlign()); - setLead(areaCurrent.getAllocBPD()); return super.getNextKnuthElements(context, alignment); } /** - * @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#addId() + * @see LeafNodeLayoutManager.makeAlignmentContext(LayoutContext) */ - protected void addId() { - getPSLM().addIDToPage(fobj.getId()); + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + return new AlignmentContext( + get(context).getAllocBPD() + , fobj.getAlignmentAdjust() + , fobj.getAlignmentBaseline() + , fobj.getBaselineShift() + , fobj.getDominantBaseline() + , context.getAlignmentContext() + ); } /** - * Offset this area. - * Offset the inline area in the bpd direction when adding the - * inline area. - * This is used for vertical alignment. - * External graphic uses the large allocation rectangle so we have - * to take the border/padding into account as well. - * @param area the inline area to be updated - * @param context the layout context used for adding the area - * @see LeafNodeLayoutManager#offsetArea(InlineArea, LayoutContext) + * @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#addId() */ - protected void offsetArea(InlineArea area, LayoutContext context) { - int bpd = area.getBPD() - + area.getBorderAndPaddingWidthBefore() - + area.getBorderAndPaddingWidthAfter(); - switch (verticalAlignment) { - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline() - bpd / 2); - break; - case EN_TOP: - area.setOffset(context.getTopBaseline()); - break; - case EN_BOTTOM: - area.setOffset(context.getBottomBaseline() - bpd); - break; - case EN_BASELINE: - default: - area.setOffset(context.getBaseline() - bpd); - break; - } + protected void addId() { + getPSLM().addIDToPage(fobj.getId()); } /** @@ -282,6 +263,8 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage return getIntrinsicWidth(); case LengthBase.IMAGE_INTRINSIC_HEIGHT: return getIntrinsicHeight(); + case LengthBase.ALIGNMENT_ADJUST: + return get(null).getBPD(); default: // Delegate to super class return super.getBaseLength(lengthBase, fobj); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java new file mode 100644 index 000000000..82cf7fbbf --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java @@ -0,0 +1,582 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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 org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.SimplePercentBaseContext; +import org.apache.fop.fo.Constants; +import org.apache.fop.fonts.Font; + +/** + * The alignment context is carried within a LayoutContext and as + * part of the Knuth Inline elements to facilitate proper line building. + * All measurements are in mpt. + */ +public class AlignmentContext implements Constants { + + /** The height or BPD of this context */ + private int areaHeight; + /** The computed line-height property value applicable */ + private int lineHeight; + /** The distance in BPD from the top of the box to the alignmentPoint */ + private int alignmentPoint; + /** The baseline shift value in effect */ + private int baselineShiftValue; + /** The computed alignment baseline identifier */ + private int alignmentBaselineIdentifier; + /** The x height */ + private int xHeight; + private ScaledBaselineTable scaledBaselineTable = null; + private ScaledBaselineTable actualBaselineTable = null; + private AlignmentContext parentAlignmentContext = null; + + /** + * Creates a new instance of AlignmentContext + * for graphics areas. + * @param height the total height of the area + * @param alignmentAdjust the alignment-adjust property + * @param alignmentBaseline the alignment-baseline property + * @param baselineShift the baseline-shift property + * @param dominantBaseline the dominant-baseline property + * @param parentAlignmentContext the parent alignment context + */ + public AlignmentContext(int height + , Length alignmentAdjust + , int alignmentBaseline + , Length baselineShift + , int dominantBaseline + , AlignmentContext parentAlignmentContext) { + + this.areaHeight = height; + this.lineHeight = height; + this.xHeight = height; + this.parentAlignmentContext = parentAlignmentContext; + this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable(); + setAlignmentBaselineIdentifier(alignmentBaseline + , parentAlignmentContext.getDominantBaselineIdentifier()); + setBaselineShift(baselineShift); + int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier(); + boolean newScaledBaselineTableRequired = false; + if (baselineShiftValue != 0) { + newScaledBaselineTableRequired = true; + } + switch (dominantBaseline) { + case EN_AUTO: + newScaledBaselineTableRequired = baselineShiftValue != 0; + break; + case EN_USE_SCRIPT: // TODO + break; + case EN_NO_CHANGE: + break; + case EN_RESET_SIZE: + newScaledBaselineTableRequired = true; + break; + default: + newScaledBaselineTableRequired = true; + dominantBaselineIdentifier = dominantBaseline; + break; + } + actualBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable( + height, + dominantBaselineIdentifier, + scaledBaselineTable.getWritingMode()); + if (newScaledBaselineTableRequired) { + scaledBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable( + height, + dominantBaselineIdentifier, + scaledBaselineTable.getWritingMode()); + } + setAlignmentAdjust(alignmentAdjust); + } + + /** + * Creates a new instance of AlignmentContext + * @param font the font + * @param lineHeight the computed value of the lineHeight property + * @param alignmentAdjust the alignment-adjust property + * @param alignmentBaseline the alignment-baseline property + * @param baselineShift the baseline-shift property + * @param dominantBaseline the dominant-baseline property + * @param parentAlignmentContext the parent alignment context + */ + public AlignmentContext(Font font + , int lineHeight + , Length alignmentAdjust + , int alignmentBaseline + , Length baselineShift + , int dominantBaseline + , AlignmentContext parentAlignmentContext) { + this.areaHeight = font.getAscender() - font.getDescender(); + this.lineHeight = lineHeight; + this.parentAlignmentContext = parentAlignmentContext; + this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable(); + this.xHeight = font.getXHeight(); + setAlignmentBaselineIdentifier(alignmentBaseline + , parentAlignmentContext.getDominantBaselineIdentifier()); + setBaselineShift(baselineShift); + int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier(); + boolean newScaledBaselineTableRequired = false; + if (baselineShiftValue != 0) { + newScaledBaselineTableRequired = true; + } + switch (dominantBaseline) { + case EN_AUTO: + newScaledBaselineTableRequired = baselineShiftValue != 0; + break; + case EN_USE_SCRIPT: // TODO + break; + case EN_NO_CHANGE: + break; + case EN_RESET_SIZE: + newScaledBaselineTableRequired = true; + break; + default: + newScaledBaselineTableRequired = true; + dominantBaselineIdentifier = dominantBaseline; + break; + } + actualBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, + dominantBaselineIdentifier, + scaledBaselineTable.getWritingMode()); + if (newScaledBaselineTableRequired) { + scaledBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, + dominantBaselineIdentifier, + scaledBaselineTable.getWritingMode()); + } + setAlignmentAdjust(alignmentAdjust); + } + + /** + * Creates a new instance of AlignmentContext based simply + * on the font and the writing mode. + * @param font the font + * @param lineHeight the omputed value of the lineHeight property + * @param writingMode the current writing mode + */ + public AlignmentContext(Font font, int lineHeight, int writingMode) { + this.areaHeight = font.getAscender() - font.getDescender(); + this.lineHeight = lineHeight; + this.xHeight = font.getXHeight(); + this.parentAlignmentContext = null; + this.scaledBaselineTable + = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, writingMode); + this.actualBaselineTable = scaledBaselineTable; + this.alignmentBaselineIdentifier = getDominantBaselineIdentifier(); + this.alignmentPoint = font.getAscender(); + this.baselineShiftValue = 0; + } + + /** + * Returns the alignment point for this context. + * This is the point on the start edge of the area this context + * applies to measured from the before edge of the area. + * @return the default alignment point + */ + public int getAlignmentPoint() { + return alignmentPoint; + } + + /** + * Returns the current value of baseline shift in effect. + * @return the baseline shift + */ + public int getBaselineShiftValue() { + return baselineShiftValue; + } + + /** + * Returns the current alignment baseline identifier + * @return the alignment baseline identifier + */ + public int getAlignmentBaselineIdentifier() { + return alignmentBaselineIdentifier; + } + + /** + * Sets the current alignment baseline identifer. For + * alignment-baseline values of "auto" and "baseline" this + * method does the conversion into the appropriate computed + * value assuming script is "auto" and the fo is not fo:character. + * @param alignmentBaseline the alignment-baseline property + * @param parentDominantBaselineIdentifier the dominant baseline of the parent fo + */ + private void setAlignmentBaselineIdentifier(int alignmentBaseline + , int parentDominantBaselineIdentifier) { + switch (alignmentBaseline) { + case EN_AUTO: // fall through + case EN_BASELINE: + this.alignmentBaselineIdentifier = parentDominantBaselineIdentifier; + break; + case EN_BEFORE_EDGE: + case EN_TEXT_BEFORE_EDGE: + case EN_CENTRAL: + case EN_MIDDLE: + case EN_AFTER_EDGE: + case EN_TEXT_AFTER_EDGE: + case EN_IDEOGRAPHIC: + case EN_ALPHABETIC: + case EN_HANGING: + case EN_MATHEMATICAL: + this.alignmentBaselineIdentifier = alignmentBaseline; + break; + case EN_TOP: + if (isHorizontalWritingMode()) { + this.alignmentBaselineIdentifier = EN_BEFORE_EDGE; + } else { + this.alignmentBaselineIdentifier = getDominantBaselineIdentifier(); + } + break; + case EN_BOTTOM: + if (isHorizontalWritingMode()) { + this.alignmentBaselineIdentifier = EN_AFTER_EDGE; + } else { + this.alignmentBaselineIdentifier = getDominantBaselineIdentifier(); + } + break; + case EN_TEXT_TOP: + if (isHorizontalWritingMode()) { + this.alignmentBaselineIdentifier = EN_TEXT_BEFORE_EDGE; + } else { + this.alignmentBaselineIdentifier = getDominantBaselineIdentifier(); + } + break; + case EN_TEXT_BOTTOM: + if (isHorizontalWritingMode()) { + this.alignmentBaselineIdentifier = EN_TEXT_AFTER_EDGE; + } else { + this.alignmentBaselineIdentifier = getDominantBaselineIdentifier(); + } + break; + } + } + + /** + * Sets the current alignment baseline identifer. For + * alignment-baseline values of "auto" and "baseline" this + * method does the conversion into the appropriate computed + * value assuming script is "auto" and the fo is not fo:character. + * @param alignmentAdjust the alignment-adjust property + */ + private void setAlignmentAdjust(Length alignmentAdjust) { + int beforeEdge = actualBaselineTable.getBaseline(EN_BEFORE_EDGE); + switch (alignmentAdjust.getEnum()) { + case EN_AUTO: + alignmentPoint = beforeEdge + - actualBaselineTable.getBaseline(alignmentBaselineIdentifier); + break; + case EN_BASELINE: + alignmentPoint = beforeEdge; + break; + case EN_BEFORE_EDGE: + case EN_TEXT_BEFORE_EDGE: + case EN_CENTRAL: + case EN_MIDDLE: + case EN_AFTER_EDGE: + case EN_TEXT_AFTER_EDGE: + case EN_IDEOGRAPHIC: + case EN_ALPHABETIC: + case EN_HANGING: + case EN_MATHEMATICAL: + alignmentPoint = beforeEdge + - actualBaselineTable.getBaseline(alignmentAdjust.getEnum()); + break; + case EN_TOP: // fall through + if (isHorizontalWritingMode()) { + alignmentPoint = 0; + } else { + alignmentPoint = beforeEdge; + } + break; + case EN_BOTTOM: + if (isHorizontalWritingMode()) { + alignmentPoint = beforeEdge - actualBaselineTable.getBaseline(EN_AFTER_EDGE); + } else { + alignmentPoint = beforeEdge; + } + break; + case EN_TEXT_TOP: + if (isHorizontalWritingMode()) { + alignmentPoint = beforeEdge + - actualBaselineTable.getBaseline(EN_TEXT_BEFORE_EDGE); + } else { + alignmentPoint = beforeEdge; + } + break; + case EN_TEXT_BOTTOM: + if (isHorizontalWritingMode()) { + alignmentPoint = beforeEdge + - actualBaselineTable.getBaseline(EN_TEXT_AFTER_EDGE); + } else { + alignmentPoint = beforeEdge; + } + break; + default: + alignmentPoint = beforeEdge + + alignmentAdjust.getValue(new SimplePercentBaseContext(null + , LengthBase.ALIGNMENT_ADJUST + , lineHeight)); + break; + } + } + + /** + * Return the scaled baseline table for this context. + * @return the scaled baseline table + */ + public ScaledBaselineTable getScaledBaselineTable() { + return this.scaledBaselineTable; + } + + /** + * Return the dominant baseline identifier. + * @return the dominant baseline identifier + */ + public int getDominantBaselineIdentifier() { + return scaledBaselineTable.getDominantBaselineIdentifier(); + } + + /** + * Return the writing mode. + * @return the writing mode + */ + public int getWritingMode() { + return scaledBaselineTable.getWritingMode(); + } + + /** + * Calculates the baseline shift value based on the baseline-shift + * property value. + * @param baselineShift the baseline shift property value + * @return the computed baseline shift value + */ + private void setBaselineShift(Length baselineShift) { + baselineShiftValue = 0; + ScaledBaselineTable sbt = null; + switch (baselineShift.getEnum()) { + case EN_BASELINE: //Nothing to do + break; + case EN_SUB: + baselineShiftValue = Math.round(-(xHeight / 2) + + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC) + ); + break; + case EN_SUPER: + baselineShiftValue = Math.round(parentAlignmentContext.getXHeight() + + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC) + ); + break; + case 0: // A or value + baselineShiftValue = baselineShift.getValue( + new SimplePercentBaseContext(null + , LengthBase.CUSTOM_BASE + , parentAlignmentContext.getLineHeight())); + break; + } + } + + /** + * Return the parent alignment context. + * @return the parent alignment context + */ + public AlignmentContext getParentAlignmentContext() { + return parentAlignmentContext; + } + + /** + * Return the offset between the current dominant baseline and + * the parent dominant baseline. + * @return the offset in shift direction + */ + public int getBaselineOffset() { + if (parentAlignmentContext == null) { + return 0; + } + return parentAlignmentContext.getScaledBaselineTable() + .getBaseline(alignmentBaselineIdentifier) + - scaledBaselineTable + .deriveScaledBaselineTable(parentAlignmentContext.getDominantBaselineIdentifier()) + .getBaseline(alignmentBaselineIdentifier) + - scaledBaselineTable + .getBaseline(parentAlignmentContext.getDominantBaselineIdentifier()) + + baselineShiftValue; + } + + /** + * Return the offset between the current dominant baseline and + * the outermost parent dominant baseline. + * @return the offet in shift direction + */ + public int getTotalBaselineOffset() { + int offset = 0; + if (parentAlignmentContext != null) { + offset = getBaselineOffset() + parentAlignmentContext.getTotalBaselineOffset(); + } + return offset; + } + + /** + * Return the offset between the alignment baseline and + * the outermost parent dominant baseline. + * @return the offset in shift direction + */ + public int getTotalAlignmentBaselineOffset() { + return getTotalAlignmentBaselineOffset(alignmentBaselineIdentifier); + } + + /** + * Return the offset between the given alignment baseline and + * the outermost parent dominant baseline. + * @param alignmentBaselineId the alignment baseline + * @return the offset + */ + public int getTotalAlignmentBaselineOffset(int alignmentBaselineId) { + int offset = baselineShiftValue; + if (parentAlignmentContext != null) { + offset = parentAlignmentContext.getTotalBaselineOffset() + + parentAlignmentContext.getScaledBaselineTable() + .getBaseline(alignmentBaselineId) + + baselineShiftValue; + } + return offset; + } + + /** + * Return the offset between the dominant baseline and + * the given actual baseline + * @param baselineIdentifier the baseline + * @return the offset + */ + public int getActualBaselineOffset(int baselineIdentifier) { + // This is the offset from the dominant baseline to the alignment baseline + int offset = getTotalAlignmentBaselineOffset() - getTotalBaselineOffset(); + // Add the offset to the actual baseline we want + offset += actualBaselineTable.deriveScaledBaselineTable(alignmentBaselineIdentifier) + .getBaseline(baselineIdentifier); + return offset; + } + + /** + * Return the offset the outermost parent dominant baseline + * and the top of this box. + * @return the offset + */ + private int getTotalTopOffset() { + int offset = getTotalAlignmentBaselineOffset() + getAltitude(); + return offset; + } + + /** + * Return the total height of the context. + * @return the height + */ + public int getHeight() { + return areaHeight; + } + + /** + * Return the line height of the context. + * @return the height + */ + public int getLineHeight() { + return lineHeight; + } + + /** + * The altitude of the context that is the height above the + * alignment point. + * @return the altitude + */ + public int getAltitude() { + return alignmentPoint; + } + + /** + * The depth of the context that is the height below + * alignment point. + * @return the altitude + */ + public int getDepth() { + return getHeight() - alignmentPoint; + } + + /** + * The x height of the context. + * @return the x height + */ + public int getXHeight() { + return this.xHeight; + } + + /** + * Resizes the line as specified. Assumes that the new alignment point + * is on the dominant baseline, that is this function should be called for + * line areas only. + * @param newLineHeight the new height of the line + * @param newAlignmentPoint the new alignment point + */ + public void resizeLine(int newLineHeight, int newAlignmentPoint) { + areaHeight = newLineHeight; + alignmentPoint = newAlignmentPoint; + scaledBaselineTable.setBeforeAndAfterBaselines(alignmentPoint + , alignmentPoint - areaHeight); + } + + /** + * Returns the offset from the before-edge of the parent to + * this context. + * @return the offset for rendering + */ + public int getOffset() { + int offset = 0; + if (parentAlignmentContext != null) { + offset = parentAlignmentContext.getTotalTopOffset() - getTotalTopOffset(); + } else { + offset = getAltitude() - scaledBaselineTable.getBaseline(EN_TEXT_BEFORE_EDGE); + } + return offset; + } + + /** + * Returns an indication if we still use the initial baseline table. + * The initial baseline table is the table generated by the Line LM. + * @return true if this is still the initial baseline table + */ + public boolean usesInitialBaselineTable() { + return parentAlignmentContext == null + || (scaledBaselineTable == parentAlignmentContext.getScaledBaselineTable() + && parentAlignmentContext.usesInitialBaselineTable()); + } + + private boolean isHorizontalWritingMode() { + return (getWritingMode() == EN_LR_TB || getWritingMode() == EN_RL_TB); + } + + /** @see java.lang.Object#toString() */ + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append("ah=" + areaHeight); + sb.append(" lp=" + lineHeight); + sb.append(" ap=" + alignmentPoint); + sb.append(" ab=" + alignmentBaselineIdentifier); + sb.append(" bs=" + baselineShiftValue); + return sb.toString(); + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/BasicScaledBaselineTable.java b/src/java/org/apache/fop/layoutmgr/inline/BasicScaledBaselineTable.java new file mode 100644 index 000000000..db2b35e22 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/BasicScaledBaselineTable.java @@ -0,0 +1,192 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.SimplePercentBaseContext; +import org.apache.fop.fo.Constants; + + +/** + * An implementation of the ScaledBaselineTable interface which calculates + * all baselines given the height above and below the dominant baseline. + */ +public class BasicScaledBaselineTable implements ScaledBaselineTable, Constants { + + /** A logger for this class */ + protected Log log = LogFactory.getLog(BasicScaledBaselineTable.class); + + private int altitude; + private int depth; + private int xHeight; + private int dominantBaselineIdentifier; + private int writingMode; + private int dominantBaselineOffset; + private int beforeEdgeOffset; + private int afterEdgeOffset; + + private static final float HANGING_BASELINE_FACTOR = 0.8f; + private static final float MATHEMATICAL_BASELINE_FACTOR = 0.5f; + + /** + * + * Creates a new instance of BasicScaledBaselineTable for the given + * altitude, depth, xHeight, baseline and writingmode. + * @param altitude the height of the box or the font ascender + * @param depth the font descender or 0 + * @param xHeight the font xHeight + * @param dominantBaselineIdentifier the dominant baseline given as an integer constant + * @param writingMode the writing mode given as an integer constant + */ + public BasicScaledBaselineTable(int altitude + , int depth + , int xHeight + , int dominantBaselineIdentifier + , int writingMode) { + this.altitude = altitude; + this.depth = depth; + this.xHeight = xHeight; + this.dominantBaselineIdentifier = dominantBaselineIdentifier; + this.writingMode = writingMode; + this.dominantBaselineOffset = getBaselineDefaultOffset(this.dominantBaselineIdentifier); + this.beforeEdgeOffset = altitude - dominantBaselineOffset; + this.afterEdgeOffset = depth - dominantBaselineOffset; + } + + /** + * Return the dominant baseline for this baseline table. + * @return the dominant baseline + */ + public int getDominantBaselineIdentifier() { + return this.dominantBaselineIdentifier; + } + + /** + * Return the writing mode for this baseline table. + * @return the writing mode + */ + public int getWritingMode() { + return this.writingMode; + } + + /** + * Return the baseline offset measured from the dominant + * baseline for the given baseline. + * @param baselineIdentifier the baseline identifier + * @return the baseline offset + */ + public int getBaseline(int baselineIdentifier) { + int offset = 0; + if (!isHorizontalWritingMode()) { + switch (baselineIdentifier) { + case EN_TOP: + case EN_TEXT_TOP: + case EN_TEXT_BOTTOM: + case EN_BOTTOM: + log.warn("The given baseline is only supported for horizontal" + + " writing modes"); + return 0; + } + } + switch (baselineIdentifier) { + case EN_TOP: // fall through + case EN_BEFORE_EDGE: + offset = beforeEdgeOffset; + break; + case EN_TEXT_TOP: + case EN_TEXT_BEFORE_EDGE: + case EN_HANGING: + case EN_CENTRAL: + case EN_MIDDLE: + case EN_MATHEMATICAL: + case EN_ALPHABETIC: + case EN_IDEOGRAPHIC: + case EN_TEXT_BOTTOM: + case EN_TEXT_AFTER_EDGE: + offset = getBaselineDefaultOffset(baselineIdentifier) - dominantBaselineOffset; + break; + case EN_BOTTOM: // fall through + case EN_AFTER_EDGE: + offset = afterEdgeOffset; + break; + } + return offset; + } + + private boolean isHorizontalWritingMode() { + return writingMode == EN_LR_TB || writingMode == EN_RL_TB; + } + + /** + * Return the baseline offset measured from the font's default + * baseline for the given baseline. + * @param baselineIdentifier the baseline identifier + * @return the baseline offset + */ + private int getBaselineDefaultOffset(int baselineIdentifier) { + int offset = 0; + switch (baselineIdentifier) { + case EN_TEXT_BEFORE_EDGE: + offset = altitude; + break; + case EN_HANGING: + offset = (int)Math.round(altitude * HANGING_BASELINE_FACTOR); + break; + case EN_CENTRAL: + offset = (altitude - depth) / 2 + depth; + break; + case EN_MIDDLE: + offset = xHeight / 2; + break; + case EN_MATHEMATICAL: + offset = (int)Math.round(altitude * MATHEMATICAL_BASELINE_FACTOR); + break; + case EN_ALPHABETIC: + offset = 0; + break; + case EN_IDEOGRAPHIC: // Fall through + case EN_TEXT_AFTER_EDGE: + offset = depth; + break; + } + return offset; + } + + /** + * @see ScaledBaselineTable#setBeforeAndAfterBaselines(int, int) + */ + public void setBeforeAndAfterBaselines(int beforeBaseline, int afterBaseline) { + beforeEdgeOffset = beforeBaseline; + afterEdgeOffset = afterBaseline; + } + + /** + * @see ScaledBaselineTable#getScaledBaselineTable(int) + */ + public ScaledBaselineTable deriveScaledBaselineTable(int baselineIdentifier) { + BasicScaledBaselineTable bac + = new BasicScaledBaselineTable(altitude, depth, xHeight + , baselineIdentifier, this.writingMode); + return bac; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java index c15ee02c4..4d3a9adc2 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java @@ -28,13 +28,15 @@ import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.Trait; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import java.util.List; import java.util.LinkedList; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.layoutmgr.inline.AlignmentContext; +import org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager.AreaInfo; /** * LayoutManager for the fo:character formatting object @@ -43,7 +45,8 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { private Character fobj; private MinOptMax letterSpaceIPD; private int hyphIPD; - private Font fs; + private Font font; + private CommonBorderPaddingBackground borderProps = null; /** * Constructor @@ -56,56 +59,29 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { fobj = node; } + /** @see LayoutManager#initialize */ public void initialize() { - InlineArea inline = getCharacterInlineArea(fobj); - setCurrentArea(inline); - - setAlignment(fobj.getVerticalAlign()); - fs = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); - + font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); SpaceVal ls = SpaceVal.makeLetterSpacing(fobj.getLetterSpacing()); letterSpaceIPD = ls.getSpace(); - hyphIPD = fs.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter); + hyphIPD = font.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter); + borderProps = fobj.getCommonBorderPaddingBackground(); + setCommonBorderPaddingBackground(borderProps); + org.apache.fop.area.inline.Character chArea = getCharacterInlineArea(fobj); + chArea.setBaselineOffset(font.getAscender()); + setCurrentArea(chArea); } - private InlineArea getCharacterInlineArea(Character node) { - org.apache.fop.area.inline.Character ch = - new org.apache.fop.area.inline.Character(node.getCharacter()); + private org.apache.fop.area.inline.Character getCharacterInlineArea(Character node) { + org.apache.fop.area.inline.Character ch + = new org.apache.fop.area.inline.Character(node.getCharacter()); TraitSetter.setProducerID(ch, node.getId()); TraitSetter.addTextDecoration(ch, fobj.getTextDecoration()); return ch; } - /** - * Offset this area. - * Offset the inline area in the bpd direction when adding the - * inline area. - * This is used for vertical alignment. - * Subclasses should override this if necessary. - * @param area the inline area to be updated - * @param context the layout context used for adding the area - */ - protected void offsetArea(InlineArea area, LayoutContext context) { - int bpd = area.getBPD(); - switch (verticalAlignment) { - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2); - break; - case EN_TOP: - area.setOffset(fs.getAscender()); - break; - case EN_BOTTOM: - area.setOffset(context.getLineHeight() - bpd + fs.getAscender()); - break; - case EN_BASELINE: - default: - area.setOffset(context.getBaseline()); - break; - } - } - - public LinkedList getNextKnuthElements(LayoutContext context, - int alignment) { + /** @see LayoutManager#getNextKnuthElements(LayoutContext, int) */ + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { MinOptMax ipd; curArea = get(context); KnuthSequence seq = new KnuthSequence(true); @@ -115,77 +91,69 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { return null; } - ipd = new MinOptMax(fs.getCharWidth(((org.apache.fop.area.inline.Character) curArea).getChar().charAt(0))); + ipd = new MinOptMax(font.getCharWidth(fobj.getCharacter())); curArea.setIPD(ipd.opt); - curArea.setBPD(fs.getAscender() - fs.getDescender()); + curArea.setBPD(font.getAscender() - font.getDescender()); - // offset is set in the offsetArea() method - //curArea.setOffset(textInfo.fs.getAscender()); - //curArea.setOffset(context.getBaseline()); - - curArea.addTrait(Trait.FONT_NAME, fs.getFontName()); - curArea.addTrait(Trait.FONT_SIZE, new Integer(fs.getFontSize())); + curArea.addTrait(Trait.FONT_NAME, font.getFontName()); + curArea.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); curArea.addTrait(Trait.COLOR, fobj.getColor()); - int bpd = curArea.getBPD(); - int lead = 0; - int total = 0; - int middle = 0; - switch (verticalAlignment) { - case EN_MIDDLE : middle = bpd / 2 ; - break; - case EN_TOP : // fall through - case EN_BOTTOM : total = bpd; - break; - case EN_BASELINE: // fall through - default : lead = fs.getAscender(); - total = bpd; - break; - } + // TODO: may need some special handling for fo:character + alignmentContext = new AlignmentContext(font + , font.getFontSize() + , fobj.getAlignmentAdjust() + , fobj.getAlignmentBaseline() + , fobj.getBaselineShift() + , fobj.getDominantBaseline() + , context.getAlignmentContext()); + addKnuthElementsForBorderPaddingStart(seq); + // create the AreaInfo object to store the computed values - areaInfo = new AreaInfo((short) 0, ipd, false, - lead, total, middle); + areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext); // node is a fo:Character if (letterSpaceIPD.min == letterSpaceIPD.max) { // constant letter space, only return a box - seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.lead, - areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), false)); + seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext, + notifyPos(new LeafPosition(this, 0)), false)); } else { // adjustable letter space, return a sequence of elements; // at the moment the character is supposed to have no letter spaces, // but returning this sequence allows us to change only one element // if addALetterSpaceTo() is called - seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.lead, - areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), false)); + seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext, + notifyPos(new LeafPosition(this, 0)), false)); seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); seq.add(new KnuthGlue(0, 0, 0, new LeafPosition(this, -1), true)); - seq.add(new KnuthInlineBox(0, 0, 0, 0, - new LeafPosition(this, -1), true)); + seq.add(new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), true)); } + addKnuthElementsForBorderPaddingEnd(seq); + LinkedList returnList = new LinkedList(); returnList.add(seq); setFinished(true); return returnList; } + /** @see InlineLevelLayoutManager#getWordChars(StringBuffer, Position) */ public void getWordChars(StringBuffer sbChars, Position bp) { sbChars.append (((org.apache.fop.area.inline.Character) curArea).getChar()); } + /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */ public void hyphenate(Position pos, HyphContext hc) { if (hc.getNextHyphPoint() == 1) { // the character ends a syllable areaInfo.bHyphenated = true; - bSomethingChanged = true; + isSomethingChanged = true; } else { // hc.getNextHyphPoint() returned -1 (no more hyphenation points) // or a number > 1; @@ -194,9 +162,10 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { hc.updateOffset(1); } + /** @see InlineLevelLayoutManager#applyChanges(list) */ public boolean applyChanges(List oldList) { setFinished(false); - if (bSomethingChanged) { + if (isSomethingChanged) { // there is nothing to do, // possible changes have already been applied // in the hyphenate() method @@ -206,24 +175,25 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } } - public LinkedList getChangedKnuthElements(List oldList, - int flaggedPenalty, - int alignment) { + /** @see LayoutManager#getChangedKnuthElements(List, int) */ + public LinkedList getChangedKnuthElements(List oldList, int alignment) { if (isFinished()) { return null; } LinkedList returnList = new LinkedList(); + addKnuthElementsForBorderPaddingStart(returnList); + if (letterSpaceIPD.min == letterSpaceIPD.max || areaInfo.iLScount == 0) { // constant letter space, or no letter space - returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.lead, - areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), false)); + returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt, + areaInfo.alignmentContext, + notifyPos(new LeafPosition(this, 0)), false)); if (areaInfo.bHyphenated) { returnList.add - (new KnuthPenalty(hyphIPD, flaggedPenalty, true, + (new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); } } else { @@ -231,8 +201,8 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { returnList.add (new KnuthInlineBox(areaInfo.ipdArea.opt - areaInfo.iLScount * letterSpaceIPD.opt, - areaInfo.lead, areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), false)); + areaInfo.alignmentContext, + notifyPos(new LeafPosition(this, 0)), false)); returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); returnList.add @@ -240,21 +210,25 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { areaInfo.iLScount * letterSpaceIPD.max - letterSpaceIPD.opt, areaInfo.iLScount * letterSpaceIPD.opt - letterSpaceIPD.min, new LeafPosition(this, -1), true)); - returnList.add(new KnuthInlineBox(0, 0, 0, 0, - new LeafPosition(this, -1), true)); + returnList.add(new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), true)); if (areaInfo.bHyphenated) { returnList.add - (new KnuthPenalty(hyphIPD, flaggedPenalty, true, + (new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); } } + addKnuthElementsForBorderPaddingEnd(returnList); + setFinished(true); return returnList; } + /** @see LeafNodeLayoutManager#addId */ protected void addId() { getPSLM().addIDToPage(fobj.getId()); } + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index 09a346664..d3abee08f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -118,21 +118,9 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager ListIterator contentIter = contentList.listIterator(); while (contentIter.hasNext()) { KnuthElement element = (KnuthElement) contentIter.next(); - if (element.isBox()) { + if (element instanceof KnuthInlineBox) { KnuthInlineBox box = (KnuthInlineBox) element; - if (box.getLead() > lineLead) { - lineLead = box.getLead(); - } - if (box.getTotal() > maxtb) { - maxtb = box.getTotal(); - } - // Is this needed? cf. LineLM.makeLineBreakPosition - // if (box.getMiddle() > lineLead) { - // lineLead = box.getMiddle(); - // } - if (box.getMiddle() > middlefollow) { - middlefollow = box.getMiddle(); - } + // TODO handle alignment here? } } @@ -141,8 +129,6 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager } LayoutContext lc = new LayoutContext(0); - lc.setBaseline(lineLead); - lc.setLineHeight(lineHeight); lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); lc.setLeadingSpace(new SpaceSpecifier(false)); diff --git a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java index 9a32ce9a3..29087b029 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java @@ -79,7 +79,7 @@ public class FootnoteLayoutManager extends AbstractLayoutManager //Inline part of the footnote is empty. Need to send back an auxiliary //zero-width, zero-height inline box so the footnote gets painted. KnuthSequence seq = new KnuthSequence(true); - seq.add(new KnuthInlineBox(0, 0, 0, 0, null, true)); + seq.add(new KnuthInlineBox(0, null, null, true)); returnedList.add(seq); } setFinished(true); diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java index 393633a29..6819cf408 100755 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java @@ -20,16 +20,21 @@ package org.apache.fop.layoutmgr.inline; import java.util.ListIterator; import java.util.LinkedList; +import java.util.List; import org.apache.fop.area.Area; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.InlineBlockParent; import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.Inline; import org.apache.fop.fo.flow.InlineLevel; +import org.apache.fop.fo.flow.Leader; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.fonts.Font; +import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthSequence; import org.apache.fop.layoutmgr.KnuthPenalty; @@ -38,7 +43,9 @@ import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.SpaceSpecifier; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager.StackingIter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -46,8 +53,7 @@ import org.apache.fop.traits.SpaceVal; * LayoutManager for objects which stack children in the inline direction, * such as Inline or Line */ -public class InlineLayoutManager extends InlineStackingLayoutManager - implements InlineLevelLayoutManager { +public class InlineLayoutManager extends InlineStackingLayoutManager { private InlineLevel fobj; private CommonMarginInline inlineProps = null; @@ -56,6 +62,23 @@ public class InlineLayoutManager extends InlineStackingLayoutManager private boolean areaCreated = false; private LayoutManager lastChildLM = null; // Set when return last breakposs; + private Position auxiliaryPosition; + + private Font font; + + /** The alignment adjust property */ + protected Length alignmentAdjust; + /** The alignment baseline property */ + protected int alignmentBaseline = EN_BASELINE; + /** The baseline shift property */ + protected Length baselineShift; + /** The dominant baseline property */ + protected int dominantBaseline; + /** The line height property */ + protected SpaceProperty lineHeight; + + private AlignmentContext alignmentContext = null; + /** * Create an inline layout manager. * This is used for fo's that create areas that @@ -73,6 +96,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager return (Inline)fobj; } + /** @see LayoutManager#initialize */ public void initialize() { inlineProps = fobj.getCommonMarginInline(); borderProps = fobj.getCommonBorderPaddingBackground(); @@ -83,32 +107,53 @@ public class InlineLayoutManager extends InlineStackingLayoutManager padding += borderProps.getPadding(CommonBorderPaddingBackground.AFTER, false, this); padding += borderProps.getBorderWidth(CommonBorderPaddingBackground.AFTER, false); extraBPD = new MinOptMax(padding); + font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); + lineHeight = fobj.getLineHeight(); + if (fobj instanceof Inline) { + alignmentAdjust = ((Inline)fobj).getAlignmentAdjust(); + alignmentBaseline = ((Inline)fobj).getAlignmentBaseline(); + baselineShift = ((Inline)fobj).getBaselineShift(); + dominantBaseline = ((Inline)fobj).getDominantBaseline(); + } else if (fobj instanceof Leader) { + alignmentAdjust = ((Leader)fobj).getAlignmentAdjust(); + alignmentBaseline = ((Leader)fobj).getAlignmentBaseline(); + baselineShift = ((Leader)fobj).getBaselineShift(); + dominantBaseline = ((Leader)fobj).getDominantBaseline(); + } + } + /** @see InlineStackingLayoutManager#getExtraIPD(boolean, boolean) */ protected MinOptMax getExtraIPD(boolean isNotFirst, boolean isNotLast) { - int borderAndPadding = borderProps.getPadding(CommonBorderPaddingBackground.START, - isNotFirst, this); - borderAndPadding += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, - isNotFirst); - borderAndPadding += borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this); - borderAndPadding += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast); + int borderAndPadding + = borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this); + borderAndPadding + += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, isNotFirst); + borderAndPadding + += borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this); + borderAndPadding + += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast); return new MinOptMax(borderAndPadding); } + /** @see InlineStackingLayoutManager#hasLeadingFence(boolean) */ protected boolean hasLeadingFence(boolean isNotFirst) { - return borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this)>0 - || borderProps.getBorderWidth(CommonBorderPaddingBackground.START, isNotFirst)>0; + return borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this) > 0 + || borderProps.getBorderWidth(CommonBorderPaddingBackground.START, isNotFirst) > 0; } + /** @see InlineStackingLayoutManager#hasTrailingFence(boolean) */ protected boolean hasTrailingFence(boolean isNotLast) { - return borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this)>0 - || borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast)>0; + return borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this) > 0 + || borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast) > 0; } + /** @see InlineStackingLayoutManager#getSpaceStart */ protected SpaceProperty getSpaceStart() { return inlineProps.spaceStart; } + /** @see InlineStackingLayoutManager#getSpaceEnd */ protected SpaceProperty getSpaceEnd() { return inlineProps.spaceEnd; } @@ -130,19 +175,16 @@ public class InlineLayoutManager extends InlineStackingLayoutManager * @see org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager#setTraits(boolean, boolean) */ protected void setTraits(boolean isNotFirst, boolean isNotLast) { - - // Add border and padding to current area and set flags (FIRST, LAST ...) - TraitSetter.setBorderPaddingTraits(getCurrentArea(), - borderProps, isNotFirst, isNotLast, this); - if (borderProps != null) { - TraitSetter.addBorders(getCurrentArea(), borderProps, this); + // Add border and padding to current area and set flags (FIRST, LAST ...) + TraitSetter.setBorderPaddingTraits(getCurrentArea(), + borderProps, isNotFirst, isNotLast, this); TraitSetter.addBackground(getCurrentArea(), borderProps, this); } } /** @see org.apache.fop.layoutmgr.LayoutManager */ - public LinkedList getNextKnuthElements(LayoutContext lc, int alignment) { + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { InlineLevelLayoutManager curILM; LayoutManager curLM, lastLM = null; @@ -154,18 +196,28 @@ public class InlineLayoutManager extends InlineStackingLayoutManager LinkedList returnList = new LinkedList(); KnuthSequence lastSequence = null; - SpaceSpecifier leadingSpace = lc.getLeadingSpace(); - - if (lc.startsNewArea()) { + SpaceSpecifier leadingSpace = context.getLeadingSpace(); + + alignmentContext = new AlignmentContext(font + , lineHeight.getOptimum(this).getLength().getValue(this) + , alignmentAdjust + , alignmentBaseline + , baselineShift + , dominantBaseline + , context.getAlignmentContext()); + + childLC = new LayoutContext(context); + childLC.setAlignmentContext(alignmentContext); + + if (context.startsNewArea()) { // First call to this LM in new parent "area", but this may // not be the first area created by this inline - childLC = new LayoutContext(lc); if (getSpaceStart() != null) { - lc.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this)); + context.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this)); } // Check for "fence" - if (hasLeadingFence(!lc.isFirstArea())) { + if (hasLeadingFence(!context.isFirstArea())) { // Reset leading space sequence for child areas leadingSpace = new SpaceSpecifier(false); } @@ -175,9 +227,32 @@ public class InlineLayoutManager extends InlineStackingLayoutManager StringBuffer trace = new StringBuffer("InlineLM:"); + // We'll add the border to the first inline sequence created. + // This flag makes sure we do it only once. + boolean borderAdded = false; + + if (borderProps != null) { + childLC.setLineStartBorderAndPaddingWidth(context.getLineStartBorderAndPaddingWidth() + + borderProps.getPadding(CommonBorderPaddingBackground.START, true, this) + + borderProps.getBorderWidth(CommonBorderPaddingBackground.START, true) + ); + childLC.setLineEndBorderAndPaddingWidth(context.getLineEndBorderAndPaddingWidth() + + borderProps.getPadding(CommonBorderPaddingBackground.END, true, this) + + borderProps.getBorderWidth(CommonBorderPaddingBackground.END, true) + ); + } + while ((curLM = (LayoutManager) getChildLM()) != null) { + if (!(curLM instanceof InlineLevelLayoutManager)) { + // A block LM + // Leave room for start/end border and padding + if (borderProps != null) { + childLC.setRefIPD(childLC.getRefIPD() + - borderProps.getIPPaddingAndBorder(false, this)); + } + } // get KnuthElements from curLM - returnedList = curLM.getNextKnuthElements(lc, alignment); + returnedList = curLM.getNextKnuthElements(childLC, alignment); if (returnedList == null) { // curLM returned null because it finished; // just iterate once more to see if there is another child @@ -199,12 +274,13 @@ public class InlineLayoutManager extends InlineStackingLayoutManager while (listIter.hasNext()) { returnedElement = (KnuthElement) listIter.next(); returnedElement.setPosition - (new NonLeafPosition(this, - returnedElement.getPosition())); + (notifyPos(new NonLeafPosition(this, + returnedElement.getPosition()))); } if (!sequence.isInlineSequence()) { if (lastSequence != null && lastSequence.isInlineSequence()) { - // log.error("Last inline sequence should be closed before a block sequence"); + // log.error("Last inline sequence should be closed before" + // + " a block sequence"); lastSequence.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); lastSequence = null; @@ -220,6 +296,10 @@ public class InlineLayoutManager extends InlineStackingLayoutManager if (lastSequence == null) { lastSequence = new KnuthSequence(true); returnList.add(lastSequence); + if (!borderAdded) { + addKnuthElementsForBorderPaddingStart(lastSequence); + borderAdded = true; + } if (log.isTraceEnabled()) { trace.append(" ["); } @@ -273,6 +353,10 @@ public class InlineLayoutManager extends InlineStackingLayoutManager if (log.isTraceEnabled()) { trace.append(" ["); } + if (!borderAdded) { + addKnuthElementsForBorderPaddingStart(lastSequence); + borderAdded = true; + } } else { if (log.isTraceEnabled()) { trace.append(" +"); @@ -282,15 +366,21 @@ public class InlineLayoutManager extends InlineStackingLayoutManager while (iter.hasNext()) { KnuthElement element = (KnuthElement) iter.next(); element.setPosition - (new NonLeafPosition(this, - element.getPosition())); + (notifyPos(new NonLeafPosition(this, + element.getPosition()))); } lastSequence.addAll(returnedList); if (log.isTraceEnabled()) { trace.append(" L"); } } + lastChildLM = curLM; } + + if (lastSequence != null) { + addKnuthElementsForBorderPaddingEnd(lastSequence); + } + setFinished(true); log.trace(trace); return returnList.size() == 0 ? null : returnList; @@ -307,6 +397,9 @@ public class InlineLayoutManager extends InlineStackingLayoutManager */ public void addAreas(PositionIterator parentIter, LayoutContext context) { + + Position lastPos = null; + addId(); setChildContext(new LayoutContext(context)); // Store current value @@ -334,14 +427,22 @@ public class InlineLayoutManager extends InlineStackingLayoutManager LayoutManager lastLM = null; // last child LM in this iterator while (parentIter.hasNext()) { pos = (NonLeafPosition) parentIter.next(); - positionList.add(pos.getPosition()); + if (pos.getPosition() != null) { + positionList.add(pos.getPosition()); + lastLM = pos.getPosition().getLM(); + lastPos = pos; + } } - if (pos != null) { + /*if (pos != null) { lastLM = pos.getPosition().getLM(); - } + }*/ - InlineArea parent = createArea(lastLM == null || lastLM instanceof InlineLevelLayoutManager); - parent.setBPD(context.getLineHeight()); + InlineArea parent = createArea(lastLM == null + || lastLM instanceof InlineLevelLayoutManager); + parent.setBPD(alignmentContext.getHeight()); + if (parent instanceof InlineParent) { + parent.setOffset(alignmentContext.getOffset()); + } setCurrentArea(parent); StackingIter childPosIter @@ -380,13 +481,14 @@ public class InlineLayoutManager extends InlineStackingLayoutManager context.getTrailingSpace().addSpace(new SpaceVal(getSpaceEnd(), this)); } + setTraits(areaCreated, !isLast(lastPos)); parentLM.addChildArea(getCurrentArea()); - setTraits(areaCreated, !isLast); context.setFlags(LayoutContext.LAST_AREA, isLast); areaCreated = true; } + /** @see LayoutManager#addChildArea(Area) */ public void addChildArea(Area childArea) { Area parent = getCurrentArea(); if (getContext().resolveLeadingSpace()) { @@ -397,154 +499,55 @@ public class InlineLayoutManager extends InlineStackingLayoutManager parent.addChildArea(childArea); } - /* - public KnuthElement addALetterSpaceTo(KnuthElement element) { - NonLeafPosition savedPos = (NonLeafPosition) element.getPosition(); - element.setPosition(savedPos.getPosition()); - - KnuthElement newElement - = ((InlineLevelLayoutManager) - element.getLayoutManager()).addALetterSpaceTo(element); - newElement.setPosition - (new NonLeafPosition(this, newElement.getPosition())); - element.setPosition(savedPos); - return newElement; - } - - public void getWordChars(StringBuffer sbChars, Position pos) { - Position newPos = ((NonLeafPosition) pos).getPosition(); - ((InlineLevelLayoutManager) - newPos.getLM()).getWordChars(sbChars, newPos); - } - - public void hyphenate(Position pos, HyphContext hc) { - Position newPos = ((NonLeafPosition) pos).getPosition(); - ((InlineLevelLayoutManager) - newPos.getLM()).hyphenate(newPos, hc); + /** @see LayoutManager#getChangedKnuthElements(List, int) */ + public LinkedList getChangedKnuthElements(List oldList, int alignment) { + LinkedList returnedList = new LinkedList(); + addKnuthElementsForBorderPaddingStart(returnedList); + returnedList.addAll(super.getChangedKnuthElements(oldList, alignment)); + addKnuthElementsForBorderPaddingEnd(returnedList); + return returnedList; } - - public boolean applyChanges(List oldList) { - // "unwrap" the Positions stored in the elements - ListIterator oldListIterator = oldList.listIterator(); - KnuthElement oldElement; - while (oldListIterator.hasNext()) { - oldElement = (KnuthElement) oldListIterator.next(); - oldElement.setPosition - (((NonLeafPosition) oldElement.getPosition()).getPosition()); - } - // reset the iterator - oldListIterator = oldList.listIterator(); - - InlineLevelLayoutManager prevLM = null; - InlineLevelLayoutManager currLM; - int fromIndex = 0; - - boolean bSomethingChanged = false; - while(oldListIterator.hasNext()) { - oldElement = (KnuthElement) oldListIterator.next(); - currLM = (InlineLevelLayoutManager) oldElement.getLayoutManager(); - // initialize prevLM - if (prevLM == null) { - prevLM = currLM; - } - - if (currLM != prevLM || !oldListIterator.hasNext()) { - if (oldListIterator.hasNext()) { - bSomethingChanged - = prevLM.applyChanges(oldList.subList(fromIndex, oldListIterator.previousIndex())) - || bSomethingChanged; - prevLM = currLM; - fromIndex = oldListIterator.previousIndex(); - } else if (currLM == prevLM) { - bSomethingChanged - = prevLM.applyChanges(oldList.subList(fromIndex, oldList.size())) - || bSomethingChanged; - } else { - bSomethingChanged - = prevLM.applyChanges(oldList.subList(fromIndex, oldListIterator.previousIndex())) - || bSomethingChanged; - bSomethingChanged - = currLM.applyChanges(oldList.subList(oldListIterator.previousIndex(), oldList.size())) - || bSomethingChanged; - } + + /** + * Creates Knuth elements for start border padding and adds them to the return list. + * @param returnList return list to add the additional elements to + */ + protected void addKnuthElementsForBorderPaddingStart(List returnList) { + //Border and Padding (start) + CommonBorderPaddingBackground borderAndPadding = fobj.getCommonBorderPaddingBackground(); + if (borderAndPadding != null) { + int ipStart = borderAndPadding.getBorderStartWidth(false) + + borderAndPadding.getPaddingStart(false, this); + if (ipStart > 0) { + returnList.add(new KnuthBox(ipStart, getAuxiliaryPosition(), true)); } } - - // "wrap" again the Positions stored in the elements - oldListIterator = oldList.listIterator(); - while (oldListIterator.hasNext()) { - oldElement = (KnuthElement) oldListIterator.next(); - oldElement.setPosition - (new NonLeafPosition(this, oldElement.getPosition())); - } - return bSomethingChanged; } - public LinkedList getChangedKnuthElements(List oldList, int flaggedPenalty, int alignment) { - // "unwrap" the Positions stored in the elements - ListIterator oldListIterator = oldList.listIterator(); - KnuthElement oldElement; - while (oldListIterator.hasNext()) { - oldElement = (KnuthElement) oldListIterator.next(); - oldElement.setPosition - (((NonLeafPosition) oldElement.getPosition()).getPosition()); - } - // reset the iterator - oldListIterator = oldList.listIterator(); - - KnuthElement returnedElement; - LinkedList returnedList = new LinkedList(); - LinkedList returnList = new LinkedList(); - InlineLevelLayoutManager prevLM = null; - InlineLevelLayoutManager currLM; - int fromIndex = 0; - - while(oldListIterator.hasNext()) { - oldElement = (KnuthElement) oldListIterator.next(); - currLM = (InlineLevelLayoutManager) oldElement.getLayoutManager(); - if (prevLM == null) { - prevLM = currLM; - } - - if (currLM != prevLM || !oldListIterator.hasNext()) { - if (oldListIterator.hasNext()) { - returnedList.addAll - (prevLM.getChangedKnuthElements - (oldList.subList(fromIndex, - oldListIterator.previousIndex()), - flaggedPenalty, alignment)); - prevLM = currLM; - fromIndex = oldListIterator.previousIndex(); - } else if (currLM == prevLM) { - returnedList.addAll - (prevLM.getChangedKnuthElements - (oldList.subList(fromIndex, oldList.size()), - flaggedPenalty, alignment)); - } else { - returnedList.addAll - (prevLM.getChangedKnuthElements - (oldList.subList(fromIndex, - oldListIterator.previousIndex()), - flaggedPenalty, alignment)); - returnedList.addAll - (currLM.getChangedKnuthElements - (oldList.subList(oldListIterator.previousIndex(), - oldList.size()), - flaggedPenalty, alignment)); - } + /** + * Creates Knuth elements for end border padding and adds them to the return list. + * @param returnList return list to add the additional elements to + */ + protected void addKnuthElementsForBorderPaddingEnd(List returnList) { + //Border and Padding (after) + CommonBorderPaddingBackground borderAndPadding = fobj.getCommonBorderPaddingBackground(); + if (borderAndPadding != null) { + int ipEnd = borderAndPadding.getBorderEndWidth(false) + + borderAndPadding.getPaddingEnd(false, this); + if (ipEnd > 0) { + returnList.add(new KnuthBox(ipEnd, getAuxiliaryPosition(), true)); } } + } - // "wrap" the Position stored in each element of returnedList - ListIterator listIter = returnedList.listIterator(); - while (listIter.hasNext()) { - returnedElement = (KnuthElement) listIter.next(); - returnedElement.setPosition - (new NonLeafPosition(this, returnedElement.getPosition())); - returnList.add(returnedElement); - } - return returnList; - }*/ + /** @return a cached auxiliary Position instance used for things like spaces. */ + protected Position getAuxiliaryPosition() { + //if (this.auxiliaryPosition == null) { + //this.auxiliaryPosition = new NonLeafPosition(this, new LeafPosition(this, -1)); + this.auxiliaryPosition = new NonLeafPosition(this, null); + //} + return this.auxiliaryPosition; + } /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#addId() */ protected void addId() { diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java index f5fc7315f..515caf578 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java @@ -75,6 +75,8 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager private Area currentArea; // LineArea or InlineParent //private BreakPoss prevBP; + + /** The child layout context */ protected LayoutContext childLC; private boolean bAreaCreated = false; @@ -105,23 +107,48 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager childLMiter = iter; } + /** + * Returns the extra IPD needed for any leading or trailing fences for the + * current area. + * @param bNotFirst true if not the first area for this layout manager + * @param bNotLast true if not the last area for this layout manager + * @return the extra IPD as a MinOptMax spec + */ protected MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) { return new MinOptMax(0); } + /** + * Indication if the current area has a leading fence. + * @param bNotFirst true if not the first area for this layout manager + * @return the leading fence flag + */ protected boolean hasLeadingFence(boolean bNotFirst) { return false; } + /** + * Indication if the current area has a trailing fence. + * @param bNotLast true if not the last area for this layout manager + * @return the trailing fence flag + */ protected boolean hasTrailingFence(boolean bNotLast) { return false; } + /** + * Get the space at the start of the inline area. + * @return the space property describing the space + */ protected SpaceProperty getSpaceStart() { return null; } + /** + * Get the space at the end of the inline area. + * @return the space property describing the space + */ protected SpaceProperty getSpaceEnd() { return null; } @@ -161,6 +188,11 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager // What about prevBP? } + /** + * TODO: Explain this method + * @param lm ??? + * @return ??? + */ protected MinOptMax getPrevIPD(LayoutManager lm) { return (MinOptMax) hmPrevIPD.get(lm); } @@ -180,27 +212,52 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager // Do nothing here, overriden in subclasses that have an 'id' property. } + /** + * Returns the current area. + * @return the current area + */ protected Area getCurrentArea() { return currentArea; } + /** + * Set the current area. + * @param area the current area + */ protected void setCurrentArea(Area area) { currentArea = area; } + /** + * Trait setter to be overridden by subclasses. + * @param bNotFirst true if this is not the first child area added + * @param bNotLast true if this is not the last child area added + */ protected void setTraits(boolean bNotFirst, boolean bNotLast) { - } + /** + * Set the current child layout context + * @param lc the child layout context + */ protected void setChildContext(LayoutContext lc) { childLC = lc; } - // Current child layout context + /** + * Current child layout context + * @return the current child layout context + */ protected LayoutContext getContext() { return childLC; } + /** + * Adds a space to the area + * @param parentArea the area to which to add the space + * @param spaceRange the space range specifier + * @param dSpaceAdjust the factor by which to stretch or shrink the space + */ protected void addSpace(Area parentArea, MinOptMax spaceRange, double dSpaceAdjust) { if (spaceRange != null) { @@ -223,6 +280,7 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager } } + /** @see InlineLevelLayoutManager#addALetterSpaceTo(List) */ public List addALetterSpaceTo(List oldList) { // old list contains only a box, or the sequence: box penalty glue box @@ -241,7 +299,7 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager oldListIterator = oldList.listIterator(); while (oldListIterator.hasNext()) { element = (KnuthElement) oldListIterator.next(); - element.setPosition(new NonLeafPosition(this, element.getPosition())); + element.setPosition(notifyPos(new NonLeafPosition(this, element.getPosition()))); } return oldList; @@ -268,18 +326,21 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager } + /** @see InlineLevelLayoutManager#getWordChars(StringBuffer, Position) */ public void getWordChars(StringBuffer sbChars, Position pos) { Position newPos = ((NonLeafPosition) pos).getPosition(); ((InlineLevelLayoutManager) newPos.getLM()).getWordChars(sbChars, newPos); } + /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */ public void hyphenate(Position pos, HyphContext hc) { Position newPos = ((NonLeafPosition) pos).getPosition(); ((InlineLevelLayoutManager) newPos.getLM()).hyphenate(newPos, hc); } + /** @see InlineLevelLayoutManager#applyChanges(List) */ public boolean applyChanges(List oldList) { // "unwrap" the Positions stored in the elements ListIterator oldListIterator = oldList.listIterator(); @@ -297,7 +358,7 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager int fromIndex = 0; boolean bSomethingChanged = false; - while(oldListIterator.hasNext()) { + while (oldListIterator.hasNext()) { oldElement = (KnuthElement) oldListIterator.next(); currLM = (InlineLevelLayoutManager) oldElement.getLayoutManager(); // initialize prevLM @@ -306,23 +367,30 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager } if (currLM != prevLM || !oldListIterator.hasNext()) { - if (oldListIterator.hasNext()) { + if (prevLM == this || currLM == this) { + prevLM = currLM; + } else if (oldListIterator.hasNext()) { bSomethingChanged - = prevLM.applyChanges(oldList.subList(fromIndex, oldListIterator.previousIndex())) + = prevLM.applyChanges(oldList.subList(fromIndex + , oldListIterator.previousIndex())) || bSomethingChanged; prevLM = currLM; fromIndex = oldListIterator.previousIndex(); } else if (currLM == prevLM) { bSomethingChanged = prevLM.applyChanges(oldList.subList(fromIndex, oldList.size())) - || bSomethingChanged; + || bSomethingChanged; } else { bSomethingChanged - = prevLM.applyChanges(oldList.subList(fromIndex, oldListIterator.previousIndex())) - || bSomethingChanged; - bSomethingChanged - = currLM.applyChanges(oldList.subList(oldListIterator.previousIndex(), oldList.size())) - || bSomethingChanged; + = prevLM.applyChanges(oldList.subList(fromIndex + , oldListIterator.previousIndex())) + || bSomethingChanged; + if (currLM != null) { + bSomethingChanged + = currLM.applyChanges(oldList.subList(oldListIterator.previousIndex() + , oldList.size())) + || bSomethingChanged; + } } } } @@ -332,12 +400,15 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager while (oldListIterator.hasNext()) { oldElement = (KnuthElement) oldListIterator.next(); oldElement.setPosition - (new NonLeafPosition(this, oldElement.getPosition())); + (notifyPos(new NonLeafPosition(this, oldElement.getPosition()))); } return bSomethingChanged; } - public LinkedList getChangedKnuthElements(List oldList, /*int flaggedPenalty,*/ int alignment) { + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) + */ + public LinkedList getChangedKnuthElements(List oldList, int alignment) { // "unwrap" the Positions stored in the elements ListIterator oldListIterator = oldList.listIterator(); KnuthElement oldElement; @@ -356,7 +427,7 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager InlineLevelLayoutManager currLM; int fromIndex = 0; - while(oldListIterator.hasNext()) { + while (oldListIterator.hasNext()) { oldElement = (KnuthElement) oldListIterator.next(); currLM = (InlineLevelLayoutManager) oldElement.getLayoutManager(); if (prevLM == null) { @@ -383,11 +454,13 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager (oldList.subList(fromIndex, oldListIterator.previousIndex()), /*flaggedPenalty,*/ alignment)); - returnedList.addAll - (currLM.getChangedKnuthElements - (oldList.subList(oldListIterator.previousIndex(), - oldList.size()), - /*flaggedPenalty,*/ alignment)); + if (currLM != null) { + returnedList.addAll + (currLM.getChangedKnuthElements + (oldList.subList(oldListIterator.previousIndex(), + oldList.size()), + /*flaggedPenalty,*/ alignment)); + } } } } @@ -397,7 +470,7 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager while (listIter.hasNext()) { returnedElement = (KnuthElement) listIter.next(); returnedElement.setPosition - (new NonLeafPosition(this, returnedElement.getPosition())); + (notifyPos(new NonLeafPosition(this, returnedElement.getPosition()))); returnList.add(returnedElement); } return returnList; diff --git a/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java b/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java index 63568bd8d..e3e896d71 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java +++ b/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java @@ -18,53 +18,34 @@ package org.apache.fop.layoutmgr.inline; +import org.apache.fop.layoutmgr.inline.AlignmentContext; import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.Position; public class KnuthInlineBox extends KnuthBox { - private int lead; - private int total; - private int middle; private FootnoteBodyLayoutManager footnoteBodyLM = null; + private AlignmentContext alignmentContext = null; /** * Create a new KnuthBox. * * @param w the width of this box - * @param l the height of this box above the main baseline - * @param t the total height of this box - * @param m the height of this box above and below the middle baseline + * @param alignmentContext the alignmentContext for this box * @param pos the Position stored in this box * @param bAux is this box auxiliary? */ - public KnuthInlineBox(int w, int l, int t, int m, Position pos, boolean bAux) { + public KnuthInlineBox(int w, AlignmentContext alignmentContext, Position pos, boolean bAux) { super(w, pos, bAux); - lead = l; - total = t; - middle = m; + this.alignmentContext = alignmentContext; } /** - * @return the height of this box above the main baseline. + * @return the alignment context. */ - public int getLead() { - return lead; - } - - /** - * @return the total height of this box. - */ - public int getTotal() { - return total; - } - - /** - * @return the height of this box above and below the middle baseline. - */ - public int getMiddle() { - return middle; + public AlignmentContext getAlignmentContext() { + return alignmentContext; } /** @@ -92,9 +73,6 @@ public class KnuthInlineBox extends KnuthBox { /** @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(super.toString()); - sb.append(" lead=").append(lead); - sb.append(" total=").append(total); - sb.append(" middle=").append(middle); return sb.toString(); } } \ No newline at end of file diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java index c09b682ef..185ab68f2 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java @@ -46,7 +46,7 @@ import org.apache.fop.fo.FObj; */ public class LeaderLayoutManager extends LeafNodeLayoutManager { private Leader fobj; - Font font = null; + private Font font = null; private LinkedList contentList = null; private ContentLayoutManager clm = null; @@ -57,35 +57,52 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { * Constructor * * @param node the formatting object that creates this area - * @todo better null checking of font object */ public LeaderLayoutManager(Leader node) { super(node); fobj = node; } + /** @see LayoutManager#initialize */ public void initialize() { font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); // the property leader-alignment does not affect vertical positioning // (see section 7.21.1 in the XSL Recommendation) // setAlignment(node.getLeaderAlignment()); - setAlignment(fobj.getVerticalAlign()); + setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground()); } + /** + * Return the inline area for this leader. + * @param context the layout context + * @return the inline area + */ public InlineArea get(LayoutContext context) { return getLeaderInlineArea(); } + /** + * Return the allocated IPD for this area. + * @param refIPD the IPD of the reference area + * @return the allocated IPD + */ protected MinOptMax getAllocationIPD(int refIPD) { return getLeaderAllocIPD(refIPD); } private MinOptMax getLeaderAllocIPD(int ipd) { // length of the leader - setContentAreaIPD(ipd); - int opt = fobj.getLeaderLength().getOptimum(this).getLength().getValue(this); - int min = fobj.getLeaderLength().getMinimum(this).getLength().getValue(this); - int max = fobj.getLeaderLength().getMaximum(this).getLength().getValue(this); + int borderPaddingWidth = 0; + if (commonBorderPaddingBackground != null) { + borderPaddingWidth = commonBorderPaddingBackground.getIPPaddingAndBorder(false, this); + } + setContentAreaIPD(ipd - borderPaddingWidth); + int opt = fobj.getLeaderLength().getOptimum(this).getLength().getValue(this) + - borderPaddingWidth; + int min = fobj.getLeaderLength().getMinimum(this).getLength().getValue(this) + - borderPaddingWidth; + int max = fobj.getLeaderLength().getMaximum(this).getLength().getValue(this) + - borderPaddingWidth; return new MinOptMax(min, opt, max); } @@ -93,24 +110,31 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { InlineArea leaderArea = null; if (fobj.getLeaderPattern() == EN_RULE) { - org.apache.fop.area.inline.Leader leader = - new org.apache.fop.area.inline.Leader(); - leader.setRuleStyle(fobj.getRuleStyle()); - leader.setRuleThickness(fobj.getRuleThickness().getValue(this)); - leader.setBPD(fobj.getRuleThickness().getValue(this)); - leaderArea = leader; + if (fobj.getRuleStyle() != EN_NONE) { + org.apache.fop.area.inline.Leader leader + = new org.apache.fop.area.inline.Leader(); + leader.setRuleStyle(fobj.getRuleStyle()); + leader.setRuleThickness(fobj.getRuleThickness().getValue(this)); + leader.setBPD(fobj.getRuleThickness().getValue(this)); + leaderArea = leader; + } else { + leaderArea = new Space(); + leaderArea.setBPD(1); + } } else if (fobj.getLeaderPattern() == EN_SPACE) { leaderArea = new Space(); - leaderArea.setBPD(font.getAscender()); + leaderArea.setBPD(1); } else if (fobj.getLeaderPattern() == EN_DOTS) { TextArea t = new TextArea(); char dot = '.'; // userAgent.getLeaderDotCharacter(); + int width = font.getCharWidth(dot); t.setTextArea("" + dot); - t.setIPD(font.getCharWidth(dot)); + t.setIPD(width); + t.setBPD(width); + t.setBaselineOffset(width); t.addTrait(Trait.FONT_NAME, font.getFontName()); t.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); - int width = font.getCharWidth(dot); Space spacer = null; if (fobj.getLeaderPatternWidth().getValue(this) > width) { spacer = new Space(); @@ -123,7 +147,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { if (spacer != null) { fa.addChildArea(spacer); } - fa.setBPD(font.getAscender()); + fa.setBPD(t.getBPD()); leaderArea = fa; } else if (fobj.getLeaderPattern() == EN_USECONTENT) { @@ -163,68 +187,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { return leaderArea; } - protected void offsetArea(InlineArea area, LayoutContext context) { - int pattern = fobj.getLeaderPattern(); - int bpd = area.getBPD(); - - switch (pattern) { - case EN_RULE: - switch (verticalAlignment) { - case EN_TOP: - area.setOffset(0); - break; - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline() - bpd / 2); - break; - case EN_BOTTOM: - area.setOffset(context.getLineHeight() - bpd); - break; - case EN_BASELINE: // fall through - default: - area.setOffset(context.getBaseline() - bpd); - break; - } - break; - case EN_DOTS: - switch (verticalAlignment) { - case EN_TOP: - area.setOffset(0); - break; - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline()); - break; - case EN_BOTTOM: - area.setOffset(context.getLineHeight() - bpd + font.getAscender()); - break; - case EN_BASELINE: // fall through - default: - area.setOffset(context.getBaseline()); - break; - } - break; - case EN_SPACE: - // nothing to do - break; - case EN_USECONTENT: - switch (verticalAlignment) { - case EN_TOP: - area.setOffset(0); - break; - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline()); - break; - case EN_BOTTOM: - area.setOffset(context.getLineHeight() - bpd); - break; - case EN_BASELINE: // fall through - default: - area.setOffset(context.getBaseline()); - break; - } - break; - } - } - + /** @see LeafNodeLayoutManager#addAreas(PositionIterator, LayoutContext) */ public void addAreas(PositionIterator posIter, LayoutContext context) { if (fobj.getLeaderPattern() != EN_USECONTENT) { // use LeafNodeLayoutManager.addAreas() @@ -247,6 +210,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { } } + /** @see LayoutManager#getNextKnuthElements(LayoutContext, int) */ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { MinOptMax ipd; @@ -258,30 +222,22 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { return null; } - ipd = getAllocationIPD(context.getRefIPD()); + alignmentContext = new AlignmentContext(curArea.getBPD() + , fobj.getAlignmentAdjust() + , fobj.getAlignmentBaseline() + , fobj.getBaselineShift() + , fobj.getDominantBaseline() + , context.getAlignmentContext()); - int bpd = curArea.getBPD(); - int lead = 0; - int total = 0; - int middle = 0; - switch (verticalAlignment) { - case EN_MIDDLE : middle = bpd / 2 ; - break; - case EN_TOP : // fall through - case EN_BOTTOM : total = bpd; - break; - case EN_BASELINE: // fall through - default: lead = bpd; - break; - } + ipd = getAllocationIPD(context.getRefIPD()); // create the AreaInfo object to store the computed values - areaInfo = new AreaInfo((short) 0, ipd, false, - lead, total, middle); + areaInfo = new AreaInfo((short) 0, ipd, false, context.getAlignmentContext()); + addKnuthElementsForBorderPaddingStart(seq); + // node is a fo:Leader - seq.add(new KnuthInlineBox(0, areaInfo.lead, areaInfo.total, - areaInfo.middle, + seq.add(new KnuthInlineBox(0, alignmentContext, new LeafPosition(this, -1), true)); seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); @@ -290,28 +246,31 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { areaInfo.ipdArea.max - areaInfo.ipdArea.opt, areaInfo.ipdArea.opt - areaInfo.ipdArea.min, new LeafPosition(this, 0), false)); - seq.add(new KnuthInlineBox(0, areaInfo.lead, areaInfo.total, - areaInfo.middle, + seq.add(new KnuthInlineBox(0, alignmentContext, new LeafPosition(this, -1), true)); + addKnuthElementsForBorderPaddingEnd(seq); + LinkedList returnList = new LinkedList(); returnList.add(seq); setFinished(true); return returnList; } + /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */ public void hyphenate(Position pos, HyphContext hc) { // use the AbstractLayoutManager.hyphenate() null implementation super.hyphenate(pos, hc); } + /** @see InlineLevelLayoutManager#applyChanges(list) */ public boolean applyChanges(List oldList) { setFinished(false); return false; } + /** @see LayoutManager#getNextKnuthElements(LayoutContext, int) */ public LinkedList getChangedKnuthElements(List oldList, - int flaggedPenalty, int alignment) { if (isFinished()) { return null; @@ -319,8 +278,9 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { LinkedList returnList = new LinkedList(); - returnList.add(new KnuthInlineBox(0, areaInfo.lead, areaInfo.total, - areaInfo.middle, + addKnuthElementsForBorderPaddingStart(returnList); + + returnList.add(new KnuthInlineBox(0, areaInfo.alignmentContext, new LeafPosition(this, -1), true)); returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); @@ -329,14 +289,16 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { areaInfo.ipdArea.max - areaInfo.ipdArea.opt, areaInfo.ipdArea.opt - areaInfo.ipdArea.min, new LeafPosition(this, 0), false)); - returnList.add(new KnuthInlineBox(0, areaInfo.lead, areaInfo.total, - areaInfo.middle, + returnList.add(new KnuthInlineBox(0, areaInfo.alignmentContext, new LeafPosition(this, -1), true)); + addKnuthElementsForBorderPaddingEnd(returnList); + setFinished(true); return returnList; } + /** @see LeafNodeLayoutManager#addId */ protected void addId() { getPSLM().addIDToPage(fobj.getId()); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java index e4e037197..ef5bee9fa 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java @@ -18,19 +18,24 @@ package org.apache.fop.layoutmgr.inline; +import java.util.LinkedList; +import java.util.List; + import org.apache.fop.area.Area; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.layoutmgr.AbstractLayoutManager; +import org.apache.fop.layoutmgr.KnuthGlue; +import org.apache.fop.layoutmgr.KnuthPenalty; import org.apache.fop.layoutmgr.KnuthSequence; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; -import java.util.List; -import java.util.LinkedList; /** * Base LayoutManager for leaf-node FObj, ie: ones which have no children. @@ -45,11 +50,16 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager * The inline area that this leafnode will add. */ protected InlineArea curArea = null; - protected int verticalAlignment; - private int lead; + /** Any border, padding and background properties applying to this area */ + protected CommonBorderPaddingBackground commonBorderPaddingBackground = null; + /** The alignment context applying to this area */ + protected AlignmentContext alignmentContext = null; + private MinOptMax ipd; - protected boolean bSomethingChanged = false; + /** Flag to indicate if something was changed as part of the getChangeKnuthElements sequence */ + protected boolean isSomethingChanged = false; + /** Our area info for the Knuth elements */ protected AreaInfo areaInfo = null; /** @@ -59,19 +69,16 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager protected short iLScount; protected MinOptMax ipdArea; protected boolean bHyphenated; - protected int lead; - protected int total; - protected int middle; + protected AlignmentContext alignmentContext; public AreaInfo(short iLS, MinOptMax ipd, boolean bHyph, - int l, int t, int m) { + AlignmentContext alignmentContext) { iLScount = iLS; ipdArea = ipd; bHyphenated = bHyph; - lead = l; - total = t; - middle = m; + this.alignmentContext = alignmentContext; } + } @@ -116,29 +123,6 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager curArea = ia; } - /** - * Set the alignment of the inline area. - * @param al the vertical alignment positioning - */ - public void setAlignment(int al) { - verticalAlignment = al; - } - - /** - * Set the lead for this inline area. - * The lead is the distance from the top of the object - * to the baseline. - * @param l the lead value - */ - public void setLead(int l) { - lead = l; - } - - /** @return the lead value (distance from the top of the object to the baseline) */ - public int getLead() { - return this.lead; - } - /** * This is a leaf-node, so this method is never called. * @param childArea the childArea to add @@ -155,6 +139,15 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager return null; } + /** + * Set the border and padding properties of the inline area. + * @param commonBorderPaddingBackground the alignment adjust property + */ + protected void setCommonBorderPaddingBackground( + CommonBorderPaddingBackground commonBorderPaddingBackground) { + this.commonBorderPaddingBackground = commonBorderPaddingBackground; + } + /** * Get the allocation ipd of the inline area. * This method may be overridden to handle percentage values. @@ -178,6 +171,13 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager if (area.getAllocIPD() > 0 || area.getAllocBPD() > 0) { offsetArea(area, context); widthAdjustArea(area, context); + if (commonBorderPaddingBackground != null) { + // Add border and padding to area + TraitSetter.setBorderPaddingTraits(area, + commonBorderPaddingBackground, + false, false, this); + TraitSetter.addBackground(area, commonBorderPaddingBackground, this); + } parentLM.addChildArea(area); } @@ -212,22 +212,19 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager * @param context the layout context used for adding the area */ protected void offsetArea(InlineArea area, LayoutContext context) { - int bpd = area.getBPD(); - switch (verticalAlignment) { - case EN_MIDDLE: - area.setOffset(context.getMiddleBaseline() - bpd / 2); - break; - case EN_TOP: - area.setOffset(context.getTopBaseline()); - break; - case EN_BOTTOM: - area.setOffset(context.getBottomBaseline() - bpd); - break; - case EN_BASELINE: - default: - area.setOffset(context.getBaseline() - bpd); - break; - } + area.setOffset(alignmentContext.getOffset()); + } + + /** + * Creates a new alignment context or returns the current + * alignment context. + * This is used for vertical alignment. + * Subclasses should override this if necessary. + * @param context the layout context used + * @return the appropriate alignment context + */ + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + return context.getAlignmentContext(); } /** @@ -249,54 +246,42 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager } area.setIPD(width); } - - public LinkedList getNextKnuthElements(LayoutContext context, - int alignment) { - MinOptMax ipd; + + /** @see LayoutManager#getNextKnuthElements(LayoutContext, int) */ + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { curArea = get(context); - + if (curArea == null) { setFinished(true); return null; } - ipd = getAllocationIPD(context.getRefIPD()); - - int bpd = curArea.getBPD(); - int lead = 0; - int total = 0; - int middle = 0; - switch (verticalAlignment) { - case EN_MIDDLE : middle = bpd / 2 ; - lead = bpd / 2 ; - break; - case EN_TOP : total = bpd; - break; - case EN_BOTTOM : total = bpd; - break; - case EN_BASELINE: - default: - //lead = bpd; - lead = getLead(); - total = bpd; - break; - } + + alignmentContext = makeAlignmentContext(context); + + MinOptMax ipd = getAllocationIPD(context.getRefIPD()); // create the AreaInfo object to store the computed values - areaInfo = new AreaInfo((short) 0, ipd, false, - lead, total, middle); + areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext); // node is a fo:ExternalGraphic, fo:InstreamForeignObject, // fo:PageNumber or fo:PageNumberCitation KnuthSequence seq = new KnuthSequence(true); - seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.lead, - areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), false)); + + addKnuthElementsForBorderPaddingStart(seq); + + seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, alignmentContext, + notifyPos(new LeafPosition(this, 0)), false)); + + addKnuthElementsForBorderPaddingEnd(seq); + LinkedList returnList = new LinkedList(); + returnList.add(seq); setFinished(true); return returnList; } + /** @see InlineLevelLayoutManager#addALetterSpaceTo(List) */ public List addALetterSpaceTo(List oldList) { // return the unchanged elements return oldList; @@ -312,19 +297,22 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager log.warn(this.getClass().getName() + " should not receive a call to removeWordSpace(list)"); } + /** @see InlineLevelLayoutManager#getWordChars(StringBuffer, Position) */ public void getWordChars(StringBuffer sbChars, Position pos) { } + /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */ public void hyphenate(Position pos, HyphContext hc) { } + /** @see InlineLevelLayoutManager#applyChanges(List) */ public boolean applyChanges(List oldList) { setFinished(false); return false; } + /** @see LayoutManager#getChangedKnuthElements(List, int) */ public LinkedList getChangedKnuthElements(List oldList, - /*int flaggedPenalty,*/ int alignment) { if (isFinished()) { return null; @@ -332,14 +320,54 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager LinkedList returnList = new LinkedList(); + addKnuthElementsForBorderPaddingStart(returnList); + // fobj is a fo:ExternalGraphic, fo:InstreamForeignObject, // fo:PageNumber or fo:PageNumberCitation - returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.lead, - areaInfo.total, areaInfo.middle, - new LeafPosition(this, 0), true)); + returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext, + notifyPos(new LeafPosition(this, 0)), true)); + addKnuthElementsForBorderPaddingEnd(returnList); + setFinished(true); return returnList; } + + /** + * Creates Knuth elements for start border padding and adds them to the return list. + * @param returnList return list to add the additional elements to + */ + protected void addKnuthElementsForBorderPaddingStart(List returnList) { + //Border and Padding (start) + if (commonBorderPaddingBackground != null) { + int ipStart = commonBorderPaddingBackground.getBorderStartWidth(false) + + commonBorderPaddingBackground.getPaddingStart(false, this); + if (ipStart > 0) { + // Add a non breakable glue + returnList.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, + false, new LeafPosition(this, -1), true)); + returnList.add(new KnuthGlue(ipStart, 0, 0, new LeafPosition(this, -1), true)); + } + } + } + + /** + * Creates Knuth elements for end border padding and adds them to the return list. + * @param returnList return list to add the additional elements to + */ + protected void addKnuthElementsForBorderPaddingEnd(List returnList) { + //Border and Padding (after) + if (commonBorderPaddingBackground != null) { + int ipEnd = commonBorderPaddingBackground.getBorderEndWidth(false) + + commonBorderPaddingBackground.getPaddingEnd(false, this); + if (ipEnd > 0) { + // Add a non breakable glue + returnList.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, + false, new LeafPosition(this, -1), true)); + returnList.add(new KnuthGlue(ipEnd, 0, 0, new LeafPosition(this, -1), true)); + } + } + } + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 4b91e737e..532b6f875 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -49,6 +49,10 @@ import java.util.ListIterator; import java.util.List; import java.util.ArrayList; import java.util.LinkedList; +import org.apache.fop.area.Trait; +import org.apache.fop.fonts.Font; +import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode; +import org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager.StackingIter; import org.apache.fop.traits.MinOptMax; @@ -102,14 +106,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int startIndent; private int lineHeight; private int lineWidth; + private int spaceBefore; + private int spaceAfter; private int baseline; - private int topShift; - private int bottomShift; LineBreakPosition(LayoutManager lm, int index, int iBreakIndex, int shrink, int stretch, int diff, double ipdA, double adjust, int ind, - int lh, int lw, int bl, int ts, int bs) { + int lh, int lw, int sb, int sa, int bl) { super(lm, iBreakIndex); availableShrink = shrink; availableStretch = stretch; @@ -120,9 +124,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager startIndent = ind; lineHeight = lh; lineWidth = lw; + spaceBefore = sb; + spaceAfter = sa; baseline = bl; - topShift = ts; - bottomShift = bs; } } @@ -141,8 +145,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager private Length lineHeight; private int lead; private int follow; - // offset of the middle baseline with respect to the main baseline - private int middleShift; + private AlignmentContext alignmentContext = null; private List knuthParagraphs = null; private int iReturnedLBP = 0; @@ -157,16 +160,20 @@ public class LineLayoutManager extends InlineStackingLayoutManager private List lineLayoutsList; private int iLineWidth = 0; - // this constant is used to create elements when text-align is center: - // every TextLM descendant of LineLM must use the same value, - // otherwise the line breaking algorithm does not find the right - // break point + /** + * this constant is used to create elements when text-align is center: + * every TextLM descendant of LineLM must use the same value, + * otherwise the line breaking algorithm does not find the right + * break point + */ public static final int DEFAULT_SPACE_WIDTH = 3336; - // this class is used to remember - // which was the first element in the paragraph - // returned by each LM + /** + * This class is used to remember + * which was the first element in the paragraph + * returned by each LM. + */ private class Update { private InlineLevelLayoutManager inlineLM; private int iFirstIndex; @@ -217,16 +224,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager if (textAlignment == EN_CENTER && textAlignmentLast != EN_JUSTIFY) { this.add(new KnuthGlue(0, 3 * DEFAULT_SPACE_WIDTH, 0, null, false)); - ignoreAtStart ++; + ignoreAtStart++; } // add the element representing text indentation // at the beginning of the first paragraph if (knuthParagraphs.size() == 0 && fobj.getTextIndent().getValue(layoutManager) != 0) { - this.add(new KnuthInlineBox(fobj.getTextIndent().getValue(layoutManager), 0, 0, 0, + this.add(new KnuthInlineBox(fobj.getTextIndent().getValue(layoutManager), null, null, false)); - ignoreAtStart ++; + ignoreAtStart++; } } @@ -364,14 +371,13 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int lineHeight; private int lead; private int follow; - private int middleshift; private int maxDiff; private static final double MAX_DEMERITS = 10e6; public LineBreakingAlgorithm (int pageAlign, int textAlign, int textAlignLast, int indent, int fillerWidth, - int lh, int ld, int fl, int ms, boolean first, + int lh, int ld, int fl, boolean first, LineLayoutManager llm) { super(textAlign, textAlignLast, first, false); pageAlignment = pageAlign; @@ -380,7 +386,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager lineHeight = lh; lead = ld; follow = fl; - middleshift = ms; thisLLM = llm; activePossibility = -1; maxDiff = fobj.getWidows() >= fobj.getOrphans() @@ -402,13 +407,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager int difference = bestActiveNode.difference; int textAlign = (bestActiveNode.line < total) ? alignment : alignmentLast; indent += (textAlign == Constants.EN_CENTER) ? - difference / 2 : - (textAlign == Constants.EN_END) ? difference : 0; - indent += (bestActiveNode.line == 1 && bFirst) ? - textIndent : 0; + difference / 2 : (textAlign == Constants.EN_END) ? difference : 0; + indent += (bestActiveNode.line == 1 && bFirst) ? textIndent : 0; double ratio = (textAlign == Constants.EN_JUSTIFY - || difference < 0 && -difference <= bestActiveNode.availableShrink) ? - bestActiveNode.adjustRatio : 0; + || difference < 0 && -difference <= bestActiveNode.availableShrink) + ? bestActiveNode.adjustRatio : 0; // add nodes at the beginning of the list, as they are found // backwards, from the last one to the first one @@ -420,7 +423,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager } if (addedPositions == lineLayouts.getLineCount(activePossibility)) { - activePossibility ++; + activePossibility++; addedPositions = 0; //System.out.println(" "); } @@ -431,7 +434,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager bestActiveNode.position, bestActiveNode.availableShrink - (addedPositions > 0 ? 0 : ((Paragraph)par).lineFiller.opt - ((Paragraph)par).lineFiller.min), bestActiveNode.availableStretch, difference, ratio, indent), activePossibility); - addedPositions ++; + addedPositions++; } /* reset activePossibility, as if breakpoints have not yet been computed @@ -447,14 +450,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager double ratio, int indent) { // line height calculation - int halfLeading = (lineHeight - lead - follow) / 2; // height before the main baseline int lineLead = lead; - // maximum size of top and bottom alignment - int maxtb = follow; - // max size of middle alignment before and after the middle baseline - int middlefollow = maxtb; + // maximum follow + int lineFollow = follow; // true if this line contains only zero-height, auxiliary boxes // and the actual line width is 0; in this case, the line "collapses" // i.e. the line area will have bpd = 0 @@ -465,57 +465,60 @@ public class LineLayoutManager extends InlineStackingLayoutManager if (fobj.getLineStackingStrategy() != EN_FONT_HEIGHT) { ListIterator inlineIterator = par.listIterator(firstElementIndex); + AlignmentContext lastAC = null; + int maxIgnoredHeight = 0; // See spec 7.13 for (int j = firstElementIndex; j <= lastElementIndex; j++) { KnuthElement element = (KnuthElement) inlineIterator.next(); - if (element.isBox()) { - if (((KnuthInlineBox) element).getLead() > lineLead) { - lineLead = ((KnuthInlineBox) element).getLead(); - } - if (((KnuthInlineBox) element).getTotal() > maxtb) { - maxtb = ((KnuthInlineBox) element).getTotal(); - } - if (((KnuthInlineBox) element).getMiddle() > lineLead + middleShift) { - lineLead += ((KnuthInlineBox) element).getMiddle() - - lineLead - middleShift; - } - if (((KnuthInlineBox) element).getMiddle() > middlefollow - middleShift) { - middlefollow += ((KnuthInlineBox) element).getMiddle() - - middlefollow + middleShift; + if (element instanceof KnuthInlineBox ) { + AlignmentContext ac = ((KnuthInlineBox) element).getAlignmentContext(); + if (ac != null && lastAC != ac) { + if (!ac.usesInitialBaselineTable() + || ac.getAlignmentBaselineIdentifier() != EN_BEFORE_EDGE + && ac.getAlignmentBaselineIdentifier() != EN_AFTER_EDGE) { + int alignmentOffset = ac.getTotalAlignmentBaselineOffset(); + if (alignmentOffset + ac.getAltitude() > lineLead) { + lineLead = alignmentOffset + ac.getAltitude(); + } + if (ac.getDepth() - alignmentOffset > lineFollow) { + lineFollow = ac.getDepth() - alignmentOffset; + } + } else { + if (ac.getHeight() > maxIgnoredHeight) { + maxIgnoredHeight = ac.getHeight(); + } + } + lastAC = ac; } if (bZeroHeightLine - && (!element.isAuxiliary() - || ((KnuthInlineBox) element).getTotal() > 0 - || ((KnuthInlineBox) element).getLead() > 0 - || ((KnuthInlineBox) element).getMiddle() > 0)) { + && (!element.isAuxiliary() || ac != null && ac.getHeight() > 0)) { bZeroHeightLine = false; } } } - if (maxtb - lineLead > middlefollow) { - middlefollow = maxtb - lineLead; + if (lineFollow < maxIgnoredHeight - lineLead) { + lineFollow = maxIgnoredHeight - lineLead; } } - constantLineHeight = lineLead + middlefollow + (lineHeight - lead - follow); + constantLineHeight = lineLead + lineFollow; if (bZeroHeightLine) { return new LineBreakPosition(thisLLM, knuthParagraphs.indexOf(par), lastElementIndex, availableShrink, availableStretch, difference, ratio, 0, indent, - 0, iLineWidth, - 0, 0, 0); + 0, iLineWidth, 0, 0, 0); } else { return new LineBreakPosition(thisLLM, knuthParagraphs.indexOf(par), lastElementIndex, availableShrink, availableStretch, difference, ratio, 0, indent, - lineLead + middlefollow + (lineHeight - lead - follow), iLineWidth, - lineLead + halfLeading, - - lineLead, middlefollow); + lineLead + lineFollow, + iLineWidth, halfLeading, halfLeading, + lineLead); } } @@ -577,12 +580,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager * Create a new Line Layout Manager. * This is used by the block layout manager to create * line managers for handling inline areas flowing into line areas. - * + * @param block the block formatting object * @param lh the default line height * @param l the default lead, from top to baseline * @param f the default follow, from baseline to bottom */ - public LineLayoutManager(Block block, Length lh, int l, int f, int ms) { + public LineLayoutManager(Block block, Length lh, int l, int f) { super(block); fobj = block; // the child FObj are owned by the parent BlockLM @@ -591,14 +594,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager lineHeight = lh; lead = l; follow = f; - middleShift = ms; } /** @see org.apache.fop.layoutmgr.LayoutManager */ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { + Font fs = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); + alignmentContext = new AlignmentContext(fs, lineHeight.getValue(this), context.getWritingMode()); + context.setAlignmentContext(alignmentContext); // Get a break from currently active child LM // Set up constraints for inline level managers - InlineLevelLayoutManager curLM ; // currently active LM + InlineLevelLayoutManager curLM; // currently active LM // IPD remaining in line MinOptMax availIPD = context.getStackLimit(); @@ -775,8 +780,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager if (lastPar.size() == 0) { //only a forced linefeed on this line //-> compensate with a zero width box - lastPar.add(new KnuthInlineBox(0, 0, 0, 0, - null, false)); + lastPar.add(new KnuthInlineBox(0, null, null, false)); } lastPar.endParagraph(); ElementListObserver.observe(lastPar, "line", null); @@ -905,9 +909,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager // height above the main baseline int lineLead = lead + halfLeading; // maximum size of top and bottom alignment - int maxtb = follow + halfLeading; - // max size of middle alignment above and below the middle baseline - int middlefollow = maxtb; + int lineFollow = follow + halfLeading; ListIterator inlineIterator = par.listIterator(firstElementIndex); @@ -920,8 +922,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager if (box.getLead() > lineLead) { lineLead = box.getLead(); } - if (box.getTotal() > maxtb) { - maxtb = box.getTotal(); + if (box.getTotal() > lineFollow) { + lineFollow = box.getTotal(); } if (box.getMiddle() > lineLead + middleShift) { lineLead += box.getMiddle() @@ -934,8 +936,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } - if (maxtb - lineLead > middlefollow) { - middlefollow = maxtb - lineLead; + if (lineFollow - lineLead > middlefollow) { + middlefollow = lineFollow - lineLead; } breakpoints.add(insertIndex, @@ -985,7 +987,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager //TODO Should this really create only a single LineBreakPosition??? //This creates an implicit keep-together on the nested block-level FOs. lineLayouts = new LineLayoutPossibilities(); - lineLayouts.addPossibility(1,0); + lineLayouts.addPossibility(1, 0); int lineHeight = 0, lineStretch = 0, lineShrink = 0; ListIterator seqIterator = seq.listIterator(); while (seqIterator.hasNext()) { @@ -1015,9 +1017,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager double maxAdjustment = 1; int iBPcount = 0; LineBreakingAlgorithm alg = new LineBreakingAlgorithm(alignment, - textAlignment, textAlignmentLast, + textAlignment, textAlignmentLast, textIndent.getValue(this), currPar.lineFiller.opt, - lineHeight.getValue(this), lead, follow, middleShift, + lineHeight.getValue(this), lead, follow, (knuthParagraphs.indexOf(currPar) == 0), this); @@ -1121,7 +1123,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager LinkedList returnList = new LinkedList(); - for (int p = 0; p < knuthParagraphs.size(); p ++) { + for (int p = 0; p < knuthParagraphs.size(); p++) { // null penalty between paragraphs if (p > 0 && !((BlockLevelLayoutManager) parentLM).mustKeepTogether()) { @@ -1138,8 +1140,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager KnuthElement tempElement; tempElement = (KnuthElement) listIter.next(); if (tempElement.getLayoutManager() != this) { - tempElement.setPosition(new NonLeafPosition(this, - tempElement.getPosition())); + tempElement.setPosition(notifyPos(new NonLeafPosition(this, + tempElement.getPosition()))); } targetList.add(tempElement); } @@ -1181,7 +1183,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager } startIndex = endIndex + 1; LineBreakPosition lbp = (LineBreakPosition) lineLayouts.getChosenPosition(i); - returnList.add(new KnuthBlockBox(lbp.lineHeight, footnoteList, lbp, false)); + returnList.add(new KnuthBlockBox(lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter + , footnoteList, lbp, false)); /* // add stretch and shrink to the returnlist if (!seq.isInlineSequence() && lbp.availableStretch != 0 || lbp.availableShrink != 0) { @@ -1322,14 +1325,23 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } + /** + * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether + */ public boolean mustKeepTogether() { return false; } + /** + * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious + */ public boolean mustKeepWithPrevious() { return false; } + /** + * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext + */ public boolean mustKeepWithNext() { return false; } @@ -1351,19 +1363,21 @@ public class LineLayoutManager extends InlineStackingLayoutManager return lineNumberDifference * constantLineHeight; } + /** + * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#discardSpace(KnuthGlue) + */ public void discardSpace(KnuthGlue spaceGlue) { } + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) + */ public LinkedList getChangedKnuthElements(List oldList, int alignment) { LinkedList returnList = new LinkedList(); - for (int p = 0; - p < knuthParagraphs.size(); - p ++) { + for (int p = 0; p < knuthParagraphs.size(); p++) { lineLayouts = (LineLayoutPossibilities)lineLayoutsList.get(p); //System.out.println("demerits of the chosen layout: " + lineLayouts.getChosenDemerits()); - for (int i = 0; - i < lineLayouts.getChosenLineCount(); - i ++) { + for (int i = 0; i < lineLayouts.getChosenLineCount(); i++) { if (!((BlockLevelLayoutManager) parentLM).mustKeepTogether() && i >= fobj.getOrphans() && i <= lineLayouts.getChosenLineCount() - fobj.getWidows()) { @@ -1401,7 +1415,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager * find hyphenation points for every word int the current paragraph * @ param currPar the paragraph whose words will be hyphenated */ - private void findHyphenationPoints(Paragraph currPar){ + private void findHyphenationPoints(Paragraph currPar) { // hyphenate every word ListIterator currParIterator = currPar.listIterator(currPar.ignoreAtStart); @@ -1447,7 +1461,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager updateList.add(new Update(currLM, currParIterator.previousIndex())); } // append text to recreate the whole word - boxCount ++; + boxCount++; currLM.getWordChars(sbChars, nextElement.getPosition()); } else if (!nextElement.isAuxiliary()) { // a non-auxiliary non-box KnuthElement: stop @@ -1455,8 +1469,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager currParIterator.previous(); break; } else { + if (currLM != nextElement.getLayoutManager()) { + currLM = (InlineLevelLayoutManager) nextElement.getLayoutManager(); + updateList.add(new Update(currLM, currParIterator.previousIndex())); + } // an auxiliary KnuthElement: simply ignore it - auxCount ++; + auxCount++; } } log.trace(" Word to hyphenate: " + sbChars.toString()); @@ -1528,13 +1546,21 @@ public class LineLayoutManager extends InlineStackingLayoutManager updateList.clear(); } - /** Line area is always considered to act as a fence. */ - protected boolean hasLeadingFence(boolean bNotFirst) { + /** + * Line area is always considered to act as a fence. + * @param isNotFirst ignored + * @return always true + */ + protected boolean hasLeadingFence(boolean isNotFirst) { return true; } - /** Line area is always considered to act as a fence. */ - protected boolean hasTrailingFence(boolean bNotLast) { + /** + * Line area is always considered to act as a fence. + * @param isNotLast ignored + * @return always true + */ + protected boolean hasTrailingFence(boolean isNotLast) { return true; } @@ -1607,6 +1633,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager LayoutContext context) { LayoutManager childLM; LayoutContext lc = new LayoutContext(0); + lc.setAlignmentContext(alignmentContext); int iCurrParIndex; while (parentIter.hasNext()) { Position pos = (Position) parentIter.next(); @@ -1626,11 +1653,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager lineArea.setStartIndent(lbp.startIndent); lineArea.setBPD(lbp.lineHeight); lineArea.setIPD(lbp.lineWidth); - lc.setBaseline(lbp.baseline); - lc.setLineHeight(lbp.lineHeight); - lc.setMiddleShift(middleShift); - lc.setTopShift(lbp.topShift); - lc.setBottomShift(lbp.bottomShift); + lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore)); + lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter)); + alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline); if (seq instanceof Paragraph) { Paragraph currPar = (Paragraph) seq; @@ -1650,7 +1675,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager seqIterator = seq.listIterator(iEndElement); tempElement = (KnuthElement) seqIterator.next(); if (tempElement.isGlue()) { - iEndElement --; + iEndElement--; // this returns the same KnuthElement seqIterator.previous(); tempElement = (KnuthElement) seqIterator.previous(); @@ -1663,7 +1688,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager tempElement = (KnuthElement) seqIterator.next(); while (!tempElement.isBox() && seqIterator.hasNext()) { tempElement = (KnuthElement) seqIterator.next(); - iStartElement ++; + iStartElement++; } // Add the inline areas to lineArea @@ -1700,11 +1725,13 @@ public class LineLayoutManager extends InlineStackingLayoutManager //System.out.println(" old ratio = " + lbp.ipdAdjust + " new ratio = " + updatedRatio); } else if (false && textAlignment == EN_CENTER) { // re-compute indent - int updatedIndent = lbp.startIndent + (context.getStackLimit().opt - lbp.lineWidth) / 2; + int updatedIndent = lbp.startIndent + + (context.getStackLimit().opt - lbp.lineWidth) / 2; lineArea.setStartIndent(updatedIndent); } else if (false && textAlignment == EN_END) { // re-compute indent - int updatedIndent = lbp.startIndent + (context.getStackLimit().opt - lbp.lineWidth); + int updatedIndent = lbp.startIndent + + (context.getStackLimit().opt - lbp.lineWidth); lineArea.setStartIndent(updatedIndent); } @@ -1780,6 +1807,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager setCurrentArea(null); // ?? necessary } + /** + * @see org.apache.fop.layoutmgr.LayoutManager#addChildArea(Area) + */ public void addChildArea(Area childArea) { // Make sure childArea is inline area if (childArea instanceof InlineArea) { diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java index e617aabe5..083d7838f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java @@ -25,6 +25,7 @@ import org.apache.fop.area.Trait; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.UnresolvedPageNumber; import org.apache.fop.area.inline.TextArea; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fonts.Font; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; @@ -53,15 +54,37 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { fobj = node; } + /** @see org.apache.fop.layoutmgr.LayoutManager#initialize */ public void initialize() { font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); + setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground()); } + /** + * @see LeafNodeLayoutManager.makeAlignmentContext(LayoutContext) + */ + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + return new AlignmentContext( + font + , fobj.getLineHeight().getOptimum(this).getLength().getValue(this) + , fobj.getAlignmentAdjust() + , fobj.getAlignmentBaseline() + , fobj.getBaselineShift() + , fobj.getDominantBaseline() + , context.getAlignmentContext() + ); + } + + /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#get(LayoutContext) */ public InlineArea get(LayoutContext context) { curArea = getPageNumberCitationInlineArea(parentLM); return curArea; } + /** + * @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#addAreas(PositionIterator + * , LayoutContext) + */ public void addAreas(PositionIterator posIter, LayoutContext context) { super.addAreas(posIter, context); if (!resolved) { @@ -74,17 +97,13 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { return font.getAscender(); } - protected void offsetArea(InlineArea area, LayoutContext context) { - area.setOffset(context.getBaseline()); - } - /** * if id can be resolved then simply return a word, otherwise * return a resolvable area */ private InlineArea getPageNumberCitationInlineArea(LayoutManager parentLM) { PageViewport page = getPSLM().getFirstPVWithID(fobj.getRefId()); - InlineArea inline = null; + TextArea inline = null; if (page != null) { String str = page.getPageNumberString(); // get page string from parent, build area @@ -105,7 +124,7 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { } TraitSetter.setProducerID(inline, fobj.getId()); inline.setBPD(font.getAscender() - font.getDescender()); - inline.setOffset(font.getAscender()); + inline.setBaselineOffset(font.getAscender()); inline.addTrait(Trait.FONT_NAME, font.getFontName()); inline.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); inline.addTrait(Trait.COLOR, fobj.getColor()); @@ -125,7 +144,8 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { } return width; } - + + /** @see org.apache.fop.layoutmgr.inline.LeafLayoutManager#addId */ protected void addId() { getPSLM().addIDToPage(fobj.getId()); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java index 743e2efce..d6cc739f2 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java @@ -22,6 +22,7 @@ import org.apache.fop.fo.flow.PageNumber; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.Trait; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fonts.Font; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.TraitSetter; @@ -46,10 +47,29 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { fobj = node; } + /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#get(LayoutContext) */ public void initialize() { font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this); + setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground()); } + /** + * @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager + * #makeAlignmentContext(LayoutContext) + */ + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + return new AlignmentContext( + font + , fobj.getLineHeight().getOptimum(this).getLength().getValue(this) + , fobj.getAlignmentAdjust() + , fobj.getAlignmentBaseline() + , fobj.getBaselineShift() + , fobj.getDominantBaseline() + , context.getAlignmentContext() + ); + } + + /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#get(LayoutContext) */ public InlineArea get(LayoutContext context) { // get page string from parent, build area TextArea text = new TextArea(); @@ -58,7 +78,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { text.setTextArea(str); text.setIPD(width); text.setBPD(font.getAscender() - font.getDescender()); - text.setOffset(font.getAscender()); + text.setBaselineOffset(font.getAscender()); text.addTrait(Trait.FONT_NAME, font.getFontName()); text.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); @@ -69,16 +89,12 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { return text; } - /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#getLead() */ public int getLead() { return font.getAscender(); } - protected void offsetArea(InlineArea area, LayoutContext context) { - area.setOffset(context.getBaseline()); - } - + /** @see org.apache.fop.layoutmgr.inline.LeafNodeLayoutManager#getEffectiveArea() */ protected InlineArea getEffectiveArea() { TextArea baseArea = (TextArea)curArea; //TODO Maybe replace that with a clone() call or better, a copy constructor @@ -89,6 +105,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { ta.setIPD(baseArea.getIPD()); ta.setBPD(baseArea.getBPD()); ta.setOffset(baseArea.getOffset()); + ta.setBaselineOffset(baseArea.getBaselineOffset()); ta.addTrait(Trait.FONT_NAME, font.getFontName()); //only to initialize the trait map ta.getTraits().putAll(baseArea.getTraits()); updateContent(ta); @@ -116,6 +133,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { return width; } + /** @see org.apache.fop.layoutmgr.inline.LeafLayoutManager#addId */ protected void addId() { getPSLM().addIDToPage(fobj.getId()); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTable.java b/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTable.java new file mode 100644 index 000000000..0aeb2b7b8 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTable.java @@ -0,0 +1,70 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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 org.apache.fop.datatypes.Length; + +/** + * The FOP specific incarnation of the XSL-FO scaled baseline table. + * All baseline tables are scaled to the font size of the font they + * apply to. This interface uses a coordinate system with its origin + * where the dominant baseline intersects the start edge of the box. + * All measurements are in mpt. + */ +public interface ScaledBaselineTable { + + /** + * Return the dominant baseline identifer for this alignment context. + * @return the dominant baseline identifier + */ + int getDominantBaselineIdentifier(); + + /** + * Return the writing mode for this aligment context. + * @return the writing mode + */ + int getWritingMode(); + + /** + * Return the offset measured from the dominant + * baseline for the given baseline identifier. + * @param baselineIdentifier the baseline identifier + * @return the baseline offset + */ + int getBaseline(int baselineIdentifier); + + /** + * Sets the position of the before and after baselines. + * This is usually only done for line areas. For other + * areas the position of the before and after baselines + * are fixed when the table is constructed. + * @param beforeBaseline the offset of the before-edge baseline from the dominant baseline + * @param afterBaseline the offset of the after-edge baseline from the dominant baseline + */ + void setBeforeAndAfterBaselines(int beforeBaseline, int afterBaseline); + + /** + * Return a new baseline table for the given baseline based + * on the current baseline table. + * @param baselineIdentifier the baseline identifer + * @return a new baseline with the new baseline + */ + ScaledBaselineTable deriveScaledBaselineTable(int baselineIdentifier); + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTableFactory.java b/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTableFactory.java new file mode 100644 index 000000000..4f36acc72 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTableFactory.java @@ -0,0 +1,74 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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 org.apache.fop.fo.Constants; +import org.apache.fop.fonts.Font; + + +/** + * A factory class for making alignment contexts. + * Currently supports alignment contexts for basic fonts + * and graphic inlines. + */ +public class ScaledBaselineTableFactory implements Constants { + + /** + * Creates a new instance of BasicScaledBaselineTable for the given + * font, baseline and writingmode. + * @param font the font for which a baseline table is requested + * @param dominantBaselineIdentifier the dominant baseline given as an integer constant + * @param writingMode the writing mode given as an integer constant + * @return a scaled baseline table for the given font + */ + public static ScaledBaselineTable makeFontScaledBaselineTable(Font font + , int dominantBaselineIdentifier + , int writingMode) { + return new BasicScaledBaselineTable(font.getAscender(), font.getDescender() + , font.getXHeight(), dominantBaselineIdentifier, writingMode); + } + + /** + * Creates a new instance of BasicScaledBaselineTable for the given + * font and writingmode. It assumes an alphabetic baseline. + * @param font the font for which a baseline table is requested + * @param writingMode the writing mode given as an integer constant + * @return a scaled baseline table for the given font + */ + public static ScaledBaselineTable makeFontScaledBaselineTable(Font font, int writingMode) { + return makeFontScaledBaselineTable(font, EN_ALPHABETIC, writingMode); + } + + /** + * Creates a new instance of BasicScaledBaselineTable for the given + * height, baseline and writingmode. This is used for non font based areas like + * external graphic or inline foreign object. + * @param height the height for which a baseline table is requested + * @param dominantBaselineIdentifier the dominant baseline given as an integer constant + * @param writingMode the writing mode given as an integer constant + * @return a scaled baseline table for the given dimensions + */ + public static ScaledBaselineTable makeGraphicsScaledBaselineTable(int height + , int dominantBaselineIdentifier + , int writingMode) { + return new BasicScaledBaselineTable(height, 0, height + , dominantBaselineIdentifier, writingMode); + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 8edd09f08..2ab8fd1a8 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -23,24 +23,24 @@ import java.util.List; import java.util.LinkedList; import java.util.ListIterator; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.TextArea; import org.apache.fop.fo.FOText; import org.apache.fop.fo.flow.Inline; import org.apache.fop.fonts.Font; -import org.apache.fop.layoutmgr.KnuthSequence; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; +import org.apache.fop.layoutmgr.KnuthSequence; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.traits.SpaceVal; -import org.apache.fop.area.Trait; -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.area.inline.TextArea; import org.apache.fop.traits.MinOptMax; +import org.apache.fop.traits.SpaceVal; /** * LayoutManager for text (a sequence of characters) which generates one @@ -70,6 +70,17 @@ public class TextLayoutManager extends LeafNodeLayoutManager { ipdArea = ipd; bHyphenated = bHyph; } + + public String toString() { + return "[ lscnt=" + iLScount + + ", wscnt=" + iWScount + + ", ipd=" + ipdArea.toString() + + ", sidx=" + iStartIndex + + ", bidx=" + iBreakIndex + + ", hyph=" + bHyphenated + + "]"; + } + } // this class stores information about changes in vecAreaInfo @@ -88,7 +99,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private ArrayList vecAreaInfo; /** Non-space characters on which we can end a line. */ - private static final String BREAK_CHARS = "-/" ; + private static final String BREAK_CHARS = "-/"; private FOText foText; private char[] textArray; @@ -101,6 +112,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // byte order mark private static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF'; + private Font font = null; /** Start index of first character in this parent Area */ private short iAreaStart = 0; /** Start index of next TextArea */ @@ -119,7 +131,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private SpaceVal halfWS; /** Number of space characters after previous possible break position. */ private int iNbSpacesPending; - private Font fs; private boolean bChanged = false; private int iReturnedIndex = 0; @@ -127,11 +138,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private short iTempStart = 0; private LinkedList changeList = null; - private int textHeight; - private int lead = 0; - private int total = 0; - private int middle = 0; - private int verticalAlignment = EN_BASELINE; + private AlignmentContext alignmentContext = null; + + private int lineStartBAP = 0; + private int lineEndBAP = 0; + /** * Create a Text layout manager. * @@ -148,16 +159,17 @@ public class TextLayoutManager extends LeafNodeLayoutManager { vecAreaInfo = new java.util.ArrayList(); } + /** @see org.apache.fop.layoutmgr.LayoutManager#initialize */ public void initialize() { - fs = foText.getCommonFont().getFontState(foText.getFOEventHandler().getFontInfo(), this); + font = foText.getCommonFont().getFontState(foText.getFOEventHandler().getFontInfo(), this); // With CID fonts, space isn't neccesary currentFontState.width(32) - spaceCharIPD = fs.getCharWidth(' '); + spaceCharIPD = font.getCharWidth(' '); // Use hyphenationChar property - hyphIPD = fs.getCharWidth(foText.getCommonHyphenation().hyphenationCharacter); + hyphIPD = font.getCharWidth(foText.getCommonHyphenation().hyphenationCharacter); // Make half-space: on either side of a word-space) SpaceVal ls = SpaceVal.makeLetterSpacing(foText.getLetterSpacing()); - SpaceVal ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, fs); + SpaceVal ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, font); halfWS = new SpaceVal(MinOptMax.multiply(ws.getSpace(), 0.5), ws.isConditional(), ws.isForcing(), ws.getPrecedence()); @@ -174,24 +186,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { letterSpaceIPD = ls.getSpace(); wordSpaceIPD = MinOptMax.add(new MinOptMax(spaceCharIPD), ws.getSpace()); - // set text height - textHeight = fs.getAscender() - - fs.getDescender(); - // if the text node is son of an inline, set vertical align if (foText.getParent() instanceof Inline) { - setAlignment(((Inline) foText.getParent()).getVerticalAlign()); - } - switch (verticalAlignment) { - case EN_MIDDLE : middle = textHeight / 2 ; - break; - case EN_TOP : // fall through - case EN_BOTTOM : total = textHeight; - break; - case EN_BASELINE: // fall through - default : lead = fs.getAscender(); - total = textHeight; - break; + Inline fobj = (Inline)foText.getParent(); } } @@ -208,8 +205,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { + "LM mismatch!!!"); } LeafPosition tbp = (LeafPosition) prevPos; - AreaInfo ai = - (AreaInfo) vecAreaInfo.get(tbp.getLeafPos()); + AreaInfo ai = (AreaInfo) vecAreaInfo.get(tbp.getLeafPos()); if (ai.iBreakIndex != iNextStart) { iNextStart = ai.iBreakIndex; vecAreaInfo.ensureCapacity(tbp.getLeafPos() + 1); @@ -241,7 +237,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { for (; iNextStart < iStopIndex; iNextStart++) { char c = textArray[iNextStart]; - hyphIPD.opt += fs.getCharWidth(c); + hyphIPD.opt += font.getCharWidth(c); // letter-space? } // Need to include hyphen size too, but don't count it in the @@ -292,7 +288,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // the line ends at a character like "/" or "-"; // remove the letter space after the last character realWidth.add(MinOptMax.multiply(letterSpaceIPD, -1)); - iLScount --; + iLScount--; } // Make an area containing all characters between start and end. @@ -413,27 +409,17 @@ public class TextLayoutManager extends LeafNodeLayoutManager { adjust); } textArea.setIPD(width.opt + adjust); - textArea.setBPD(fs.getAscender() - fs.getDescender()); - int bpd = textArea.getBPD(); - switch (verticalAlignment) { - case EN_MIDDLE: - textArea.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2); - break; - case EN_TOP: - textArea.setOffset(context.getTopBaseline() + fs.getAscender()); - break; - case EN_BOTTOM: - textArea.setOffset(context.getBottomBaseline() - bpd + fs.getAscender()); - break; - case EN_BASELINE: - default: - textArea.setOffset(context.getBaseline()); - break; + textArea.setBPD(font.getAscender() - font.getDescender()); + textArea.setBaselineOffset(font.getAscender()); + if (textArea.getBPD() == alignmentContext.getHeight()) { + textArea.setOffset(0); + } else { + textArea.setOffset(alignmentContext.getOffset()); } textArea.setTextArea(str); - textArea.addTrait(Trait.FONT_NAME, fs.getFontName()); - textArea.addTrait(Trait.FONT_SIZE, new Integer(fs.getFontSize())); + textArea.addTrait(Trait.FONT_NAME, font.getFontName()); + textArea.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); textArea.addTrait(Trait.COLOR, foText.getColor()); TraitSetter.addTextDecoration(textArea, foText.getTextDecoration()); @@ -441,16 +427,12 @@ public class TextLayoutManager extends LeafNodeLayoutManager { return textArea; } - /** - * Set the alignment of the inline area. - * @param al the vertical alignment positioning - */ - public void setAlignment(int al) { - verticalAlignment = al; - } + /** @see LayoutManager#getNextKnuthElements(LayoutContext, int) */ + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { + lineStartBAP = context.getLineStartBorderAndPaddingWidth(); + lineEndBAP = context.getLineEndBorderAndPaddingWidth(); + alignmentContext = context.getAlignmentContext(); - public LinkedList getNextKnuthElements(LayoutContext context, - int alignment) { LinkedList returnList = new LinkedList(); KnuthSequence sequence = new KnuthSequence(true); AreaInfo ai = null; @@ -468,13 +450,18 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // create the elements sequence.addAll - (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1)); + (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1)); // advance to the next character - iNextStart ++; + iNextStart++; } else if (textArray[iNextStart] == NEWLINE) { // linefeed; this can happen when linefeed-treatment="preserve" // add a penalty item to the list and start a new sequence + if (lineEndBAP != 0) { + sequence.add + (new KnuthGlue(lineEndBAP, 0, 0, + new LeafPosition(this, -1), true)); + } sequence.add (new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); @@ -482,7 +469,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { returnList.add(sequence); // advance to the next character - iNextStart ++; + iNextStart++; } else { // the beginning of a word iThisStart = iNextStart; @@ -495,7 +482,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { && !(iTempStart > iNextStart && BREAK_CHARS.indexOf(textArray[iTempStart - 1]) >= 0); iTempStart++) { - wordIPD.add(fs.getCharWidth(textArray[iTempStart])); + wordIPD.add(font.getCharWidth(textArray[iTempStart])); } int iLetterSpaces = iTempStart - iThisStart - 1; // if the last character is '-' or '/' and the next one @@ -505,7 +492,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { && iTempStart < textArray.length && textArray[iTempStart] != SPACE && textArray[iTempStart] != NBSPACE) { - iLetterSpaces ++; + iLetterSpaces++; } wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces)); @@ -536,6 +523,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } + /** @see InlineLevelLayoutManager#addALetterSpaceTo(List) */ public List addALetterSpaceTo(List oldList) { // old list contains only a box, or the sequence: box penalty glue box; // look at the Position stored in the first element in oldList @@ -544,7 +532,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { KnuthElement el = (KnuthElement)oldListIterator.next(); LeafPosition pos = (LeafPosition) ((KnuthBox) el).getPosition(); AreaInfo ai = (AreaInfo) vecAreaInfo.get(pos.getLeafPos()); - ai.iLScount ++; + ai.iLScount++; ai.ipdArea.add(letterSpaceIPD); if (BREAK_CHARS.indexOf(textArray[iTempStart - 1]) >= 0) { // the last character could be used as a line break @@ -558,7 +546,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { new LeafPosition(this, -1), false)); } else if (letterSpaceIPD.min == letterSpaceIPD.max) { // constant letter space: replace the box - oldListIterator.set(new KnuthInlineBox(ai.ipdArea.opt, lead, total, middle, pos, false)); + oldListIterator.set(new KnuthInlineBox(ai.ipdArea.opt, alignmentContext, pos, false)); } else { // adjustable letter space: replace the glue oldListIterator.next(); // this would return the penalty element @@ -601,6 +589,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } + /** @see InlineLevelLayoutManager#hyphenate(Position, HyphContext) */ public void hyphenate(Position pos, HyphContext hc) { AreaInfo ai = (AreaInfo) vecAreaInfo.get(((LeafPosition) pos).getLeafPos()); @@ -629,7 +618,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { for (int i = iStartIndex; i < iStopIndex; i++) { char c = textArray[i]; - newIPD.add(new MinOptMax(fs.getCharWidth(c))); + newIPD.add(new MinOptMax(font.getCharWidth(c))); } // add letter spaces boolean bIsWordEnd @@ -665,6 +654,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } + /** @see InlineLevelLayoutManager#applyChanges(List) */ public boolean applyChanges(List oldList) { setFinished(false); @@ -677,14 +667,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager { while (changeListIterator.hasNext()) { currChange = (PendingChange) changeListIterator.next(); if (currChange.index != iOldIndex) { - iRemovedAI ++; - iAddedAI ++; + iRemovedAI++; + iAddedAI++; iOldIndex = currChange.index; vecAreaInfo.remove(currChange.index + iAddedAI - iRemovedAI); vecAreaInfo.add(currChange.index + iAddedAI - iRemovedAI, currChange.ai); } else { - iAddedAI ++; + iAddedAI++; vecAreaInfo.add(currChange.index + iAddedAI - iRemovedAI, currChange.ai); } @@ -696,6 +686,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { return bChanged; } + /** @see org.aapache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int) */ public LinkedList getChangedKnuthElements(List oldList, int alignment) { if (isFinished()) { @@ -715,12 +706,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager { returnList.addAll (createElementsForASpace(alignment, ai, iReturnedIndex)); } - iReturnedIndex ++; + iReturnedIndex++; } // end of while setFinished(true); return returnList; } + /** @see InlineLevelLayoutManager#getWordChars(StringBuffer, Position) */ public void getWordChars(StringBuffer sbChars, Position pos) { int iLeafValue = ((LeafPosition) pos).getLeafPos(); if (iLeafValue != -1) { @@ -752,6 +744,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // if the second element is chosen as a line break these elements // add a constant amount of stretch at the end of a line and at the // beginning of the next one, otherwise they don't add any stretch + /* spaceElements.add (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), false)); @@ -772,6 +765,27 @@ public class TextLayoutManager extends LeafNodeLayoutManager { spaceElements.add (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), false)); + */ + spaceElements.add + (new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), true)); + spaceElements.add + (new KnuthPenalty(0, + (textArray[ai.iStartIndex] == NBSPACE ? KnuthElement.INFINITE : 0), + false, new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt - (lineStartBAP + lineEndBAP), + -6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + mainPosition, false)); + spaceElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), true)); + spaceElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), true)); + spaceElements.add + (new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), true)); break; case EN_START : // fall through @@ -780,6 +794,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // if the second element is chosen as a line break these elements // add a constant amount of stretch at the end of a line, otherwise // they don't add any stretch + /* spaceElements.add (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), false)); @@ -790,25 +805,116 @@ public class TextLayoutManager extends LeafNodeLayoutManager { (new KnuthGlue(ai.ipdArea.opt, - 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, mainPosition, false)); + */ + if (lineStartBAP != 0 || lineEndBAP != 0) { + spaceElements.add + (new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthPenalty(0, 0, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt - (lineStartBAP + lineEndBAP), + -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + mainPosition, false)); + spaceElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), false)); + spaceElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(lineStartBAP, 0, 0, + new LeafPosition(this, -1), false)); + } else { + spaceElements.add + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthPenalty(0, 0, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt, + -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + mainPosition, false)); + } break; case EN_JUSTIFY: // justified text: // the stretch and shrink depends on the space width + /* spaceElements.add (new KnuthGlue(ai.ipdArea.opt, ai.ipdArea.max - ai.ipdArea.opt, ai.ipdArea.opt - ai.ipdArea.min, mainPosition, false)); + */ + if (lineStartBAP != 0 || lineEndBAP != 0) { + spaceElements.add + (new KnuthGlue(lineEndBAP, 0, 0, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthPenalty(0, 0, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt - (lineStartBAP + lineEndBAP), + ai.ipdArea.max - ai.ipdArea.opt, + ai.ipdArea.opt - ai.ipdArea.min, + mainPosition, false)); + spaceElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), false)); + spaceElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(lineStartBAP, 0, 0, + new LeafPosition(this, -1), false)); + } else { + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt, + ai.ipdArea.max - ai.ipdArea.opt, + ai.ipdArea.opt - ai.ipdArea.min, + mainPosition, false)); + } break; default: // last line justified, the other lines unjustified: // use only the space stretch + /* spaceElements.add (new KnuthGlue(ai.ipdArea.opt, ai.ipdArea.max - ai.ipdArea.opt, 0, mainPosition, false)); + */ + if (lineStartBAP != 0 || lineEndBAP != 0) { + spaceElements.add + (new KnuthGlue(lineEndBAP, 0, 0, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthPenalty(0, 0, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt - (lineStartBAP + lineEndBAP), + ai.ipdArea.max - ai.ipdArea.opt, 0, + mainPosition, false)); + spaceElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), false)); + spaceElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), false)); + spaceElements.add + (new KnuthGlue(lineStartBAP, 0, 0, + new LeafPosition(this, -1), false)); + } else { + spaceElements.add + (new KnuthGlue(ai.ipdArea.opt, + ai.ipdArea.max - ai.ipdArea.opt, 0, + mainPosition, false)); + } } return spaceElements; @@ -822,40 +928,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // if the last character of the word fragment is '-' or '/', // the fragment could end a line; in this case, it loses one // of its letter spaces; - boolean bSuppressibleLetterSpace = - ai.iLScount == (ai.iBreakIndex - ai.iStartIndex) - && BREAK_CHARS.indexOf(textArray[ai.iBreakIndex - 1]) >= 0; + boolean bSuppressibleLetterSpace + = ai.iLScount == (ai.iBreakIndex - ai.iStartIndex) + && BREAK_CHARS.indexOf(textArray[ai.iBreakIndex - 1]) >= 0; if (letterSpaceWidth.min == letterSpaceWidth.max) { // constant letter spacing wordElements.add - (new KnuthInlineBox( - bSuppressibleLetterSpace ? - ai.ipdArea.opt - letterSpaceWidth.opt : - ai.ipdArea.opt, - lead, total, middle, - mainPosition, false)); + (new KnuthInlineBox( + bSuppressibleLetterSpace + ? ai.ipdArea.opt - letterSpaceWidth.opt + : ai.ipdArea.opt, + alignmentContext, + notifyPos(mainPosition), false)); } else { // adjustable letter spacing - int unsuppressibleLetterSpaces = bSuppressibleLetterSpace ? - ai.iLScount - 1 : - ai.iLScount; + int unsuppressibleLetterSpaces + = bSuppressibleLetterSpace ? ai.iLScount - 1 : ai.iLScount; wordElements.add - (new KnuthInlineBox(ai.ipdArea.opt - - ai.iLScount * letterSpaceWidth.opt, - lead, total, middle, - mainPosition, false)); + (new KnuthInlineBox(ai.ipdArea.opt + - ai.iLScount * letterSpaceWidth.opt, + alignmentContext, + notifyPos(mainPosition), false)); wordElements.add - (new KnuthPenalty(0, KnuthElement.INFINITE, false, - new LeafPosition(this, -1), true)); + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), true)); wordElements.add - (new KnuthGlue(unsuppressibleLetterSpaces * letterSpaceWidth.opt, - unsuppressibleLetterSpaces * (letterSpaceWidth.max - letterSpaceWidth.opt), - unsuppressibleLetterSpaces * (letterSpaceWidth.opt - letterSpaceWidth.min), - new LeafPosition(this, -1), true)); + (new KnuthGlue(unsuppressibleLetterSpaces * letterSpaceWidth.opt, + unsuppressibleLetterSpaces * (letterSpaceWidth.max - letterSpaceWidth.opt), + unsuppressibleLetterSpaces * (letterSpaceWidth.opt - letterSpaceWidth.min), + new LeafPosition(this, -1), true)); wordElements.add - (new KnuthInlineBox(0, 0, 0, 0, - new LeafPosition(this, -1), true)); + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), true)); } // extra-elements if the word fragment is the end of a syllable, @@ -871,7 +976,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // otherwise there is one more letter space wordElements.addAll(createElementsForAHyphen(alignment, 0, letterSpaceWidth)); } - return wordElements; } @@ -882,60 +986,157 @@ public class TextLayoutManager extends LeafNodeLayoutManager { switch (alignment) { case EN_CENTER : // centered text: + /* hyphenElements.add - (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, - new LeafPosition(this, -1), false)); + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, - new LeafPosition(this, -1), false)); + (new KnuthPenalty(hyphIPD, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthGlue(widthIfNoBreakOccurs.opt, - - 6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, - new LeafPosition(this, -1), false)); + (new KnuthGlue(0, + - 6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthInlineBox(0, 0, 0, 0, - new LeafPosition(this, -1), false)); + (new KnuthInlineBox(0, 0, 0, 0, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthPenalty(0, KnuthElement.INFINITE, true, - new LeafPosition(this, -1), false)); + (new KnuthPenalty(0, KnuthElement.INFINITE, true, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, - new LeafPosition(this, -1), false)); + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + */ + hyphenElements.add + (new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), true)); + hyphenElements.add + (new KnuthPenalty(hyphIPD, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthGlue(-(lineEndBAP + lineStartBAP), + -6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), true)); + hyphenElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), true)); + hyphenElements.add + (new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), true)); break; case EN_START : // fall through case EN_END : // left- or right-aligned text: + /* hyphenElements.add - (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, - new LeafPosition(this, -1), false)); + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, - new LeafPosition(this, -1), false)); + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); hyphenElements.add - (new KnuthGlue(widthIfNoBreakOccurs.opt, - - 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, - new LeafPosition(this, -1), false)); + (new KnuthGlue(widthIfNoBreakOccurs.opt, + - 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + */ + if (lineStartBAP != 0 || lineEndBAP != 0) { + hyphenElements.add + (new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthGlue(widthIfNoBreakOccurs.opt - (lineStartBAP + lineEndBAP), + -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), false)); + hyphenElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthGlue(lineStartBAP, 0, 0, + new LeafPosition(this, -1), false)); + } else { + hyphenElements.add + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthGlue(widthIfNoBreakOccurs.opt, + -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, + new LeafPosition(this, -1), false)); + } break; default: // justified text, or last line justified: // just a flagged penalty + /* hyphenElements.add - (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, - new LeafPosition(this, -1), false)); - // extra elements representing a letter space that is suppressed - // if a break occurs - if (widthIfNoBreakOccurs.min != 0 - || widthIfNoBreakOccurs.max != 0) { - hyphenElements.add - (new KnuthGlue(widthIfNoBreakOccurs.opt, - widthIfNoBreakOccurs.max - widthIfNoBreakOccurs.opt, - widthIfNoBreakOccurs.opt - widthIfNoBreakOccurs.min, + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); + */ + if (lineStartBAP != 0 || lineEndBAP != 0) { + hyphenElements.add + (new KnuthGlue(lineEndBAP, 0, 0, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); + // extra elements representing a letter space that is suppressed + // if a break occurs + if (widthIfNoBreakOccurs.min != 0 + || widthIfNoBreakOccurs.max != 0) { + hyphenElements.add + (new KnuthGlue(widthIfNoBreakOccurs.opt - (lineStartBAP + lineEndBAP), + widthIfNoBreakOccurs.max - widthIfNoBreakOccurs.opt, + widthIfNoBreakOccurs.opt - widthIfNoBreakOccurs.min, + new LeafPosition(this, -1), false)); + } else { + hyphenElements.add + (new KnuthGlue(-(lineStartBAP + lineEndBAP), 0, 0, + new LeafPosition(this, -1), false)); + } + hyphenElements.add + (new KnuthInlineBox(0, null, + notifyPos(new LeafPosition(this, -1)), false)); + hyphenElements.add + (new KnuthPenalty(0, KnuthElement.INFINITE, false, + new LeafPosition(this, -1), false)); + hyphenElements.add + (new KnuthGlue(lineStartBAP, 0, 0, + new LeafPosition(this, -1), false)); + } else { + hyphenElements.add + (new KnuthPenalty(widthIfBreakOccurs, + KnuthPenalty.FLAGGED_PENALTY, true, + new LeafPosition(this, -1), false)); + // extra elements representing a letter space that is suppressed + // if a break occurs + if (widthIfNoBreakOccurs.min != 0 + || widthIfNoBreakOccurs.max != 0) { + hyphenElements.add + (new KnuthGlue(widthIfNoBreakOccurs.opt, + widthIfNoBreakOccurs.max - widthIfNoBreakOccurs.opt, + widthIfNoBreakOccurs.opt - widthIfNoBreakOccurs.min, + new LeafPosition(this, -1), false)); + } } } diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index a89ee7383..703ab4294 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -30,6 +30,8 @@ import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.InlineBlockParent; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Space; import org.apache.fop.area.inline.Viewport; import org.apache.fop.datatypes.ColorType; import org.apache.fop.fo.Constants; @@ -365,14 +367,48 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { } } + /** + * Common method to render the background and borders for any inline area. + * The all borders and padding are drawn outside the specified area. + * @param area the inline area for which the background, border and padding is to be + * rendered + */ + protected void renderInlineAreaBackAndBorders(InlineArea area) { + float x = currentIPPosition / 1000f; + float y = (currentBPPosition + area.getOffset()) / 1000f; + float width = area.getIPD() / 1000f; + float height = area.getBPD() / 1000f; + float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f; + float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f; + float bpwidth = borderPaddingStart + + (area.getBorderAndPaddingWidthEnd() / 1000f); + float bpheight = borderPaddingBefore + + (area.getBorderAndPaddingWidthAfter() / 1000f); + + if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) { + drawBackAndBorders(area, x, y - borderPaddingBefore + , width + bpwidth + , height + bpheight); + } + + } + + /** @see org.apache.fop.render.AbstractRenderer#renderInlineSpace(Space) */ + protected void renderInlineSpace(Space space) { + space.setBPD(0); + renderInlineAreaBackAndBorders(space); + super.renderInlineSpace(space); + } + + /** @see org.apache.fop.render.AbstractRenderer#renderInlineParent(InlineParent) */ + protected void renderInlineParent(InlineParent ip) { + renderInlineAreaBackAndBorders(ip); + super.renderInlineParent(ip); + } + /** @see org.apache.fop.render.AbstractRenderer */ protected void renderInlineBlockParent(InlineBlockParent ibp) { - float start = currentIPPosition / 1000f; - float top = (ibp.getOffset() + currentBPPosition) / 1000f; - float width = ibp.getIPD() / 1000f; - float height = ibp.getBPD() / 1000f; - drawBackAndBorders(ibp, start, top, width, height); - + renderInlineAreaBackAndBorders(ibp); super.renderInlineBlockParent(ibp); } diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 2c31c0cee..eda205d94 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -569,13 +569,19 @@ public abstract class AbstractRenderer */ protected void renderLineArea(LineArea line) { List children = line.getInlineAreas(); - + int saveBP = currentBPPosition; + currentBPPosition += line.getSpaceBefore(); for (int count = 0; count < children.size(); count++) { InlineArea inline = (InlineArea) children.get(count); renderInlineArea(inline); } + currentBPPosition = saveBP; } + /** + * Render the given InlineArea. + * @param inlineArea inline area text to render + */ protected void renderInlineArea(InlineArea inlineArea) { if (inlineArea instanceof TextArea) { renderText((TextArea) inlineArea); @@ -595,10 +601,18 @@ public abstract class AbstractRenderer } + /** + * Render the given Character. + * @param ch the character to render + */ protected void renderCharacter(Character ch) { currentIPPosition += ch.getAllocIPD(); } + /** + * Render the given Space. + * @param space the space to render + */ protected void renderInlineSpace(Space space) { // an inline space moves the inline progression position // for the current block by the width or height of the space @@ -607,23 +621,43 @@ public abstract class AbstractRenderer currentIPPosition += space.getAllocIPD(); } + /** + * Render the given Leader. + * @param area the leader to render + */ protected void renderLeader(Leader area) { currentIPPosition += area.getAllocIPD(); } + /** + * Render the given TextArea. + * @param text the text to render + */ protected void renderText(TextArea text) { currentIPPosition += text.getAllocIPD(); } + /** + * Render the given InlineParent. + * @param ip the inline parent to render + */ protected void renderInlineParent(InlineParent ip) { int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + currentIPPosition += ip.getBorderAndPaddingWidthStart(); + currentBPPosition += ip.getOffset(); Iterator iter = ip.getChildAreas().iterator(); while (iter.hasNext()) { renderInlineArea((InlineArea) iter.next()); } currentIPPosition = saveIP + ip.getAllocIPD(); + currentBPPosition = saveBP; } + /** + * Render the given InlineBlockParent. + * @param ibp the inline block parent to render + */ protected void renderInlineBlockParent(InlineBlockParent ibp) { // For inline content the BP position is updated by the enclosing line area int saveBP = currentBPPosition; @@ -631,6 +665,10 @@ public abstract class AbstractRenderer currentBPPosition = saveBP; } + /** + * Render the given Viewport. + * @param viewport the viewport to render + */ protected void renderViewport(Viewport viewport) { Area content = viewport.getContent(); int saveBP = currentBPPosition; diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 0230f9e45..4e6cfb20f 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -732,7 +732,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab public void renderText(TextArea text) { float x = currentIPPosition; - float y = currentBPPosition + text.getOffset(); // baseline + float y = currentBPPosition + text.getOffset() + text.getBaselineOffset(); // baseline String name = (String) text.getTrait(Trait.FONT_NAME); int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); @@ -761,7 +761,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab public void renderCharacter(Character ch) { float x = currentIPPosition; - float y = currentBPPosition + ch.getOffset(); // baseline + float y = currentBPPosition + ch.getOffset() + ch.getBaselineOffset(); // baseline String name = (String) ch.getTrait(Trait.FONT_NAME); int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue(); diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 4f23730cb..ba8b6796e 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -967,10 +967,9 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { public void renderInlineParent(InlineParent ip) { float start = currentIPPosition / 1000f; float top = (ip.getOffset() + currentBPPosition) / 1000f; + float width = ip.getIPD() / 1000f; float height = ip.getBPD() / 1000f; - drawBackAndBorders(ip, start, top, width, height); - // render contents super.renderInlineParent(ip); @@ -1011,6 +1010,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { * @see org.apache.fop.render.AbstractRenderer#renderCharacter(Character) */ public void renderCharacter(Character ch) { + renderInlineAreaBackAndBorders(ch); + beginTextObject(); StringBuffer pdf = new StringBuffer(); @@ -1034,8 +1035,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { // word.getOffset() = only height of text itself // currentBlockIPPosition: 0 for beginning of line; nonzero // where previous line area failed to take up entire allocated space - int rx = currentIPPosition; - int bl = currentBPPosition + ch.getOffset(); + int rx = currentIPPosition + ch.getBorderAndPaddingWidthStart(); + int bl = currentBPPosition + ch.getOffset() + ch.getBaselineOffset(); /* System.out.println("Text = " + ch.getTextArea() + "; text width: " + ch.getWidth() + @@ -1085,6 +1086,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea) */ public void renderText(TextArea text) { + renderInlineAreaBackAndBorders(text); beginTextObject(); StringBuffer pdf = new StringBuffer(); @@ -1106,8 +1108,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { // word.getOffset() = only height of text itself // currentBlockIPPosition: 0 for beginning of line; nonzero // where previous line area failed to take up entire allocated space - int rx = currentIPPosition; - int bl = currentBPPosition + text.getOffset(); + int rx = currentIPPosition + text.getBorderAndPaddingWidthStart(); + int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset(); /* System.out.println("Text = " + text.getTextArea() + "; text width: " + text.getWidth() + @@ -1448,6 +1450,9 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { * @param area the leader area to render */ public void renderLeader(Leader area) { + renderInlineAreaBackAndBorders(area); + + currentState.push(); saveGraphicsState(); int style = area.getRuleStyle(); boolean alt = false; @@ -1467,19 +1472,23 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { alt = true; break; } - float startx = ((float) currentIPPosition) / 1000f; - float starty = ((currentBPPosition + area.getOffset()) / 1000f); - float endx = (currentIPPosition + area.getIPD()) / 1000f; + float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f; + float starty = (currentBPPosition + area.getOffset()) / 1000f; + float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() + + area.getIPD()) / 1000f; + // PDF draws lines centered on the Y coordiante, therefore we need to + // add half of the line thickness to the Y positions. if (!alt) { updateLineWidth(area.getRuleThickness() / 1000f); - drawLine(startx, starty, endx, starty); + drawLine(startx, starty + area.getRuleThickness() / 2000f + , endx, starty + area.getRuleThickness() / 2000f); } else { if (style == EN_DOUBLE) { float third = area.getRuleThickness() / 3000f; updateLineWidth(third); - drawLine(startx, starty, endx, starty); + drawLine(startx, starty + 0.5f * third, endx, starty + 0.5f * third); - drawLine(startx, (starty + 2 * third), endx, (starty + 2 * third)); + drawLine(startx, (starty + 2.5f * third), endx, (starty + 2.5f * third)); } else { float half = area.getRuleThickness() / 2000f; @@ -1512,6 +1521,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } restoreGraphicsState(); + currentState.pop(); beginTextObject(); super.renderLeader(area); } diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 7d3c046a1..34a5be8cb 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -821,6 +821,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer { } private void renderText(AbstractTextArea area, String text) { + renderInlineAreaBackAndBorders(area); String fontname = (String)area.getTrait(Trait.FONT_NAME); int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE); @@ -829,7 +830,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer { //Determine position int rx = currentIPPosition; - int bl = currentBPPosition + area.getOffset(); + int bl = currentBPPosition + area.getOffset() + area.getBaselineOffset(); useFont(fontname, fontsize); ColorType ct = (ColorType)area.getTrait(Trait.COLOR); @@ -976,12 +977,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer { /** @see org.apache.fop.render.AbstractRenderer */ protected void renderInlineParent(InlineParent ip) { - float start = currentIPPosition / 1000f; - float top = (ip.getOffset() + currentBPPosition) / 1000f; - float width = ip.getIPD() / 1000f; - float height = ip.getBPD() / 1000f; - drawBackAndBorders(ip, start, top, width, height); - super.renderInlineParent(ip); } diff --git a/src/java/org/apache/fop/render/svg/SVGRenderer.java b/src/java/org/apache/fop/render/svg/SVGRenderer.java index eb525e5f2..74b418a5c 100644 --- a/src/java/org/apache/fop/render/svg/SVGRenderer.java +++ b/src/java/org/apache/fop/render/svg/SVGRenderer.java @@ -391,7 +391,8 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { public void renderText(TextArea text) { Element textElement = SVGUtilities.createText(svgDocument, currentIPPosition / 1000, - (currentBPPosition + text.getOffset()) / 1000, + (currentBPPosition + text.getOffset() + + text.getBaselineOffset()) / 1000, text.getTextArea()); currentPageG.appendChild(textElement); @@ -404,7 +405,8 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { public void renderCharacter(org.apache.fop.area.inline.Character ch) { Element text = SVGUtilities.createText(svgDocument, currentIPPosition / 1000, - (currentBPPosition + ch.getOffset()) / 1000, + (currentBPPosition + ch.getOffset() + + ch.getBaselineOffset()) / 1000, "" + ch.getChar()); currentPageG.appendChild(text); diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index ba395c984..cedbb404f 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -512,7 +512,6 @@ public class XMLRenderer extends PrintRenderer { if (line.getStartIndent() != 0) { addAttribute("start-indent", line.getStartIndent()); } - addAttribute("vpos", currentBPPosition); startElement("lineArea", atts); super.renderLineArea(line); endElement("lineArea"); @@ -577,8 +576,10 @@ public class XMLRenderer extends PrintRenderer { */ protected void renderCharacter(org.apache.fop.area.inline.Character ch) { atts.clear(); + addAreaAttributes(ch); addTraitAttributes(ch); - addAttribute("vpos", ch.getOffset()); + addAttribute("offset", ch.getOffset()); + addAttribute("baseline", ch.getBaselineOffset()); startElement("char", atts); characters(ch.getChar()); endElement("char"); @@ -590,6 +591,8 @@ public class XMLRenderer extends PrintRenderer { protected void renderInlineSpace(Space space) { atts.clear(); addAreaAttributes(space); + addTraitAttributes(space); + addAttribute("offset", space.getOffset()); startElement("space", atts); endElement("space"); } @@ -605,7 +608,8 @@ public class XMLRenderer extends PrintRenderer { if (text.getTextLetterSpaceAdjust() != 0) { addAttribute("tlsadjust", text.getTextLetterSpaceAdjust()); } - addAttribute("vpos", text.getOffset()); + addAttribute("offset", text.getOffset()); + addAttribute("baseline", text.getBaselineOffset()); addAreaAttributes(text); addTraitAttributes(text); startElement("text", atts); @@ -621,6 +625,7 @@ public class XMLRenderer extends PrintRenderer { atts.clear(); addAreaAttributes(ip); addTraitAttributes(ip); + addAttribute("offset", ip.getOffset()); startElement("inlineparent", atts); super.renderInlineParent(ip); endElement("inlineparent"); @@ -661,11 +666,16 @@ public class XMLRenderer extends PrintRenderer { case EN_RIDGE: style = "ridge"; break; + case EN_NONE: + style = "none"; + break; default: style = "--NYI--"; } atts.clear(); addAreaAttributes(area); + addTraitAttributes(area); + addAttribute("offset", area.getOffset()); addAttribute("ruleStyle", style); addAttribute("ruleThickness", area.getRuleThickness()); startElement("leader", atts); diff --git a/test/layoutengine/disabled-testcases.txt b/test/layoutengine/disabled-testcases.txt index 078a3e068..dfb38521e 100644 --- a/test/layoutengine/disabled-testcases.txt +++ b/test/layoutengine/disabled-testcases.txt @@ -1,5 +1,5 @@ -character_background-image.xml block-container_reference-orientation_bug36391.xml +block_font-family_asian.xml block_font-stretch.xml block_padding_2.xml block_space-before_space-after_2.xml @@ -9,7 +9,7 @@ block_word-spacing_text-align_justify.xml external-graphic_oversized.xml inline-block_keep-together.xml inline_block_nested_3.xml -inline_border_padding.xml +inline_border_padding_block_nested.xml inline-container_block_nested.xml inline-container_border_padding.xml inline_letter-spacing.xml @@ -23,6 +23,7 @@ list-item_space-before_space-after_2.xml page-breaking_4.xml page-breaking_6.xml page-height_indefinite_simple.xml +page-number-citation_background-image.xml page-number-citation_complex_1.xml page-number-citation_complex_2.xml page-number_initial-page-number_2.xml diff --git a/test/layoutengine/testcases/basic-link_background-image.xml b/test/layoutengine/testcases/basic-link_background-image.xml index ce3c7bdd6..7ec697ffa 100644 --- a/test/layoutengine/testcases/basic-link_background-image.xml +++ b/test/layoutengine/testcases/basic-link_background-image.xml @@ -42,7 +42,7 @@ - - + + diff --git a/test/layoutengine/testcases/block_basic_2.xml b/test/layoutengine/testcases/block_basic_2.xml index f27c04585..84e485e24 100644 --- a/test/layoutengine/testcases/block_basic_2.xml +++ b/test/layoutengine/testcases/block_basic_2.xml @@ -56,18 +56,24 @@ 3 - - - - - - + + + + + + - - - - - - + + + + + + + + + + + + diff --git a/test/layoutengine/testcases/block_line-height.xml b/test/layoutengine/testcases/block_line-height.xml index 5908e14ce..03bec53cc 100644 --- a/test/layoutengine/testcases/block_line-height.xml +++ b/test/layoutengine/testcases/block_line-height.xml @@ -55,20 +55,69 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/layoutengine/testcases/character_background-color.xml b/test/layoutengine/testcases/character_background-color.xml new file mode 100755 index 000000000..a95d2cf50 --- /dev/null +++ b/test/layoutengine/testcases/character_background-color.xml @@ -0,0 +1,43 @@ + + + + + +

+ This test checks fo:character with background-color property. +

+
+ + + + + + + + + + + To mphasize a character highlight it. + + + + + + + + +
diff --git a/test/layoutengine/testcases/character_background-image.xml b/test/layoutengine/testcases/character_background-image.xml index d71072076..8dc1f4361 100644 --- a/test/layoutengine/testcases/character_background-image.xml +++ b/test/layoutengine/testcases/character_background-image.xml @@ -18,7 +18,7 @@

- This test checks background image on a character. + This test checks fo:character with background-image property.

@@ -33,13 +33,16 @@ - - + + + + +
diff --git a/test/layoutengine/testcases/character_border_padding.xml b/test/layoutengine/testcases/character_border_padding.xml new file mode 100755 index 000000000..a5c6f6f7a --- /dev/null +++ b/test/layoutengine/testcases/character_border_padding.xml @@ -0,0 +1,98 @@ + + + + + +

+ This test checks fo:character with border and padding properties. +

+
+ + + + + + + + + + + To mphasize a letter we give it a 1pt border. + + + To really mphasize a letter we give it a 5pt border and padding. + + + To onfuse give it unsymmetric borders and padding. + + + Big order but a smaller font. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/character_vertical-align.xml b/test/layoutengine/testcases/character_vertical-align.xml new file mode 100755 index 000000000..60f15505e --- /dev/null +++ b/test/layoutengine/testcases/character_vertical-align.xml @@ -0,0 +1,59 @@ + + + + + +

+ This test checks fo:character with vertical-align property. +

+
+ + + + + + + + + + + vertical-alignnot specified + + + vertical-alignbaseline + + + vertical-aligntop + + + vertical-alignmiddle + + + vertical-alignbottom + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/external-graphic_border_padding.xml b/test/layoutengine/testcases/external-graphic_border_padding.xml index 43ff49649..a05c367b9 100644 --- a/test/layoutengine/testcases/external-graphic_border_padding.xml +++ b/test/layoutengine/testcases/external-graphic_border_padding.xml @@ -49,7 +49,7 @@ - + @@ -65,7 +65,7 @@ - + diff --git a/test/layoutengine/testcases/footnote_basic.xml b/test/layoutengine/testcases/footnote_basic.xml index 41395bd77..888c0b1c6 100644 --- a/test/layoutengine/testcases/footnote_basic.xml +++ b/test/layoutengine/testcases/footnote_basic.xml @@ -69,7 +69,7 @@ - + diff --git a/test/layoutengine/testcases/footnote_footnote-separator.xml b/test/layoutengine/testcases/footnote_footnote-separator.xml index 2eb4a41f8..4bfdb64e1 100644 --- a/test/layoutengine/testcases/footnote_footnote-separator.xml +++ b/test/layoutengine/testcases/footnote_footnote-separator.xml @@ -79,13 +79,13 @@ - + - + - + @@ -102,10 +102,10 @@ - + - + diff --git a/test/layoutengine/testcases/inline_alignment-adjust_1.xml b/test/layoutengine/testcases/inline_alignment-adjust_1.xml new file mode 100755 index 000000000..ac6a6233f --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-adjust_1.xml @@ -0,0 +1,107 @@ + + + + + +

+ This test checks inline level alignment-adjust. +

+
+ + + + + + + + + + + Before alignment-adjust not specified After + + + Before alignment-adjust="auto" After + + + Before alignment-adjust="baseline" After + + + Before alignment-adjust="before-edge" After + + + Before alignment-adjust="text-before-edge" After + + + Before alignment-adjust="central" After + + + Before alignment-adjust="middle" After + + + Before alignment-adjust="after-edge" After + + + Before alignment-adjust="text-after-edge" After + + + Before alignment-adjust="ideographic" After + + + Before alignment-adjust="alphabetic" After + + + Before alignment-adjust="hanging" After + + + Before alignment-adjust="mathematical" After + + + Before alignment-adjust="top" After + + + Before alignment-adjust="bottom" After + + + Before alignment-adjust="text-top" After + + + Before alignment-adjust="text-bottom" After + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_alignment-adjust_2.xml b/test/layoutengine/testcases/inline_alignment-adjust_2.xml new file mode 100755 index 000000000..fd21545b2 --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-adjust_2.xml @@ -0,0 +1,98 @@ + + + + + +

+ This test checks inline level alignment-adjust. +

+
+ + + + + + + + + + + Before alignment-adjust="0pt" After + + + Before alignment-adjust="0%" After + + + Before alignment-adjust="3pt" After + + + Before alignment-adjust="-3pt" After + + + Before alignment-adjust="30%" After + + + Before alignment-adjust="-30%" After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_alignment-baseline_1.xml b/test/layoutengine/testcases/inline_alignment-baseline_1.xml new file mode 100755 index 000000000..128fd6b00 --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-baseline_1.xml @@ -0,0 +1,107 @@ + + + + + +

+ This test checks inline level alignment-baseline. +

+
+ + + + + + + + + + + Before alignment-baseline not specified After + + + Before alignment-baseline="auto" After + + + Before alignment-baseline="baseline" After + + + Before alignment-baseline="before-edge" After + + + Before alignment-baseline="text-before-edge" After + + + Before alignment-baseline="central" After + + + Before alignment-baseline="middle" After + + + Before alignment-baseline="after-edge" After + + + Before alignment-baseline="text-after-edge" After + + + Before alignment-baseline="ideographic" After + + + Before alignment-baseline="alphabetic" After + + + Before alignment-baseline="hanging" After + + + Before alignment-baseline="mathematical" After + + + Before alignment-baseline="top" After + + + Before alignment-baseline="bottom" After + + + Before alignment-baseline="text-top" After + + + Before alignment-baseline="text-bottom" After + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_alignment-baseline_2.xml b/test/layoutengine/testcases/inline_alignment-baseline_2.xml new file mode 100755 index 000000000..f5559f435 --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-baseline_2.xml @@ -0,0 +1,140 @@ + + + + + +

+ This test checks inline level alignment-baseline. +

+
+ + + + + + + + + + + Before alignment-baseline not specified After + + + Before alignment-baseline="auto" After + + + Before alignment-baseline="baseline" After + + + Before alignment-baseline="before-edge" After + + + Before alignment-baseline="text-before-edge" After + + + Before alignment-baseline="central" After + + + Before alignment-baseline="middle" After + + + Before alignment-baseline="after-edge" After + + + Before alignment-baseline="text-after-edge" After + + + Before alignment-baseline="ideographic" After + + + Before alignment-baseline="alphabetic" After + + + Before alignment-baseline="hanging" After + + + Before alignment-baseline="mathematical" After + + + Before alignment-baseline="top" After + + + Before alignment-baseline="bottom" After + + + Before alignment-baseline="text-top" After + + + Before alignment-baseline="text-bottom" After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_alignment-baseline_3.xml b/test/layoutengine/testcases/inline_alignment-baseline_3.xml new file mode 100755 index 000000000..77cc07167 --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-baseline_3.xml @@ -0,0 +1,107 @@ + + + + + +

+ This test checks inline level alignment-baseline. +

+
+ + + + + + + + + + + Before alignment-baseline not specified After + + + Before alignment-baseline="auto" After + + + Before alignment-baseline="baseline" After + + + Before alignment-baseline="before-edge" After + + + Before alignment-baseline="text-before-edge" After + + + Before alignment-baseline="central" After + + + Before alignment-baseline="middle" After + + + Before alignment-baseline="after-edge" After + + + Before alignment-baseline="text-after-edge" After + + + Before alignment-baseline="ideographic" After + + + Before alignment-baseline="alphabetic" After + + + Before alignment-baseline="hanging" After + + + Before alignment-baseline="mathematical" After + + + Before alignment-baseline="top" After + + + Before alignment-baseline="bottom" After + + + Before alignment-baseline="text-top" After + + + Before alignment-baseline="text-bottom" After + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_alignment-baseline_4.xml b/test/layoutengine/testcases/inline_alignment-baseline_4.xml new file mode 100755 index 000000000..794c81e5a --- /dev/null +++ b/test/layoutengine/testcases/inline_alignment-baseline_4.xml @@ -0,0 +1,231 @@ + + + + + +

+ This test checks inline level alignment-baseline for nested inlines. +

+
+ + + + + + + + + + Big + alphabetic + alphabetic + + Big Baseline table unchanged + + Big + alphabetic + alphabetic + + Big Baseline table changed + + Big + hanging + middle + + Big Baseline table unchanged + + Big + hanging + middle + + Big Baseline table changed + + Big + text-before-edge + after-edge + + Big Baseline table unchanged + + Big + text-before-edge + after-edge + + Big Baseline table changed + + Big + central + text-before-edge + alphabetic + + + Big Baseline table unchanged + + Big + central + text-before-edge + alphabetic + + + Big Baseline table changed + + Big + central + text-before-edge + alphabetic + + + Big Baseline table changed twice + + Big + before-edge + after-edge + + Big This is over constraint + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_background-color.xml b/test/layoutengine/testcases/inline_background-color.xml new file mode 100755 index 000000000..7b5fcdb03 --- /dev/null +++ b/test/layoutengine/testcases/inline_background-color.xml @@ -0,0 +1,132 @@ + + + + + +

+ This test checks fo:inline with background-color properties. +

+
+ + + + + + + + + + + To emphasize a phrase highlight it. + + + To emphasize a phrase highlight it with text-align="end". + + + To emphasize a phrase highlight it with text-align="justify". + + + To emphasize a phrase highlight it with text-align="center". + + + This demonstrates a long inline + which stretches over multiple lines to + show how the highlight extends from line to line while + correctly honouring the text-align (not specified) property + back to normal + + + This demonstrates a long inline + which stretches over multiple lines to + show how the highlight extends from line to line while + correctly honouring the text-align="end" property + back to normal + + + This demonstrates a long inline + which stretches over multiple lines to + show how the highlight extends from line to line while + correctly honouring the text-align="justify" property + back to normal + + + This demonstrates a long inline + which stretches over multiple lines to + show how the highlight extends from line to line while + correctly honouring the text-align="center" property + back to normal + + + Nested inline highlights + this is 10pt text + nested within is 14pt text + followed by 10pt text + back to normal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_background-image.xml b/test/layoutengine/testcases/inline_background-image.xml index 92f3c31f3..570be1d8d 100644 --- a/test/layoutengine/testcases/inline_background-image.xml +++ b/test/layoutengine/testcases/inline_background-image.xml @@ -42,7 +42,7 @@ - - + + diff --git a/test/layoutengine/testcases/inline_baseline-shift_1.xml b/test/layoutengine/testcases/inline_baseline-shift_1.xml new file mode 100755 index 000000000..723abfc9d --- /dev/null +++ b/test/layoutengine/testcases/inline_baseline-shift_1.xml @@ -0,0 +1,164 @@ + + + + + +

+ This test checks inline level baseline-shift. +

+
+ + + + + + + + + + + Before + baseline-shift="baseline" + After + + + Before + baseline-shift="sub" + After + + + Before + baseline-shift="super" + After + + + Before + baseline-shift="0pt" + After + + + Before + baseline-shift="0%" + After + + + Before + baseline-shift="3pt" + After + + + Before + baseline-shift="-3pt" + After + + + Before + baseline-shift="30%" + After + + + Before + baseline-shift="-30%" + After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_baseline-shift_2.xml b/test/layoutengine/testcases/inline_baseline-shift_2.xml new file mode 100755 index 000000000..6bc6d60bc --- /dev/null +++ b/test/layoutengine/testcases/inline_baseline-shift_2.xml @@ -0,0 +1,171 @@ + + + + + +

+ This test checks inline level baseline-shift. +

+
+ + + + + + + + + + + Before + sub + sub + sub + + After + + + Before + sub + super + sub + + After + + + Before + super + super + super + + After + + + Before + super + sub + super + + After + + + Before + 30% + -50% + 30% + + After + + + Before + super + sub + super + sub + super + + After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_baseline-shift_3.xml b/test/layoutengine/testcases/inline_baseline-shift_3.xml new file mode 100755 index 000000000..eee8906b7 --- /dev/null +++ b/test/layoutengine/testcases/inline_baseline-shift_3.xml @@ -0,0 +1,210 @@ + + + + + +

+ This test checks inline level baseline-shift. +

+
+ + + + + + + + + + + Before + middle + sub + middle + + After Baseline table changed + + + Before + middle + super + middle + + After Baseline table changed + + + Before + text-after-edge + 30% + text-after-edge + + After Baseline table changed + + + Before + text-before-edge + -50% + text-before-edge + + After Baseline table changed + + + Before + middle + sub + middle + + After Baseline table unchanged + + + Before + middle + super + middle + + After Baseline table unchanged + + + Before + text-after-edge + 30% + text-after-edge + + After Baseline table unchanged + + + Before + text-before-edge + -50% + text-before-edge + + After Baseline table unchanged + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_baseline-shift_4.xml b/test/layoutengine/testcases/inline_baseline-shift_4.xml new file mode 100755 index 000000000..87055ac0e --- /dev/null +++ b/test/layoutengine/testcases/inline_baseline-shift_4.xml @@ -0,0 +1,184 @@ + + + + + +

+ This test checks inline level baseline-shift. +

+
+ + + + + + + + + + + Before + 6pt central + + central + + After + + + Before + -6pt central + + central + + After + + + Before + sub + text-before-edge + Baseline unchanged + central + + After + + + Before + super + text-after-edge + Baseline unchanged + central + + After + + + Before + sub + text-before-edge + Baseline changed + central + + After + + + Before + super + text-after-edge + Baseline changed + central + + After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_border_padding.xml b/test/layoutengine/testcases/inline_border_padding.xml index 474191416..08cabc67c 100644 --- a/test/layoutengine/testcases/inline_border_padding.xml +++ b/test/layoutengine/testcases/inline_border_padding.xml @@ -24,25 +24,117 @@ - + - + - - Start of file + + To emphasize a word we give it a 1pt border and a background. - - Normal text inline with border="solid 5pt red" padding="5pt" normal finish + + Demonstrates a big border inline with border="solid 5pt red" padding="5pt" extending over the small allocation rectangle to the top and bottom. - - End of file + + Demonstrates unsymmetric borders and padding but the baselines should align. + + + Big border with a smaller font but the baselines should align. + + + This demonstrates correct line breaking of a fo:inline because it does fit nicely.. + This demonstrates correct line breaking of a fo:inline because it does fit nicely.. + Not really as we started a fo:inline with border/padding just before the word "nicely" which forces it to the next line. + + + Demonstrates nested + inlines + finishing together + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/layoutengine/testcases/inline_border_padding_block_nested.xml b/test/layoutengine/testcases/inline_border_padding_block_nested.xml new file mode 100755 index 000000000..60fca3d16 --- /dev/null +++ b/test/layoutengine/testcases/inline_border_padding_block_nested.xml @@ -0,0 +1,146 @@ + + + + + +

+ This test checks fo:inlines with border and padding properties and nested inner blocks. +

+
+ + + + + + + + + + + Before inline + starting with a block + after block + After inline + + + Before inline + before block + having a block at the end of an inline + After inline + + + Before inline + before block + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + after block + After inline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_border_padding_conditionality_1.xml b/test/layoutengine/testcases/inline_border_padding_conditionality_1.xml new file mode 100755 index 000000000..744b6b33f --- /dev/null +++ b/test/layoutengine/testcases/inline_border_padding_conditionality_1.xml @@ -0,0 +1,398 @@ + + + + + +

+ This test checks fo:inlines with border and padding properties and conditionality. +

+
+ + + + + + + + + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align not set .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="end" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="justify" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="center" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align not set .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="end" .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="justify" .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="center" .conditionality="discard". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_border_padding_conditionality_2.xml b/test/layoutengine/testcases/inline_border_padding_conditionality_2.xml new file mode 100755 index 000000000..bb9b50ab5 --- /dev/null +++ b/test/layoutengine/testcases/inline_border_padding_conditionality_2.xml @@ -0,0 +1,311 @@ + + + + + +

+ This test checks fo:inlines with border and padding properties and conditionality retain. +

+
+ + + + + + + + + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align not set padding .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="end" padding .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="justify" padding .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="center" padding .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, + they are not certain, and as far as they are certain, + they do not refer to reality - Albert Einstein + text-align="center" .conditionality="retain" linefeed-treatment="preserve". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, + they are not certain, and as far as they are certain, + they do not refer to reality - Albert Einstein + text-align="center" .conditionality="discard" linefeed-treatment="preserve". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_border_padding_hyphenate.xml b/test/layoutengine/testcases/inline_border_padding_hyphenate.xml new file mode 100755 index 000000000..b2a0444ad --- /dev/null +++ b/test/layoutengine/testcases/inline_border_padding_hyphenate.xml @@ -0,0 +1,399 @@ + + + + + +

+ This test checks fo:inlines with border and padding properties and hyphenation. +

+
+ + + + + + + + + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="start" .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="end" .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="justify" .conditionality="discard". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="center" .conditionality="discard". + + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="start" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="end" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="justify" .conditionality="retain". + + + Multi-line fo:inline + As far as the laws of mathematics refer to reality, they are not certain, + and as far as they are certain, they do not refer to reality - Albert Einstein + text-align="center" .conditionality="retain". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_border_padding_hyphenate_de.xml b/test/layoutengine/testcases/inline_border_padding_hyphenate_de.xml new file mode 100755 index 000000000..06bfae0ea --- /dev/null +++ b/test/layoutengine/testcases/inline_border_padding_hyphenate_de.xml @@ -0,0 +1,399 @@ + + + + + +

+ This test checks inlines with border and padding properties and hyphenation. +

+
+ + + + + + + + + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="start" .conditionality="discard". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="end" .conditionality="discard". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="justify" .conditionality="discard". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="center" .conditionality="discard". + + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="start" .conditionality="retain". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="end" .conditionality="retain". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="justify" .conditionality="retain". + + + Multi-line fo:inline + Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz + Donaudampfschiffahrtselektrizitaetenhauptbetriebswerkbauunterbeamtengesellschaft + text-align="center" .conditionality="retain". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_dominant-baseline_1.xml b/test/layoutengine/testcases/inline_dominant-baseline_1.xml new file mode 100755 index 000000000..550bca8cb --- /dev/null +++ b/test/layoutengine/testcases/inline_dominant-baseline_1.xml @@ -0,0 +1,128 @@ + + + + + +

+ This test checks inline level dominant-baseline. +

+
+ + + + + + + + + + + Before dominant-baseline="auto" After + + + Before dominant-baseline="no-change" After + + + Before dominant-baseline="ideographic" After + + + Before dominant-baseline="alphabetic" After + + + Before dominant-baseline="hanging" After + + + Before dominant-baseline="mathematical" After + + + Before dominant-baseline="central" After + + + Before dominant-baseline="middle" After + + + Before dominant-baseline="text-after-edge" After + + + Before dominant-baseline="text-before-edge" After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_dominant-baseline_2.xml b/test/layoutengine/testcases/inline_dominant-baseline_2.xml new file mode 100755 index 000000000..1d863bfc1 --- /dev/null +++ b/test/layoutengine/testcases/inline_dominant-baseline_2.xml @@ -0,0 +1,128 @@ + + + + + +

+ This test checks inline level dominant-baseline. +

+
+ + + + + + + + + + + Before dominant-baseline="auto" After + + + Before dominant-baseline="no-change" After + + + Before dominant-baseline="ideographic" After + + + Before dominant-baseline="alphabetic" After + + + Before dominant-baseline="hanging" After + + + Before dominant-baseline="mathematical" After + + + Before dominant-baseline="central" After + + + Before dominant-baseline="middle" After + + + Before dominant-baseline="text-after-edge" After + + + Before dominant-baseline="text-before-edge" After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_dominant-baseline_3.xml b/test/layoutengine/testcases/inline_dominant-baseline_3.xml new file mode 100755 index 000000000..8b1056f62 --- /dev/null +++ b/test/layoutengine/testcases/inline_dominant-baseline_3.xml @@ -0,0 +1,115 @@ + + + + + +

+ This test checks inline level dominant-baseline. +

+
+ + + + + + + + + + + Before + central + Baseline changed + + After + + + Before + text-before-edge + Baseline changed + + After + + + Before + text-after-edge + Baseline changed + + After + + + Before + middle + hanging + Baseline changed + + + + After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_vertical-align_1.xml b/test/layoutengine/testcases/inline_vertical-align_1.xml new file mode 100755 index 000000000..1ff5ca2f1 --- /dev/null +++ b/test/layoutengine/testcases/inline_vertical-align_1.xml @@ -0,0 +1,148 @@ + + + + + +

+ This test checks inline level vertical align. +

+
+ + + + + + + + + + + Before vertical-align not specified After + + + Before vertical-align="baseline" After + + + Before vertical-align="top" After + + + Before vertical-align="text-top" After + + + Before vertical-align="middle" After + + + Before vertical-align="text-bottom" After + + + Before vertical-align="bottom" After + + + Before vertical-align="super" After + + + Before vertical-align="sub" After + + + Before vertical-align="super" After + + + Before vertical-align="sub" After + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/inline_vertical-align_2.xml b/test/layoutengine/testcases/inline_vertical-align_2.xml new file mode 100755 index 000000000..53749b355 --- /dev/null +++ b/test/layoutengine/testcases/inline_vertical-align_2.xml @@ -0,0 +1,121 @@ + + + + + +

+ This test checks inline level vertical align. + This example is taken from the spec section 7.13. +

+
+ + + + + + + + + + + This is a longer line that provides a context for the line with images aligned on it. + Before edge , + after edge , + middle , + none . + And this is a line of text that follows the line with the objects aligned on it. + + + This is a longer line that provides a context for the line with images aligned on it. + Before edge , + after edge , + middle . + And this is a line of text that follows the line with the objects aligned on it. + + + This is a longer line that provides a context for the line with images aligned on it. + Before edge , + after edge . + And this is a line of text that follows the line with the objects aligned on it. + + + This is a longer line that provides a context for the line with images aligned on it. + Before edge , + after edge . + And this is a line of text that follows the line with the objects aligned on it. + + + This is a longer line that provides a context for the line with images aligned on it. + Before edge , + after edge , + middle . + And this is a line of text that follows the line with the objects aligned on it. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/instream-foreign-object_border_padding.xml b/test/layoutengine/testcases/instream-foreign-object_border_padding.xml index 51c1ffa0a..16d89eb22 100644 --- a/test/layoutengine/testcases/instream-foreign-object_border_padding.xml +++ b/test/layoutengine/testcases/instream-foreign-object_border_padding.xml @@ -63,7 +63,7 @@ - + @@ -79,7 +79,7 @@ - + diff --git a/test/layoutengine/testcases/leader_alignment-baseline.xml b/test/layoutengine/testcases/leader_alignment-baseline.xml new file mode 100755 index 000000000..630d40e88 --- /dev/null +++ b/test/layoutengine/testcases/leader_alignment-baseline.xml @@ -0,0 +1,170 @@ + + + + + +

+ This test checks fo:leader with different alignment-baseline values. +

+
+ + + + + + + + + + + + dots baseline + + + + rule solid baseline + + + + rule double baseline + + + + + + + dots before-edge + + + + rule solid before-edge + + + + rule double before-edge + + + + + + + dots middle + + + + rule solid middle + + + + rule double middle + + + + + + + dots after-edge + + + + rule solid after-edge + + + + rule double after-edge + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/leader_background-color.xml b/test/layoutengine/testcases/leader_background-color.xml new file mode 100755 index 000000000..05dd381a7 --- /dev/null +++ b/test/layoutengine/testcases/leader_background-color.xml @@ -0,0 +1,81 @@ + + + + + +

+ This test checks fo:leader with background-color +

+
+ + + + + + + + + + + + dots yellow background + + + + rule solid yellow background + + + + rule double yellow background + + + + space yellow background + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/leader_border_padding.xml b/test/layoutengine/testcases/leader_border_padding.xml new file mode 100755 index 000000000..6c0c99a75 --- /dev/null +++ b/test/layoutengine/testcases/leader_border_padding.xml @@ -0,0 +1,256 @@ + + + + + +

+ This test checks fo:leader with border and padding +

+
+ + + + + + + + + + + + dots solid 1pt red border + + + + rule solid solid 1pt red border + + + + rule double solid 1pt red border + + + + space solid 1pt red border + + + + + + + dots solid 5pt red border 5pt padding + + + + rule solid solid 5pt red border 5pt padding + + + + rule double solid 5pt red border 5pt padding + + + + space solid 5pt red border 5pt padding + + + + + + + dots uneven border and padding + + + + rule solid uneven border and padding + + + + rule double uneven border and padding + + + + space uneven border and padding + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/leader_leader-pattern_dots.xml b/test/layoutengine/testcases/leader_leader-pattern_dots.xml index d5ac49b92..55af7c317 100644 --- a/test/layoutengine/testcases/leader_leader-pattern_dots.xml +++ b/test/layoutengine/testcases/leader_leader-pattern_dots.xml @@ -35,23 +35,23 @@ Default dots pattern - + leader-pattern-width="use-font-metrics" - + leader-length="20mm" leader-pattern-width="5mm" - + leader-length="20%" leader-pattern-width="5mm" - + leader-pattern-width="1pt" - + leader-length="20%" leader-pattern-width="5%" @@ -59,29 +59,29 @@ - + - + - + - + - + - + diff --git a/test/layoutengine/testcases/leader_leader-pattern_rule.xml b/test/layoutengine/testcases/leader_leader-pattern_rule.xml index 4e65823fa..bfba5ea26 100644 --- a/test/layoutengine/testcases/leader_leader-pattern_rule.xml +++ b/test/layoutengine/testcases/leader_leader-pattern_rule.xml @@ -31,169 +31,146 @@ - + No rule-style given - + rule-style="none" - + rule-style="dotted" - + rule-style="dashed" - + rule-style="solid" - + rule-style="double" - + rule-style="groove" - + rule-style="ridge" - + rule-style="dotted" rule-thickness="3pt" - + rule-style="dashed" rule-thickness="3pt" - + rule-style="solid" rule-thickness="3pt" - + rule-style="double" rule-thickness="3pt" - + rule-style="groove" rule-thickness="3pt" - + rule-style="ridge" rule-thickness="3pt" - - - No rule-style given alignment-baseline="middle" - - - - rule-style="none" alignment-baseline="middle" - - - - rule-style="dotted" alignment-baseline="middle" - - - - rule-style="dashed" alignment-baseline="middle" - - - - rule-style="solid" alignment-baseline="middle" - - - - rule-style="double" alignment-baseline="middle" - - - - rule-style="groove" alignment-baseline="middle" - - - - rule-style="ridge" alignment-baseline="middle" - - + - + - + + - - - - + + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - + + - + - diff --git a/test/layoutengine/testcases/leader_leader-pattern_space.xml b/test/layoutengine/testcases/leader_leader-pattern_space.xml index e82dfa680..61ee71e7d 100644 --- a/test/layoutengine/testcases/leader_leader-pattern_space.xml +++ b/test/layoutengine/testcases/leader_leader-pattern_space.xml @@ -47,13 +47,13 @@ - + - + - + diff --git a/test/layoutengine/testcases/leader_leader-pattern_use-content.xml b/test/layoutengine/testcases/leader_leader-pattern_use-content.xml index 00b0d97fd..0a297ee3a 100644 --- a/test/layoutengine/testcases/leader_leader-pattern_use-content.xml +++ b/test/layoutengine/testcases/leader_leader-pattern_use-content.xml @@ -31,24 +31,12 @@ - - Default dots pattern + x + Content is "x" - - leader-pattern-width="use-font-metrics" - - - - leader-length="20mm" leader-pattern-width="5mm" - - - - leader-pattern-width="1pt" - - - - leader-pattern-width="5%" + => + Content is "=>" with background diff --git a/test/layoutengine/testcases/leader_toc.xml b/test/layoutengine/testcases/leader_toc.xml new file mode 100755 index 000000000..c8b85ce1b --- /dev/null +++ b/test/layoutengine/testcases/leader_toc.xml @@ -0,0 +1,153 @@ + + + + + +

+ This test checks fo:leader in a typical table of content scenario. + This example is taken from the spec section 6.6.1.1.4 +

+
+ + + + + + + + + + + 1. Chapter + + + + + + + 1.1 Section + + + + + + + 1.2 Section + + + + + + + 2. Chapter + + + + + + + 2.1 Section + + + + + + + 2.2 Section + + + + + + + 1. Chapter + + + Text + + + 1.1 Section + + + Text + + + 1.2 Section + + + Text + + + 2. Chapter + + + Text + + + 2.1 Section + + + Text + + + 2.2 Section + + + Text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number-citation_background-color.xml b/test/layoutengine/testcases/page-number-citation_background-color.xml new file mode 100755 index 000000000..2edf06916 --- /dev/null +++ b/test/layoutengine/testcases/page-number-citation_background-color.xml @@ -0,0 +1,43 @@ + + + + + +

+ This test checks fo:page-number-citation with background-color property. +

+
+ + + + + + + + + + + To emphasize a page number citation highlight it. + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number-citation_background-image.xml b/test/layoutengine/testcases/page-number-citation_background-image.xml new file mode 100755 index 000000000..4cbf84105 --- /dev/null +++ b/test/layoutengine/testcases/page-number-citation_background-image.xml @@ -0,0 +1,49 @@ + + + + + +

+ This test checks fo:page-number-citation with background-image property. +

+
+ + ../../resources/images/bgimg300dpi.jpg + + + + + + + + + + + + Page number citation + Page number citation + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number-citation_border_padding.xml b/test/layoutengine/testcases/page-number-citation_border_padding.xml new file mode 100755 index 000000000..7512c1e94 --- /dev/null +++ b/test/layoutengine/testcases/page-number-citation_border_padding.xml @@ -0,0 +1,98 @@ + + + + + +

+ This test checks fo:page-number-citation with border and padding properties. +

+
+ + + + + + + + + + + Page number citation with a 1pt border. + + + Page number citation with 5pt border and padding. + + + Page number citation with unsymmetric borders and padding. + + + Page number citation with border and padding in a smaller font. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number-citation_vertical-align.xml b/test/layoutengine/testcases/page-number-citation_vertical-align.xml new file mode 100755 index 000000000..be9bbb707 --- /dev/null +++ b/test/layoutengine/testcases/page-number-citation_vertical-align.xml @@ -0,0 +1,59 @@ + + + + + +

+ This test checks fo:page-number-citation with vertical-align property. +

+
+ + + + + + + + + + + Page citation vertical-align not specified + + + Page citation vertical-align="baseline" + + + Page citation vertical-align="top" + + + Page citation vertical-align="middle" + + + Page citation vertical-align="bottom" + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number_background-color.xml b/test/layoutengine/testcases/page-number_background-color.xml new file mode 100755 index 000000000..c052bb4c4 --- /dev/null +++ b/test/layoutengine/testcases/page-number_background-color.xml @@ -0,0 +1,43 @@ + + + + + +

+ This test checks fo:page-number with background-color property. +

+
+ + + + + + + + + + + To emphasize a page number highlight it. + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number_background-image.xml b/test/layoutengine/testcases/page-number_background-image.xml new file mode 100755 index 000000000..08d2e1484 --- /dev/null +++ b/test/layoutengine/testcases/page-number_background-image.xml @@ -0,0 +1,48 @@ + + + + + +

+ This test checks fo:page-number with background-image property. +

+
+ + ../../resources/images/bgimg300dpi.jpg + + + + + + + + + + + + Page + Page + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number_border_padding.xml b/test/layoutengine/testcases/page-number_border_padding.xml new file mode 100755 index 000000000..c099d1c1e --- /dev/null +++ b/test/layoutengine/testcases/page-number_border_padding.xml @@ -0,0 +1,98 @@ + + + + + +

+ This test checks fo:page-number with border and padding properties. +

+
+ + + + + + + + + + + Page number with a 1pt border. + + + Page number with 5pt border and padding. + + + Page number with unsymmetric borders and padding. + + + Page number with border and padding in a smaller font. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/page-number_vertical-align.xml b/test/layoutengine/testcases/page-number_vertical-align.xml new file mode 100755 index 000000000..f436bbd30 --- /dev/null +++ b/test/layoutengine/testcases/page-number_vertical-align.xml @@ -0,0 +1,59 @@ + + + + + +

+ This test checks fo:page-number with vertical-align property. +

+
+ + + + + + + + + + + Page vertical-align not specified + + + Page vertical-align="baseline" + + + Page vertical-align="top" + + + Page vertical-align="middle" + + + Page vertical-align="bottom" + + + + + + + + + + + + +
diff --git a/test/layoutengine/testcases/table-cell_background-image.xml b/test/layoutengine/testcases/table-cell_background-image.xml index dbb9cd42f..f64663990 100644 --- a/test/layoutengine/testcases/table-cell_background-image.xml +++ b/test/layoutengine/testcases/table-cell_background-image.xml @@ -1,130 +1,130 @@ - - - - - -

- This test checks relative positioned background images on a fo:table-cell. -

-
- - ../../resources/images/box1.png - - - - - - - - - - - - - - - - - - image in top right corner - - - image in center right - - - image in bottom right corner - - - - - image in top center - - - image in center - - - image in bottom center - - - - - image in top left - - - image in center left - - - image in bottom left - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + +

+ This test checks relative positioned background images on a fo:table-cell. +

+
+ + ../../resources/images/box1.png + + + + + + + + + + + + + + + + + + image in top right corner + + + image in center right + + + image in bottom right corner + + + + + image in top center + + + image in center + + + image in bottom center + + + + + image in top left + + + image in center left + + + image in bottom left + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-- 2.39.5