a few more convenience accessors to PV. This will give us a little more flexibility in which LM's we place functionality. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198629 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_90-alpha1
/** | /** | ||||
* Add a span area to this area. | * Add a span area to this area. | ||||
* | * | ||||
* @param span the span area to add | |||||
* @param spanAll whether to make a single-column span | |||||
*/ | */ | ||||
public Span createSpan(boolean spanAll) { | public Span createSpan(boolean spanAll) { | ||||
RegionViewport rv = parent.getRegionViewport(); | RegionViewport rv = parent.getRegionViewport(); |
* Create a page viewport. | * Create a page viewport. | ||||
* @param spm SimplePageMaster indicating the page and region dimensions | * @param spm SimplePageMaster indicating the page and region dimensions | ||||
*/ | */ | ||||
public PageViewport(SimplePageMaster spm) { | |||||
public PageViewport(SimplePageMaster spm, String pageStr) { | |||||
this.spm = spm; | this.spm = spm; | ||||
int pageWidth = spm.getPageWidth().getValue(); | int pageWidth = spm.getPageWidth().getValue(); | ||||
int pageHeight = spm.getPageHeight().getValue(); | int pageHeight = spm.getPageHeight().getValue(); | ||||
pageNumberString = pageStr; | |||||
viewArea = new Rectangle(0, 0, pageWidth, pageHeight); | viewArea = new Rectangle(0, 0, pageWidth, pageHeight); | ||||
page = new Page(spm); | page = new Page(spm); | ||||
} | } | ||||
* @param p Page Reference Area | * @param p Page Reference Area | ||||
* @param bounds Page Viewport dimensions | * @param bounds Page Viewport dimensions | ||||
*/ | */ | ||||
public PageViewport(SimplePageMaster spm, Page p, Rectangle2D bounds) { | |||||
public PageViewport(SimplePageMaster spm, String pageStr, Page p, Rectangle2D bounds) { | |||||
this.spm = spm; | this.spm = spm; | ||||
this.pageNumberString = pageStr; | |||||
this.page = p; | this.page = p; | ||||
this.viewArea = bounds; | this.viewArea = bounds; | ||||
} | } | ||||
/** | |||||
* Convenience method to get BodyRegion of this PageViewport | |||||
* @return BodyRegion object | |||||
*/ | |||||
public BodyRegion getBodyRegion() { | |||||
return (BodyRegion) getPage().getRegionViewport( | |||||
Constants.FO_REGION_BODY).getRegionReference(); | |||||
} | |||||
/** | |||||
* Convenience method to create a new Span for this | |||||
* this PageViewport. | |||||
* | |||||
* @param spanAll whether this is a single-column span | |||||
* @return Span object created | |||||
*/ | |||||
public Span createSpan(boolean spanAll) { | |||||
return getBodyRegion().getMainReference().createSpan(spanAll); | |||||
} | |||||
/** | |||||
* Convenience method to get the span-reference-area currently | |||||
* being processed | |||||
* | |||||
* @return span currently being processed. | |||||
*/ | |||||
public Span getCurrentSpan() { | |||||
return getBodyRegion().getMainReference().getCurrentSpan(); | |||||
} | |||||
/** | /** | ||||
* Set if this viewport should clip. | * Set if this viewport should clip. | ||||
* @param c true if this viewport should clip | * @param c true if this viewport should clip | ||||
return page; | return page; | ||||
} | } | ||||
/** | |||||
* Set the page number for this page. | |||||
* @param num the string representing the page number | |||||
*/ | |||||
public void setPageNumberString(String num) { | |||||
pageNumberString = num; | |||||
} | |||||
/** | /** | ||||
* Get the page number of this page. | * Get the page number of this page. | ||||
* @return the string that represents this page | * @return the string that represents this page | ||||
*/ | */ | ||||
public Object clone() { | public Object clone() { | ||||
Page p = (Page)page.clone(); | Page p = (Page)page.clone(); | ||||
PageViewport ret = new PageViewport(spm, p, (Rectangle2D)viewArea.clone()); | |||||
PageViewport ret = new PageViewport(spm, pageNumberString, | |||||
p, (Rectangle2D)viewArea.clone()); | |||||
return ret; | return ret; | ||||
} | } | ||||
public SimplePageMaster getSPM() { | public SimplePageMaster getSPM() { | ||||
return spm; | return spm; | ||||
} | } | ||||
/** | |||||
* Convenience method to get BodyRegion of this PageViewport | |||||
* @return BodyRegion object | |||||
*/ | |||||
public BodyRegion getBodyRegion() { | |||||
return (BodyRegion) getPage().getRegionViewport( | |||||
Constants.FO_REGION_BODY).getRegionReference(); | |||||
} | |||||
/** | |||||
* Convenience method to create a new Span for this | |||||
* this PageViewport. | |||||
* | |||||
* @param spanAll whether this is a single-column span | |||||
* @return Span object created | |||||
*/ | |||||
public Span createSpan(boolean spanAll) { | |||||
return getBodyRegion().getMainReference().createSpan(spanAll); | |||||
} | |||||
/** | |||||
* Convenience method to get the span-reference-area currently | |||||
* being processed | |||||
* | |||||
* @return span currently being processed. | |||||
*/ | |||||
public Span getCurrentSpan() { | |||||
return getBodyRegion().getMainReference().getCurrentSpan(); | |||||
} | |||||
/** | |||||
* Convenience method to get the normal-flow-reference-area | |||||
* currently being processed | |||||
* | |||||
* @return span currently being processed. | |||||
*/ | |||||
public NormalFlow getCurrentFlow() { | |||||
return getCurrentSpan().getCurrentFlow(); | |||||
} | |||||
/** | |||||
* Convenience method to increment the Span to the | |||||
* next NormalFlow to be processed, and to return that flow. | |||||
* | |||||
* @return the next NormalFlow in the Span. | |||||
*/ | |||||
public NormalFlow moveToNextFlow() { | |||||
return getCurrentSpan().moveToNextFlow(); | |||||
} | |||||
} | } |
private int colCount; | private int colCount; | ||||
private int colGap; | private int colGap; | ||||
private int colWidth; // width for each normal flow, calculated value | private int colWidth; // width for each normal flow, calculated value | ||||
private int curFlowIdx; // n-f-r-a currently being processed, zero-based | |||||
/** | /** | ||||
* Create a span area with the number of columns for this span area. | * Create a span area with the number of columns for this span area. | ||||
* | * | ||||
this.colCount = colCount; | this.colCount = colCount; | ||||
this.colGap = colGap; | this.colGap = colGap; | ||||
this.ipd = ipd; | this.ipd = ipd; | ||||
curFlowIdx = 0; | |||||
createNormalFlows(); | createNormalFlows(); | ||||
} | } | ||||
" available."); | " available."); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Get the NormalFlow area currently being processed | |||||
* | |||||
* @return the current NormalFlow | |||||
*/ | |||||
public NormalFlow getCurrentFlow() { | |||||
return getNormalFlow(curFlowIdx); | |||||
} | |||||
/** | |||||
* Indicate to the Span that the next column is being | |||||
* processed. | |||||
* | |||||
* @return the new NormalFlow (in the next column) | |||||
*/ | |||||
public NormalFlow moveToNextFlow() { | |||||
if (hasMoreFlows()) { | |||||
curFlowIdx++; | |||||
return getNormalFlow(curFlowIdx); | |||||
} else { | |||||
throw new IllegalStateException("(Internal error.)" + | |||||
" No more flows left in span."); | |||||
} | |||||
} | |||||
/** | |||||
* Indicates if the Span has unprocessed flows. | |||||
* | |||||
* @return true if Span can increment to the next flow, | |||||
* false otherwise. | |||||
*/ | |||||
public boolean hasMoreFlows() { | |||||
return (curFlowIdx < colCount-1); | |||||
} | |||||
} | } | ||||
*/ | */ | ||||
private PageViewport curPV = null; | private PageViewport curPV = null; | ||||
/** | |||||
* Zero-based index of column (Normal Flow) in span (of the PV) | |||||
* being filled. See XSL Rec description of fo:region-body | |||||
* and fop.Area package classes for more information. | |||||
*/ | |||||
private int curFlowIdx = -1; | |||||
/** | /** | ||||
* The FlowLayoutManager object, which processes | * The FlowLayoutManager object, which processes | ||||
* the single fo:flow of the fo:page-sequence | * the single fo:flow of the fo:page-sequence | ||||
//algorithm so we have a BPD and IPD. This may subject to change later when we | //algorithm so we have a BPD and IPD. This may subject to change later when we | ||||
//start handling more complex cases. | //start handling more complex cases. | ||||
if (!firstPart) { | if (!firstPart) { | ||||
if (curFlowIdx < curPV.getCurrentSpan().getColumnCount()-1) { | |||||
curFlowIdx++; | |||||
if (curPV.getCurrentSpan().hasMoreFlows()) { | |||||
curPV.getCurrentSpan().moveToNextFlow(); | |||||
} else { | } else { | ||||
// if this is the first page that will be created by | // if this is the first page that will be created by | ||||
// the current BlockSequence, it could have a break | // the current BlockSequence, it could have a break | ||||
+ spm.getMasterName() + "'. FOP presently " | + spm.getMasterName() + "'. FOP presently " | ||||
+ "does not support this."); | + "does not support this."); | ||||
} | } | ||||
curPV = new PageViewport(spm); | |||||
curPV = new PageViewport(spm, pageNumberString); | |||||
} catch (FOPException fopex) { | } catch (FOPException fopex) { | ||||
throw new IllegalArgumentException("Cannot create page: " + fopex.getMessage()); | throw new IllegalArgumentException("Cannot create page: " + fopex.getMessage()); | ||||
} | } | ||||
curPV.setPageNumberString(pageNumberString); | |||||
if (log.isDebugEnabled()) { | if (log.isDebugEnabled()) { | ||||
log.debug("[" + curPV.getPageNumberString() + (bIsBlank ? "*" : "") + "]"); | log.debug("[" + curPV.getPageNumberString() + (bIsBlank ? "*" : "") + "]"); | ||||
} | } | ||||
curPV.createSpan(false); | curPV.createSpan(false); | ||||
curFlowIdx = 0; | |||||
return curPV; | return curPV; | ||||
} | } | ||||
log.debug("page finished: " + curPV.getPageNumberString() | log.debug("page finished: " + curPV.getPageNumberString() | ||||
+ ", current num: " + currentPageNum); | + ", current num: " + currentPageNum); | ||||
curPV = null; | curPV = null; | ||||
curFlowIdx = -1; | |||||
} | } | ||||
/** | /** | ||||
int aclass = childArea.getAreaClass(); | int aclass = childArea.getAreaClass(); | ||||
if (aclass == Area.CLASS_NORMAL) { | if (aclass == Area.CLASS_NORMAL) { | ||||
return curPV.getCurrentSpan().getNormalFlow(curFlowIdx); | |||||
return curPV.getCurrentFlow(); | |||||
} else if (aclass == Area.CLASS_BEFORE_FLOAT) { | } else if (aclass == Area.CLASS_BEFORE_FLOAT) { | ||||
return curPV.getBodyRegion().getBeforeFloat(); | return curPV.getBodyRegion().getBeforeFloat(); | ||||
} else if (aclass == Area.CLASS_FOOTNOTE) { | } else if (aclass == Area.CLASS_FOOTNOTE) { | ||||
} | } | ||||
/** | /** | ||||
* Depending on the kind of break condition, make new column | |||||
* Depending on the kind of break condition, move to next column | |||||
* or page. May need to make an empty page if next page would | * or page. May need to make an empty page if next page would | ||||
* not have the desired "handedness". | * not have the desired "handedness". | ||||
* @param breakVal - value of break-before or break-after trait. | * @param breakVal - value of break-before or break-after trait. | ||||
*/ | */ | ||||
private void handleBreakTrait(int breakVal) { | private void handleBreakTrait(int breakVal) { | ||||
if (breakVal == Constants.EN_COLUMN) { | if (breakVal == Constants.EN_COLUMN) { | ||||
if (curFlowIdx < curPV.getCurrentSpan().getColumnCount()) { | |||||
// Move to next column | |||||
curFlowIdx++; | |||||
if (curPV.getCurrentSpan().hasMoreFlows()) { | |||||
curPV.getCurrentSpan().moveToNextFlow(); | |||||
} else { | } else { | ||||
curPV = makeNewPage(false, false, false); | curPV = makeNewPage(false, false, false); | ||||
} | } |