diff options
29 files changed, 913 insertions, 468 deletions
diff --git a/src/org/apache/fop/area/Area.java b/src/org/apache/fop/area/Area.java index f041f9227..8a3552f0b 100644 --- a/src/org/apache/fop/area/Area.java +++ b/src/org/apache/fop/area/Area.java @@ -10,6 +10,8 @@ package org.apache.fop.area; import java.io.Serializable; import org.apache.fop.fo.FObj; +import java.util.HashMap; + // If the area appears more than once in the output // or if the area has external data it is cached // to keep track of it and to minimize rendered output @@ -126,4 +128,33 @@ public class Area implements Serializable { public FObj getGeneratingFObj() { return this.genFObj; } + + // Do nothing! Let subclasses do something if they can have child areas. + public void addChild(Area child) { + } + + + HashMap props = null; + + public void addTrait(Trait prop) { + if (props == null) { + props = new HashMap(20); + } + props.put(prop.propType, prop.data); + } + + public void addTrait(Object traitCode, Object prop) { + if (props == null) { + props = new HashMap(20); + } + props.put(traitCode, prop); + } + + public HashMap getTraits() { + return this.props; + } + + public Object getTrait(Object oTraitCode) { + return (props != null? props.get(oTraitCode) : null); + } } diff --git a/src/org/apache/fop/area/Block.java b/src/org/apache/fop/area/Block.java index 5dcbb7df4..d1e605d43 100644 --- a/src/org/apache/fop/area/Block.java +++ b/src/org/apache/fop/area/Block.java @@ -71,18 +71,6 @@ public class Block extends BlockParent implements Serializable { return positioning; } - // store properties in array list, need better solution - ArrayList traits = null; - public void addTrait(Trait prop) { - if (traits == null) { - traits = new ArrayList(); - } - traits.add(prop); - } - - public List getTraitList() { - return traits; - } } diff --git a/src/org/apache/fop/area/LineArea.java b/src/org/apache/fop/area/LineArea.java index 25d4d66dc..306d50be6 100644 --- a/src/org/apache/fop/area/LineArea.java +++ b/src/org/apache/fop/area/LineArea.java @@ -46,6 +46,12 @@ public class LineArea extends Area { return new MinOptMax(lineHeight); } + public void addChild(Area childArea) { + if (childArea instanceof InlineArea) { + addInlineArea((InlineArea)childArea); + } + } + public void addInlineArea(InlineArea area) { inlineAreas.add(area); } @@ -54,20 +60,6 @@ public class LineArea extends Area { return inlineAreas; } - // store properties in array list, need better solution - ArrayList props = null; - - public void addTrait(Trait prop) { - if (props == null) { - props = new ArrayList(); - } - props.add(prop); - } - - public List getTraitList() { - return props; - } - public void verticalAlign(int lh, int lead, int follow) { int maxHeight = lh; List inlineAreas = getInlineAreas(); diff --git a/src/org/apache/fop/area/Trait.java b/src/org/apache/fop/area/Trait.java index 7ac537a79..dede23a57 100644 --- a/src/org/apache/fop/area/Trait.java +++ b/src/org/apache/fop/area/Trait.java @@ -8,32 +8,179 @@ package org.apache.fop.area; import org.apache.fop.datatypes.ColorType; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.layout.FontState; import java.io.Serializable; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; // properties should be serialized by the holder public class Trait implements Serializable { - public static final int ID_LINK = 0; - public static final int INTERNAL_LINK = 1; //resolved - public static final int EXTERNAL_LINK = 2; - public static final int FONT_FAMILY = 3; - public static final int FONT_SIZE = 4; - public static final int FONT_WEIGHT = 5; - public static final int FONT_STYLE = 6; - public static final int COLOR = 7; - public static final int ID_AREA = 8; - public static final int BACKGROUND = 9; - public static final int UNDERLINE = 10; - public static final int OVERLINE = 11; - public static final int LINETHROUGH = 12; - public static final int OFFSET = 13; - public static final int SHADOW = 14; - - public static final int FONT_STATE = 100; - - public int propType; + public static final Integer ID_LINK = new Integer(0); + public static final Integer INTERNAL_LINK = new Integer(1); //resolved + public static final Integer EXTERNAL_LINK = new Integer(2); + public static final Integer FONT_FAMILY = new Integer(3); + public static final Integer FONT_SIZE = new Integer(4); + public static final Integer FONT_WEIGHT = new Integer(5); + public static final Integer FONT_STYLE = new Integer(6); + public static final Integer COLOR = new Integer(7); + public static final Integer ID_AREA = new Integer(8); + public static final Integer BACKGROUND = new Integer(9); + public static final Integer UNDERLINE = new Integer(10); + public static final Integer OVERLINE = new Integer(11); + public static final Integer LINETHROUGH = new Integer(12); + public static final Integer OFFSET = new Integer(13); + public static final Integer SHADOW = new Integer(14); + public static final Integer BORDER_START = new Integer(15); + public static final Integer BORDER_END = new Integer(16); + public static final Integer BORDER_BEFORE = new Integer(17); + public static final Integer BORDER_AFTER = new Integer(18); + public static final Integer PADDING_START = new Integer(19); + public static final Integer PADDING_END = new Integer(20); + public static final Integer PADDING_BEFORE = new Integer(21); + public static final Integer PADDING_AFTER = new Integer(22); + + public static final Integer FONT_STATE = new Integer(100); + + static HashMap s_hmTraitInfo; + + private static class TraitInfo { + String sName; + Class sClass; // Class of trait data + TraitInfo(String sName, Class sClass) { + this.sName = sName; + this.sClass = sClass; + } + } + + static { + // Create a hashmap mapping trait code to name for external representation + s_hmTraitInfo = new HashMap(); + s_hmTraitInfo.put(ID_LINK, + new TraitInfo("id-link", String.class)); + s_hmTraitInfo.put(INTERNAL_LINK, + new TraitInfo("internal-link", String.class)); + s_hmTraitInfo.put(EXTERNAL_LINK, + new TraitInfo("external-link", String.class)); + s_hmTraitInfo.put(FONT_FAMILY, + new TraitInfo("font-family", String.class)); + s_hmTraitInfo.put(FONT_SIZE, + new TraitInfo("font-size", Integer.class)); + s_hmTraitInfo.put(FONT_WEIGHT, + new TraitInfo("font-weight", Integer.class)); + s_hmTraitInfo.put(FONT_STYLE, + new TraitInfo("font-style", String.class)); + s_hmTraitInfo.put(COLOR, + new TraitInfo("color", String.class)); + s_hmTraitInfo.put(ID_AREA, + new TraitInfo("id-area", String.class)); + s_hmTraitInfo.put(BACKGROUND, + new TraitInfo("background", String.class)); + s_hmTraitInfo.put(UNDERLINE, + new TraitInfo("underline", Integer.class)); + s_hmTraitInfo.put(OVERLINE, + new TraitInfo("overline", Integer.class)); + s_hmTraitInfo.put(LINETHROUGH, + new TraitInfo("linethrough", Integer.class)); + s_hmTraitInfo.put(OFFSET, + new TraitInfo("offset", Integer.class)); + s_hmTraitInfo.put(SHADOW, + new TraitInfo("shadow", Integer.class)); + s_hmTraitInfo.put(BORDER_START, + new TraitInfo("border-start", BorderProps.class)); + s_hmTraitInfo.put(BORDER_END, + new TraitInfo("border-end", BorderProps.class)); + s_hmTraitInfo.put(BORDER_BEFORE, + new TraitInfo("border-before", BorderProps.class)); + s_hmTraitInfo.put(BORDER_AFTER, + new TraitInfo("border-after", BorderProps.class)); + s_hmTraitInfo.put(PADDING_START, + new TraitInfo("padding-start", Integer.class)); + s_hmTraitInfo.put(PADDING_END, + new TraitInfo("padding-end", Integer.class)); + s_hmTraitInfo.put(PADDING_BEFORE, + new TraitInfo("padding-before", Integer.class)); + s_hmTraitInfo.put(PADDING_AFTER, + new TraitInfo("padding-after", Integer.class)); + + s_hmTraitInfo.put(FONT_STATE, + new TraitInfo("font-state", FontState.class)); + } + + public static String getTraitName(Object traitCode) { + Object obj = s_hmTraitInfo.get(traitCode); + if (obj != null) { + return ((TraitInfo)obj).sName; + } + else { + return "unknown-trait-" + traitCode.toString(); + } + } + + public static Object getTraitCode(String sTraitName) { + Iterator iter = s_hmTraitInfo.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry)iter.next(); + TraitInfo ti = (TraitInfo)entry.getValue(); + if (ti != null && ti.sName.equals(sTraitName)) { + return entry.getKey(); + } + } + return null; + } + + private static Class getTraitClass(Object oTraitCode) { + TraitInfo ti = (TraitInfo)s_hmTraitInfo.get(oTraitCode); + return (ti != null? ti.sClass : null); + } + + public Object propType; public Object data; + public Trait() { + this.propType = null; + this.data = null; + } + + public Trait(Object propType, Object data) { + this.propType = propType; + this.data = data; + } + + public String toString() { + return data.toString(); + } + + public static Object makeTraitValue(Object oCode, String sTraitValue) { + // Get the code from the name + // See what type of object it is + // Convert string value to an object of that type + Class tclass = getTraitClass(oCode); + if (tclass == null) return null; + if (tclass.equals(String.class)) { + return sTraitValue; + } + if (tclass.equals(Integer.class)) { + return new Integer(sTraitValue); + } + // See if the class has a constructor from string or can read from a string + try { + Object o = tclass.newInstance(); + //return o.fromString(sTraitValue); + } catch (IllegalAccessException e1) { + System.err.println("Can't create instance of " + tclass.getName()); + return null; + } catch (InstantiationException e2) { + System.err.println("Can't create instance of " + tclass.getName()); + return null; + } + + + return null; + } + public static class Background { ColorType color; String url; @@ -41,5 +188,6 @@ public class Trait implements Serializable { int horiz; int vertical; } + } diff --git a/src/org/apache/fop/area/inline/InlineArea.java b/src/org/apache/fop/area/inline/InlineArea.java index b7ad5ad29..645e67a0b 100644 --- a/src/org/apache/fop/area/inline/InlineArea.java +++ b/src/org/apache/fop/area/inline/InlineArea.java @@ -11,6 +11,7 @@ import org.apache.fop.area.Area; import org.apache.fop.area.MinOptMax; import org.apache.fop.area.Trait; import org.apache.fop.render.Renderer; +import org.apache.fop.traits.BorderProps; import org.apache.fop.layoutmgr.LayoutInfo; @@ -25,8 +26,10 @@ import java.util.ArrayList; * requested renderer. */ public class InlineArea extends Area { - int width; + // int width; int height; + protected int contentIPD = 0; + // position within the line area, either top or baseline int verticalPosition; // width, height, vertical alignment @@ -42,11 +45,19 @@ public class InlineArea extends Area { } public void setWidth(int w) { - width = w; + contentIPD = w; } public int getWidth() { - return width; + return contentIPD; + } + + public void setIPD(int ipd) { + this.contentIPD = ipd; + } + + public void increaseIPD(int ipd) { + this.contentIPD += ipd; } public void setHeight(int h) { @@ -57,10 +68,27 @@ public class InlineArea extends Area { return height; } + public int getAllocIPD() { + // If start or end border or padding is non-zero, add to content IPD + int iBP = contentIPD; + Object t; + if ((t = getTrait(Trait.PADDING_START)) != null) { + iBP += ((Integer)t).intValue(); + } + if ((t = getTrait(Trait.PADDING_END)) != null) { + iBP += ((Integer)t).intValue(); + } + if ((t = getTrait(Trait.BORDER_START)) != null) { + iBP += ((BorderProps)t).width;; + } + if ((t = getTrait(Trait.BORDER_END)) != null) { + iBP += ((BorderProps)t).width;; + } + return iBP; + } + public MinOptMax getAllocationIPD() { - // Should also account for any borders and padding in the - // inline progression dimension - return new MinOptMax(width); + return new MinOptMax(getAllocIPD()); } public void setOffset(int v) { @@ -71,14 +99,4 @@ public class InlineArea extends Area { return verticalPosition; } - public void addTrait(Trait prop) { - if (props == null) { - props = new ArrayList(); - } - props.add(prop); - } - - public List getTraitList() { - return props; - } } diff --git a/src/org/apache/fop/area/inline/InlineParent.java b/src/org/apache/fop/area/inline/InlineParent.java index 4ec3d0447..8ea743d9c 100644 --- a/src/org/apache/fop/area/inline/InlineParent.java +++ b/src/org/apache/fop/area/inline/InlineParent.java @@ -17,7 +17,6 @@ import java.util.ArrayList; // this is an inline area that can have other inlines as children public class InlineParent extends InlineArea { ArrayList inlines = new ArrayList(); - int width; public InlineParent() { } @@ -26,16 +25,19 @@ public class InlineParent extends InlineArea { renderer.renderInlineParent(this); } - public void addChild(InlineArea child) { - inlines.add(child); + + /** + * Override generic Area method. + */ + public void addChild(Area childArea) { + if (childArea instanceof InlineArea) { + inlines.add(childArea); + increaseIPD( ((InlineArea)childArea).getAllocIPD()); + } } public List getChildAreas() { return inlines; } - public int getWidth() { - return width; - } - } diff --git a/src/org/apache/fop/area/inline/Word.java b/src/org/apache/fop/area/inline/Word.java index 51b009b28..047433c89 100644 --- a/src/org/apache/fop/area/inline/Word.java +++ b/src/org/apache/fop/area/inline/Word.java @@ -13,6 +13,7 @@ public class Word extends InlineArea { // character info: font, char spacing, colour, baseline String word; + int iWSadjust = 0; public void render(Renderer renderer) { renderer.renderWord(this); @@ -25,4 +26,12 @@ public class Word extends InlineArea { public String getWord() { return word; } + + public int getWSadjust() { + return iWSadjust; + } + + public void setWSadjust(int iWSadjust) { + this.iWSadjust = iWSadjust; + } } diff --git a/src/org/apache/fop/datatypes/ColorType.java b/src/org/apache/fop/datatypes/ColorType.java index c44ba60df..ae0284bf0 100644 --- a/src/org/apache/fop/datatypes/ColorType.java +++ b/src/org/apache/fop/datatypes/ColorType.java @@ -165,6 +165,21 @@ public class ColorType { return this.alpha; } + public String toString() { + StringBuffer sbuf = new StringBuffer(8); + sbuf.append('#'); + String s = Integer.toHexString((int)(red * 255.0)); + if (s.length() == 1) sbuf.append('0'); + sbuf.append(s); + s = Integer.toHexString((int)(green * 255.0)); + if (s.length() == 1) sbuf.append('0'); + sbuf.append(s); + s = Integer.toHexString((int)(blue * 255.0)); + if (s.length() == 1) sbuf.append('0'); + sbuf.append(s); + return sbuf.toString(); + } + final static String[] names = { "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", diff --git a/src/org/apache/fop/layout/BorderAndPadding.java b/src/org/apache/fop/layout/BorderAndPadding.java index 42ee3df52..d42b82cf6 100644 --- a/src/org/apache/fop/layout/BorderAndPadding.java +++ b/src/org/apache/fop/layout/BorderAndPadding.java @@ -9,6 +9,7 @@ package org.apache.fop.layout; import org.apache.fop.datatypes.ColorType; import org.apache.fop.datatypes.CondLength; +import org.apache.fop.fo.properties.Constants; public class BorderAndPadding implements Cloneable { @@ -132,11 +133,13 @@ public class BorderAndPadding implements Cloneable { public int getBorderWidth(int side, boolean bDiscard) { - if ((borderInfo[side] == null) - || (bDiscard && borderInfo[side].mWidth.bDiscard)) { + if ((borderInfo[side] == null) || + (borderInfo[side].mStyle == Constants.NONE) || + (bDiscard && borderInfo[side].mWidth.bDiscard)) { return 0; - } else + } else { return borderInfo[side].mWidth.iLength; + } } public ColorType getBorderColor(int side) { diff --git a/src/org/apache/fop/layout/FontState.java b/src/org/apache/fop/layout/FontState.java index 16264d6a1..b63143d13 100644 --- a/src/org/apache/fop/layout/FontState.java +++ b/src/org/apache/fop/layout/FontState.java @@ -121,6 +121,21 @@ public class FontState { return c; } + public String toString() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append('('); + sbuf.append(_fontFamily); + sbuf.append(','); + sbuf.append(_fontName); + sbuf.append(','); + sbuf.append(_fontSize); + sbuf.append(','); + sbuf.append(_fontStyle); + sbuf.append(','); + sbuf.append(_fontWeight); + sbuf.append(')'); + return sbuf.toString(); + } } diff --git a/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java b/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java index 57725fb4a..88a84b8ab 100644 --- a/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/AbstractBPLayoutManager.java @@ -67,14 +67,28 @@ public abstract class AbstractBPLayoutManager extends AbstractLayoutManager return null; } + protected boolean hasMoreLM(BPLayoutManager prevLM) { + // prevLM should = m_curChildLM + if (prevLM != m_curChildLM) { + System.err.println("AbstractBPLayoutManager.peekNextLM: " + + "passed LM is not current child LM!"); + return false; + } + return !m_childLMiter.hasNext(); + } + /** * Reset the layoutmanager "iterator" so that it will start - * with the passed bplm on the next call to getChildLM. - * @param bplm Reset iterator to this LayoutManager. + * with the passed Position's generating LM + * on the next call to getChildLM. + * @param pos a Position returned by a child layout manager + * representing a potential break decision. + * If pos is null, then back up to the first child LM. */ - protected void reset(LayoutManager lm, BreakPoss.Position pos) { + protected void reset(Position pos) { //if (lm == null) return; + BPLayoutManager lm = (pos != null)? pos.getLM(): null; if (m_curChildLM != lm) { // ASSERT m_curChildLM == (BPLayoutManager)m_childLMiter.previous() if (m_curChildLM != (BPLayoutManager)m_childLMiter.previous()) { @@ -92,10 +106,10 @@ public abstract class AbstractBPLayoutManager extends AbstractLayoutManager } } - public void resetPosition(BreakPoss.Position resetPos) { - if (resetPos == null) { - reset(null, null); - } + public void resetPosition(Position resetPos) { +// if (resetPos == null) { +// reset(null); +// } } @@ -146,7 +160,7 @@ public abstract class AbstractBPLayoutManager extends AbstractLayoutManager public BreakPoss getNextBreakPoss(LayoutContext context, - BreakPoss.Position prevBreakPoss) { + Position prevBreakPoss) { return null; } @@ -167,12 +181,12 @@ public abstract class AbstractBPLayoutManager extends AbstractLayoutManager } - public void addAreas(PositionIterator parentIter, double dSpaceAdjust) { + public void addAreas(PositionIterator posIter, LayoutContext context) { } public void getWordChars(StringBuffer sbChars, - BreakPoss.Position bp1, BreakPoss.Position bp2) { + Position bp1, Position bp2) { } /* --------------------------------------------------------- diff --git a/src/org/apache/fop/layoutmgr/BPLayoutManager.java b/src/org/apache/fop/layoutmgr/BPLayoutManager.java index 26245b464..51feb1f1f 100644 --- a/src/org/apache/fop/layoutmgr/BPLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/BPLayoutManager.java @@ -35,7 +35,7 @@ public interface BPLayoutManager extends LayoutManager { * BreakPoss. */ public BreakPoss getNextBreakPoss(LayoutContext context, - BreakPoss.Position prevBreakPosition); + Position prevBreakPosition); public BreakPoss getNextBreakPoss(LayoutContext context); @@ -55,16 +55,16 @@ public interface BPLayoutManager extends LayoutManager { /** * Tell the layout manager to add all the child areas implied - * by BreakPoss.Position objectw which will be returned by the + * by Position objects which will be returned by the * Iterator. */ - public void addAreas(PositionIterator posIter, double dSpaceAdjust) ; + public void addAreas(PositionIterator posIter, LayoutContext context) ; public void init() ; - public void resetPosition(BreakPoss.Position position); + public void resetPosition(Position position); public void getWordChars(StringBuffer sbChars, - BreakPoss.Position bp1, BreakPoss.Position bp2); + Position bp1, Position bp2); } diff --git a/src/org/apache/fop/layoutmgr/BreakPoss.java b/src/org/apache/fop/layoutmgr/BreakPoss.java index 484988160..668348871 100644 --- a/src/org/apache/fop/layoutmgr/BreakPoss.java +++ b/src/org/apache/fop/layoutmgr/BreakPoss.java @@ -14,20 +14,13 @@ import org.apache.fop.traits.LayoutProps; * Used to pass information between different levels of layout manager concerning * the break positions. In an inline context, before and after are interpreted as * start and end. - * The m_position field is opaque but should represent meaningful information to - * the layout manager stored in m_lm. + * The m_position field is opaque represents where the break occurs. It is a + * nested structure with one level for each layout manager involved in generating + * the BreakPoss.. * @author Karen Lease */ public class BreakPoss { - /** - * Marker interface. Generally a LayoutManager class will include - * a class implementing this interface which it uses to store its - * own Break Position information. - */ - public interface Position { - } - /** Values for m_flags returned from lower level LM. */ public static final int CAN_BREAK_AFTER= 0x01; // May break after @@ -42,10 +35,10 @@ public class BreakPoss { public static final int ALL_ARE_SUPPRESS_AT_LB = 0x80; /** This break possibility is a hyphenation */ public static final int HYPHENATED = 0x100; - - - /** The top-level layout manager which generated this BreakPoss. */ - private BPLayoutManager m_lm; + /** If this break possibility ends the line, all remaining characters + * in the lowest level text LM will be suppressed. + */ + public static final int REST_ARE_SUPPRESS_AT_LB = 0x200; /** The opaque position object used by m_lm to record its * break position. @@ -69,12 +62,6 @@ public class BreakPoss { private long m_flags = 0; private LayoutProps m_layoutProps = new LayoutProps(); - /** - private boolean m_bIsFirst=false; - private boolean m_bIsLast=false; - private boolean m_bCanBreakAfter; - private boolean m_bCanBreakBefore; - **/ /** Store space-after (or end) and space-before (or start) to be * added if this break position is used. @@ -82,12 +69,11 @@ public class BreakPoss { private SpaceSpecifier m_spaceSpecTrailing; private SpaceSpecifier m_spaceSpecLeading; - public BreakPoss(BPLayoutManager lm, Position position) { - this(lm,position,0); + public BreakPoss(Position position) { + this(position,0); } - public BreakPoss(BPLayoutManager lm, Position position, long flags) { - m_lm = lm; + public BreakPoss(Position position, long flags) { m_position = position; m_flags = flags; } @@ -96,12 +82,12 @@ public class BreakPoss { * The top-level layout manager responsible for this break */ public BPLayoutManager getLayoutManager() { - return m_lm; + return m_position.getLM(); } - public void setLayoutManager(BPLayoutManager lm) { - m_lm = lm; - } +// public void setLayoutManager(BPLayoutManager lm) { +// m_lm = lm; +// } /** * An object representing the break position in this layout manager. @@ -163,6 +149,10 @@ public class BreakPoss { return ((m_flags & CAN_BREAK_BEFORE) != 0); } + public boolean couldEndLine() { + return ((m_flags & REST_ARE_SUPPRESS_AT_LB) != 0); + } + public boolean isForcedBreak() { return ((m_flags & FORCE) != 0); } diff --git a/src/org/apache/fop/layoutmgr/BreakPossPosIter.java b/src/org/apache/fop/layoutmgr/BreakPossPosIter.java index 59a80cec1..68f867691 100644 --- a/src/org/apache/fop/layoutmgr/BreakPossPosIter.java +++ b/src/org/apache/fop/layoutmgr/BreakPossPosIter.java @@ -43,7 +43,7 @@ public class BreakPossPosIter extends PositionIterator { return ((BreakPoss)nextObj).getLayoutManager(); } - protected BreakPoss.Position getPos(Object nextObj) { + protected Position getPos(Object nextObj) { return ((BreakPoss)nextObj).getPosition(); } diff --git a/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java b/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java index 0f21d0e7b..7dc0ed31d 100644 --- a/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/InlineStackingBPLayoutManager.java @@ -27,20 +27,6 @@ import java.util.HashMap; */ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { - /** - * Private class to store information about a lower-level BreakPosition. - * Note: fields are directly readable in this class - */ - private static class WrappedPosition implements BreakPoss.Position { - BPLayoutManager m_childLM; - BreakPoss.Position m_childPosition; - - WrappedPosition(BPLayoutManager childLM, - BreakPoss.Position childPosition) { - m_childLM = childLM; - m_childPosition = childPosition; - } - } private static class StackingIter extends PositionIterator { @@ -49,11 +35,11 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { } protected BPLayoutManager getLM(Object nextObj) { - return ((WrappedPosition)nextObj).m_childLM; + return ((Position)nextObj).getPosition().getLM(); } - protected BreakPoss.Position getPos(Object nextObj) { - return ((WrappedPosition)nextObj).m_childPosition; + protected Position getPos(Object nextObj) { + return ((Position)nextObj).getPosition(); } } @@ -73,11 +59,14 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { private InlineProps m_inlineProps = null; private BorderAndPadding m_borderProps = null; - private InlineParent m_inlineArea; + private Area m_currentArea; // LineArea or InlineParent private BreakPoss m_prevBP; private LayoutContext m_childLC ; + private BPLayoutManager m_lastChildLM=null; // Set when return last breakposs + private boolean m_bAreaCreated = false; + /** Used to store previous content IPD for each child LM. */ private HashMap m_hmPrevIPD = new HashMap(); @@ -111,6 +100,7 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { return new MinOptMax(iBP); } + protected boolean hasLeadingFence(boolean bNotFirst) { int iBP = m_borderProps.getPadding(BorderAndPadding.START, bNotFirst); iBP += m_borderProps.getBorderWidth(BorderAndPadding.START, bNotFirst); @@ -124,24 +114,35 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { } - /** Reset position for returning next BreakPossibility. */ + /** + * Reset position for returning next BreakPossibility. + * @param prevPos a Position returned by this layout manager + * representing a potential break decision. + */ - public void resetPosition(BreakPoss.Position prevPos) { - WrappedPosition wrappedPos = (WrappedPosition)prevPos; - if (wrappedPos != null) { - // Back up the layout manager iterator - reset(wrappedPos.m_childLM, wrappedPos.m_childPosition); + public void resetPosition(Position prevPos) { + if (prevPos != null) { + // ASSERT (prevPos.getLM() == this) + if (prevPos.getLM() != this) { + System.err.println("InlineStackingBPLayoutManager.resetPosition: " + + "LM mismatch!!!"); + } + // Back up the child LM Position + Position childPos = prevPos.getPosition(); + reset(childPos); if (m_prevBP != null && - m_prevBP.getLayoutManager() !=wrappedPos.m_childLM) { + m_prevBP.getLayoutManager() !=childPos.getLM()) { m_childLC = null; } - m_prevBP = new BreakPoss(wrappedPos.m_childLM, - wrappedPos.m_childPosition); + m_prevBP = new BreakPoss(childPos); } else { // Backup to start of first child layout manager m_prevBP = null; - super.resetPosition(prevPos); + // super.resetPosition(prevPos); + reset(prevPos); + // If any areas created, we are restarting! + m_bAreaCreated = false; } // Do we need to reset some context like pending or prevContent? // What about m_prevBP? @@ -177,18 +178,18 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { } - public BreakPoss getNextBreakPoss(LayoutContext lc, - BreakPoss.Position pbp) { + public BreakPoss getNextBreakPoss(LayoutContext lc, Position pbp) { // Get a break from currently active child LM BreakPoss bp =null; BPLayoutManager curLM ; - SpaceSpecifier leadingSpace = lc.getPendingSpace(); + SpaceSpecifier leadingSpace = lc.getLeadingSpace(); if (lc.startsNewArea()) { // First call to this LM in new parent "area", but this may // not be the first area created by this inline m_childLC = new LayoutContext(lc); - lc.getPendingSpace().addSpace(m_inlineProps.spaceStart); + lc.getLeadingSpace().addSpace(m_inlineProps.spaceStart); + // Check for "fence" if (hasLeadingFence(!lc.isFirstArea())) { // Reset leading space sequence for child areas @@ -228,7 +229,18 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { // Alternative is to return a BP with the isLast flag set } else { - return makeBreakPoss(bp, lc, (getChildLM() == null)); + boolean bIsLast = false; + if (getChildLM() == null) { + bIsLast = true; + setFinished(true); + } + else if (bp.couldEndLine()) { + /* Child LM ends with suppressible spaces. See if it could + * end this LM's area too. Child LM finish flag is NOT set! + */ + bIsLast = !hasMoreLM(bp.getLayoutManager()); + } + return makeBreakPoss(bp, lc, bIsLast); } } @@ -242,15 +254,15 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { if (bStartParent) { // Start of a new line area or inline parent area childLC.setFlags(LayoutContext.FIRST_AREA, bFirstChildBP ); - childLC.setPendingSpace(leadingSpace); + childLC.setLeadingSpace(leadingSpace); } else if (bFirstChildBP) { // Space-after sequence from previous "area" childLC.setFlags(LayoutContext.FIRST_AREA, true); - childLC.setPendingSpace(prevBP.getTrailingSpace()); + childLC.setLeadingSpace(prevBP.getTrailingSpace()); } else { - childLC.setPendingSpace(null); + childLC.setLeadingSpace(null); } } @@ -258,13 +270,17 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { private BreakPoss makeBreakPoss(BreakPoss bp, LayoutContext lc, boolean bIsLast) { - WrappedPosition inlbp = - new WrappedPosition(bp.getLayoutManager(), bp.getPosition()); - BreakPoss myBP = new BreakPoss(this, inlbp, bp.getFlags()); + NonLeafPosition inlbp = + new NonLeafPosition(this, bp.getPosition()); + BreakPoss myBP = new BreakPoss(inlbp, bp.getFlags()); myBP.setFlag(BreakPoss.ISFIRST, lc.isFirstArea()); myBP.setFlag(BreakPoss.ISLAST, bIsLast); + if (bIsLast) { + m_lastChildLM = bp.getLayoutManager(); + } + // Update dimension information for our allocation area, // including child areas // generated by previous childLM which have completed layout @@ -276,7 +292,7 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { lc.startsNewArea(), lc.isFirstArea()); if (lc.startsNewArea()) { - myBP.setLeadingSpace(lc.getPendingSpace()); + myBP.setLeadingSpace(lc.getLeadingSpace()); } @@ -288,6 +304,12 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { bpDim.add(bp.resolveTrailingSpace(false)); trailingSpace = new SpaceSpecifier(false); } + else { + // Need this to avoid modifying pending space specifiers + // on previous BP from child as we use these on the next + // call in this LM + trailingSpace = (SpaceSpecifier)trailingSpace.clone(); + } trailingSpace.addSpace(m_inlineProps.spaceEnd); myBP.setTrailingSpace(trailingSpace); @@ -298,9 +320,9 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { m_extraBPD)); m_prevBP = bp; - if (bIsLast) { - setFinished(true); // Our last area, so indicate done - } +// if (bIsLast) { +// setFinished(true); // Our last area, so indicate done +// } return myBP; } @@ -339,15 +361,16 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { } public void getWordChars(StringBuffer sbChars, - BreakPoss.Position bp1, BreakPoss.Position bp2) { - WrappedPosition endPos = (WrappedPosition)bp2; + Position bp1, Position bp2) { + Position endPos = ((NonLeafPosition)bp2).getPosition(); + Position prevPos = null; if (bp1 != null) { - WrappedPosition prevPos = (WrappedPosition)bp1; - if (prevPos.m_childLM == endPos.m_childLM) { - bp1 = prevPos.m_childPosition; + prevPos = ((NonLeafPosition)bp1).getPosition(); + if (prevPos.getLM() != endPos.getLM()) { + prevPos = null; } } - endPos.m_childLM.getWordChars(sbChars, bp1, endPos.m_childPosition); + endPos.getLM().getWordChars(sbChars, prevPos, endPos); } /****** @@ -358,44 +381,126 @@ public class InlineStackingBPLayoutManager extends AbstractBPLayoutManager { /** * Generate and add areas to parent area. * Set size of each area. - * @param parentIter Iterator over BreakPoss.Position information returned + * @param parentIter Iterator over Position information returned * by this LayoutManager. * @param dSpaceAdjust Factor controlling how much extra space to add * in order to justify the line. */ - public void addAreas(PositionIterator parentIter, double dSpaceAdjust) { - // Make areas from start to end - // Update childLM based on bpEnd - // It might be a previous sibling of the current one! - - m_inlineArea = new InlineParent(); - - // Note: if first, bpStart is perhaps null???? - // If we are first in parent, set ISFIRST... + public void addAreas(PositionIterator parentIter, LayoutContext context) { + setCurrentArea(new InlineParent()); + + setChildContext(new LayoutContext(context)); // Store current value + + // If has fence, make a new leadingSS + /* How to know if first area created by this LM? Keep a count and + * reset it if getNextBreakPoss() is called again. + */ + if (hasLeadingFence(m_bAreaCreated)) { + getContext().setLeadingSpace(new SpaceSpecifier(false)); + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + } + else { + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, false); + } + context.getLeadingSpace().addSpace(m_inlineProps.spaceStart); + // posIter iterates over positions returned by this LM StackingIter childPosIter = new StackingIter(parentIter); + BPLayoutManager prevLM = null; BPLayoutManager childLM ; while ((childLM = childPosIter.getNextChildLM())!= null) { - childLM.addAreas(childPosIter, dSpaceAdjust); + //getContext().setTrailingSpace(new SpaceSpecifier(false)); + childLM.addAreas(childPosIter, getContext()); + getContext().setLeadingSpace(getContext().getTrailingSpace()); + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + prevLM = childLM; + } + + /* If has trailing fence, resolve trailing space specs from descendants. + * Otherwise, propagate any trailing space specs to parent LM via + * the context object. + * If the last child LM called return ISLAST in the context object + * and it is the last child LM for this LM, then this must be + * the last area for the current LM also. + */ + boolean bIsLast = (getContext().isLastArea() && prevLM == m_lastChildLM); + if (hasTrailingFence(bIsLast)) { + addSpace(getCurrentArea(), + getContext().getTrailingSpace().resolve(false), + getContext().getSpaceAdjust()); + context.setTrailingSpace(new SpaceSpecifier(false)); } + else { + // Propagate trailing space-spec sequence to parent LM in context + context.setTrailingSpace(getContext().getTrailingSpace()); + } + // Add own trailing space to parent context (or set on area?) + context.getTrailingSpace().addSpace(m_inlineProps.spaceEnd); - parentLM.addChild(m_inlineArea); + // Add border and padding to current area and set flags (FIRST, LAST ...) + TraitSetter.setBorderPaddingTraits(getCurrentArea(), m_borderProps, + m_bAreaCreated, !bIsLast); + parentLM.addChild(getCurrentArea()); + context.setFlags(LayoutContext.LAST_AREA, bIsLast); + m_bAreaCreated = true; } + protected Area getCurrentArea() { + return m_currentArea; + } + + protected void setCurrentArea(Area area) { + m_currentArea = area; + } -// protected Area createArea() { -// return new InlineParent(); -// } public boolean addChild(Area childArea) { // Make sure childArea is inline area if (childArea instanceof InlineArea) { - m_inlineArea.addChild((InlineArea)childArea); + Area parent = getCurrentArea(); + if (getContext().resolveLeadingSpace()) { + addSpace(parent, + getContext().getLeadingSpace().resolve(false), + getContext().getSpaceAdjust()); + } + parent.addChild(childArea); } return false; } + protected void setChildContext(LayoutContext lc) { + m_childLC = lc; + } + + // Current child layout context + protected LayoutContext getContext() { + return m_childLC ; + } + + protected void addSpace(Area parentArea, MinOptMax spaceRange, + double dSpaceAdjust) { + if (spaceRange != null) { + int iAdjust= spaceRange.opt; + if (dSpaceAdjust > 0.0) { + // Stretch by factor + iAdjust += (int)((double)(spaceRange.max - spaceRange.opt) * + dSpaceAdjust); + } + else if (dSpaceAdjust < 0.0) { + // Shrink by factor + iAdjust += (int)((double)(spaceRange.opt - spaceRange.min) * + dSpaceAdjust); + } + if (iAdjust != 0) { + System.err.println("Add leading space: " + iAdjust); + Space ls = new Space(); + ls.setWidth(iAdjust); + parentArea.addChild(ls); + } + } + } + } diff --git a/src/org/apache/fop/layoutmgr/LayoutContext.java b/src/org/apache/fop/layoutmgr/LayoutContext.java index a3dd778ce..9c8eb56ff 100644 --- a/src/org/apache/fop/layoutmgr/LayoutContext.java +++ b/src/org/apache/fop/layoutmgr/LayoutContext.java @@ -35,6 +35,9 @@ public class LayoutContext { public static final int SUPPRESS_LEADING_SPACE = 0x10; public static final int FIRST_AREA = 0x20; public static final int TRY_HYPHENATE = 0x40; + public static final int LAST_AREA = 0x80; + + public static final int RESOLVE_LEADING_SPACE = 0x100; public int flags; // Contains some set of flags defined above @@ -55,17 +58,25 @@ public class LayoutContext { int refIPD; /** Current pending space-after or space-end from preceding area */ - SpaceSpecifier m_pendingSpace; + SpaceSpecifier m_trailingSpace; + + /** Current pending space-before or space-start from ancestor areas */ + SpaceSpecifier m_leadingSpace; /** Current hyphenation context. May be null. */ private HyphContext m_hyphContext=null; + /** Stretch or shrink value when making areas. */ + private double m_dSpaceAdjust = 0.0; + public LayoutContext(LayoutContext parentLC) { this.flags = parentLC.flags; this.refIPD = parentLC.refIPD; this.m_stackLimit = null; // Don't reference parent MinOptMax! - this.m_pendingSpace = parentLC.m_pendingSpace; //??? + this.m_leadingSpace = parentLC.m_leadingSpace; //??? + this.m_trailingSpace = parentLC.m_trailingSpace; //??? this.m_hyphContext = parentLC.m_hyphContext; + this.m_dSpaceAdjust = parentLC.m_dSpaceAdjust; // Copy other fields as necessary. Use clone??? } @@ -73,7 +84,8 @@ public class LayoutContext { this.flags = flags; this.refIPD = 0; m_stackLimit = new MinOptMax(0); - m_pendingSpace = null; + m_leadingSpace = null; + m_trailingSpace = null; } public void setFlags(int flags) { @@ -98,23 +110,39 @@ public class LayoutContext { } public boolean startsNewArea() { - return ((this.flags & NEW_AREA) != 0 && m_pendingSpace != null); + return ((this.flags & NEW_AREA) != 0 && m_leadingSpace != null); } public boolean isFirstArea() { return ((this.flags & FIRST_AREA) != 0); } + public boolean isLastArea() { + return ((this.flags & LAST_AREA) != 0); + } + public boolean suppressLeadingSpace() { return ((this.flags & SUPPRESS_LEADING_SPACE) != 0); } - public void setPendingSpace(SpaceSpecifier space) { - m_pendingSpace = space; + public void setLeadingSpace(SpaceSpecifier space) { + m_leadingSpace = space; + } + + public SpaceSpecifier getLeadingSpace() { + return m_leadingSpace; } - public SpaceSpecifier getPendingSpace() { - return m_pendingSpace; + public boolean resolveLeadingSpace() { + return ((this.flags & RESOLVE_LEADING_SPACE) != 0); + } + + public void setTrailingSpace(SpaceSpecifier space) { + m_trailingSpace = space; + } + + public SpaceSpecifier getTrailingSpace() { + return m_trailingSpace; } public void setStackLimit(MinOptMax stackLimit) { @@ -136,4 +164,12 @@ public class LayoutContext { public boolean tryHyphenate() { return ((this.flags & TRY_HYPHENATE) != 0); } + + public void setSpaceAdjust(double dSpaceAdjust) { + m_dSpaceAdjust = dSpaceAdjust ; + } + + public double getSpaceAdjust() { + return m_dSpaceAdjust; + } } diff --git a/src/org/apache/fop/layoutmgr/LeafPosition.java b/src/org/apache/fop/layoutmgr/LeafPosition.java new file mode 100644 index 000000000..b11f8dfdf --- /dev/null +++ b/src/org/apache/fop/layoutmgr/LeafPosition.java @@ -0,0 +1,23 @@ +/* + * $Id$ + * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr; + +public class LeafPosition extends Position { + + private int m_iLeafPos; + + public LeafPosition(BPLayoutManager lm, int iLeafPos) { + super(lm); + m_iLeafPos = iLeafPos; + } + + public int getLeafPos() { + return m_iLeafPos; + } +} + diff --git a/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java b/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java index ff3cffd64..79a9575c3 100644 --- a/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/LineBPLayoutManager.java @@ -45,19 +45,19 @@ public class LineBPLayoutManager extends * Each value holds the start and end indexes into a List of * inline break positions. */ - private static class LineBreakPosition implements BreakPoss.Position { - int m_iPos; + // private static class LineBreakPosition implements Position { + private static class LineBreakPosition extends LeafPosition { + // int m_iPos; double m_dAdjust; // Percentage to adjust (stretch or shrink) - LineBreakPosition(int iBreakIndex, double dAdjust) { - m_iPos = iBreakIndex; + LineBreakPosition(BPLayoutManager lm, int iBreakIndex, double dAdjust) { + super(lm, iBreakIndex); + // m_iPos = iBreakIndex; m_dAdjust = dAdjust; } } - private LineArea m_lineArea; // LineArea currently being filled - /** Break positions returned by inline content. */ private Vector m_vecInlineBreaks = new Vector(100); @@ -96,7 +96,7 @@ public class LineBPLayoutManager extends * finish any line being filled and return to the parent LM. */ public BreakPoss getNextBreakPoss(LayoutContext context, - BreakPoss.Position prevLineBP) { + Position prevLineBP) { // Get a break from currently active child LM // Set up constraints for inline level managers @@ -105,7 +105,8 @@ public class LineBPLayoutManager extends * (page) should check reference area and possibly * create a new one. */ - return new BreakPoss(this, null, BreakPoss.NEED_IPD); + return new BreakPoss(new LineBreakPosition(this, -1, 0.0), + BreakPoss.NEED_IPD); } BPLayoutManager curLM ; // currently active LM @@ -137,7 +138,8 @@ public class LineBPLayoutManager extends prevBP = (m_vecInlineBreaks.isEmpty())? null: (BreakPoss)m_vecInlineBreaks.lastElement(); initChildLC(inlineLC, prevBP, - (m_vecInlineBreaks.size()==iPrevLineEnd), bFirstBPforLM, + (m_vecInlineBreaks.size()==iPrevLineEnd), + bFirstBPforLM, new SpaceSpecifier(true)); @@ -146,7 +148,8 @@ public class LineBPLayoutManager extends * then set the SUPPRESS_LEADING_SPACE flag. */ inlineLC.setFlags(LayoutContext.SUPPRESS_LEADING_SPACE, - (prevBP == null && !m_vecInlineBreaks.isEmpty() && + (m_vecInlineBreaks.size()==iPrevLineEnd && + !m_vecInlineBreaks.isEmpty() && ((BreakPoss)m_vecInlineBreaks.lastElement()). isForcedBreak()==false)); @@ -281,7 +284,7 @@ public class LineBPLayoutManager extends while (m_vecInlineBreaks.lastElement()!=m_prevBP) { m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1); } - reset(m_prevBP.getLayoutManager(), m_prevBP.getPosition()); + reset(m_prevBP.getPosition()); } protected boolean couldEndLine(BreakPoss bp) { @@ -413,9 +416,8 @@ public class LineBPLayoutManager extends } System.err.println("Adjustment factor=" + dAdjust); BreakPoss curLineBP = - new BreakPoss(this, - new LineBreakPosition(m_vecInlineBreaks.size()-1, - dAdjust)); + new BreakPoss(new LineBreakPosition(this, m_vecInlineBreaks.size()-1, + dAdjust)); /* FIX ME!! * Need to calculate line height based on all inline BP info @@ -433,58 +435,33 @@ public class LineBPLayoutManager extends public void addAreas(PositionIterator parentIter, double dSpaceAdjust) { BPLayoutManager childLM ; int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); while (parentIter.hasNext()) { LineBreakPosition lbp = (LineBreakPosition)parentIter.next(); - m_lineArea = new LineArea(); + LineArea lineArea = new LineArea(); + setCurrentArea(lineArea); // Add the inline areas to lineArea - BreakPossPosIter inlinePosIter = + PositionIterator inlinePosIter = new BreakPossPosIter(m_vecInlineBreaks, - iStartPos, lbp.m_iPos+1); - iStartPos = lbp.m_iPos+1; + iStartPos, lbp.getLeafPos()+1); + iStartPos = lbp.getLeafPos()+1; + lc.setSpaceAdjust(lbp.m_dAdjust); + lc.setLeadingSpace(new SpaceSpecifier(true)); + lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + setChildContext(lc); while ((childLM = inlinePosIter.getNextChildLM())!= null) { - BreakPoss bp = inlinePosIter.getBP(); - int iSpaceSize = getLeadingSpace(bp, lbp.m_dAdjust); - if (iSpaceSize != 0) { - System.err.println("Add leading space: " + iSpaceSize); - Space ls = new Space(); - ls.setWidth(iSpaceSize); - addChild(ls); - } - childLM.addAreas(inlinePosIter, lbp.m_dAdjust); + childLM.addAreas(inlinePosIter, lc); + lc.setLeadingSpace(lc.getTrailingSpace()); + lc.setTrailingSpace(new SpaceSpecifier(false)); } - m_lineArea.verticalAlign(lineHeight, lead, follow); - parentLM.addChild(m_lineArea); + addSpace(lineArea, lc.getTrailingSpace().resolve(true), + lc.getSpaceAdjust()); + lineArea.verticalAlign(lineHeight, lead, follow); + parentLM.addChild(lineArea); } - m_lineArea = null; + setCurrentArea(null); // ?? necessary } - protected int getLeadingSpace(BreakPoss bp, double dSpaceAdjust) { - MinOptMax leadSpace = bp.resolveLeadingSpace(); - if (leadSpace != null) { - int iAdjust=0; - if (dSpaceAdjust > 0.0) { - // Stretch by factor - iAdjust = (int)((double)(leadSpace.max - leadSpace.opt) * - dSpaceAdjust); - } - else if (dSpaceAdjust < 0.0) { - // Shrink by factor - iAdjust = (int)((double)(leadSpace.opt - leadSpace.min) * - dSpaceAdjust); - } - return leadSpace.opt + iAdjust; - } - else return 0; - } - - - public boolean addChild(Area childArea) { - // Make sure childArea is inline area - if (childArea instanceof InlineArea) { - m_lineArea.addInlineArea((InlineArea)childArea); - } - return false; - } // NOTE: PATCHED FOR NOW TO ADD BreakPoss stuff to Kerion's changes public boolean generateAreas() { diff --git a/src/org/apache/fop/layoutmgr/NonLeafPosition.java b/src/org/apache/fop/layoutmgr/NonLeafPosition.java new file mode 100644 index 000000000..675515a2a --- /dev/null +++ b/src/org/apache/fop/layoutmgr/NonLeafPosition.java @@ -0,0 +1,23 @@ +/* + * $Id$ + * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr; + +public class NonLeafPosition extends Position { + + private Position m_subPos ; + + public NonLeafPosition(BPLayoutManager lm, Position subPos) { + super(lm); + m_subPos = subPos; + } + + public Position getPosition() { + return m_subPos; + } +} + diff --git a/src/org/apache/fop/layoutmgr/Position.java b/src/org/apache/fop/layoutmgr/Position.java new file mode 100644 index 000000000..1f00070f5 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/Position.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr; + +public class Position { + private BPLayoutManager m_lm; + + public Position(BPLayoutManager lm) { + m_lm = lm; + } + + public BPLayoutManager getLM() { + return m_lm; + } + + /** + * Overridden by NonLeafPosition to return the Position of its + * child LM. + */ + public Position getPosition() { + return null; + } +} + diff --git a/src/org/apache/fop/layoutmgr/PositionIterator.java b/src/org/apache/fop/layoutmgr/PositionIterator.java index cd98c4136..39af1a834 100644 --- a/src/org/apache/fop/layoutmgr/PositionIterator.java +++ b/src/org/apache/fop/layoutmgr/PositionIterator.java @@ -35,7 +35,7 @@ abstract class PositionIterator implements Iterator abstract protected BPLayoutManager getLM(Object nextObj); - abstract protected BreakPoss.Position getPos(Object nextObj); + abstract protected Position getPos(Object nextObj); private void lookAhead() { if (m_parentIter.hasNext()) { diff --git a/src/org/apache/fop/layoutmgr/SpaceSpecifier.java b/src/org/apache/fop/layoutmgr/SpaceSpecifier.java index ad7193c4e..287b14d08 100644 --- a/src/org/apache/fop/layoutmgr/SpaceSpecifier.java +++ b/src/org/apache/fop/layoutmgr/SpaceSpecifier.java @@ -42,13 +42,19 @@ public class SpaceSpecifier implements Cloneable { } /** - * Clear all space specifiers and fences. + * Clear all space specifiers */ public void clear() { m_bHasForcing=false; m_vecSpaceVals.clear(); } + + /** Return true if any space-specifiers have been added. */ + public boolean hasSpaces() { + return (m_vecSpaceVals.size() > 0); + } + /** * Add a new space to the sequence. If this sequence starts a reference * area, and the added space is conditional, and there are no @@ -61,31 +67,25 @@ public class SpaceSpecifier implements Cloneable { if (moreSpace.bForcing) { if (m_bHasForcing == false) { // Remove all other values (must all be non-forcing) - // Back to the preceding fence m_vecSpaceVals.clear(); m_bHasForcing = true; } m_vecSpaceVals.add(moreSpace); } else if (m_bHasForcing==false) { - m_vecSpaceVals.add(moreSpace); + // Don't bother adding all 0 space-specifier if not forcing + if (moreSpace.space.min != 0 || moreSpace.space.opt != 0 || + moreSpace.space.max != 0) { + m_vecSpaceVals.add(moreSpace); + } } } } - /** - * Add a "fence" following or preceding any space-specifiers. - * Note that we always add specifiers to the sequence in the - * progression direction, either inline or block. - */ - public void addFence() { - // Fence as first value clears m_bStartsRefArea - // Fence clears m_bHasForcing - } /** * Resolve the current sequence of space-specifiers, accounting for - * forcing values and "fence" behavior. + * forcing values. * @param bEndsReferenceArea True if the sequence should be resolved * at the trailing edge of reference area. * @return The resolved value as a min/opt/max triple. @@ -94,7 +94,7 @@ public class SpaceSpecifier implements Cloneable { int lastIndex = m_vecSpaceVals.size(); if (bEndsReferenceArea) { // Start from the end and count conditional specifiers - // Stop at first non-conditional or first fence + // Stop at first non-conditional for (; lastIndex > 0; --lastIndex) { SpaceVal sval = (SpaceVal)m_vecSpaceVals.elementAt(lastIndex-1); @@ -104,7 +104,6 @@ public class SpaceSpecifier implements Cloneable { } } MinOptMax resSpace = new MinOptMax(0); - // Must calculate in sub-sequences delimited by fences! int iMaxPrec = -1; for(int index=0; index < lastIndex; index++) { SpaceVal sval = (SpaceVal)m_vecSpaceVals.elementAt(index); diff --git a/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java b/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java index 7cf628e2c..94bf93de4 100644 --- a/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/TextBPLayoutManager.java @@ -29,19 +29,6 @@ import java.util.Vector; // or use ArrayList ??? * or more inline areas. */ public class TextBPLayoutManager extends AbstractBPLayoutManager { - /** - * Private class to store information about the break index. - * the field stores the index in the vector of AreaInfo which - * corresponds to this break position. - * Note: fields are directly readable in this class - */ - private static class TextBreakPosition implements BreakPoss.Position { - short m_iAreaIndex; - - TextBreakPosition(int iAreaIndex) { - m_iAreaIndex = (short)iAreaIndex; - } - } /** * Store information about each potential word area. @@ -147,10 +134,10 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { public void getWordChars(StringBuffer sbChars, - BreakPoss.Position bp1, BreakPoss.Position bp2) { - TextBreakPosition endPos = (TextBreakPosition)bp2; + Position bp1, Position bp2) { + LeafPosition endPos = (LeafPosition)bp2; AreaInfo ai = - (AreaInfo) m_vecAreaInfo.elementAt(endPos.m_iAreaIndex); + (AreaInfo) m_vecAreaInfo.elementAt(endPos.getLeafPos()); // Skip all leading spaces for hyphenation int i; for (i=ai.m_iStartIndex;i < ai.m_iBreakIndex && @@ -172,14 +159,19 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { /** Reset position for returning next BreakPossibility. */ - public void resetPosition(BreakPoss.Position prevPos) { + public void resetPosition(Position prevPos) { if (prevPos != null) { - TextBreakPosition tbp = (TextBreakPosition)prevPos; + // ASSERT (prevPos.getLM() == this) + if (prevPos.getLM() != this) { + System.err.println("TextBPLayoutManager.resetPosition: " + + "LM mismatch!!!"); + } + LeafPosition tbp = (LeafPosition)prevPos; AreaInfo ai = - (AreaInfo) m_vecAreaInfo.elementAt(tbp.m_iAreaIndex); + (AreaInfo) m_vecAreaInfo.elementAt(tbp.getLeafPos()); if (ai.m_iBreakIndex != m_iNextStart) { m_iNextStart = ai.m_iBreakIndex; - m_vecAreaInfo.setSize(tbp.m_iAreaIndex+1); + m_vecAreaInfo.setSize(tbp.getLeafPos()+1); // TODO: reset or recalculate total IPD = sum of all word IPD // up to the break position m_ipdTotal = ai.m_ipdArea; @@ -238,7 +230,7 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { * into spaces. A LINEFEED always forces a break. */ public BreakPoss getNextBreakPoss(LayoutContext context, - BreakPoss.Position prevPos) { + Position prevPos) { /* On first call in a new Line, the START_AREA * flag in LC is set. */ @@ -284,6 +276,7 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { // Sum of glyph IPD of all characters in a word, inc. leading space int wordIPD = 0; short iWScount=0; // Count of word spaces + boolean bSawNonSuppressible = false; for (; m_iNextStart < chars.length; m_iNextStart++) { char c = chars[m_iNextStart]; @@ -293,7 +286,15 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { // Counted as word-space if (m_iNextStart == iThisStart && (iFlags & BreakPoss.ISFIRST) !=0 ) { - context.getPendingSpace().addSpace(m_halfWS); + // If possible, treat as normal inter-word space + if (context.getLeadingSpace().hasSpaces()) { + context.getLeadingSpace().addSpace(m_halfWS); + } + else { + // Doesn't combine with any other leading spaces + // from ancestors + spaceIPD.add(m_halfWS.space); + } } else { pendingSpace.addSpace(m_halfWS); @@ -302,10 +303,14 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { wordIPD += m_spaceIPD; // Space glyph IPD pendingSpace.clear(); pendingSpace.addSpace(m_halfWS); + if (c == NBSPACE) { + bSawNonSuppressible = true; + } } else { // If we have letter-space, so we apply this to fixed- // width spaces (which are not word-space) also? + bSawNonSuppressible = true; spaceIPD.add(pendingSpace.resolve(false)); pendingSpace.clear(); wordIPD += CharUtilities.getCharWidth(c, textInfo.fs); @@ -317,9 +322,11 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { } else { // This FO ended with spaces. Return the BP - iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB; + if (!bSawNonSuppressible) { + iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB; + } return makeBreakPoss(iThisStart, spaceIPD, wordIPD, - context.getPendingSpace(), pendingSpace, + context.getLeadingSpace(), pendingSpace, iFlags, iWScount); } @@ -353,8 +360,17 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { iFlags |= BreakPoss.FORCE; } } + // If all remaining characters would be suppressed at + // line-end, set a flag for parent LM. + int iLastChar; + for (iLastChar = m_iNextStart; + iLastChar < chars.length && chars[iLastChar]==SPACE; + iLastChar++); + if (iLastChar == chars.length) { + iFlags |= BreakPoss.REST_ARE_SUPPRESS_AT_LB; + } return makeBreakPoss(iThisStart, spaceIPD, wordIPD, - context.getPendingSpace(), null, + context.getLeadingSpace(), null, iFlags, iWScount); } wordIPD += CharUtilities.getCharWidth(c, textInfo.fs); @@ -363,7 +379,7 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { } } return makeBreakPoss(iThisStart, spaceIPD, wordIPD, - context.getPendingSpace(), null, iFlags, iWScount); + context.getLeadingSpace(), null, iFlags, iWScount); } @@ -380,8 +396,7 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { // Position is the index of the info for this word in the vector m_vecAreaInfo.add(new AreaInfo(iWordStart, m_iNextStart, iWScount, ipd)); BreakPoss bp = - new BreakPoss(this, - new TextBreakPosition(m_vecAreaInfo.size()-1)); + new BreakPoss(new LeafPosition(this, m_vecAreaInfo.size()-1)); m_ipdTotal = ipd; if ((flags & BreakPoss.HYPHENATED)!=0) { // Add the hyphen size, but don't change total IPD! @@ -426,12 +441,12 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { * an area containing all text with a parameter controlling the size of * the word space. The latter is most efficient for PDF generation. * Set size of each area. - * @param parentIter Iterator over BreakPoss.Position information returned + * @param parentIter Iterator over Position information returned * by this LayoutManager. * @param dSpaceAdjust Factor controlling how much extra space to add * in order to justify the line. */ - public void addAreas(PositionIterator posIter, double dSpaceAdjust) { + public void addAreas(PositionIterator posIter, LayoutContext context) { // Add word areas AreaInfo ai=null ; int iStart = -1; @@ -441,8 +456,8 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { * Calculate word-space stretch value. */ while (posIter.hasNext()) { - TextBreakPosition tbpNext = (TextBreakPosition)posIter.next(); - ai = (AreaInfo)m_vecAreaInfo.elementAt(tbpNext.m_iAreaIndex); + LeafPosition tbpNext = (LeafPosition)posIter.next(); + ai = (AreaInfo)m_vecAreaInfo.elementAt(tbpNext.getLeafPos()); if (iStart == -1) { iStart = ai.m_iStartIndex; } @@ -450,30 +465,49 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { } // Calculate total adjustment int iAdjust = 0; + double dSpaceAdjust = context.getSpaceAdjust(); if (dSpaceAdjust > 0.0) { // Stretch by factor - System.err.println("Potential stretch = " + - (ai.m_ipdArea.max - ai.m_ipdArea.opt)); +// System.err.println("Potential stretch = " + +// (ai.m_ipdArea.max - ai.m_ipdArea.opt)); iAdjust = (int)((double)(ai.m_ipdArea.max - ai.m_ipdArea.opt) * dSpaceAdjust); } else if (dSpaceAdjust < 0.0) { // Shrink by factor - System.err.println("Potential shrink = " + - (ai.m_ipdArea.opt - ai.m_ipdArea.min)); +// System.err.println("Potential shrink = " + +// (ai.m_ipdArea.opt - ai.m_ipdArea.min)); iAdjust = (int)((double)(ai.m_ipdArea.opt - ai.m_ipdArea.min) * dSpaceAdjust); } - System.err.println("Text adjustment factor = " + dSpaceAdjust + - " total=" + iAdjust); - if (iWScount > 0) { - System.err.println("Adjustment per word-space= " + iAdjust/iWScount); - } +// System.err.println("Text adjustment factor = " + dSpaceAdjust + +// " total=" + iAdjust); + // Make an area containing all characters between start and end. - Word word = createWord(new String(chars, iStart, ai.m_iBreakIndex - iStart), + Word word = createWord(new String(chars, iStart, + ai.m_iBreakIndex - iStart), ai.m_ipdArea.opt + iAdjust); - if (chars[iStart] == SPACE || chars[iStart] == NBSPACE ) { - // word.setLeadingSpace(m_halfWS); + if (iWScount > 0) { + System.err.println("Adjustment per word-space= " + + iAdjust/iWScount); + word.setWSadjust(iAdjust/iWScount); + } + if ((chars[iStart] == SPACE || chars[iStart] == NBSPACE) && + context.getLeadingSpace().hasSpaces()) { + context.getLeadingSpace().addSpace(m_halfWS); + } + // Set LAST flag if done making characters + int iLastChar; + for (iLastChar = ai.m_iBreakIndex; + iLastChar < chars.length && chars[iLastChar]==SPACE; + iLastChar++); + context.setFlags(LayoutContext.LAST_AREA, iLastChar==chars.length ); + + // Can we have any trailing space? Yes, if last char was a space! + context.setTrailingSpace(new SpaceSpecifier(false)); + if (chars[ai.m_iBreakIndex-1] == SPACE || + chars[ai.m_iBreakIndex-1] == NBSPACE ) { + context.getTrailingSpace().addSpace(m_halfWS); } parentLM.addChild(word); } @@ -491,10 +525,8 @@ public class TextBPLayoutManager extends AbstractBPLayoutManager { curWordArea.info.blOffset = true; curWordArea.setWord(str); - Trait prop = new Trait(); - prop.propType = Trait.FONT_STATE; - prop.data = textInfo.fs; - curWordArea.addTrait(prop); + //curWordArea.addTrait(new Trait(Trait.FONT_STATE, textInfo.fs)); + curWordArea.addTrait(Trait.FONT_STATE, textInfo.fs); return curWordArea; } diff --git a/src/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/org/apache/fop/layoutmgr/TextLayoutManager.java index 04add7dfb..a8a31096c 100644 --- a/src/org/apache/fop/layoutmgr/TextLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/TextLayoutManager.java @@ -246,10 +246,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { curWordArea.info.blOffset = true; curWordArea.setWord(str); - Trait prop = new Trait(); - prop.propType = Trait.FONT_STATE; - prop.data = textInfo.fs; - curWordArea.addTrait(prop); + // curWordArea.addTrait(new Trait(Trait.FONT_STATE, textInfo.fs)); + curWordArea.addTrait(Trait.FONT_STATE, textInfo.fs); return curWordArea; } diff --git a/src/org/apache/fop/layoutmgr/TraitSetter.java b/src/org/apache/fop/layoutmgr/TraitSetter.java new file mode 100644 index 000000000..4badc6ab5 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/TraitSetter.java @@ -0,0 +1,70 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr; + +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.area.Area; +import org.apache.fop.area.Trait; + +public class TraitSetter { + + public static void setBorderPaddingTraits(Area area, BorderAndPadding bpProps, + boolean bNotFirst, boolean bNotLast) { + int iBP; + iBP = bpProps.getPadding(BorderAndPadding.START, bNotFirst); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_START, new Integer(iBP))); + area.addTrait(Trait.PADDING_START, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.END, bNotLast); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_END, new Integer(iBP))); + area.addTrait(Trait.PADDING_END, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.BEFORE, false); + if (iBP > 0) { + // area.addTrait(new Trait(Trait.PADDING_BEFORE, new Integer(iBP))); + area.addTrait(Trait.PADDING_BEFORE, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.AFTER, false); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_AFTER, new Integer(iBP))); + area.addTrait(Trait.PADDING_AFTER, new Integer(iBP)); + } + + addBorderTrait(area, bpProps, bNotFirst, BorderAndPadding.START, + Trait.BORDER_START); + + addBorderTrait(area, bpProps, bNotLast, BorderAndPadding.END, + Trait.BORDER_END); + + addBorderTrait(area, bpProps, false, BorderAndPadding.BEFORE, + Trait.BORDER_BEFORE); + + addBorderTrait(area, bpProps, false, BorderAndPadding.AFTER, + Trait.BORDER_AFTER); + } + + private static void addBorderTrait(Area area, BorderAndPadding bpProps, + boolean bDiscard, + int iSide, Object oTrait) { + int iBP = bpProps.getBorderWidth(iSide, bDiscard); + if (iBP > 0) { +// area.addTrait(new Trait(oTrait, +// new BorderProps(bpProps.getBorderStyle(iSide), +// iBP, +// bpProps.getBorderColor(iSide)))); + area.addTrait(oTrait, + new BorderProps(bpProps.getBorderStyle(iSide), + iBP, + bpProps.getBorderColor(iSide))); + } + } + +} diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index cedd387c3..9633c6b3e 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -266,13 +266,7 @@ public class PDFRenderer extends PrintRenderer { FontState fs = null; - List props = word.getTraitList(); - for(int count = 0; count < props.size(); count++) { - Trait pro = (Trait)props.get(count); - if(pro.propType == Trait.FONT_STATE) { - fs = (FontState)pro.data; - } - } + fs = (FontState)word.getTrait(Trait.FONT_STATE); String name = fs.getFontName(); int size = fs.getFontSize(); diff --git a/src/org/apache/fop/render/xml/XMLRenderer.java b/src/org/apache/fop/render/xml/XMLRenderer.java index 85aa688ef..8250ae4df 100644 --- a/src/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/org/apache/fop/render/xml/XMLRenderer.java @@ -29,8 +29,9 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.OutputStream; import java.util.Enumeration; -import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Iterator; import java.awt.geom.Rectangle2D; import org.w3c.dom.Document; @@ -278,9 +279,9 @@ public class XMLRenderer extends AbstractRenderer { protected void renderBlock(Block block) { String prop = ""; - List list = block.getTraitList(); - if (list != null) { - prop = " props=\"" + getPropString(list) + "\""; + Map map = block.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; } writeStartTag("<block" + prop + ">"); super.renderBlock(block); @@ -289,9 +290,9 @@ public class XMLRenderer extends AbstractRenderer { protected void renderLineArea(LineArea line) { String prop = ""; - List list = line.getTraitList(); - if (list != null) { - prop = " props=\"" + getPropString(list) + "\""; + Map map = line.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; } writeStartTag("<lineArea height=\"" + line.getHeight() + "\"" + prop + ">"); @@ -327,9 +328,9 @@ public class XMLRenderer extends AbstractRenderer { public void renderCharacter(org.apache.fop.area.inline.Character ch) { String prop = ""; - List list = ch.getTraitList(); - if (list != null) { - prop = " props=\"" + getPropString(list) + "\""; + Map map = ch.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; } writeElement("<char" + prop + ">" + ch.getChar() + "</char>"); } @@ -340,19 +341,20 @@ public class XMLRenderer extends AbstractRenderer { public void renderWord(Word word) { String prop = ""; - List list = word.getTraitList(); - if (list != null) { - prop = " props=\"" + getPropString(list) + "\""; + Map map = word.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; } - writeElement("<word" + prop + ">" + word.getWord() + "</word>"); + writeElement("<word wsadjust=\"" + word.getWSadjust() + "\"" + + prop + ">" + word.getWord() + "</word>"); super.renderWord(word); } public void renderInlineParent(InlineParent ip) { String prop = ""; - List list = ip.getTraitList(); - if (list != null) { - prop = " props=\"" + getPropString(list) + "\""; + Map map = ip.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; } writeStartTag("<inlineparent" + prop + ">"); super.renderInlineParent(ip); @@ -385,56 +387,18 @@ public class XMLRenderer extends AbstractRenderer { super.renderLeader(area); } - protected String getPropString(List list) { - String str = ""; - for (int count = 0; count < list.size(); count++) { - Trait prop = (Trait) list.get(count); - switch (prop.propType) { - case Trait.INTERNAL_LINK: - str += "internal-link:" + prop.data; - break; - case Trait.EXTERNAL_LINK: - str += "external-link:" + prop.data; - break; - case Trait.FONT_FAMILY: - str += "font-family:" + prop.data; - break; - case Trait.FONT_SIZE: - str += "font-size:" + prop.data; - break; - case Trait.FONT_WEIGHT: - str += "font-weight:" + prop.data; - break; - case Trait.FONT_STYLE: - str += "font-style:" + prop.data; - break; - case Trait.COLOR: - str += "color:" + prop.data; - break; - case Trait.BACKGROUND: - str += "background:" + prop.data; - break; - case Trait.UNDERLINE: - str += "underline:" + prop.data; - break; - case Trait.OVERLINE: - str += "overline:" + prop.data; - break; - case Trait.LINETHROUGH: - str += "linethrough:" + prop.data; - break; - case Trait.OFFSET: - str += "offset:" + prop.data; - break; - case Trait.SHADOW: - str += "shadow:" + prop.data; - break; - default: - break; - } - str += ";"; - } - return str; + protected String getPropString(Map traitMap) { + StringBuffer strbuf = new StringBuffer(); + Iterator iter = traitMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry traitEntry = (Map.Entry) iter.next(); + strbuf.append(Trait.getTraitName(traitEntry.getKey())); + strbuf.append(':'); + strbuf.append(traitEntry.getValue().toString()); + strbuf.append(';'); + } + return strbuf.toString(); } + } diff --git a/src/org/apache/fop/tools/AreaTreeBuilder.java b/src/org/apache/fop/tools/AreaTreeBuilder.java index 330924926..89888d434 100644 --- a/src/org/apache/fop/tools/AreaTreeBuilder.java +++ b/src/org/apache/fop/tools/AreaTreeBuilder.java @@ -408,10 +408,7 @@ class TreeLoader { Node obj = childs.item(i); if (obj.getNodeName().equals("block")) { Block block = new Block(); - List props = getProperties((Element) obj); - for (int count = 0; count < props.size(); count++) { - block.addTrait((Trait) props.get(count)); - } + addTraits((Element)obj, block); addBlockChildren(block, (Element) obj); list.add(block); } @@ -437,10 +434,7 @@ class TreeLoader { // error } LineArea line = new LineArea(); - List props = getProperties((Element) obj); - for (int count = 0; count < props.size(); count++) { - line.addTrait((Trait) props.get(count)); - } + addTraits((Element) obj, line); String height = ((Element) obj).getAttribute("height"); int h = Integer.parseInt(height); line.setHeight(h); @@ -466,7 +460,7 @@ class TreeLoader { if (obj.getNodeName().equals("char")) { Character ch = new Character(getString((Element) obj).charAt(0)); - addProperties((Element) obj, ch); + addTraits((Element) obj, ch); try { currentFontState = new FontState(fontInfo, "sans-serif", "normal", @@ -503,10 +497,8 @@ class TreeLoader { e.printStackTrace(); } Word word = getWord((Element) obj); - Trait prop = new Trait(); - prop.propType = Trait.FONT_STATE; - prop.data = currentFontState; - word.addTrait(prop); + + word.addTrait(Trait.FONT_STATE, currentFontState); if (word != null) { list.add(word); } @@ -632,7 +624,7 @@ class TreeLoader { leader.setWidth(thick); } leader.setOffset(currentFontState.getCapHeight()); - addProperties(root, leader); + addTraits(root, leader); return leader; } @@ -640,7 +632,7 @@ class TreeLoader { String str = getString(root); Word word = new Word(); word.setWord(str); - addProperties(root, word); + addTraits(root, word); int width = 0; for (int count = 0; count < str.length(); count++) { width += currentFontState.width(str.charAt(count)); @@ -651,80 +643,24 @@ class TreeLoader { return word; } - public void addProperties(Element ele, InlineArea inline) { - List props = getProperties(ele); - for (int count = 0; count < props.size(); count++) { - inline.addTrait((Trait) props.get(count)); - } - String str = ele.getAttribute("width"); - } - - public List getProperties(Element ele) { - ArrayList list = new ArrayList(); + public void addTraits(Element ele, Area area) { String str = ele.getAttribute("props"); StringTokenizer st = new StringTokenizer(str, ";"); while (st.hasMoreTokens()) { String tok = st.nextToken(); int index = tok.indexOf(":"); String id = tok.substring(0, index); - String val = tok.substring(index + 1); - Trait prop = new Trait(); - if ("internal-link".equals(id)) { - prop.propType = Trait.INTERNAL_LINK; - prop.data = val; - list.add(prop); - } else if ("external-link".equals(id)) { - prop.propType = Trait.EXTERNAL_LINK; - prop.data = val; - list.add(prop); - } else if ("font-family".equals(id)) { - prop.propType = Trait.FONT_FAMILY; - prop.data = val; - list.add(prop); - } else if ("font-size".equals(id)) { - prop.propType = Trait.FONT_SIZE; - prop.data = Integer.valueOf(val); - list.add(prop); - } else if ("font-weight".equals(id)) { - prop.propType = Trait.FONT_WEIGHT; - prop.data = val; - list.add(prop); - } else if ("font-style".equals(id)) { - prop.propType = Trait.FONT_STYLE; - prop.data = val; - list.add(prop); - } else if ("color".equals(id)) { - prop.propType = Trait.COLOR; - prop.data = val; - list.add(prop); - } else if ("background".equals(id)) { - prop.propType = Trait.BACKGROUND; - prop.data = val; - list.add(prop); - } else if ("underline".equals(id)) { - prop.propType = Trait.UNDERLINE; - prop.data = new Boolean(val); - list.add(prop); - } else if ("overline".equals(id)) { - prop.propType = Trait.OVERLINE; - prop.data = new Boolean(val); - list.add(prop); - } else if ("linethrough".equals(id)) { - prop.propType = Trait.LINETHROUGH; - prop.data = new Boolean(val); - list.add(prop); - } else if ("offset".equals(id)) { - prop.propType = Trait.OFFSET; - prop.data = Integer.valueOf(val); - list.add(prop); - } else if ("shadow".equals(id)) { - prop.propType = Trait.SHADOW; - prop.data = val; - list.add(prop); - } + Object traitCode = Trait.getTraitCode(id); + if (traitCode != null) { + area.addTrait(traitCode, + Trait.makeTraitValue(traitCode, + tok.substring(index + 1))); + } + else { + System.err.println("Unknown trait: " + id ); + } } - return list; } public List getRanges(Element ele) { diff --git a/src/org/apache/fop/traits/BorderProps.java b/src/org/apache/fop/traits/BorderProps.java new file mode 100644 index 000000000..99303eee2 --- /dev/null +++ b/src/org/apache/fop/traits/BorderProps.java @@ -0,0 +1,34 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.traits; + +import org.apache.fop.datatypes.ColorType; + +public class BorderProps { + public int style; // Enum for border style + public ColorType color; // Border color + public int width; // Border width + + public BorderProps(int style, int width, ColorType color) { + this.style = style; + this.width = width; + this.color = color; + } + + public String toString() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append('('); + sbuf.append(style); // Should get a String value for this enum constant + sbuf.append(','); + sbuf.append(color); + sbuf.append(','); + sbuf.append(width); + sbuf.append(')'); + return sbuf.toString(); + } +} |