aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/layoutmgr/inline
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/inline')
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java59
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java582
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/BasicScaledBaselineTable.java192
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java152
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java18
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java2
-rwxr-xr-xsrc/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java357
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java115
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java38
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java172
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java200
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java232
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java34
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java30
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTable.java70
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ScaledBaselineTableFactory.java74
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java467
17 files changed, 1984 insertions, 810 deletions
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 <length> or <percentage> 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;
}
+
}
@@ -117,29 +124,6 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
}
/**
- * 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
*/
@@ -156,6 +140,15 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
}
/**
+ * 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.
* @param refIPD the ipd of the parent reference area
@@ -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: <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));
+ }
}
}