/**
* The base class for all BPLayoutManagers.
*/
-public abstract class AbstractBPLayoutManager extends AbstractLayoutManager
- implements BPLayoutManager {
+public abstract class AbstractBPLayoutManager extends AbstractLayoutManager implements BPLayoutManager {
/** True if this LayoutManager has handled all of its content. */
private boolean m_bFinished = false;
- private BPLayoutManager m_curChildLM=null;
- private ListIterator m_childLMiter;
- private boolean m_bInited=false;
+ protected BPLayoutManager m_curChildLM = null;
+ protected ListIterator m_childLMiter;
+ protected boolean m_bInited = false;
public AbstractBPLayoutManager(FObj fobj) {
- this(fobj, new LMiter(fobj.getChildren()));
+ this(fobj, new LMiter(fobj.getChildren()));
}
public AbstractBPLayoutManager(FObj fobj, ListIterator lmIter) {
- super(fobj);
- m_childLMiter = lmIter;
+ super(fobj);
+ m_childLMiter = lmIter;
}
* and print a warning.
*/
protected BPLayoutManager getChildLM() {
- if (m_curChildLM != null && !m_curChildLM.isFinished()) {
- return m_curChildLM;
- }
- while (m_childLMiter.hasNext()) {
- Object obj = m_childLMiter.next();
- if (obj instanceof BPLayoutManager) {
- m_curChildLM = (BPLayoutManager)obj;
- m_curChildLM.setParentLM(this);
- m_curChildLM.init();
- return m_curChildLM;
- }
- else {
- m_childLMiter.remove();
- System.err.println("WARNING: child LM not a BPLayoutManager: "
- + obj.getClass().getName());
- }
- }
- return null;
+ if (m_curChildLM != null && !m_curChildLM.isFinished()) {
+ return m_curChildLM;
+ }
+ while (m_childLMiter.hasNext()) {
+ Object obj = m_childLMiter.next();
+ if (obj instanceof BPLayoutManager) {
+ m_curChildLM = (BPLayoutManager) obj;
+ m_curChildLM.setParentLM(this);
+ m_curChildLM.init();
+ return m_curChildLM;
+ } else {
+ m_childLMiter.remove();
+ System.err.println(
+ "WARNING: child LM not a BPLayoutManager: " +
+ obj.getClass().getName());
+ }
+ }
+ 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();
+ // 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();
}
* If pos is null, then back up to the first child LM.
*/
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()) {
- System.err.println("LMiter problem!");
- }
- while (m_curChildLM != lm && m_childLMiter.hasPrevious()) {
- m_curChildLM.resetPosition(null);
- m_curChildLM = (BPLayoutManager)m_childLMiter.previous();
- }
- m_childLMiter.next(); // Otherwise next returns same object
- }
- m_curChildLM.resetPosition(pos);
- if (isFinished()) {
- setFinished(false);
- }
+ //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()) {
+ System.err.println("LMiter problem!");
+ }
+ while (m_curChildLM != lm && m_childLMiter.hasPrevious()) {
+ m_curChildLM.resetPosition(null);
+ m_curChildLM = (BPLayoutManager) m_childLMiter.previous();
+ }
+ m_childLMiter.next(); // Otherwise next returns same object
+ }
+ m_curChildLM.resetPosition(pos);
+ if (isFinished()) {
+ setFinished(false);
+ }
}
public void resetPosition(Position resetPos) {
-// if (resetPos == null) {
-// reset(null);
-// }
+ // if (resetPos == null) {
+ // reset(null);
+ // }
}
* for the areas it will create, based on Properties set on its FO.
*/
public void init() {
- if (fobj != null && m_bInited == false) {
- initProperties(fobj.getPropertyManager());
- m_bInited=true;
- }
+ if (fobj != null && m_bInited == false) {
+ initProperties(fobj.getPropertyManager());
+ m_bInited = true;
+ }
}
* for the areas it will create, based on Properties set on its FO.
*/
protected void initProperties(PropertyManager pm) {
- System.err.println("AbstractBPLayoutManager.initProperties");
+ System.err.println("AbstractBPLayoutManager.initProperties");
}
* ie. the last one returned represents the end of the content.
*/
public boolean isFinished() {
- return m_bFinished;
+ return m_bFinished;
}
public void setFinished(boolean bFinished) {
- m_bFinished = bFinished;
+ m_bFinished = bFinished;
}
* default implementation?
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
- return getNextBreakPoss(context, null);
+ return getNextBreakPoss(context, null);
}
public BreakPoss getNextBreakPoss(LayoutContext context,
- Position prevBreakPoss) {
- return null;
+ Position prevBreakPoss) {
+ return null;
}
/**
* Default implementation always returns true.
*/
public boolean canBreakBefore(LayoutContext context) {
- return true;
+ return true;
}
public void addAreas(PositionIterator posIter, LayoutContext context) {
}
-
- public void getWordChars(StringBuffer sbChars,
- Position bp1, Position bp2) {
+
+ public void getWordChars(StringBuffer sbChars, Position bp1,
+ Position bp2) {
}
/* ---------------------------------------------------------
* interface which are declared abstract in AbstractLayoutManager.
* ---------------------------------------------------------*/
public Area getParentArea(Area childArea) {
- return null;
+ return null;
}
protected boolean flush() {
- return false;
+ return false;
}
* BreakPoss.
*/
public BreakPoss getNextBreakPoss(LayoutContext context,
- Position prevBreakPosition);
+ Position prevBreakPosition);
public BreakPoss getNextBreakPoss(LayoutContext context);
* Return a value indicating whether this LayoutManager has laid out
* all its content (or generated BreakPossibilities for all content.)
*/
- public boolean isFinished() ;
+ public boolean isFinished();
/**
* Set a flag indicating whether the LayoutManager has laid out all
* its content. This is generally called by the LM itself, but can
* be called by a parentLM when backtracking.
*/
- public void setFinished(boolean isFinished) ;
+ public void setFinished(boolean isFinished);
/**
* Tell the layout manager to add all the child areas implied
* by Position objects which will be returned by the
* Iterator.
*/
- public void addAreas(PositionIterator posIter, LayoutContext context) ;
+ public void addAreas(PositionIterator posIter, LayoutContext context);
- public void init() ;
+ public void init();
public void resetPosition(Position position);
- public void getWordChars(StringBuffer sbChars,
- Position bp1, Position bp2);
+ public void getWordChars(StringBuffer sbChars, Position bp1,
+ Position bp2);
}
import java.util.ListIterator;
import java.util.ArrayList;
+import java.util.List;
/**
* LayoutManager for a block FO.
return curBlockArea.getIPD();
}
+ private static class BlockBreakPosition extends LeafPosition {
+ List blockps;
+
+ BlockBreakPosition(BPLayoutManager lm, int iBreakIndex, List bps) {
+ super(lm, iBreakIndex);
+ blockps = bps;
+ }
+ }
+
+ protected BPLayoutManager getChildLM() {
+ if (m_curChildLM != null && !m_curChildLM.isFinished()) {
+ return m_curChildLM;
+ }
+ while (m_childLMiter.hasNext()) {
+ LayoutManager lm = (LayoutManager) m_childLMiter.next();
+ if (lm.generatesInlineAreas()) {
+ ArrayList inlines = new ArrayList();
+ inlines.add(lm);
+ //lms.remove(count);
+ while (m_childLMiter.hasNext()) {
+ lm = (LayoutManager) m_childLMiter.next();
+ if (lm.generatesInlineAreas()) {
+ inlines.add(lm);
+ //lms.remove(count + 1);
+ } else {
+ m_childLMiter.previousIndex();
+ break;
+ }
+ }
+ m_curChildLM = new LineBPLayoutManager(fobj, inlines,
+ lineHeight, lead, follow);
+ m_curChildLM.setParentLM(this);
+ m_curChildLM.init();
+ return m_curChildLM;
+ //lms.set(count, lm);
+ } else if (lm instanceof BPLayoutManager) {
+ m_curChildLM = (BPLayoutManager) lm;
+ m_curChildLM.setParentLM(this);
+ m_curChildLM.init();
+ return m_curChildLM;
+ } else {
+ m_childLMiter.remove();
+ System.err.println(
+ "WARNING: child LM not a BPLayoutManager: " +
+ lm.getClass().getName());
+ }
+ }
+ return null;
+ }
+
+ public BreakPoss getNextBreakPoss(LayoutContext context,
+ Position prevLineBP) {
+
+ BPLayoutManager curLM ; // currently active LM
+ ArrayList list = new ArrayList();
+
+ while ((curLM = getChildLM()) != null) {
+ // Make break positions and return lines!
+ // Set up a LayoutContext
+ int ipd = 0;
+ BreakPoss bp;
+ ArrayList vecBreakPoss = new ArrayList();
+
+ // Force area creation on first call
+ // NOTE: normally not necessary when fully integrated!
+ LayoutContext childLC =
+ new LayoutContext(LayoutContext.CHECK_REF_AREA);
+
+ while (!curLM.isFinished()) {
+ if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) {
+ if (bp.checkIPD()) {
+ // Need IPD in order to layout lines!
+ // This is supposed to bubble up to PageLM to
+ // make the necessary flow reference area, depending
+ // on span and break-before flags set as the BreakPoss
+ // makes its way back up the call stack.
+ // Fake it for now!
+ getParentArea(null);
+ ipd = getContentIPD();
+ childLC.flags &= ~LayoutContext.CHECK_REF_AREA;
+ childLC.setStackLimit(new MinOptMax(ipd/* - m_iIndents -
+ m_iTextIndent*/));
+ } else {
+ vecBreakPoss.add(bp);
+ // Reset stackLimit for non-first lines
+ childLC.setStackLimit(new MinOptMax(ipd/* - m_iIndents*/));
+ }
+ }
+ }
+ list.add(vecBreakPoss);
+ return new BreakPoss(
+ new BlockBreakPosition(curLM, 0, vecBreakPoss));
+ }
+ setFinished(true);
+ return new BreakPoss(new BlockBreakPosition(this, 0, list));
+ }
+
+ public void addAreas(PositionIterator parentIter, LayoutContext lc) {
+
+ while (parentIter.hasNext()) {
+ BlockBreakPosition bbp = (BlockBreakPosition) parentIter.next();
+ bbp.getLM().addAreas( new BreakPossPosIter(bbp.blockps, 0,
+ bbp.blockps.size()), null);
+ }
+ flush();
+ }
+
+
/**
- * Generate areas by tellings all layout managers for its FO's
+ * Generate areas by telling all layout managers for its FO's
* children to generate areas.
*/
public boolean generateAreas() {
ArrayList lms = new ArrayList();
LayoutManager lm = null;
- FObj curFobj = fobj;
+ FObj curFobj = fobj;
if (fobj != null) {
ListIterator children = fobj.getChildren();
while (children.hasNext()) {
Object childFO = children.next();
- if(childFO instanceof FObj) {
- ((FObj)childFO).addLayoutManager(lms);
+ if (childFO instanceof FObj) {
+ ((FObj) childFO).addLayoutManager(lms);
}
}
- fobj = null;
+ //fobj = null;
}
- for (int count = 0; count < lms.size(); count++) {
- lm = (LayoutManager) lms.get(count);
- if (lm.generatesInlineAreas()) {
- ArrayList inlines = new ArrayList();
- inlines.add(lm);
- //lms.remove(count);
- while (count + 1 < lms.size()) {
- lm = (LayoutManager) lms.get(count + 1);
+ ArrayList vecBreakPoss = new ArrayList();
+
+ BreakPoss bp;
+ LayoutContext childLC = new LayoutContext(0);
+ while (!isFinished()) {
+ if ((bp = getNextBreakPoss(childLC, null)) != null) {
+ vecBreakPoss.add(bp);
+ }
+ }
+
+ addAreas( new BreakPossPosIter(vecBreakPoss, 0,
+ vecBreakPoss.size()), null);
+
+
+ /*
+ for (int count = 0; count < lms.size(); count++) {
+ lm = (LayoutManager) lms.get(count);
if (lm.generatesInlineAreas()) {
+ ArrayList inlines = new ArrayList();
inlines.add(lm);
- lms.remove(count + 1);
- } else {
- break;
+ //lms.remove(count);
+ while (count + 1 < lms.size()) {
+ lm = (LayoutManager) lms.get(count + 1);
+ if (lm.generatesInlineAreas()) {
+ inlines.add(lm);
+ lms.remove(count + 1);
+ } else {
+ break;
+ }
+ }
+ lm = new LineBPLayoutManager(curFobj, inlines,
+ lineHeight, lead, follow);
+ lms.set(count, lm);
+ }
+ lm.setParentLM(this);
+ if (lm.generateAreas()) {
+ if (flush()) {
+ return true;
+ }
}
}
- /*
- lm = new LineLayoutManager(curFobj, inlines, lineHeight, lead,
- follow);
- */
- // !!!! To test BreakPoss Line LayoutManager, uncomment!
- lm = new LineBPLayoutManager(curFobj, inlines, lineHeight,
- lead, follow);
- lms.set(count, lm);
- }
- lm.setParentLM(this);
- if (lm.generateAreas()) {
- if (flush()) {
- return true;
- }
- }
- }
+ */
return flush(); // Add last area to parent
}
* Base LayoutManager class for all areas which stack their child
* areas in the block-progression direction, such as Flow, Block, ListBlock.
*/
-public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
+public abstract class BlockStackingLayoutManager extends AbstractBPLayoutManager {
/** Reference to FO whose areas it's managing or to the traits
* of the FO.
*/
// Logically a BlockStacking LM only handles Block-type areas
if (!(area instanceof BlockParent)) {
return false;
- }
+ }
Iterator areaIter = ((BlockParent) area).getChildAreas().iterator();
// If already saw several a potential break, use it
if (minBreakCost != null) {
/* Split 'area', placing all children after
- * minBreakCost.getArea() into a new area,
- * which we store in the splitContext.
- *
+ * minBreakCost.getArea() into a new area,
+ * which we store in the splitContext.
+ *
// splitContext.nextArea = area.splitAfter(minBreakCost.getArea());
} else {
/* This area will be shorter than the desired minimum.
- * Split before the current childArea (which will be
- * the first area in the newly created Area.
- *
+ * Split before the current childArea (which will be
+ * the first area in the newly created Area.
+ *
//splitContext.nextArea = area.splitBefore(childArea);
}
} else
}
//Note: size of area when split can depend on conditional
// space, border and padding of the split area!!!
- }
+ }
// True if some part of area can be placed, false if none is placed
return (splitContext.nextArea != area);
- */
+ */
return false;
}
* @param childArea the area to add: will be some block-stacked Area.
* @param parentArea the area in which to add the childArea
*/
- protected boolean addChildToArea(Area childArea, BlockParent parentArea) {
+ protected boolean addChildToArea(Area childArea,
+ BlockParent parentArea) {
// This should be a block-level Area (Block in the generic sense)
if (!(childArea instanceof Block)) {
System.err.println("Child not a Block in BlockStackingLM!");
if (childLM.splitArea(childArea, splitContext)) {
//parentArea.addBlock(new InterBlockSpace(spaceBefore));
parentArea.addBlock((Block) childArea);
- }*/
+ }*/
//flush(); // hand off current area to parent
//getParentArea(splitContext.nextArea);
//getParentArea(childArea);
/** Values for m_flags returned from lower level LM. */
- public static final int CAN_BREAK_AFTER= 0x01; // May break after
- public static final int ISLAST= 0x02; // Last area generated by FO
- public static final int ISFIRST= 0x04; // First area generated by FO
- public static final int FORCE= 0x08; // Forced break (ie LF)
- public static final int CAN_BREAK_BEFORE=0x10;
- public static final int NEED_IPD = 0x20;
- public static final int HAS_ANCHORS = 0x40;
+ public static final int CAN_BREAK_AFTER = 0x01; // May break after
+ public static final int ISLAST = 0x02; // Last area generated by FO
+ public static final int ISFIRST = 0x04; // First area generated by FO
+ public static final int FORCE = 0x08; // Forced break (ie LF)
+ public static final int CAN_BREAK_BEFORE = 0x10;
+ public static final int NEED_IPD = 0x20;
+ public static final int HAS_ANCHORS = 0x40;
// Set this flag if all fo:character generated Areas would
// suppressed at the end or beginning of a line
- public static final int ALL_ARE_SUPPRESS_AT_LB = 0x80;
+ public static final int ALL_ARE_SUPPRESS_AT_LB = 0x80;
/** This break possibility is a hyphenation */
- public static final int HYPHENATED = 0x100;
+ public static final int HYPHENATED = 0x100;
/** If this break possibility ends the line, all remaining characters
* in the lowest level text LM will be suppressed.
*/
/**
* Max height above and below the baseline. These are cumulative.
*/
- private int m_iMaxAscender;
- private int m_iMaxDescender;
+ private int m_iMaxAscender;
+ private int m_iMaxDescender;
/** Size in the non-stacking direction (perpendicular). */
private MinOptMax m_nonStackSize;
private SpaceSpecifier m_spaceSpecLeading;
public BreakPoss(Position position) {
- this(position,0);
+ this(position, 0);
}
public BreakPoss(Position position, long flags) {
m_position = position;
- m_flags = flags;
+ m_flags = flags;
}
/**
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.
}
public void setStackingSize(MinOptMax size) {
- this.m_stackSize = size;
+ this.m_stackSize = size;
}
public MinOptMax getStackingSize() {
- return this.m_stackSize ;
+ return this.m_stackSize ;
}
public void setNonStackingSize(MinOptMax size) {
- this.m_nonStackSize = size;
+ this.m_nonStackSize = size;
}
public MinOptMax getNonStackingSize() {
- return this.m_nonStackSize ;
+ return this.m_nonStackSize ;
}
public long getFlags() {
- return m_flags;
+ return m_flags;
}
public void setFlag(int flagBit) {
public void setFlag(int flagBit, boolean bSet) {
if (bSet) {
m_flags |= flagBit;
- }
- else {
+ } else {
m_flags &= ~flagBit;
}
}
}
public SpaceSpecifier getLeadingSpace() {
- return m_spaceSpecLeading;
+ return m_spaceSpecLeading;
}
public MinOptMax resolveLeadingSpace() {
- if (m_spaceSpecLeading != null) {
- return m_spaceSpecLeading.resolve(false);
- }
- else return new MinOptMax(0);
+ if (m_spaceSpecLeading != null) {
+ return m_spaceSpecLeading.resolve(false);
+ } else
+ return new MinOptMax(0);
}
public SpaceSpecifier getTrailingSpace() {
- return m_spaceSpecTrailing;
+ return m_spaceSpecTrailing;
}
public MinOptMax resolveTrailingSpace(boolean bEndsRefArea) {
- if (m_spaceSpecTrailing != null) {
- return m_spaceSpecTrailing.resolve(bEndsRefArea);
- }
- else return new MinOptMax(0);
+ if (m_spaceSpecTrailing != null) {
+ return m_spaceSpecTrailing.resolve(bEndsRefArea);
+ } else
+ return new MinOptMax(0);
}
public void setLeadingSpace(SpaceSpecifier spaceSpecLeading) {
- m_spaceSpecLeading = spaceSpecLeading;
+ m_spaceSpecLeading = spaceSpecLeading;
}
public void setTrailingSpace(SpaceSpecifier spaceSpecTrailing) {
- m_spaceSpecTrailing = spaceSpecTrailing;
+ m_spaceSpecTrailing = spaceSpecTrailing;
}
public LayoutProps getLayoutProps() {
- return m_layoutProps;
+ return m_layoutProps;
}
public boolean checkIPD() {
- return ((m_flags & NEED_IPD) != 0);
+ return ((m_flags & NEED_IPD) != 0);
}
}
private int m_iterCount ;
BreakPossPosIter(List bpList, int startPos, int endPos) {
- super(bpList.listIterator(startPos));
- m_iterCount = endPos - startPos;
+ super(bpList.listIterator(startPos));
+ m_iterCount = endPos - startPos;
}
// Check position < endPos
protected boolean checkNext() {
- if (m_iterCount > 0) {
- return super.checkNext();
- }
- else {
- endIter();
- return false;
- }
+ if (m_iterCount > 0) {
+ return super.checkNext();
+ } else {
+ endIter();
+ return false;
+ }
}
public Object next() {
- --m_iterCount;
- return super.next();
+ --m_iterCount;
+ return super.next();
}
public BreakPoss getBP() {
- return (BreakPoss)peekNext();
+ return (BreakPoss) peekNext();
}
protected BPLayoutManager getLM(Object nextObj) {
- return ((BreakPoss)nextObj).getLayoutManager();
+ return ((BreakPoss) nextObj).getLayoutManager();
}
protected Position getPos(Object nextObj) {
- return ((BreakPoss)nextObj).getPosition();
+ return ((BreakPoss) nextObj).getPosition();
}
}
import org.apache.fop.fo.properties.Constants;
import org.apache.fop.area.*;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* LayoutManager for an fo:flow object.
* Its parent LM is the PageLayoutManager.
*/
public class FlowLayoutManager extends BlockStackingLayoutManager {
+ private static class BlockBreakPosition extends LeafPosition {
+ List blockps;
+
+ BlockBreakPosition(BPLayoutManager lm, int iBreakIndex, List bps) {
+ super(lm, iBreakIndex);
+ blockps = bps;
+ }
+ }
+
/** Array of areas currently being filled stored by area class */
private BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX];
super(fobj);
}
+ public boolean generateAreas() {
+
+ ArrayList vecBreakPoss = new ArrayList();
+
+ BreakPoss bp;
+ LayoutContext childLC = new LayoutContext(0);
+ while (!isFinished()) {
+ if ((bp = getNextBreakPoss(childLC, null)) != null) {
+ System.out.println("Flow Break: " + bp);
+ vecBreakPoss.add(bp);
+ }
+ }
+
+ addAreas( new BreakPossPosIter(vecBreakPoss, 0,
+ vecBreakPoss.size()), null);
+ flush();
+ return false;
+ }
+
+ public BreakPoss getNextBreakPoss(LayoutContext context,
+ Position prevLineBP) {
+
+ BPLayoutManager curLM ; // currently active LM
+
+ while ((curLM = getChildLM()) != null) {
+ // Make break positions and return lines!
+ // Set up a LayoutContext
+ int bpd = 0;
+ BreakPoss bp;
+ ArrayList vecBreakPoss = new ArrayList();
+
+ // Force area creation on first call
+ // NOTE: normally not necessary when fully integrated!
+ LayoutContext childLC = new LayoutContext(0);
+
+ while (!curLM.isFinished()) {
+ if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) {
+ vecBreakPoss.add(bp);
+ // Reset stackLimit for non-first lines
+ childLC.setStackLimit(new MinOptMax(bpd));
+ }
+ }
+
+System.out.println("Flow BreakPoss: " + vecBreakPoss);
+
+ return new BreakPoss(
+ new BlockBreakPosition(curLM, 0, vecBreakPoss));
+ }
+ setFinished(true);
+ return null;
+ }
+
+ public void addAreas(PositionIterator parentIter, LayoutContext lc) {
+System.out.println("FL add: " + parentIter);
+ while (parentIter.hasNext()) {
+ BlockBreakPosition bbp = (BlockBreakPosition) parentIter.next();
+System.out.println("FL add: " + bbp);
+ bbp.getLM().addAreas( new BreakPossPosIter(bbp.blockps, 0,
+ bbp.blockps.size()), null);
+ }
+ flush();
+ }
/**
*/
public boolean addChild(Area childArea) {
return addChildToArea(childArea,
- this.currentAreas[childArea.getAreaClass()]);
+ this.currentAreas[childArea.getAreaClass()]);
}
public Area getParentArea(Area childArea) {
return parentArea;
}
-
}
+
*/
public class HyphContext {
private int[] m_hyphPoints;
- private int m_iCurOffset=0;
- private int m_iCurIndex=0;
+ private int m_iCurOffset = 0;
+ private int m_iCurIndex = 0;
public HyphContext(int[] hyphPoints) {
- m_hyphPoints = hyphPoints;
+ m_hyphPoints = hyphPoints;
}
public int getNextHyphPoint() {
- for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
- if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
- return (m_hyphPoints[m_iCurIndex] - m_iCurOffset);
- }
- }
- return -1; // AT END!
+ for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
+ if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
+ return (m_hyphPoints[m_iCurIndex] - m_iCurOffset);
+ }
+ }
+ return -1; // AT END!
}
public boolean hasMoreHyphPoints() {
- for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
- if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
- return true;
- }
- }
- return false;
+ for (; m_iCurIndex < m_hyphPoints.length; m_iCurIndex++) {
+ if (m_hyphPoints[m_iCurIndex] > m_iCurOffset) {
+ return true;
+ }
+ }
+ return false;
}
public void updateOffset(int iCharsProcessed) {
- m_iCurOffset += iCharsProcessed;
+ m_iCurOffset += iCharsProcessed;
}
}
private static class StackingIter extends PositionIterator {
- StackingIter(Iterator parentIter) {
- super(parentIter);
- }
+ StackingIter(Iterator parentIter) {
+ super(parentIter);
+ }
- protected BPLayoutManager getLM(Object nextObj) {
- return ((Position)nextObj).getPosition().getLM();
- }
+ protected BPLayoutManager getLM(Object nextObj) {
+ return ((Position) nextObj).getPosition().getLM();
+ }
- protected Position getPos(Object nextObj) {
- return ((Position)nextObj).getPosition();
- }
+ protected Position getPos(Object nextObj) {
+ return ((Position) nextObj).getPosition();
+ }
}
private BreakPoss m_prevBP;
private LayoutContext m_childLC ;
- private BPLayoutManager m_lastChildLM=null; // Set when return last breakposs
+ 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();
- public InlineStackingBPLayoutManager(FObj fobj, ListIterator childLMiter) {
- super(fobj, childLMiter);
- // Initialize inline properties (borders, padding, space)
- // initProperties();
+ public InlineStackingBPLayoutManager(FObj fobj,
+ ListIterator childLMiter) {
+ super(fobj, childLMiter);
+ // Initialize inline properties (borders, padding, space)
+ // initProperties();
}
public boolean generatesInlineAreas() {
}
protected void initProperties(PropertyManager propMgr) {
- // super.initProperties(propMgr);
+ // super.initProperties(propMgr);
m_inlineProps = propMgr.getInlineProps();
m_borderProps = propMgr.getBorderAndPadding();
- // Calculdate border and padding size in BPD
- int iPad = m_borderProps.getPadding(BorderAndPadding.BEFORE, false);
- iPad += m_borderProps.getBorderWidth(BorderAndPadding.BEFORE, false);
- iPad += m_borderProps.getPadding(BorderAndPadding.AFTER, false);
- iPad += m_borderProps.getBorderWidth(BorderAndPadding.AFTER, false);
- m_extraBPD = new MinOptMax(iPad);
+ // Calculdate border and padding size in BPD
+ int iPad = m_borderProps.getPadding(BorderAndPadding.BEFORE, false);
+ iPad += m_borderProps.getBorderWidth(BorderAndPadding.BEFORE,
+ false);
+ iPad += m_borderProps.getPadding(BorderAndPadding.AFTER, false);
+ iPad += m_borderProps.getBorderWidth(BorderAndPadding.AFTER, false);
+ m_extraBPD = new MinOptMax(iPad);
}
private MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.START, bNotFirst);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.START, bNotFirst);
- iBP += m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
- return new MinOptMax(iBP);
+ int iBP = m_borderProps.getPadding(BorderAndPadding.START,
+ bNotFirst);
+ iBP += m_borderProps.getBorderWidth(BorderAndPadding.START,
+ bNotFirst);
+ iBP += m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
+ iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
+ return new MinOptMax(iBP);
}
protected boolean hasLeadingFence(boolean bNotFirst) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.START, bNotFirst);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.START, bNotFirst);
- return (iBP > 0);
+ int iBP = m_borderProps.getPadding(BorderAndPadding.START,
+ bNotFirst);
+ iBP += m_borderProps.getBorderWidth(BorderAndPadding.START,
+ bNotFirst);
+ return (iBP > 0);
}
-
+
protected boolean hasTrailingFence(boolean bNotLast) {
- int iBP = m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
- iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
- return (iBP > 0);
+ int iBP = m_borderProps.getPadding(BorderAndPadding.END, bNotLast);
+ iBP += m_borderProps.getBorderWidth(BorderAndPadding.END, bNotLast);
+ return (iBP > 0);
}
-
+
/**
* Reset position for returning next BreakPossibility.
*/
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() !=childPos.getLM()) {
- m_childLC = null;
- }
- m_prevBP = new BreakPoss(childPos);
- }
- else {
- // Backup to start of first child layout manager
- m_prevBP = null;
- // 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?
+ 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() != childPos.getLM()) {
+ m_childLC = null;
+ }
+ m_prevBP = new BreakPoss(childPos);
+ } else {
+ // Backup to start of first child layout manager
+ m_prevBP = null;
+ // 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?
}
* propagate to first child LM
*/
public boolean canBreakBefore(LayoutContext context) {
- if (m_inlineProps.spaceStart.space.min > 0 ||
- hasLeadingFence(false)) {
- return true;
- }
- BPLayoutManager lm = getChildLM();
- if (lm != null) {
- return lm.canBreakBefore(context);
- }
- else return false; // ??? NO child LM?
+ if (m_inlineProps.spaceStart.space.min > 0 ||
+ hasLeadingFence(false)) {
+ return true;
+ }
+ BPLayoutManager lm = getChildLM();
+ if (lm != null) {
+ return lm.canBreakBefore(context);
+ } else
+ return false; // ??? NO child LM?
}
protected MinOptMax getPrevIPD(LayoutManager lm) {
- return (MinOptMax)m_hmPrevIPD.get(lm);
+ return (MinOptMax) m_hmPrevIPD.get(lm);
}
protected void clearPrevIPD() {
- m_hmPrevIPD.clear();
+ m_hmPrevIPD.clear();
}
public BreakPoss getNextBreakPoss(LayoutContext lc, Position pbp) {
// Get a break from currently active child LM
- BreakPoss bp =null;
- BPLayoutManager curLM ;
- 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.getLeadingSpace().addSpace(m_inlineProps.spaceStart);
-
- // Check for "fence"
- if (hasLeadingFence(!lc.isFirstArea())) {
- // Reset leading space sequence for child areas
- leadingSpace = new SpaceSpecifier(false);
- }
- // Reset state variables
- clearPrevIPD(); // Clear stored prev content dimensions
- }
-
- // We only do this loop more than once if a childLM returns
- // a null BreakPoss, meaning it has nothing (more) to layout.
+ BreakPoss bp = null;
+ BPLayoutManager curLM ;
+ 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.getLeadingSpace().addSpace(m_inlineProps.spaceStart);
+
+ // Check for "fence"
+ if (hasLeadingFence(!lc.isFirstArea())) {
+ // Reset leading space sequence for child areas
+ leadingSpace = new SpaceSpecifier(false);
+ }
+ // Reset state variables
+ clearPrevIPD(); // Clear stored prev content dimensions
+ }
+
+ // We only do this loop more than once if a childLM returns
+ // a null BreakPoss, meaning it has nothing (more) to layout.
while ((curLM = getChildLM()) != null) {
- /* If first break for this child LM, set START_AREA flag
- * and initialize pending space from previous LM sibling's
- * trailing space specifiers.
- */
- boolean bFirstChildBP = (m_prevBP == null ||
- m_prevBP.getLayoutManager()!=curLM);
-
- initChildLC(m_childLC, m_prevBP, lc.startsNewArea(), bFirstChildBP,
- leadingSpace);
- if (lc.tryHyphenate()) {
- m_childLC.setHyphContext(lc.getHyphContext());
- }
-
- if (((bp = curLM.getNextBreakPoss(m_childLC)) != null) ||
- (lc.tryHyphenate() && !lc.getHyphContext().hasMoreHyphPoints())) {
- break;
- }
- // If LM has no content, should it generate any area? If not,
- // should trailing space from a previous area interact with
- // leading space from a following area?
+ /* If first break for this child LM, set START_AREA flag
+ * and initialize pending space from previous LM sibling's
+ * trailing space specifiers.
+ */
+ boolean bFirstChildBP = (m_prevBP == null ||
+ m_prevBP.getLayoutManager() != curLM);
+
+ initChildLC(m_childLC, m_prevBP, lc.startsNewArea(),
+ bFirstChildBP, leadingSpace);
+ if (lc.tryHyphenate()) {
+ m_childLC.setHyphContext(lc.getHyphContext());
+ }
+
+ if (((bp = curLM.getNextBreakPoss(m_childLC)) != null) ||
+ (lc.tryHyphenate() &&
+ !lc.getHyphContext().hasMoreHyphPoints())) {
+ break;
+ }
+ // If LM has no content, should it generate any area? If not,
+ // should trailing space from a previous area interact with
+ // leading space from a following area?
}
- if (bp==null) {
- setFinished(true);
+ if (bp == null) {
+ setFinished(true);
return null; // There was no childLM with anything to layout
// Alternative is to return a BP with the isLast flag set
- }
- else {
- 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());
- }
+ } else {
+ 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);
}
}
/** ATTENTION: ALSO USED BY LineBPLayoutManager! */
protected void initChildLC(LayoutContext childLC, BreakPoss prevBP,
- boolean bStartParent, boolean bFirstChildBP,
- SpaceSpecifier leadingSpace) {
-
- childLC.setFlags(LayoutContext.NEW_AREA,
- (bFirstChildBP || bStartParent));
- if (bStartParent) {
- // Start of a new line area or inline parent area
- childLC.setFlags(LayoutContext.FIRST_AREA, bFirstChildBP );
- childLC.setLeadingSpace(leadingSpace);
- }
- else if (bFirstChildBP) {
- // Space-after sequence from previous "area"
- childLC.setFlags(LayoutContext.FIRST_AREA, true);
- childLC.setLeadingSpace(prevBP.getTrailingSpace());
- }
- else {
- childLC.setLeadingSpace(null);
- }
+ boolean bStartParent, boolean bFirstChildBP,
+ SpaceSpecifier leadingSpace) {
+
+ childLC.setFlags(LayoutContext.NEW_AREA,
+ (bFirstChildBP || bStartParent));
+ if (bStartParent) {
+ // Start of a new line area or inline parent area
+ childLC.setFlags(LayoutContext.FIRST_AREA, bFirstChildBP);
+ childLC.setLeadingSpace(leadingSpace);
+ } else if (bFirstChildBP) {
+ // Space-after sequence from previous "area"
+ childLC.setFlags(LayoutContext.FIRST_AREA, true);
+ childLC.setLeadingSpace(prevBP.getTrailingSpace());
+ } else {
+ childLC.setLeadingSpace(null);
+ }
}
private BreakPoss makeBreakPoss(BreakPoss bp, LayoutContext lc,
- boolean bIsLast) {
- NonLeafPosition inlbp =
- new NonLeafPosition(this, bp.getPosition());
- BreakPoss myBP = new BreakPoss(inlbp, bp.getFlags());
+ boolean bIsLast) {
+ 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);
+ myBP.setFlag(BreakPoss.ISFIRST, lc.isFirstArea());
+ myBP.setFlag(BreakPoss.ISLAST, bIsLast);
- if (bIsLast) {
- m_lastChildLM = bp.getLayoutManager();
- }
+ if (bIsLast) {
+ m_lastChildLM = bp.getLayoutManager();
+ }
// Update dimension information for our allocation area,
- // including child areas
+ // including child areas
// generated by previous childLM which have completed layout
// Update pending area measure
// This includes all previous breakinfo
-
- MinOptMax bpDim = (MinOptMax)bp.getStackingSize().clone();
- MinOptMax prevIPD = updatePrevIPD(bp, m_prevBP,
- lc.startsNewArea(), lc.isFirstArea());
-
- if (lc.startsNewArea()) {
- myBP.setLeadingSpace(lc.getLeadingSpace());
- }
-
-
- // Add size of previous child areas which are finished
- bpDim.add(prevIPD);
-
- SpaceSpecifier trailingSpace = bp.getTrailingSpace();
- if (hasTrailingFence(!bIsLast)) {
- 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);
-
- // Add start and end borders and padding
- bpDim.add(getExtraIPD(!lc.isFirstArea(), !bIsLast));
- myBP.setStackingSize(bpDim);
- myBP.setNonStackingSize(MinOptMax.add(bp.getNonStackingSize(),
- m_extraBPD));
-
- m_prevBP = bp;
-// if (bIsLast) {
-// setFinished(true); // Our last area, so indicate done
-// }
- return myBP;
+
+ MinOptMax bpDim = (MinOptMax) bp.getStackingSize().clone();
+ MinOptMax prevIPD = updatePrevIPD(bp, m_prevBP, lc.startsNewArea(),
+ lc.isFirstArea());
+
+ if (lc.startsNewArea()) {
+ myBP.setLeadingSpace(lc.getLeadingSpace());
+ }
+
+
+ // Add size of previous child areas which are finished
+ bpDim.add(prevIPD);
+
+ SpaceSpecifier trailingSpace = bp.getTrailingSpace();
+ if (hasTrailingFence(!bIsLast)) {
+ 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);
+
+ // Add start and end borders and padding
+ bpDim.add(getExtraIPD(!lc.isFirstArea(), !bIsLast));
+ myBP.setStackingSize(bpDim);
+ myBP.setNonStackingSize(
+ MinOptMax.add(bp.getNonStackingSize(), m_extraBPD));
+
+ m_prevBP = bp;
+ // if (bIsLast) {
+ // setFinished(true); // Our last area, so indicate done
+ // }
+ return myBP;
}
/** ATTENTION: ALSO USED BY LineBPLayoutManager! */
protected MinOptMax updatePrevIPD(BreakPoss bp, BreakPoss prevBP,
- boolean bStartParent, boolean bFirstArea)
- {
- MinOptMax prevIPD = new MinOptMax(0);
-
- if (bStartParent) {
- if (hasLeadingFence(!bFirstArea)) {
- // Space-start before first child area placed
- prevIPD.add(bp.resolveLeadingSpace());
- }
- m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
- }
- else {
- // In case of reset to a previous position, it may already
- // be calculated
- prevIPD = (MinOptMax)m_hmPrevIPD.get(bp.getLayoutManager());
- if (prevIPD == null) {
- // ASSERT(prevBP.getLayoutManager() != bp.getLayoutManager());
- /* This is first bp generated by child (in this parent area).
- * Calculate space-start on this area in combination with any
- * pending space-end with previous break.
- * Corresponds to Space between two child areas.
- */
- prevIPD = (MinOptMax)m_hmPrevIPD.get(prevBP.getLayoutManager());
- prevIPD = MinOptMax.add(prevIPD, bp.resolveLeadingSpace());
- prevIPD.add(prevBP.getStackingSize());
- m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
- }
- }
- return prevIPD;
+ boolean bStartParent, boolean bFirstArea) {
+ MinOptMax prevIPD = new MinOptMax(0);
+
+ if (bStartParent) {
+ if (hasLeadingFence(!bFirstArea)) {
+ // Space-start before first child area placed
+ prevIPD.add(bp.resolveLeadingSpace());
+ }
+ m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
+ } else {
+ // In case of reset to a previous position, it may already
+ // be calculated
+ prevIPD = (MinOptMax) m_hmPrevIPD.get(bp.getLayoutManager());
+ if (prevIPD == null) {
+ // ASSERT(prevBP.getLayoutManager() != bp.getLayoutManager());
+ /* This is first bp generated by child (in this parent area).
+ * Calculate space-start on this area in combination with any
+ * pending space-end with previous break.
+ * Corresponds to Space between two child areas.
+ */
+ prevIPD = (MinOptMax) m_hmPrevIPD.get(
+ prevBP.getLayoutManager());
+ prevIPD = MinOptMax.add(prevIPD, bp.resolveLeadingSpace());
+ prevIPD.add(prevBP.getStackingSize());
+ m_hmPrevIPD.put(bp.getLayoutManager(), prevIPD);
+ }
+ }
+ return prevIPD;
}
- public void getWordChars(StringBuffer sbChars,
- Position bp1, Position bp2) {
- Position endPos = ((NonLeafPosition)bp2).getPosition();
- Position prevPos = null;
- if (bp1 != null) {
- prevPos = ((NonLeafPosition)bp1).getPosition();
- if (prevPos.getLM() != endPos.getLM()) {
- prevPos = null;
- }
- }
- endPos.getLM().getWordChars(sbChars, prevPos, endPos);
+ public void getWordChars(StringBuffer sbChars, Position bp1,
+ Position bp2) {
+ Position endPos = ((NonLeafPosition) bp2).getPosition();
+ Position prevPos = null;
+ if (bp1 != null) {
+ prevPos = ((NonLeafPosition) bp1).getPosition();
+ if (prevPos.getLM() != endPos.getLM()) {
+ prevPos = null;
+ }
+ }
+ endPos.getLM().getWordChars(sbChars, prevPos, endPos);
}
/******
- protected BreakableText getText(BreakPoss prevBP, BreakPoss lastBP) {
- }
- *****/
+ protected BreakableText getText(BreakPoss prevBP, BreakPoss lastBP) {
+ }
+ *****/
/**
* Generate and add areas to parent area.
* @param dSpaceAdjust Factor controlling how much extra space to add
* in order to justify the line.
*/
- public void addAreas(PositionIterator parentIter, LayoutContext context) {
+ 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) {
- //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);
-
- // 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;
+ 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) {
+ //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);
+
+ // 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;
+ return m_currentArea;
}
protected void setCurrentArea(Area area) {
- m_currentArea = area;
+ m_currentArea = area;
}
public boolean addChild(Area childArea) {
- // Make sure childArea is inline area
- if (childArea instanceof InlineArea) {
- Area parent = getCurrentArea();
- if (getContext().resolveLeadingSpace()) {
- addSpace(parent,
- getContext().getLeadingSpace().resolve(false),
- getContext().getSpaceAdjust());
- }
- parent.addChild(childArea);
- }
- return false;
+ // Make sure childArea is inline area
+ if (childArea instanceof InlineArea) {
+ 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;
+ m_childLC = lc;
}
// Current child layout context
protected LayoutContext getContext() {
- return m_childLC ;
+ 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);
- }
- }
+ 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);
+ }
+ }
}
private ListIterator m_baseIter;
private FObj m_curFO;
private ArrayList m_listLMs;
- private int m_curPos=0;
+ private int m_curPos = 0;
public LMiter(ListIterator baseIter) {
- m_baseIter = baseIter;
- m_listLMs = new ArrayList(10);
+ m_baseIter = baseIter;
+ m_listLMs = new ArrayList(10);
}
public boolean hasNext() {
- return (m_curPos < m_listLMs.size())? true :
- preLoadNext();
+ return (m_curPos < m_listLMs.size()) ? true : preLoadNext();
}
private boolean preLoadNext() {
- if (m_baseIter.hasNext()) {
- FObj fobj = (FObj)m_baseIter.next();
- //m_listLMs.add(fobj.getLayoutManager());
- fobj.addLayoutManager(m_listLMs);
- return true;
- }
- else return false;
+ if (m_baseIter.hasNext()) {
+ FObj fobj = (FObj) m_baseIter.next();
+ //m_listLMs.add(fobj.getLayoutManager());
+ fobj.addLayoutManager(m_listLMs);
+ return m_curPos < m_listLMs.size();
+ } else
+ return false;
}
public boolean hasPrevious() {
- return (m_curPos > 0);
+ return (m_curPos > 0);
}
public Object previous() throws NoSuchElementException {
- if (m_curPos > 0) {
- return m_listLMs.get(--m_curPos);
- }
- else throw new NoSuchElementException();
+ if (m_curPos > 0) {
+ return m_listLMs.get(--m_curPos);
+ } else
+ throw new NoSuchElementException();
}
public Object next() throws NoSuchElementException {
- if (m_curPos < m_listLMs.size()) {
- return m_listLMs.get(m_curPos++);
- }
- else throw new NoSuchElementException();
+ if (m_curPos < m_listLMs.size()) {
+ return m_listLMs.get(m_curPos++);
+ } else
+ throw new NoSuchElementException();
}
-
+
public void remove() throws NoSuchElementException {
- if (m_curPos > 0) {
- m_listLMs.remove(--m_curPos);
- // Note: doesn't actually remove it from the base!
- }
- else throw new NoSuchElementException();
-
+ if (m_curPos > 0) {
+ m_listLMs.remove(--m_curPos);
+ // Note: doesn't actually remove it from the base!
+ } else
+ throw new NoSuchElementException();
+
}
- public void add(Object o) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("LMiter doesn't support add");
+ public void add(Object o) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("LMiter doesn't support add");
}
public void set(Object o) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("LMiter doesn't support set");
+ throw new UnsupportedOperationException("LMiter doesn't support set");
}
public int nextIndex() {
- return m_curPos;
+ return m_curPos;
}
public int previousIndex() {
- return m_curPos - 1;
+ return m_curPos - 1;
}
}
*/
public static final int LINEBREAK_AT_LF_ONLY = 0x01;
/** Generated break possibility is first in a new area */
- public static final int NEW_AREA = 0x02;
- public static final int IPD_UNKNOWN = 0x04;
+ public static final int NEW_AREA = 0x02;
+ public static final int IPD_UNKNOWN = 0x04;
/** Signal to a Line LM that a higher level LM may provoke a change
* in the reference area, thus ref area IPD. The LineLM should return
* without looking for a line break.
*/
- public static final int CHECK_REF_AREA = 0x08;
+ public static final int CHECK_REF_AREA = 0x08;
/**
* If this flag is set, it indicates that any leading fo:character
* areas. This is the case at the beginning of each new LineArea
* except the first.
*/
- 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 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 static final int RESOLVE_LEADING_SPACE = 0x100;
- public int flags; // Contains some set of flags defined above
+ public int flags; // Contains some set of flags defined above
/**
* Total available stacking dimension for a "galley-level" layout
* manager (Line or Flow). It is passed by the parent LM. For LineLM,
SpaceSpecifier m_leadingSpace;
/** Current hyphenation context. May be null. */
- private HyphContext m_hyphContext=null;
+ private HyphContext m_hyphContext = null;
/** Stretch or shrink value when making areas. */
private double m_dSpaceAdjust = 0.0;
this.flags = parentLC.flags;
this.refIPD = parentLC.refIPD;
this.m_stackLimit = null; // Don't reference parent MinOptMax!
- this.m_leadingSpace = parentLC.m_leadingSpace; //???
- this.m_trailingSpace = parentLC.m_trailingSpace; //???
- this.m_hyphContext = parentLC.m_hyphContext;
- this.m_dSpaceAdjust = parentLC.m_dSpaceAdjust;
+ 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???
}
public LayoutContext(int flags) {
this.flags = flags;
this.refIPD = 0;
- m_stackLimit = new MinOptMax(0);
- m_leadingSpace = null;
- m_trailingSpace = null;
+ m_stackLimit = new MinOptMax(0);
+ m_leadingSpace = null;
+ m_trailingSpace = null;
}
public void setFlags(int flags) {
- setFlags(flags, true);
+ setFlags(flags, true);
}
public void setFlags(int flags, boolean bSet) {
- if (bSet) {
- this.flags |= flags;
- }
- else {
- this.flags &= ~flags;
- }
+ if (bSet) {
+ this.flags |= flags;
+ } else {
+ this.flags &= ~flags;
+ }
}
public void unsetFlags(int flags) {
- setFlags(flags, false);
+ setFlags(flags, false);
}
public boolean isStart() {
- return ((this.flags & NEW_AREA) != 0);
+ return ((this.flags & NEW_AREA) != 0);
}
public boolean startsNewArea() {
- return ((this.flags & NEW_AREA) != 0 && m_leadingSpace != null);
+ return ((this.flags & NEW_AREA) != 0 && m_leadingSpace != null);
}
public boolean isFirstArea() {
- return ((this.flags & FIRST_AREA) != 0);
+ return ((this.flags & FIRST_AREA) != 0);
}
public boolean isLastArea() {
- return ((this.flags & LAST_AREA) != 0);
+ return ((this.flags & LAST_AREA) != 0);
}
public boolean suppressLeadingSpace() {
- return ((this.flags & SUPPRESS_LEADING_SPACE) != 0);
+ return ((this.flags & SUPPRESS_LEADING_SPACE) != 0);
}
public void setLeadingSpace(SpaceSpecifier space) {
- m_leadingSpace = space;
+ m_leadingSpace = space;
}
public SpaceSpecifier getLeadingSpace() {
- return m_leadingSpace;
+ return m_leadingSpace;
}
public boolean resolveLeadingSpace() {
- return ((this.flags & RESOLVE_LEADING_SPACE) != 0);
+ return ((this.flags & RESOLVE_LEADING_SPACE) != 0);
}
public void setTrailingSpace(SpaceSpecifier space) {
- m_trailingSpace = space;
+ m_trailingSpace = space;
}
public SpaceSpecifier getTrailingSpace() {
- return m_trailingSpace;
+ return m_trailingSpace;
}
public void setStackLimit(MinOptMax stackLimit) {
- m_stackLimit = stackLimit;
+ m_stackLimit = stackLimit;
}
public MinOptMax getStackLimit() {
- return m_stackLimit ;
+ return m_stackLimit ;
}
public void setHyphContext(HyphContext hyphContext) {
- m_hyphContext = hyphContext;
+ m_hyphContext = hyphContext;
}
public HyphContext getHyphContext() {
- return m_hyphContext;
+ return m_hyphContext;
}
public boolean tryHyphenate() {
- return ((this.flags & TRY_HYPHENATE) != 0);
+ return ((this.flags & TRY_HYPHENATE) != 0);
}
public void setSpaceAdjust(double dSpaceAdjust) {
- m_dSpaceAdjust = dSpaceAdjust ;
+ m_dSpaceAdjust = dSpaceAdjust ;
}
public double getSpaceAdjust() {
- return m_dSpaceAdjust;
+ return m_dSpaceAdjust;
}
}
public class LayoutInfo {
public int alignment;
public int lead;
- public boolean blOffset = false;
+ public boolean blOffset = false;
public boolean breakAfter = false;
public boolean keepNext = false;
}
public InlineArea get(int index) {
- if(index > 0)
+ if (index > 0)
return null;
return curArea;
}
/**
* This is a leaf-node, so this method is never called.
*/
- public boolean addChild(Area childArea) {return false;}
+ public boolean addChild(Area childArea) {
+ return false;
+ }
/**
}
public BreakPoss getNextBreakPoss(LayoutContext context,
- Position prevBreakPoss) {
+ Position prevBreakPoss) {
curArea = get(0);
- if(curArea == null) {
+ if (curArea == null) {
setFinished(true);
return null;
}
- BreakPoss bp = new BreakPoss(new LeafPosition(this, 0), BreakPoss.CAN_BREAK_AFTER | BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST | BreakPoss.ISLAST | BreakPoss.REST_ARE_SUPPRESS_AT_LB);
+ BreakPoss bp = new BreakPoss(new LeafPosition(this, 0),
+ BreakPoss.CAN_BREAK_AFTER |
+ BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST |
+ BreakPoss.ISLAST | BreakPoss.REST_ARE_SUPPRESS_AT_LB);
bp.setStackingSize(curArea.getAllocationIPD());
setFinished(true);
return bp;
public void addAreas(PositionIterator posIter, LayoutContext context) {
parentLM.addChild(curArea);
- while(posIter.hasNext()) {
+ while (posIter.hasNext()) {
posIter.next();
}
}
private int m_iLeafPos;
public LeafPosition(BPLayoutManager lm, int iLeafPos) {
- super(lm);
- m_iLeafPos = iLeafPos;
+ super(lm);
+ m_iLeafPos = iLeafPos;
}
public int getLeafPos() {
- return m_iLeafPos;
+ return m_iLeafPos;
}
}
* BPLayoutManager for lines. It builds one or more lines containing
* inline areas generated by its sub layout managers.
*/
-public class LineBPLayoutManager extends
- InlineStackingBPLayoutManager {
+public class LineBPLayoutManager extends InlineStackingBPLayoutManager {
/**
* Private class to store information about inline breaks.
// private static class LineBreakPosition implements Position {
private static class LineBreakPosition extends LeafPosition {
// int m_iPos;
- double m_dAdjust; // Percentage to adjust (stretch or shrink)
+ double m_dAdjust; // Percentage to adjust (stretch or shrink)
- LineBreakPosition(BPLayoutManager lm, int iBreakIndex, double dAdjust) {
- super(lm, iBreakIndex);
+ LineBreakPosition(BPLayoutManager lm, int iBreakIndex,
+ double dAdjust) {
+ super(lm, iBreakIndex);
// m_iPos = iBreakIndex;
- m_dAdjust = dAdjust;
+ m_dAdjust = dAdjust;
}
}
private int follow;
public LineBPLayoutManager(FObj fobj, List lms, int lh, int l, int f) {
- //super(fobj, lms.listIterator(), lh, l, f);
- super(fobj, lms.listIterator());
+ //super(fobj, lms.listIterator(), lh, l, f);
+ super(fobj, lms.listIterator());
lineHeight = lh;
lead = l;
follow = f;
- init(); // Normally done when started by parent!
+ init(); // Normally done when started by parent!
}
protected void initProperties(PropertyManager propMgr) {
MarginProps marginProps = propMgr.getMarginProps();
m_iIndents = marginProps.startIndent + marginProps.endIndent;
- BlockProps blockProps = propMgr.getBlockProps();
- m_bJustify = (blockProps.textAlign == TextAlign.JUSTIFY);
- m_iTextIndent = blockProps.firstIndent;
- m_hyphProps = propMgr.getHyphenationProps();
+ BlockProps blockProps = propMgr.getBlockProps();
+ m_bJustify = (blockProps.textAlign == TextAlign.JUSTIFY);
+ m_iTextIndent = blockProps.firstIndent;
+ m_hyphProps = propMgr.getHyphenationProps();
}
-
+
/**
* Call child layout managers to generate content as long as they
* finish any line being filled and return to the parent LM.
*/
public BreakPoss getNextBreakPoss(LayoutContext context,
- Position prevLineBP) {
+ Position prevLineBP) {
// Get a break from currently active child LM
// Set up constraints for inline level managers
if ((context.flags & LayoutContext.CHECK_REF_AREA) != 0) {
/* Return a BreakPoss indicating that higher level LM
- * (page) should check reference area and possibly
- * create a new one.
- */
- return new BreakPoss(new LineBreakPosition(this, -1, 0.0),
- BreakPoss.NEED_IPD);
+ * (page) should check reference area and possibly
+ * create a new one.
+ */
+ return new BreakPoss(new LineBreakPosition(this, -1, 0.0),
+ BreakPoss.NEED_IPD);
}
- BPLayoutManager curLM ; // currently active LM
- BreakPoss prevBP=null;
- BreakPoss bp=null; // proposed BreakPoss
+ BPLayoutManager curLM ; // currently active LM
+ BreakPoss prevBP = null;
+ BreakPoss bp = null; // proposed BreakPoss
- Vector vecPossEnd = new Vector();
+ Vector vecPossEnd = new Vector();
- // IPD remaining in line
+ // IPD remaining in line
MinOptMax availIPD = context.getStackLimit();
- // QUESTION: maybe LayoutContext holds the Properties which
- // come from block-level?
+ // QUESTION: maybe LayoutContext holds the Properties which
+ // come from block-level?
- LayoutContext inlineLC = new LayoutContext(context);
+ LayoutContext inlineLC = new LayoutContext(context);
- clearPrevIPD();
- int iPrevLineEnd = m_vecInlineBreaks.size();
+ clearPrevIPD();
+ int iPrevLineEnd = m_vecInlineBreaks.size();
while ((curLM = getChildLM()) != null) {
- // INITIALIZE LAYOUT CONTEXT FOR CALL TO CHILD LM
- // First break for the child LM in each of its areas
- boolean bFirstBPforLM =
- (m_vecInlineBreaks.isEmpty() ||
- (((BreakPoss)m_vecInlineBreaks.lastElement()).
- getLayoutManager() != curLM));
-
- // Need previous breakpoint! ATTENTION when backing up for hyphenation!
- prevBP = (m_vecInlineBreaks.isEmpty())? null:
- (BreakPoss)m_vecInlineBreaks.lastElement();
- initChildLC(inlineLC, prevBP,
- (m_vecInlineBreaks.size()==iPrevLineEnd),
- bFirstBPforLM,
- new SpaceSpecifier(true));
+ // INITIALIZE LAYOUT CONTEXT FOR CALL TO CHILD LM
+ // First break for the child LM in each of its areas
+ boolean bFirstBPforLM = (m_vecInlineBreaks.isEmpty() ||
+ (((BreakPoss) m_vecInlineBreaks.lastElement()).
+ getLayoutManager() != curLM));
+
+ // Need previous breakpoint! ATTENTION when backing up for hyphenation!
+ prevBP = (m_vecInlineBreaks.isEmpty()) ? null :
+ (BreakPoss) m_vecInlineBreaks.lastElement();
+ initChildLC(inlineLC, prevBP,
+ (m_vecInlineBreaks.size() == iPrevLineEnd),
+ bFirstBPforLM, new SpaceSpecifier(true));
/* If first BP in this line but line is not first in this
* LM and previous line end decision was not forced (LINEFEED),
* then set the SUPPRESS_LEADING_SPACE flag.
*/
- inlineLC.setFlags(LayoutContext.SUPPRESS_LEADING_SPACE,
- (m_vecInlineBreaks.size()==iPrevLineEnd &&
- !m_vecInlineBreaks.isEmpty() &&
- ((BreakPoss)m_vecInlineBreaks.lastElement()).
- isForcedBreak()==false));
-
- // GET NEXT POSSIBLE BREAK FROM CHILD LM
- // prevBP = bp;
+ inlineLC.setFlags(LayoutContext.SUPPRESS_LEADING_SPACE,
+ (m_vecInlineBreaks.size() == iPrevLineEnd &&
+ !m_vecInlineBreaks.isEmpty() &&
+ ((BreakPoss) m_vecInlineBreaks.lastElement()).
+ isForcedBreak() == false));
+
+ // GET NEXT POSSIBLE BREAK FROM CHILD LM
+ // prevBP = bp;
if ((bp = curLM.getNextBreakPoss(inlineLC, null)) != null) {
- // Add any space before and previous content dimension
- MinOptMax prevIPD =
- updatePrevIPD(bp, prevBP,
- (m_vecInlineBreaks.size()==iPrevLineEnd),
- inlineLC.isFirstArea());
- MinOptMax bpDim = MinOptMax.add(bp.getStackingSize(), prevIPD);
-
- // check if this bp fits in line
- boolean bBreakOK = couldEndLine(bp);
- if (bBreakOK) {
- /* Add any non-conditional trailing space, assuming we
- * end the line here. If we can't break here, we just
- * check if the content fits. */
- bpDim.add(bp.resolveTrailingSpace(true));
- }
- // TODO: stop if linebreak is forced (NEWLINE)
- // PROBLEM: interaction with wrap which can be set
- // at lower levels!
- // System.err.println("BPdim=" + bpDim.opt);
-
- // Check if proposed area would fit in line
- if (bpDim.min > availIPD.max) {
- // See if we have already found a potential break
- //if (vecPossEnd.size() > 0) break;
-
- // This break position doesn't fit
- // TODO: If we are in nowrap, we use it as is!
- if (m_bJustify || m_prevBP == null) {
- // If we are already in a hyphenation loop, then stop.
-
- if (inlineLC.tryHyphenate()) {
- break;
- }
- // Otherwise, prepare to try hyphenation
- if (!bBreakOK) {
- // Make sure we collect the entire word!
- m_vecInlineBreaks.add(bp);
- continue;
- }
-
- inlineLC.setHyphContext(getHyphenContext(m_prevBP, bp));
- if (inlineLC.getHyphContext()==null) break;
- inlineLC.setFlags(LayoutContext.TRY_HYPHENATE, true);
- // Reset to previous acceptable break
- reset();
- }
- /* If we are not in justified text, we can end the line at
- * prevBP.
- */
- else {
- break;
- }
- }
- else {
- // Add the BP to the list whether or not we can break
- m_vecInlineBreaks.add(bp);
- // Handle end of this LM's areas
- if (bBreakOK) {
- m_prevBP = bp; // Save reference to this BP
- if (bp.isForcedBreak()) {
- break;
- }
- if (bpDim.max >= availIPD.min) {
- /* This is a possible line BP (line could be filled)
- * bpDim.max >= availIPD.min
- * Keep this as a possible break, depending on
- * "cost". We will choose lowest cost.
- * Cost depends on stretch
- * (ie, bpDim.opt closes to availIPD.opt), keeps
- * and hyphenation.
- */
- vecPossEnd.add(new BreakCost(bp,
- Math.abs(availIPD.opt - bpDim.opt )));
- }
- // Otherwise it's short
- }
- else {
- /* Can't end line here. */
- }
- } // end of bpDim.min <= availIPD.max
- } // end of getNextBreakPoss!=null on current child LM
- else {
- /* The child LM can return a null BreakPoss if it has
- * nothing (more) to layout. This can happen when backing
- * up. Just try the next child LM.
- */
- }
- if (inlineLC.tryHyphenate() &&
- !inlineLC.getHyphContext().hasMoreHyphPoints()) {
- break;
- }
- } // end of while on child LM
- if ((curLM = getChildLM())== null) {
- // No more content to layout!
- setFinished(true);
- }
-
- if(bp == null) return null;
- if(m_prevBP == null) m_prevBP = bp;
-
- // Choose the best break
- if (!bp.isForcedBreak() && vecPossEnd.size()>0) {
- m_prevBP = getBestBP(vecPossEnd);
- }
- // Backup child LM if necessary
- if (bp != m_prevBP && !bp.couldEndLine()) {
- reset();
- }
- // Distribute space in the line
- MinOptMax actual;
- if(bp != m_prevBP) {
- MinOptMax mom = getPrevIPD(m_prevBP.getLayoutManager());
- if(mom != null) {
- actual = MinOptMax.add(m_prevBP.getStackingSize(), mom);
- } else {
- actual = m_prevBP.getStackingSize();
+ // Add any space before and previous content dimension
+ MinOptMax prevIPD = updatePrevIPD(bp, prevBP,
+ (m_vecInlineBreaks.size() == iPrevLineEnd),
+ inlineLC.isFirstArea());
+ MinOptMax bpDim =
+ MinOptMax.add(bp.getStackingSize(), prevIPD);
+
+ // check if this bp fits in line
+ boolean bBreakOK = couldEndLine(bp);
+ if (bBreakOK) {
+ /* Add any non-conditional trailing space, assuming we
+ * end the line here. If we can't break here, we just
+ * check if the content fits. */
+ bpDim.add(bp.resolveTrailingSpace(true));
+ }
+ // TODO: stop if linebreak is forced (NEWLINE)
+ // PROBLEM: interaction with wrap which can be set
+ // at lower levels!
+ // System.err.println("BPdim=" + bpDim.opt);
+
+ // Check if proposed area would fit in line
+ if (bpDim.min > availIPD.max) {
+ // See if we have already found a potential break
+ //if (vecPossEnd.size() > 0) break;
+
+ // This break position doesn't fit
+ // TODO: If we are in nowrap, we use it as is!
+ if (m_bJustify || m_prevBP == null) {
+ // If we are already in a hyphenation loop, then stop.
+
+ if (inlineLC.tryHyphenate()) {
+ break;
+ }
+ // Otherwise, prepare to try hyphenation
+ if (!bBreakOK) {
+ // Make sure we collect the entire word!
+ m_vecInlineBreaks.add(bp);
+ continue;
+ }
+
+ inlineLC.setHyphContext(
+ getHyphenContext(m_prevBP, bp));
+ if (inlineLC.getHyphContext() == null)
+ break;
+ inlineLC.setFlags(LayoutContext.TRY_HYPHENATE,
+ true);
+ // Reset to previous acceptable break
+ reset();
+ }
+ /* If we are not in justified text, we can end the line at
+ * prevBP.
+ */
+ else {
+ break;
+ }
+ } else {
+ // Add the BP to the list whether or not we can break
+ m_vecInlineBreaks.add(bp);
+ // Handle end of this LM's areas
+ if (bBreakOK) {
+ m_prevBP = bp; // Save reference to this BP
+ if (bp.isForcedBreak()) {
+ break;
+ }
+ if (bpDim.max >= availIPD.min) {
+ /* This is a possible line BP (line could be filled)
+ * bpDim.max >= availIPD.min
+ * Keep this as a possible break, depending on
+ * "cost". We will choose lowest cost.
+ * Cost depends on stretch
+ * (ie, bpDim.opt closes to availIPD.opt), keeps
+ * and hyphenation.
+ */
+ vecPossEnd.add( new BreakCost(bp,
+ Math.abs(availIPD.opt - bpDim.opt)));
+ }
+ // Otherwise it's short
+ } else {
+ /* Can't end line here. */
+ }
+ } // end of bpDim.min <= availIPD.max
+ } // end of getNextBreakPoss!=null on current child LM
+ else {
+ /* The child LM can return a null BreakPoss if it has
+ * nothing (more) to layout. This can happen when backing
+ * up. Just try the next child LM.
+ */
+ }
+ if (inlineLC.tryHyphenate() &&
+ !inlineLC.getHyphContext().hasMoreHyphPoints()) {
+ break;
+ }
+ } // end of while on child LM
+ if ((curLM = getChildLM()) == null) {
+ // No more content to layout!
+ setFinished(true);
+ }
+
+ if (bp == null)
+ return null;
+ if (m_prevBP == null)
+ m_prevBP = bp;
+
+ // Choose the best break
+ if (!bp.isForcedBreak() && vecPossEnd.size() > 0) {
+ m_prevBP = getBestBP(vecPossEnd);
+ }
+ // Backup child LM if necessary
+ if (bp != m_prevBP && !bp.couldEndLine()) {
+ reset();
}
+ // Distribute space in the line
+ MinOptMax actual;
+ if (bp != m_prevBP) {
+ MinOptMax mom = getPrevIPD(m_prevBP.getLayoutManager());
+ if (mom != null) {
+ actual = MinOptMax.add(m_prevBP.getStackingSize(), mom);
+ } else {
+ actual = m_prevBP.getStackingSize();
+ }
} else {
actual = m_prevBP.getStackingSize();
}
- // ATTENTION: make sure this hasn't gotten start space for next
- // LM added onto it!
- actual.add(m_prevBP.resolveTrailingSpace(true));
- System.err.println("Target opt=" + availIPD.opt +
- " bp.opt=" + actual.opt + " bp.max=" + actual.max
- + " bm.min=" + actual.min);
-
- // Don't justify last line in the sequence or if forced line-end
- boolean bJustify = (m_bJustify && !m_prevBP.isForcedBreak() &&
- !isFinished());
+ // ATTENTION: make sure this hasn't gotten start space for next
+ // LM added onto it!
+ actual.add(m_prevBP.resolveTrailingSpace(true));
+ System.err.println("Target opt=" + availIPD.opt + " bp.opt=" +
+ actual.opt + " bp.max=" + actual.max + " bm.min=" +
+ actual.min);
+
+ // Don't justify last line in the sequence or if forced line-end
+ boolean bJustify = (m_bJustify && !m_prevBP.isForcedBreak() &&
+ !isFinished());
return makeLineBreak(m_prevBP, availIPD, actual, bJustify);
}
private void reset() {
- while (m_vecInlineBreaks.lastElement()!=m_prevBP) {
- m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1);
- }
- reset(m_prevBP.getPosition());
+ while (m_vecInlineBreaks.lastElement() != m_prevBP) {
+ m_vecInlineBreaks.remove(m_vecInlineBreaks.size() - 1);
+ }
+ reset(m_prevBP.getPosition());
}
protected boolean couldEndLine(BreakPoss bp) {
- if (bp.canBreakAfter()) {
- return true; // no keep, ends on break char
- }
- else if (bp.isSuppressible()) {
- // NOTE: except at end of content for this LM!!
- // Never break after only space chars or any other sequence
- // of areas which would be suppressed at the end of the line.
- return false;
- }
- else {
- // See if could break before next area
- // TODO: do we need to set anything on the layout context?
- LayoutContext lc=new LayoutContext(0);
- BPLayoutManager nextLM = getChildLM();
- return (nextLM == null ||
- nextLM.canBreakBefore(lc));
- }
+ if (bp.canBreakAfter()) {
+ return true; // no keep, ends on break char
+ } else if (bp.isSuppressible()) {
+ // NOTE: except at end of content for this LM!!
+ // Never break after only space chars or any other sequence
+ // of areas which would be suppressed at the end of the line.
+ return false;
+ } else {
+ // See if could break before next area
+ // TODO: do we need to set anything on the layout context?
+ LayoutContext lc = new LayoutContext(0);
+ BPLayoutManager nextLM = getChildLM();
+ return (nextLM == null || nextLM.canBreakBefore(lc));
+ }
}
private BreakPoss getBestBP(Vector vecPossEnd) {
- if (vecPossEnd.size()==1) {
- return ((BreakCost)vecPossEnd.elementAt(0)).getBP();
- }
- // Choose the best break (use a sort on cost!)
- Iterator iter = vecPossEnd.iterator();
- int minCost= Integer.MAX_VALUE;
- BreakPoss bestBP = null;
- while (iter.hasNext()) {
- BreakCost bc = (BreakCost)iter.next();
- if (bc.getCost() < minCost) {
- minCost = bc.getCost();
- bestBP = bc.getBP();
- }
- }
- return bestBP;
+ if (vecPossEnd.size() == 1) {
+ return ((BreakCost) vecPossEnd.elementAt(0)).getBP();
+ }
+ // Choose the best break (use a sort on cost!)
+ Iterator iter = vecPossEnd.iterator();
+ int minCost = Integer.MAX_VALUE;
+ BreakPoss bestBP = null;
+ while (iter.hasNext()) {
+ BreakCost bc = (BreakCost) iter.next();
+ if (bc.getCost() < minCost) {
+ minCost = bc.getCost();
+ bestBP = bc.getBP();
+ }
+ }
+ return bestBP;
}
/** Line area is always considered to act as a fence. */
protected boolean hasLeadingFence(boolean bNotFirst) {
- return true;
+ return true;
}
-
+
/** Line area is always considered to act as a fence. */
protected boolean hasTrailingFence(boolean bNotLast) {
- return true;
+ return true;
}
-
-
-
- private HyphContext getHyphenContext(BreakPoss prevBP, BreakPoss newBP) {
- // Get a "word" to hyphenate by getting characters from all
- // pending break poss which are in m_vecInlineBreaks, starting
- // with the position just AFTER prevBP.getPosition()
-
- m_vecInlineBreaks.add(newBP);
- ListIterator bpIter = m_vecInlineBreaks.
- listIterator(m_vecInlineBreaks.size());
- while (bpIter.hasPrevious() && bpIter.previous() != prevBP);
- if (bpIter.next() != prevBP) {
- System.err.println("findHyphenPoss: problem!");
- return null;
- }
- StringBuffer sbChars = new StringBuffer(30);
- while (bpIter.hasNext()) {
- BreakPoss bp = (BreakPoss)bpIter.next();
- if (bp.getLayoutManager() == prevBP.getLayoutManager()) {
- bp.getLayoutManager().getWordChars(sbChars, prevBP.getPosition(),
- bp.getPosition());
- }
- else {
- bp.getLayoutManager().getWordChars(sbChars, null, bp.getPosition());
- }
- prevBP = bp;
- }
- m_vecInlineBreaks.remove(m_vecInlineBreaks.size()-1); // remove last
- System.err.println("Word to hyphenate: " + sbChars.toString());
-
- // Now find all hyphenation points in this word (get in an array of offsets)
- // hyphProps are from the block level?. Note that according to the spec,
- // they also "apply to" fo:character. I don't know what that means, since
- // if we change language in the middle of a "word", the effect would seem
- // quite strange! Or perhaps in that case, we say that it's several words.
- // We probably should bring the hyphenation props up from the actual
- // TextLM which generate the hyphenation buffer, since these properties
- // inherit and could be specified on an inline or wrapper below the block
- // level.
- Hyphenation hyph =
- Hyphenator.hyphenate(m_hyphProps.language, m_hyphProps.country,
- sbChars.toString(),
- m_hyphProps.hyphenationRemainCharacterCount,
- m_hyphProps.hyphenationPushCharacterCount);
- // They hyph structure contains the information we need
- // Now start from prevBP: reset to that position, ask that LM to get
- // a Position for the first hyphenation offset. If the offset isn't in
- // its characters, it returns null, but must tell how many chars it had.
- // Keep looking at currentBP using next hyphenation point until the
- // returned size is greater than the available size or no more hyphenation
- // points remain. Choose the best break.
- if (hyph != null) {
- return new HyphContext(hyph.getHyphenationPoints());
- }
- else return null;
+
+
+
+ private HyphContext getHyphenContext(BreakPoss prevBP,
+ BreakPoss newBP) {
+ // Get a "word" to hyphenate by getting characters from all
+ // pending break poss which are in m_vecInlineBreaks, starting
+ // with the position just AFTER prevBP.getPosition()
+
+ m_vecInlineBreaks.add(newBP);
+ ListIterator bpIter =
+ m_vecInlineBreaks. listIterator(m_vecInlineBreaks.size());
+ while (bpIter.hasPrevious() && bpIter.previous() != prevBP)
+ ;
+ if (bpIter.next() != prevBP) {
+ System.err.println("findHyphenPoss: problem!");
+ return null;
+ }
+ StringBuffer sbChars = new StringBuffer(30);
+ while (bpIter.hasNext()) {
+ BreakPoss bp = (BreakPoss) bpIter.next();
+ if (bp.getLayoutManager() == prevBP.getLayoutManager()) {
+ bp.getLayoutManager().getWordChars(sbChars,
+ prevBP.getPosition(), bp.getPosition());
+ } else {
+ bp.getLayoutManager().getWordChars(sbChars, null,
+ bp.getPosition());
+ }
+ prevBP = bp;
+ }
+ m_vecInlineBreaks.remove(m_vecInlineBreaks.size() - 1); // remove last
+ System.err.println("Word to hyphenate: " + sbChars.toString());
+
+ // Now find all hyphenation points in this word (get in an array of offsets)
+ // hyphProps are from the block level?. Note that according to the spec,
+ // they also "apply to" fo:character. I don't know what that means, since
+ // if we change language in the middle of a "word", the effect would seem
+ // quite strange! Or perhaps in that case, we say that it's several words.
+ // We probably should bring the hyphenation props up from the actual
+ // TextLM which generate the hyphenation buffer, since these properties
+ // inherit and could be specified on an inline or wrapper below the block
+ // level.
+ Hyphenation hyph = Hyphenator.hyphenate(m_hyphProps.language,
+ m_hyphProps.country, sbChars.toString(),
+ m_hyphProps.hyphenationRemainCharacterCount,
+ m_hyphProps.hyphenationPushCharacterCount);
+ // They hyph structure contains the information we need
+ // Now start from prevBP: reset to that position, ask that LM to get
+ // a Position for the first hyphenation offset. If the offset isn't in
+ // its characters, it returns null, but must tell how many chars it had.
+ // Keep looking at currentBP using next hyphenation point until the
+ // returned size is greater than the available size or no more hyphenation
+ // points remain. Choose the best break.
+ if (hyph != null) {
+ return new HyphContext(hyph.getHyphenationPoints());
+ } else
+ return null;
}
- private BreakPoss makeLineBreak(BreakPoss inlineBP, MinOptMax target,
- MinOptMax actual, boolean bJustify) {
+ private BreakPoss makeLineBreak(BreakPoss inlineBP,
+ MinOptMax target, MinOptMax actual, boolean bJustify) {
// make a new BP
- // Store information needed to make areas in the LineBreakPosition!
- // Calculate stretch or shrink factor
-
- double dAdjust=0.0;
- if (bJustify) {
- if (actual.opt < target.opt) {
- // Stretch
- dAdjust = (double)(target.opt - actual.opt)/
- (double)(actual.max - actual.opt);
- }
- else {
- // Shrink
- dAdjust = (double)(target.opt - actual.opt)/
- (double)( actual.opt - actual.min);
- }
- }
- System.err.println("Adjustment factor=" + dAdjust);
- BreakPoss curLineBP =
- new BreakPoss(new LineBreakPosition(this, m_vecInlineBreaks.size()-1,
- dAdjust));
-
- /* FIX ME!!
- * Need to calculate line height based on all inline BP info
- * for this line not just the current inlineBP!
- */
- curLineBP.setFlag(BreakPoss.ISLAST, isFinished());
- curLineBP.setStackingSize(inlineBP.getNonStackingSize());
+ // Store information needed to make areas in the LineBreakPosition!
+ // Calculate stretch or shrink factor
+
+ double dAdjust = 0.0;
+ if (bJustify) {
+ if (actual.opt < target.opt) {
+ // Stretch
+ dAdjust = (double)(target.opt - actual.opt) /
+ (double)(actual.max - actual.opt);
+ } else {
+ // Shrink
+ dAdjust = (double)(target.opt - actual.opt) /
+ (double)(actual.opt - actual.min);
+ }
+ }
+ System.err.println("Adjustment factor=" + dAdjust);
+ BreakPoss curLineBP = new BreakPoss( new LineBreakPosition(this,
+ m_vecInlineBreaks.size() - 1, dAdjust));
+
+ /* FIX ME!!
+ * Need to calculate line height based on all inline BP info
+ * for this line not just the current inlineBP!
+ */
+ curLineBP.setFlag(BreakPoss.ISLAST, isFinished());
+ curLineBP.setStackingSize(inlineBP.getNonStackingSize());
return curLineBP;
}
+ public void addAreas(PositionIterator parentIter,
+ LayoutContext context) {
+ addAreas(parentIter, 0.0);
+ }
// Generate and add areas to parent area
// Set size etc
// dSpaceAdjust should reference extra space in the BPD
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();
- LineArea lineArea = new LineArea();
- setCurrentArea(lineArea);
- // Add the inline areas to lineArea
- PositionIterator inlinePosIter =
- new BreakPossPosIter(m_vecInlineBreaks,
- 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) {
- childLM.addAreas(inlinePosIter, lc);
- lc.setLeadingSpace(lc.getTrailingSpace());
- lc.setTrailingSpace(new SpaceSpecifier(false));
- }
- addSpace(lineArea, lc.getTrailingSpace().resolve(true),
- lc.getSpaceAdjust());
- lineArea.verticalAlign(lineHeight, lead, follow);
- parentLM.addChild(lineArea);
- }
- setCurrentArea(null); // ?? necessary
+ BPLayoutManager childLM ;
+ int iStartPos = 0;
+ LayoutContext lc = new LayoutContext(0);
+ while (parentIter.hasNext()) {
+ LineBreakPosition lbp = (LineBreakPosition) parentIter.next();
+ LineArea lineArea = new LineArea();
+ setCurrentArea(lineArea);
+ // Add the inline areas to lineArea
+ PositionIterator inlinePosIter =
+ new BreakPossPosIter(m_vecInlineBreaks, 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) {
+ childLM.addAreas(inlinePosIter, lc);
+ lc.setLeadingSpace(lc.getTrailingSpace());
+ lc.setTrailingSpace(new SpaceSpecifier(false));
+ }
+ addSpace(lineArea, lc.getTrailingSpace().resolve(true),
+ lc.getSpaceAdjust());
+ lineArea.verticalAlign(lineHeight, lead, follow);
+ parentLM.addChild(lineArea);
+ }
+ setCurrentArea(null); // ?? necessary
}
// NOTE: PATCHED FOR NOW TO ADD BreakPoss stuff to Kerion's changes
public boolean generateAreas() {
- // Make break positions and return lines!
- // Set up a LayoutContext
- int ipd = 0;
- BreakPoss bp;
- Vector vecBreakPoss = new Vector(20);
-
- // Force area creation on first call
- // NOTE: normally not necessary when fully integrated!
- LayoutContext childLC = new LayoutContext(LayoutContext.CHECK_REF_AREA);
-
- while (!isFinished()) {
- if ((bp = getNextBreakPoss(childLC, null)) != null) {
- if (bp.checkIPD()) {
- // Need IPD in order to layout lines!
- // This is supposed to bubble up to PageLM to
- // make the necessary flow reference area, depending
- // on span and break-before flags set as the BreakPoss
- // makes its way back up the call stack.
- // Fake it for now!
- parentLM.getParentArea(null);
- ipd = parentLM.getContentIPD();
- childLC.flags &= ~LayoutContext.CHECK_REF_AREA;
- childLC.setStackLimit(new MinOptMax(ipd - m_iIndents -
- m_iTextIndent));
- }
- else {
- vecBreakPoss.add(bp);
- // Reset stackLimit for non-first lines
- childLC.setStackLimit(new MinOptMax(ipd - m_iIndents));
- }
- }
+ // Make break positions and return lines!
+ // Set up a LayoutContext
+ int ipd = 0;
+ BreakPoss bp;
+ Vector vecBreakPoss = new Vector(20);
+
+ // Force area creation on first call
+ // NOTE: normally not necessary when fully integrated!
+ LayoutContext childLC =
+ new LayoutContext(LayoutContext.CHECK_REF_AREA);
+
+ while (!isFinished()) {
+ if ((bp = getNextBreakPoss(childLC, null)) != null) {
+ if (bp.checkIPD()) {
+ // Need IPD in order to layout lines!
+ // This is supposed to bubble up to PageLM to
+ // make the necessary flow reference area, depending
+ // on span and break-before flags set as the BreakPoss
+ // makes its way back up the call stack.
+ // Fake it for now!
+ parentLM.getParentArea(null);
+ ipd = parentLM.getContentIPD();
+ childLC.flags &= ~LayoutContext.CHECK_REF_AREA;
+ childLC.setStackLimit( new MinOptMax(ipd - m_iIndents -
+ m_iTextIndent));
+ } else {
+ vecBreakPoss.add(bp);
+ // Reset stackLimit for non-first lines
+ childLC.setStackLimit(new MinOptMax(ipd - m_iIndents));
+ }
+ }
}
- addAreas(new BreakPossPosIter(vecBreakPoss, 0, vecBreakPoss.size()), 0.0);
+ addAreas( new BreakPossPosIter(vecBreakPoss, 0,
+ vecBreakPoss.size()), 0.0);
return false;
}
// footnotes, floats?
}
- public LineLayoutManager(FObj fobjBlock, List lms, int lh, int l, int f) {
+ public LineLayoutManager(FObj fobjBlock, List lms, int lh, int l,
+ int f) {
super(fobjBlock);
lmList = lms;
lineHeight = lh;
private Position m_subPos ;
public NonLeafPosition(BPLayoutManager lm, Position subPos) {
- super(lm);
- m_subPos = subPos;
+ super(lm);
+ m_subPos = subPos;
}
public Position getPosition() {
- return m_subPos;
+ return m_subPos;
}
}
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.properties.Constants;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* LayoutManager for a PageSequence and its flow.
* It manages all page-related layout.
*/
-public class PageLayoutManager extends AbstractLayoutManager implements Runnable {
+public class PageLayoutManager extends AbstractBPLayoutManager implements Runnable {
+
+ private static class BlockBreakPosition extends LeafPosition {
+ List blockps;
+
+ BlockBreakPosition(BPLayoutManager lm, int iBreakIndex, List bps) {
+ super(lm, iBreakIndex);
+ blockps = bps;
+ }
+ }
/** True if haven't yet laid out any pages.*/
private boolean bFirstPage;
* rendering process can also run in a parallel thread.
*/
public void run() {
- generateAreas();
+ //generateAreas();
+ doLayout();
flush();
}
+ public void doLayout() {
+
+ //ArrayList vecBreakPoss = new ArrayList();
+
+ BreakPoss bp;
+ LayoutContext childLC = new LayoutContext(0);
+ while (!isFinished()) {
+ ArrayList vecBreakPoss = new ArrayList();
+ makeNewPage(false, false);
+ if ((bp = getNextBreakPoss(childLC, null)) != null) {
+ vecBreakPoss.add(bp);
+ addAreas( new BreakPossPosIter(vecBreakPoss, 0,
+ vecBreakPoss.size()), null);
+ }
+ }
+
+ //addAreas( new BreakPossPosIter(vecBreakPoss, 0,
+ // vecBreakPoss.size()), null);
+
+ }
+
+
+ public BreakPoss getNextBreakPoss(LayoutContext context,
+ Position prevLineBP) {
+
+ BPLayoutManager curLM ; // currently active LM
+
+ while ((curLM = getChildLM()) != null) {
+ // Make break positions and return lines!
+ // Set up a LayoutContext
+ int bpd = 0;
+ BreakPoss bp;
+ ArrayList vecBreakPoss = new ArrayList();
+
+ // Force area creation on first call
+ // NOTE: normally not necessary when fully integrated!
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimit(new MinOptMax(bpd));
+
+ if (!curLM.isFinished()) {
+ if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) {
+ vecBreakPoss.add(bp);
+ }
+ }
+System.out.println("BREAKS: " + vecBreakPoss.size());
+ return new BreakPoss(
+ new BlockBreakPosition(curLM, 0, vecBreakPoss));
+ }
+ setFinished(true);
+ return null;
+ }
+
+ public void addAreas(PositionIterator parentIter, LayoutContext lc) {
+
+ while (parentIter.hasNext()) {
+ BlockBreakPosition bbp = (BlockBreakPosition) parentIter.next();
+System.out.println("ADD BREAKS: " + bbp.blockps.size());
+ bbp.getLM().addAreas( new BreakPossPosIter(bbp.blockps, 0,
+ bbp.blockps.size()), null);
+ }
+ }
/**
* For now, only handle normal flow areas.
// The Flow LM sets the "finished" flag on the Flow Area if it has
// completely filled it. In this case, if on the last column
// end the page.
-
+getParentArea(area);
// Alternatively the child LM indicates to parent that it's full?
-System.out.println("size: " + area.getAllocationBPD().max + ":" + curSpan.getMaxBPD().min);
+ System.out.println("size: " + area.getAllocationBPD().max +
+ ":" + curSpan.getMaxBPD().min);
if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) {
// Consider it filled
if (curSpan.getColumnCount() == curSpanColumns) {
// else newpos = new MinOptMax();
curSpan = new Span(numCols);
// get Width or Height as IPD for span
- curSpan.setIPD((int) curPage.getPage(). getRegion(
- RegionReference.BODY).getViewArea().getWidth());
+ curSpan.setIPD( (int) curPage.getPage(). getRegion(
+ RegionReference.BODY).getViewArea().getWidth());
//curSpan.setPosition(BPD, newpos);
curBody.getMainReference().addSpan(curSpan);
private BPLayoutManager m_lm;
public Position(BPLayoutManager lm) {
- m_lm = lm;
+ m_lm = lm;
}
public BPLayoutManager getLM() {
- return m_lm;
+ return m_lm;
}
/**
* child LM.
*/
public Position getPosition() {
- return null;
+ return null;
}
}
import java.util.Iterator;
import java.util.NoSuchElementException;
-abstract class PositionIterator implements Iterator
-{
+abstract class PositionIterator implements Iterator {
Iterator m_parentIter;
Object m_nextObj;
BPLayoutManager m_childLM;
boolean m_bHasNext;
PositionIterator(Iterator parentIter) {
- m_parentIter = parentIter;
- lookAhead();
- //checkNext();
+ m_parentIter = parentIter;
+ lookAhead();
+ //checkNext();
}
BPLayoutManager getNextChildLM() {
- // Move to next "segment" of iterator, ie: new childLM
- if (m_childLM == null && m_nextObj != null) {
- m_childLM = getLM(m_nextObj);
- m_bHasNext = true;
- }
- return m_childLM;
+ // Move to next "segment" of iterator, ie: new childLM
+ if (m_childLM == null && m_nextObj != null) {
+ m_childLM = getLM(m_nextObj);
+ m_bHasNext = true;
+ }
+ return m_childLM;
}
abstract protected BPLayoutManager getLM(Object nextObj);
abstract protected Position getPos(Object nextObj);
private void lookAhead() {
- if (m_parentIter.hasNext()) {
- m_bHasNext = true;
- m_nextObj = m_parentIter.next();
- }
- else {
- endIter();
- }
+ if (m_parentIter.hasNext()) {
+ m_bHasNext = true;
+ m_nextObj = m_parentIter.next();
+ } else {
+ endIter();
+ }
}
protected boolean checkNext() {
- BPLayoutManager lm = getLM(m_nextObj);
- if (m_childLM==null) {
- m_childLM = lm;
- }
- else if (m_childLM != lm) {
- // End of this sub-sequence with same child LM
- m_bHasNext = false;
- m_childLM = null;
- return false;
- }
- return true;
+ BPLayoutManager lm = getLM(m_nextObj);
+ if (m_childLM == null) {
+ m_childLM = lm;
+ } else if (m_childLM != lm) {
+ // End of this sub-sequence with same child LM
+ m_bHasNext = false;
+ m_childLM = null;
+ return false;
+ }
+ return true;
}
protected void endIter() {
- m_bHasNext = false;
- m_nextObj = null;
- m_childLM = null;
+ m_bHasNext = false;
+ m_nextObj = null;
+ m_childLM = null;
}
public boolean hasNext() {
- return (m_bHasNext && checkNext());
+ return (m_bHasNext && checkNext());
}
public Object next() throws NoSuchElementException {
- if (m_bHasNext) {
- Object retObj = getPos(m_nextObj);
- lookAhead();
- return retObj;
- }
- else {
- throw new NoSuchElementException("PosIter");
- }
+ if (m_bHasNext) {
+ Object retObj = getPos(m_nextObj);
+ lookAhead();
+ return retObj;
+ } else {
+ throw new NoSuchElementException("PosIter");
+ }
}
protected Object peekNext() {
- return m_nextObj;
+ return m_nextObj;
}
public void remove() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("PositionIterator doesn't support remove");
+ throw new UnsupportedOperationException("PositionIterator doesn't support remove");
}
}
private boolean m_bStartsRefArea;
- private boolean m_bHasForcing=false;
+ private boolean m_bHasForcing = false;
private Vector m_vecSpaceVals = new Vector(3);
public SpaceSpecifier(boolean bStartsRefArea) {
- m_bStartsRefArea = bStartsRefArea;
+ m_bStartsRefArea = bStartsRefArea;
}
public Object clone() {
- try {
- SpaceSpecifier ss = (SpaceSpecifier)super.clone();
- // Clone the vector, but share the objects in it!
- ss.m_vecSpaceVals = new Vector(this.m_vecSpaceVals.size());
- ss.m_vecSpaceVals.addAll(this.m_vecSpaceVals);
- return ss;
- } catch (CloneNotSupportedException cnse) {
- return null;
- }
-
+ try {
+ SpaceSpecifier ss = (SpaceSpecifier) super.clone();
+ // Clone the vector, but share the objects in it!
+ ss.m_vecSpaceVals = new Vector(this.m_vecSpaceVals.size());
+ ss.m_vecSpaceVals.addAll(this.m_vecSpaceVals);
+ return ss;
+ } catch (CloneNotSupportedException cnse) {
+ return null;
+ }
+
}
/**
* Clear all space specifiers
*/
public void clear() {
- m_bHasForcing=false;
- m_vecSpaceVals.clear();
+ m_bHasForcing = false;
+ m_vecSpaceVals.clear();
}
/** Return true if any space-specifiers have been added. */
public boolean hasSpaces() {
- return (m_vecSpaceVals.size() > 0);
+ return (m_vecSpaceVals.size() > 0);
}
/**
* add it to the sequence.
*/
public void addSpace(SpaceVal moreSpace) {
- if (!m_bStartsRefArea || !moreSpace.bConditional ||
- !m_vecSpaceVals.isEmpty()) {
- if (moreSpace.bForcing) {
- if (m_bHasForcing == false) {
- // Remove all other values (must all be non-forcing)
- m_vecSpaceVals.clear();
- m_bHasForcing = true;
- }
- m_vecSpaceVals.add(moreSpace);
- }
- else if (m_bHasForcing==false) {
- // 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);
- }
- }
- }
+ if (!m_bStartsRefArea || !moreSpace.bConditional ||
+ !m_vecSpaceVals.isEmpty()) {
+ if (moreSpace.bForcing) {
+ if (m_bHasForcing == false) {
+ // Remove all other values (must all be non-forcing)
+ m_vecSpaceVals.clear();
+ m_bHasForcing = true;
+ }
+ m_vecSpaceVals.add(moreSpace);
+ } else if (m_bHasForcing == false) {
+ // 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);
+ }
+ }
+ }
}
* @return The resolved value as a min/opt/max triple.
*/
public MinOptMax resolve(boolean bEndsReferenceArea) {
- int lastIndex = m_vecSpaceVals.size();
- if (bEndsReferenceArea) {
- // Start from the end and count conditional specifiers
- // Stop at first non-conditional
- for (; lastIndex > 0; --lastIndex) {
- SpaceVal sval =
- (SpaceVal)m_vecSpaceVals.elementAt(lastIndex-1);
- if (!sval.bConditional) {
- break;
- }
- }
- }
- MinOptMax resSpace = new MinOptMax(0);
- int iMaxPrec = -1;
- for(int index=0; index < lastIndex; index++) {
- SpaceVal sval = (SpaceVal)m_vecSpaceVals.elementAt(index);
- if (m_bHasForcing) {
- resSpace.add(sval.space);
- }
- else if (sval.iPrecedence > iMaxPrec) {
- iMaxPrec = sval.iPrecedence;
- resSpace = sval.space;
- }
- else if (sval.iPrecedence == iMaxPrec) {
- if (sval.space.opt > resSpace.opt) {
- resSpace = sval.space;
- }
- else if (sval.space.opt == resSpace.opt) {
- if (resSpace.min < sval.space.min) {
- resSpace.min = sval.space.min;
- }
- if (resSpace.max > sval.space.max) {
- resSpace.max = sval.space.max;
- }
- }
- }
-
- }
- return resSpace;
+ int lastIndex = m_vecSpaceVals.size();
+ if (bEndsReferenceArea) {
+ // Start from the end and count conditional specifiers
+ // Stop at first non-conditional
+ for (; lastIndex > 0; --lastIndex) {
+ SpaceVal sval = (SpaceVal) m_vecSpaceVals.elementAt(
+ lastIndex - 1);
+ if (!sval.bConditional) {
+ break;
+ }
+ }
+ }
+ MinOptMax resSpace = new MinOptMax(0);
+ int iMaxPrec = -1;
+ for (int index = 0; index < lastIndex; index++) {
+ SpaceVal sval = (SpaceVal) m_vecSpaceVals.elementAt(index);
+ if (m_bHasForcing) {
+ resSpace.add(sval.space);
+ } else if (sval.iPrecedence > iMaxPrec) {
+ iMaxPrec = sval.iPrecedence;
+ resSpace = sval.space;
+ } else if (sval.iPrecedence == iMaxPrec) {
+ if (sval.space.opt > resSpace.opt) {
+ resSpace = sval.space;
+ } else if (sval.space.opt == resSpace.opt) {
+ if (resSpace.min < sval.space.min) {
+ resSpace.min = sval.space.min;
+ }
+ if (resSpace.max > sval.space.max) {
+ resSpace.max = sval.space.max;
+ }
+ }
+ }
+
+ }
+ return resSpace;
}
}
* Number of word-spaces?
*/
private class AreaInfo {
- short m_iStartIndex;
- short m_iBreakIndex;
- short m_iWScount;
- MinOptMax m_ipdArea;
- AreaInfo(short iStartIndex, short iBreakIndex, short iWScount,
- MinOptMax ipdArea) {
- m_iStartIndex = iStartIndex;
- m_iBreakIndex = iBreakIndex;
- m_iWScount = iWScount;
- m_ipdArea = ipdArea;
- }
+ short m_iStartIndex;
+ short m_iBreakIndex;
+ short m_iWScount;
+ MinOptMax m_ipdArea;
+ AreaInfo(short iStartIndex, short iBreakIndex, short iWScount,
+ MinOptMax ipdArea) {
+ m_iStartIndex = iStartIndex;
+ m_iBreakIndex = iBreakIndex;
+ m_iWScount = iWScount;
+ m_ipdArea = ipdArea;
+ }
}
private TextInfo textInfo;
private static final char NEWLINE = '\n';
- private static final char SPACE = '\u0020'; // Normal space
+ private static final char SPACE = '\u0020'; // Normal space
private static final char NBSPACE = '\u00A0'; // Non-breaking space
private static final char LINEBREAK = '\u2028';
private static final char ZERO_WIDTH_SPACE = '\u200B';
/** 1/2 of word-spacing value */
private SpaceVal m_halfWS;
/** Number of space characters after previous possible break position. */
- private int m_iNbSpacesPending;
+ private int m_iNbSpacesPending;
- public TextBPLayoutManager(FObj fobj, char[] chars,
- TextInfo textInfo) {
+ public TextBPLayoutManager(FObj fobj, char[] chars, TextInfo textInfo) {
super(fobj);
this.chars = chars;
this.textInfo = textInfo;
- this.m_vecAreaInfo = new Vector(chars.length/5); // Guess
+ this.m_vecAreaInfo = new Vector(chars.length / 5); // Guess
// With CID fonts, space isn't neccesary currentFontState.width(32)
m_spaceIPD = CharUtilities.getCharWidth(' ', textInfo.fs);
- // Use hyphenationChar property
+ // Use hyphenationChar property
m_hyphIPD = CharUtilities.getCharWidth('-', textInfo.fs);
- // Make half-space: <space> on either side of a word-space)
- SpaceVal ws = textInfo.wordSpacing;
- m_halfWS = new SpaceVal(MinOptMax.multiply(ws.space, 0.5),
- ws.bConditional, ws.bForcing,
- ws.iPrecedence);
+ // Make half-space: <space> on either side of a word-space)
+ SpaceVal ws = textInfo.wordSpacing;
+ m_halfWS = new SpaceVal(MinOptMax.multiply(ws.space, 0.5),
+ ws.bConditional, ws.bForcing, ws.iPrecedence);
}
* used in Keiron's implemenation, but not here (yet at least).
*/
public int size() {
- return 0;
+ return 0;
}
public InlineArea get(int index) {
}
- public void getWordChars(StringBuffer sbChars,
- Position bp1, Position bp2) {
- LeafPosition endPos = (LeafPosition)bp2;
- AreaInfo ai =
- (AreaInfo) m_vecAreaInfo.elementAt(endPos.getLeafPos());
- // Skip all leading spaces for hyphenation
- int i;
- for (i=ai.m_iStartIndex;i < ai.m_iBreakIndex &&
- CharUtilities.isAnySpace(chars[i])==true ;i++);
- sbChars.append(new String(chars, i, ai.m_iBreakIndex-i));
+ public void getWordChars(StringBuffer sbChars, Position bp1,
+ Position bp2) {
+ LeafPosition endPos = (LeafPosition) bp2;
+ AreaInfo ai =
+ (AreaInfo) m_vecAreaInfo.elementAt(endPos.getLeafPos());
+ // Skip all leading spaces for hyphenation
+ int i;
+ for (i = ai.m_iStartIndex; i < ai.m_iBreakIndex &&
+ CharUtilities.isAnySpace(chars[i]) == true ; i++)
+ ;
+ sbChars.append(new String(chars, i, ai.m_iBreakIndex - i));
}
/**
* Return true if the first character is a potential linebreak character.
*/
public boolean canBreakBefore(LayoutContext context) {
- char c = chars[m_iNextStart];
- return ((c == NEWLINE) || (textInfo.bWrap &&
- (CharUtilities.isSpace(c) || s_breakChars.indexOf(c)>=0)));
+ char c = chars[m_iNextStart];
+ return ((c == NEWLINE) || (textInfo.bWrap &&
+ (CharUtilities.isSpace(c) ||
+ s_breakChars.indexOf(c) >= 0)));
}
/** Reset position for returning next BreakPossibility. */
public void resetPosition(Position prevPos) {
- if (prevPos != null) {
- // 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.getLeafPos());
- if (ai.m_iBreakIndex != m_iNextStart) {
- m_iNextStart = ai.m_iBreakIndex;
- 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;
- setFinished(false);
- }
- }
- else {
- // Reset to beginning!
- m_vecAreaInfo.setSize(0);
- m_iNextStart = 0;
- setFinished(false);
- }
+ if (prevPos != null) {
+ // 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.getLeafPos());
+ if (ai.m_iBreakIndex != m_iNextStart) {
+ m_iNextStart = ai.m_iBreakIndex;
+ 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;
+ setFinished(false);
+ }
+ } else {
+ // Reset to beginning!
+ m_vecAreaInfo.setSize(0);
+ m_iNextStart = 0;
+ setFinished(false);
+ }
}
// TODO: see if we can use normal getNextBreakPoss for this with
// extra hyphenation information in LayoutContext
private boolean getHyphenIPD(HyphContext hc, MinOptMax hyphIPD) {
- // Skip leading word-space before calculating count?
- boolean bCanHyphenate = true;
- int iStopIndex = m_iNextStart + hc.getNextHyphPoint();
+ // Skip leading word-space before calculating count?
+ boolean bCanHyphenate = true;
+ int iStopIndex = m_iNextStart + hc.getNextHyphPoint();
- if (chars.length < iStopIndex || textInfo.bCanHyphenate==false ) {
- iStopIndex = chars.length;
- bCanHyphenate = false;
- }
- hc.updateOffset(iStopIndex - m_iNextStart);
+ if (chars.length < iStopIndex || textInfo.bCanHyphenate == false) {
+ iStopIndex = chars.length;
+ bCanHyphenate = false;
+ }
+ hc.updateOffset(iStopIndex - m_iNextStart);
for (; m_iNextStart < iStopIndex; m_iNextStart++) {
char c = chars[m_iNextStart];
- hyphIPD.opt += CharUtilities.getCharWidth(c, textInfo.fs);
- // letter-space?
- }
- // Need to include hyphen size too, but don't count it in the
- // stored running total, since it would be double counted
- // with later hyphenation points
- return bCanHyphenate;
+ hyphIPD.opt += CharUtilities.getCharWidth(c, textInfo.fs);
+ // letter-space?
+ }
+ // Need to include hyphen size too, but don't count it in the
+ // stored running total, since it would be double counted
+ // with later hyphenation points
+ return bCanHyphenate;
}
/**
* into spaces. A LINEFEED always forces a break.
*/
public BreakPoss getNextBreakPoss(LayoutContext context,
- Position prevPos) {
- /* On first call in a new Line, the START_AREA
- * flag in LC is set.
- */
+ Position prevPos) {
+ /* On first call in a new Line, the START_AREA
+ * flag in LC is set.
+ */
+
+ int iFlags = 0;
+
+ if (context.startsNewArea()) {
+ /* This could be first call on this LM, or the first call
+ * in a new (possible) LineArea.
+ */
+ m_ipdTotal = new MinOptMax(0);
+ iFlags |= BreakPoss.ISFIRST;
+ }
+
- int iFlags = 0;
+ /* HANDLE SUPPRESSED LEADING SPACES
+ * See W3C XSL Rec. 7.16.3.
+ * Suppress characters whose "suppress-at-line-break" property = "suppress"
+ * This can only be set on an explicit fo:character object. The default
+ * behavior is that U+0020 is suppressed; all other character codes are
+ * retained.
+ */
+ if (context.suppressLeadingSpace()) {
+ for (; m_iNextStart < chars.length &&
+ chars[m_iNextStart] == SPACE; m_iNextStart++)
+ ;
+ // If now at end, nothing to compose here!
+ if (m_iNextStart >= chars.length) {
+ setFinished(true);
+ return null; // Or an "empty" BreakPoss?
+ }
+ }
- if (context.startsNewArea()) {
- /* This could be first call on this LM, or the first call
- * in a new (possible) LineArea.
- */
- m_ipdTotal = new MinOptMax(0);
- iFlags |= BreakPoss.ISFIRST;
- }
+ /* Start of this "word", plus any non-suppressed leading space.
+ * Collapse any remaining word-space with leading space from
+ * ancestor FOs.
+ * Add up other leading space which is counted in the word IPD.
+ */
- /* HANDLE SUPPRESSED LEADING SPACES
- * See W3C XSL Rec. 7.16.3.
- * Suppress characters whose "suppress-at-line-break" property = "suppress"
- * This can only be set on an explicit fo:character object. The default
- * behavior is that U+0020 is suppressed; all other character codes are
- * retained.
- */
- if (context.suppressLeadingSpace()) {
- for (; m_iNextStart < chars.length &&
- chars[m_iNextStart]==SPACE; m_iNextStart++);
- // If now at end, nothing to compose here!
- if (m_iNextStart >= chars.length) {
- setFinished(true);
- return null; // Or an "empty" BreakPoss?
- }
- }
-
-
- /* Start of this "word", plus any non-suppressed leading space.
- * Collapse any remaining word-space with leading space from
- * ancestor FOs.
- * Add up other leading space which is counted in the word IPD.
- */
-
- SpaceSpecifier pendingSpace= new SpaceSpecifier(false);
+ SpaceSpecifier pendingSpace = new SpaceSpecifier(false);
short iThisStart = m_iNextStart; // Index of first character counted
MinOptMax spaceIPD = new MinOptMax(0); // Extra IPD from word-spacing
- // Sum of glyph IPD of all characters in a word, inc. leading space
+ // 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;
+ short iWScount = 0; // Count of word spaces
+ boolean bSawNonSuppressible = false;
for (; m_iNextStart < chars.length; m_iNextStart++) {
char c = chars[m_iNextStart];
- if (CharUtilities.isAnySpace(c)==false) break;
- if (c==SPACE || c==NBSPACE) {
- ++iWScount;
- // Counted as word-space
- if (m_iNextStart == iThisStart &&
- (iFlags & BreakPoss.ISFIRST) !=0 ) {
- // 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);
- spaceIPD.add(pendingSpace.resolve(false));
- }
- 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);
- }
- }
-
- if (m_iNextStart < chars.length) {
- spaceIPD.add(pendingSpace.resolve(false));
- }
- else {
- // This FO ended with spaces. Return the BP
- if (!bSawNonSuppressible) {
- iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB;
- }
- return makeBreakPoss(iThisStart, spaceIPD, wordIPD,
- context.getLeadingSpace(), pendingSpace,
- iFlags, iWScount);
- }
-
- if (context.tryHyphenate()) {
- // Get the size of the next syallable
- MinOptMax hyphIPD = new MinOptMax(0);
- if (getHyphenIPD(context.getHyphContext(), hyphIPD)) {
- iFlags |= (BreakPoss.CAN_BREAK_AFTER | BreakPoss.HYPHENATED);
- }
- wordIPD += hyphIPD.opt;
- }
- else {
- // Look for a legal line-break: breakable white-space and certain
- // characters such as '-' which can serve as word breaks.
- // Don't look for hyphenation points here though
- for (; m_iNextStart < chars.length; m_iNextStart++) {
- char c = chars[m_iNextStart];
- if ((c == NEWLINE) ||
- // Include any breakable white-space as break char
- // even if fixed width
- (textInfo.bWrap &&
- (CharUtilities.isSpace(c) ||
- s_breakChars.indexOf(c)>=0))) {
- iFlags |= BreakPoss.CAN_BREAK_AFTER;
- if (c != SPACE) {
- m_iNextStart++;
- if (c != NEWLINE) {
- wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
- }
- else {
- 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.getLeadingSpace(), null,
- iFlags, iWScount);
- }
- wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
- // Note, if a normal non-breaking space, is it stretchable???
- // If so, keep a count of these embedded spaces.
- }
- }
- return makeBreakPoss(iThisStart, spaceIPD, wordIPD,
- context.getLeadingSpace(), null, iFlags, iWScount);
+ if (CharUtilities.isAnySpace(c) == false)
+ break;
+ if (c == SPACE || c == NBSPACE) {
+ ++iWScount;
+ // Counted as word-space
+ if (m_iNextStart == iThisStart &&
+ (iFlags & BreakPoss.ISFIRST) != 0) {
+ // 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);
+ spaceIPD.add(pendingSpace.resolve(false));
+ }
+ 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);
+ }
+ }
+
+ if (m_iNextStart < chars.length) {
+ spaceIPD.add(pendingSpace.resolve(false));
+ } else {
+ // This FO ended with spaces. Return the BP
+ if (!bSawNonSuppressible) {
+ iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB;
+ }
+ return makeBreakPoss(iThisStart, spaceIPD, wordIPD,
+ context.getLeadingSpace(), pendingSpace, iFlags,
+ iWScount);
+ }
+
+ if (context.tryHyphenate()) {
+ // Get the size of the next syallable
+ MinOptMax hyphIPD = new MinOptMax(0);
+ if (getHyphenIPD(context.getHyphContext(), hyphIPD)) {
+ iFlags |= (BreakPoss.CAN_BREAK_AFTER |
+ BreakPoss.HYPHENATED);
+ }
+ wordIPD += hyphIPD.opt;
+ } else {
+ // Look for a legal line-break: breakable white-space and certain
+ // characters such as '-' which can serve as word breaks.
+ // Don't look for hyphenation points here though
+ for (; m_iNextStart < chars.length; m_iNextStart++) {
+ char c = chars[m_iNextStart];
+ if ((c == NEWLINE) || // Include any breakable white-space as break char
+ // even if fixed width
+ (textInfo.bWrap && (CharUtilities.isSpace(c) ||
+ s_breakChars.indexOf(c) >= 0))) {
+ iFlags |= BreakPoss.CAN_BREAK_AFTER;
+ if (c != SPACE) {
+ m_iNextStart++;
+ if (c != NEWLINE) {
+ wordIPD += CharUtilities.getCharWidth(c,
+ textInfo.fs);
+ } else {
+ 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.getLeadingSpace(), null, iFlags,
+ iWScount);
+ }
+ wordIPD += CharUtilities.getCharWidth(c, textInfo.fs);
+ // Note, if a normal non-breaking space, is it stretchable???
+ // If so, keep a count of these embedded spaces.
+ }
+ }
+ return makeBreakPoss(iThisStart, spaceIPD, wordIPD,
+ context.getLeadingSpace(), null, iFlags, iWScount);
}
- private BreakPoss makeBreakPoss(short iWordStart, MinOptMax spaceIPD,
- int wordDim, SpaceSpecifier leadingSpace,
- SpaceSpecifier trailingSpace,
- int flags, short iWScount)
- {
- MinOptMax ipd = new MinOptMax(wordDim);
- ipd.add(spaceIPD);
- if(m_ipdTotal != null) {
- ipd.add(m_ipdTotal); // sum of all words so far in line
+ private BreakPoss makeBreakPoss(short iWordStart,
+ MinOptMax spaceIPD, int wordDim,
+ SpaceSpecifier leadingSpace, SpaceSpecifier trailingSpace,
+ int flags, short iWScount) {
+ MinOptMax ipd = new MinOptMax(wordDim);
+ ipd.add(spaceIPD);
+ if (m_ipdTotal != null) {
+ ipd.add(m_ipdTotal); // sum of all words so far in line
+ }
+ // Note: break position now stores total size to here
+
+ // 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(
+ 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!
+ bp.setStackingSize(
+ MinOptMax.add(ipd, new MinOptMax(m_hyphIPD)));
+ } else {
+ bp.setStackingSize(ipd);
+ }
+ // TODO: make this correct (see Keiron's vertical alignment code)
+ bp.setNonStackingSize(new MinOptMax(textInfo.lineHeight));
+
+ /* Set max ascender and descender (offset from baseline),
+ * used for calculating the bpd of the line area containing
+ * this text.
+ */
+ //bp.setDescender(textInfo.fs.getDescender());
+ //bp.setAscender(textInfo.fs.getAscender());
+ if (m_iNextStart == chars.length) {
+ flags |= BreakPoss.ISLAST;
+ setFinished(true);
+ }
+ bp.setFlag(flags);
+ if (trailingSpace != null) {
+ bp.setTrailingSpace(trailingSpace);
+ } else {
+ bp.setTrailingSpace(new SpaceSpecifier(false));
+ }
+ if (leadingSpace != null) {
+ bp.setLeadingSpace(leadingSpace);
+ } else {
+ bp.setLeadingSpace(new SpaceSpecifier(false));
}
- // Note: break position now stores total size to here
-
- // 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(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!
- bp.setStackingSize(MinOptMax.add(ipd, new MinOptMax(m_hyphIPD)));
- }
- else {
- bp.setStackingSize(ipd);
- }
- // TODO: make this correct (see Keiron's vertical alignment code)
- bp.setNonStackingSize(new MinOptMax(textInfo.lineHeight));
-
- /* Set max ascender and descender (offset from baseline),
- * used for calculating the bpd of the line area containing
- * this text.
- */
- //bp.setDescender(textInfo.fs.getDescender());
- //bp.setAscender(textInfo.fs.getAscender());
- if (m_iNextStart == chars.length) {
- flags |= BreakPoss.ISLAST;
- setFinished(true);
- }
- bp.setFlag(flags);
- if (trailingSpace != null) {
- bp.setTrailingSpace(trailingSpace);
- }
- else {
- bp.setTrailingSpace(new SpaceSpecifier(false));
- }
- if (leadingSpace != null) {
- bp.setLeadingSpace(leadingSpace);
- }
- else {
- bp.setLeadingSpace(new SpaceSpecifier(false));
- }
return bp;
}
* in order to justify the line.
*/
public void addAreas(PositionIterator posIter, LayoutContext context) {
- // Add word areas
- AreaInfo ai=null ;
- int iStart = -1;
- int iWScount = 0;
-
- /* On first area created, add any leading space.
- * Calculate word-space stretch value.
- */
- while (posIter.hasNext()) {
- LeafPosition tbpNext = (LeafPosition)posIter.next();
- ai = (AreaInfo)m_vecAreaInfo.elementAt(tbpNext.getLeafPos());
- if (iStart == -1) {
- iStart = ai.m_iStartIndex;
- }
- iWScount += ai.m_iWScount;
- }
- // 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));
- 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));
- iAdjust = (int)((double)(ai.m_ipdArea.opt - ai.m_ipdArea.min) *
- dSpaceAdjust);
- }
-// 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),
- ai.m_ipdArea.opt + iAdjust);
- 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);
+ // Add word areas
+ AreaInfo ai = null ;
+ int iStart = -1;
+ int iWScount = 0;
+
+ /* On first area created, add any leading space.
+ * Calculate word-space stretch value.
+ */
+ while (posIter.hasNext()) {
+ LeafPosition tbpNext = (LeafPosition) posIter.next();
+ ai = (AreaInfo) m_vecAreaInfo.elementAt(tbpNext.getLeafPos());
+ if (iStart == -1) {
+ iStart = ai.m_iStartIndex;
+ }
+ iWScount += ai.m_iWScount;
+ }
+ // 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));
+ 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));
+ iAdjust = (int)((double)(ai.m_ipdArea.opt -
+ ai.m_ipdArea.min) * dSpaceAdjust);
+ }
+ // 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),
+ ai.m_ipdArea.opt + iAdjust);
+ 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);
}
protected Word createWord(String str, int width) {
Word curWordArea = new Word();
curWordArea.setWidth(width);
- curWordArea.setHeight(textInfo.fs.getAscender() - textInfo.fs.getDescender());
+ curWordArea.setHeight(textInfo.fs.getAscender() -
+ textInfo.fs.getDescender());
curWordArea.setOffset(textInfo.fs.getAscender());
curWordArea.info = new LayoutInfo();
curWordArea.info.lead = textInfo.fs.getAscender();
curWordArea.setWord(str);
curWordArea.addTrait(Trait.FONT_NAME, textInfo.fs.getFontName());
- curWordArea.addTrait(Trait.FONT_SIZE, new Integer(textInfo.fs.getFontSize()));
+ curWordArea.addTrait(Trait.FONT_SIZE,
+ new Integer(textInfo.fs.getFontSize()));
return curWordArea;
}
protected static final int WHITESPACE = 1;
protected static final int TEXT = 2;
- public TextLayoutManager(FObj fobj, char[] chars,
- TextInfo textInfo) {
+ public TextLayoutManager(FObj fobj, char[] chars, TextInfo textInfo) {
super(fobj);
this.chars = chars;
this.textInfo = textInfo;
public InlineArea get(int index) {
parseChars();
- return (InlineArea)words.get(index);
+ return (InlineArea) words.get(index);
}
/**
}
protected void parseChars() {
- if(chars == null) {
+ if (chars == null) {
return;
}
- int whitespaceWidth;
+ int whitespaceWidth;
// With CID fonts, space isn't neccesary currentFontState.width(32)
whitespaceWidth = CharUtilities.getCharWidth(' ', textInfo.fs);
int spaceWidth = 0;
int prev = NOTHING;
- int i = 0;
+ int i = 0;
/* iterate over each character */
for (; i < chars.length; i++) {
// spaces. Split the word and add Space
// as necessary. All spaces inside the word
// Have a fixed width.
- words.add(createWord(new String(chars, wordStart + 1,
- wordLength), wordWidth));
+ words.add( createWord(
+ new String(chars, wordStart + 1,
+ wordLength), wordWidth));
// reset word width
wordWidth = 0;
wordLength = chars.length - 1 - wordStart;
}
- words.add(createWord(new String(chars, wordStart + 1, wordLength), wordWidth));
+ words.add( createWord(
+ new String(chars, wordStart + 1, wordLength),
+ wordWidth));
}
chars = null;
protected Word createWord(String str, int width) {
Word curWordArea = new Word();
curWordArea.setWidth(width);
- curWordArea.setHeight(textInfo.fs.getAscender() - textInfo.fs.getDescender());
+ curWordArea.setHeight(textInfo.fs.getAscender() -
+ textInfo.fs.getDescender());
curWordArea.setOffset(textInfo.fs.getAscender());
curWordArea.info = new LayoutInfo();
curWordArea.info.lead = textInfo.fs.getAscender();
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));
- }
+ 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, bNotFirst,
+ BorderAndPadding.START, Trait.BORDER_START);
- addBorderTrait(area, bpProps, bNotLast, BorderAndPadding.END,
- Trait.BORDER_END);
+ addBorderTrait(area, bpProps, bNotLast, BorderAndPadding.END,
+ Trait.BORDER_END);
- addBorderTrait(area, bpProps, false, BorderAndPadding.BEFORE,
- Trait.BORDER_BEFORE);
+ addBorderTrait(area, bpProps, false, BorderAndPadding.BEFORE,
+ Trait.BORDER_BEFORE);
- addBorderTrait(area, bpProps, false, BorderAndPadding.AFTER,
- Trait.BORDER_AFTER);
+ 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)));
- }
+ 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)));
+ }
}
}