* See if this ID is in the unresolved idref list, if so
* resolve Resolvable objects tied to it.
*/
- Set todo = (Set) unresolvedIDRefs.get(id);
- if (todo != null) {
- for (Iterator iter = todo.iterator(); iter.hasNext();) {
- Resolvable res = (Resolvable) iter.next();
- res.resolveIDRef(id, pvList);
- }
- unresolvedIDRefs.remove(id);
- }
+ tryIDResolution(id, pv, pvList);
} else {
pvList.add(pv);
}
}
+ /**
+ * Tries to resolve all unresolved ID references on the given page.
+ * @param id ID to resolve
+ * @param pv page viewport whose ID refs to resolve
+ * @param List of PageViewports
+ */
+ private void tryIDResolution(String id, PageViewport pv, List pvList) {
+ Set todo = (Set) unresolvedIDRefs.get(id);
+ if (todo != null) {
+ for (Iterator iter = todo.iterator(); iter.hasNext();) {
+ Resolvable res = (Resolvable) iter.next();
+ res.resolveIDRef(id, pvList);
+ }
+ unresolvedIDRefs.remove(id);
+ }
+ }
+
+ /**
+ * Tries to resolve all unresolved ID references on the given page.
+ * @param pv page viewport whose ID refs to resolve
+ */
+ public void tryIDResolution(PageViewport pv) {
+ String[] ids = pv.getIDRefs();
+ if (ids != null) {
+ for (int i = 0; i < ids.length; i++) {
+ List pvList = (List) idLocations.get(ids[i]);
+ if (pvList != null) {
+ tryIDResolution(ids[i], pv, pvList);
+ }
+ }
+ }
+ }
+
/**
* Get the list of page viewports that have an area with a given id.
* @param id the id to lookup
* inline area.
* This is used for vertical alignment.
* Subclasses should override this if necessary.
+ * @param area the inline area to be updated
* @param context the layout context used for adding the area
*/
- protected void offsetArea(LayoutContext context) {
- int bpd = curArea.getBPD();
+ protected void offsetArea(InlineArea area, LayoutContext context) {
+ int bpd = area.getBPD();
switch (verticalAlignment) {
case EN_MIDDLE:
- curArea.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2);
+ area.setOffset(context.getMiddleBaseline() + fs.getXHeight() / 2);
break;
case EN_TOP:
- curArea.setOffset(fs.getAscender());
+ area.setOffset(fs.getAscender());
break;
case EN_BOTTOM:
- curArea.setOffset(context.getLineHeight() - bpd + fs.getAscender());
+ area.setOffset(context.getLineHeight() - bpd + fs.getAscender());
break;
case EN_BASELINE:
default:
- curArea.setOffset(context.getBaseline());
+ area.setOffset(context.getBaseline());
break;
}
}
return false;
}
- /** @see org.apache.fop.layoutmgr.LayoutManager */
- public BreakPoss getNextBreakPoss(LayoutContext context) {
- return null;
- }
-
/** @see org.apache.fop.layoutmgr.LayoutManager */
public boolean isFinished() {
return false;
return leaderArea;
}
- protected void offsetArea(LayoutContext context) {
+ protected void offsetArea(InlineArea area, LayoutContext context) {
int pattern = fobj.getLeaderPattern();
- int bpd = curArea.getBPD();
+ int bpd = area.getBPD();
switch (pattern) {
case EN_RULE:
switch (verticalAlignment) {
case EN_TOP:
- curArea.setOffset(0);
+ area.setOffset(0);
break;
case EN_MIDDLE:
- curArea.setOffset(context.getMiddleBaseline() - bpd / 2);
+ area.setOffset(context.getMiddleBaseline() - bpd / 2);
break;
case EN_BOTTOM:
- curArea.setOffset(context.getLineHeight() - bpd);
+ area.setOffset(context.getLineHeight() - bpd);
break;
case EN_BASELINE: // fall through
default:
- curArea.setOffset(context.getBaseline() - bpd);
+ area.setOffset(context.getBaseline() - bpd);
break;
}
break;
case EN_DOTS:
switch (verticalAlignment) {
case EN_TOP:
- curArea.setOffset(0);
+ area.setOffset(0);
break;
case EN_MIDDLE:
- curArea.setOffset(context.getMiddleBaseline());
+ area.setOffset(context.getMiddleBaseline());
break;
case EN_BOTTOM:
- curArea.setOffset(context.getLineHeight() - bpd + font.getAscender());
+ area.setOffset(context.getLineHeight() - bpd + font.getAscender());
break;
case EN_BASELINE: // fall through
default:
- curArea.setOffset(context.getBaseline());
+ area.setOffset(context.getBaseline());
break;
}
break;
case EN_USECONTENT:
switch (verticalAlignment) {
case EN_TOP:
- curArea.setOffset(0);
+ area.setOffset(0);
break;
case EN_MIDDLE:
- curArea.setOffset(context.getMiddleBaseline());
+ area.setOffset(context.getMiddleBaseline());
break;
case EN_BOTTOM:
- curArea.setOffset(context.getLineHeight() - bpd);
+ area.setOffset(context.getLineHeight() - bpd);
break;
case EN_BASELINE: // fall through
default:
- curArea.setOffset(context.getBaseline());
+ area.setOffset(context.getBaseline());
break;
}
break;
} else {
addId();
- widthAdjustArea(context);
+ widthAdjustArea(curArea, context);
// add content areas
KnuthPossPosIter contentIter = new KnuthPossPosIter(contentList, 0, contentList.size());
clm.addAreas(contentIter, context);
- offsetArea(context);
+ offsetArea(curArea, context);
parentLM.addChildArea(curArea);
* This class can be extended to handle the creation and adding of the
* inline area.
*/
-public class LeafNodeLayoutManager extends AbstractLayoutManager
+public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
implements InlineLevelLayoutManager {
/**
* The inline area that this leafnode will add.
public void addAreas(PositionIterator posIter, LayoutContext context) {
addId();
- offsetArea(context);
- widthAdjustArea(context);
- parentLM.addChildArea(curArea);
+ InlineArea area = getEffectiveArea();
+ offsetArea(area, context);
+ widthAdjustArea(area, context);
+ parentLM.addChildArea(area);
while (posIter.hasNext()) {
posIter.next();
}
}
+ /**
+ * @return the effective area to be added to the area tree. Normally, this is simply "curArea"
+ * but in the case of page-number(-citation) curArea is cloned, updated and returned.
+ */
+ protected InlineArea getEffectiveArea() {
+ return curArea;
+ }
+
protected void addId() {
- // Do nothing here, overriden in subclasses that has a 'id' property.
+ // Do nothing here, overriden in subclasses that have an 'id' property.
}
/**
* inline area.
* This is used for vertical alignment.
* Subclasses should override this if necessary.
+ * @param area the inline area to be updated
* @param context the layout context used for adding the area
*/
- protected void offsetArea(LayoutContext context) {
- int bpd = curArea.getBPD();
+ protected void offsetArea(InlineArea area, LayoutContext context) {
+ int bpd = area.getBPD();
switch (verticalAlignment) {
case EN_MIDDLE:
- curArea.setOffset(context.getMiddleBaseline() - bpd / 2);
+ area.setOffset(context.getMiddleBaseline() - bpd / 2);
break;
case EN_TOP:
- curArea.setOffset(context.getTopBaseline());
+ area.setOffset(context.getTopBaseline());
break;
case EN_BOTTOM:
- curArea.setOffset(context.getBottomBaseline() - bpd);
+ area.setOffset(context.getBottomBaseline() - bpd);
break;
case EN_BASELINE:
default:
- curArea.setOffset(context.getBaseline() - bpd);
+ area.setOffset(context.getBaseline() - bpd);
break;
}
}
* Adjust the width of the area when adding.
* This uses the min/opt/max values to adjust the with
* of the inline area by a percentage.
+ * @param area the inline area to be updated
* @param context the layout context for adding this area
*/
- protected void widthAdjustArea(LayoutContext context) {
+ protected void widthAdjustArea(InlineArea area, LayoutContext context) {
double dAdjust = context.getIPDAdjust();
int width = areaInfo.ipdArea.opt;
if (dAdjust < 0) {
width = (int) (width + dAdjust * (areaInfo.ipdArea.max
- areaInfo.ipdArea.opt));
}
- curArea.setIPD(width);
+ area.setIPD(width);
}
/**
public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
private PageNumberCitation fobj;
- Font font = null;
+ private Font font = null;
// whether the page referred to by the citation has been resolved yet
private boolean resolved = false;
}
}
- protected void offsetArea(LayoutContext context) {
- curArea.setOffset(context.getBaseline());
+ protected void offsetArea(InlineArea area, LayoutContext context) {
+ area.setOffset(context.getBaseline());
}
/**
int width = getStringWidth(str);
text.setTextArea(str);
inline.setIPD(width);
- inline.setBPD(font.getAscender() - font.getDescender());
- inline.setOffset(font.getAscender());
- inline.addTrait(Trait.FONT_NAME, font.getFontName());
- inline.addTrait(Trait.FONT_SIZE,
- new Integer(font.getFontSize()));
resolved = true;
} else {
resolved = false;
String str = "MMM"; // reserve three spaces for page number
int width = getStringWidth(str);
inline.setIPD(width);
- inline.setBPD(font.getAscender() - font.getDescender());
- inline.setOffset(font.getAscender());
- inline.addTrait(Trait.FONT_NAME, font.getFontName());
- inline.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
}
+ inline.setBPD(font.getAscender() - font.getDescender());
+ inline.setOffset(font.getAscender());
+ inline.addTrait(Trait.FONT_NAME, font.getFontName());
+ inline.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
TraitSetter.addTextDecoration(inline, fobj.getTextDecoration());
return inline;
*/
public class PageNumberLayoutManager extends LeafNodeLayoutManager {
private PageNumber fobj;
- Font font = null;
+ private Font font = null;
/**
* Constructor
return inline;
}
- protected void offsetArea(LayoutContext context) {
- curArea.setOffset(context.getBaseline());
+ protected void offsetArea(InlineArea area, LayoutContext context) {
+ area.setOffset(context.getBaseline());
+ }
+
+ protected InlineArea getEffectiveArea() {
+ TextArea baseArea = (TextArea)curArea;
+ //TODO Maybe replace that with a clone() call or better, a copy constructor
+ //TODO or even better: delay area creation until addAreas() stage
+ //TextArea is cloned because the LM is reused in static areas and the area can't be.
+ TextArea ta = new TextArea();
+ ta.setIPD(baseArea.getIPD());
+ ta.setBPD(baseArea.getBPD());
+ ta.setOffset(baseArea.getOffset());
+ ta.addTrait(Trait.FONT_NAME, font.getFontName()); //only to initialize the trait map
+ ta.getTraits().putAll(baseArea.getTraits());
+ updateContent(ta);
+ return ta;
+ }
+
+ private void updateContent(TextArea area) {
+ area.setTextArea(getCurrentPV().getPageNumberString());
}
protected void addId() {
layoutSideRegion(FO_REGION_AFTER);
layoutSideRegion(FO_REGION_START);
layoutSideRegion(FO_REGION_END);
+
+ // Try to resolve any unresolved IDs for the current page.
+ //
+ areaTreeHandler.tryIDResolution(curPV);
// Queue for ID resolution and rendering
areaTreeHandler.getAreaTreeModel().addPage(curPV);
log.debug("page finished: " + curPV.getPageNumberString()