From e17e45b0924c5af3a443cf0ae52199df2df326ab Mon Sep 17 00:00:00 2001 From: Glen Mazza Date: Sat, 1 Nov 2003 04:28:02 +0000 Subject: [PATCH] Layout changed to account for fo:region-body borders and padding when determining printable width and height for each page. Various method nitpicks also fixed. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196974 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/area/Page.java | 4 +- .../fop/layoutmgr/PageLayoutManager.java | 62 ++++++++++++++++--- .../fop/layoutmgr/TextLayoutManager.java | 55 ++++++++-------- .../apache/fop/render/AbstractRenderer.java | 10 +-- .../apache/fop/render/pdf/PDFRenderer.java | 8 +-- .../org/apache/fop/tools/AreaTreeBuilder.java | 10 +-- src/java/org/apache/fop/traits/MinOptMax.java | 3 + .../org/apache/fop/util/CharUtilities.java | 8 +-- 8 files changed, 105 insertions(+), 55 deletions(-) diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java index f5cda397f..b55af90bc 100644 --- a/src/java/org/apache/fop/area/Page.java +++ b/src/java/org/apache/fop/area/Page.java @@ -83,7 +83,7 @@ public class Page implements Serializable, Cloneable { * @param areaclass the area class of the region to set * @param port the region viewport to set */ - public void setRegion(int areaclass, RegionViewport port) { + public void setRegionViewport(int areaclass, RegionViewport port) { if (areaclass == Region.BEFORE_CODE) { regionBefore = port; } else if (areaclass == Region.START_CODE) { @@ -103,7 +103,7 @@ public class Page implements Serializable, Cloneable { * @param areaclass the region area class * @return the region viewport or null if none */ - public RegionViewport getRegion(int areaclass) { + public RegionViewport getRegionViewport(int areaclass) { if (areaclass == Region.BEFORE_CODE) { return regionBefore; } else if (areaclass == Region.START_CODE) { diff --git a/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java index 9861423c5..00899dc6e 100644 --- a/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java @@ -67,6 +67,7 @@ import org.apache.fop.area.Span; import org.apache.fop.area.BeforeFloat; import org.apache.fop.area.Footnote; import org.apache.fop.area.Resolveable; +import org.apache.fop.area.Trait; import org.apache.fop.datatypes.FODimension; @@ -78,12 +79,12 @@ import org.apache.fop.fo.pagination.Region; import org.apache.fop.fo.properties.RetrieveBoundary; import org.apache.fop.fo.pagination.SimplePageMaster; import org.apache.fop.fo.pagination.StaticContent; - import org.apache.fop.fo.properties.CommonBackground; import org.apache.fop.fo.properties.CommonBorderAndPadding; import org.apache.fop.fo.properties.CommonMarginBlock; import org.apache.fop.fo.properties.Constants; import org.apache.fop.fo.properties.Overflow; +import org.apache.fop.traits.BorderProps; import java.util.ArrayList; import java.util.List; @@ -471,10 +472,32 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable } curPage.setPageNumber(getCurrentPageNumber()); - RegionViewport reg = curPage.getPage().getRegion( + RegionViewport rv = curPage.getPage().getRegionViewport( Region.BODY_CODE); - curBody = (BodyRegion) reg.getRegion(); - flowBPD = (int)reg.getViewArea().getHeight(); + curBody = (BodyRegion) rv.getRegion(); + flowBPD = (int) rv.getViewArea().getHeight(); + + // adjust flowBPD for borders and padding + BorderProps bps = (BorderProps) rv.getTrait(Trait.BORDER_BEFORE); + if (bps != null) { + flowBPD -= bps.width; + } + + bps = (BorderProps) rv.getTrait(Trait.BORDER_AFTER); + if (bps != null) { + flowBPD -= bps.width; + } + + java.lang.Integer padWidth = (java.lang.Integer) rv.getTrait(Trait.PADDING_BEFORE); + if (padWidth != null) { + flowBPD -= padWidth.intValue(); + } + + padWidth = (java.lang.Integer) rv.getTrait(Trait.PADDING_AFTER); + if (padWidth != null) { + flowBPD -= padWidth.intValue(); + } + return curPage; } @@ -486,7 +509,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable if (flow == null) { return; } - RegionViewport reg = curPage.getPage().getRegion(regionClass); + RegionViewport reg = curPage.getPage().getRegionViewport(regionClass); reg.getRegion().setIPD((int)reg.getViewArea().getWidth()); if (reg == null) { getLogger().error("no region viewport: shouldn't happen"); @@ -710,9 +733,32 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable //else newpos = new MinOptMax(); curSpan = new Span(numCols); // get Width or Height as IPD for span - curSpan.setIPD((int) curPage.getPage().getRegion( - Region.BODY_CODE).getViewArea().getWidth()); + + RegionViewport rv = curPage.getPage().getRegionViewport(Region.BODY_CODE); + int ipdWidth = (int) rv.getViewArea().getWidth(); + + // adjust IPD for borders and padding + BorderProps bps = (BorderProps) rv.getTrait(Trait.BORDER_START); + if (bps != null) { + ipdWidth -= bps.width; + } + + bps = (BorderProps) rv.getTrait(Trait.BORDER_END); + if (bps != null) { + ipdWidth -= bps.width; + } + java.lang.Integer padWidth = (java.lang.Integer) rv.getTrait(Trait.PADDING_START); + if (padWidth != null) { + ipdWidth -= padWidth.intValue(); + } + + padWidth = (java.lang.Integer) rv.getTrait(Trait.PADDING_END); + if (padWidth != null) { + ipdWidth -= padWidth.intValue(); + } + + curSpan.setIPD(ipdWidth); //curSpan.setPosition(BPD, newpos); curBody.getMainReference().addSpan(curSpan); createFlow(); @@ -803,7 +849,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable } else { rvp.setRegion(makeRegionReferenceArea(r, rvp.getViewArea())); } - page.setRegion(r.getRegionClassCode(), rvp); + page.setRegionViewport(r.getRegionClassCode(), rvp); if (r.getRegionClassCode() == Region.BODY_CODE) { bHasBody = true; } diff --git a/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java index d10be582f..7b36f3b3b 100644 --- a/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java @@ -107,7 +107,7 @@ public class TextLayoutManager extends AbstractLayoutManager { /** Start index of first character in this parent Area */ private short iAreaStart = 0; - /** Start index of next "word" */ + /** Start index of next TextArea */ private short iNextStart = 0; /** Size since last makeArea call, except for last break */ private MinOptMax ipdTotal; @@ -187,7 +187,7 @@ public class TextLayoutManager extends AbstractLayoutManager { public boolean canBreakBefore(LayoutContext context) { char c = chars[iNextStart]; return ((c == NEWLINE) - || (textInfo.bWrap && (CharUtilities.isSpace(c) + || (textInfo.bWrap && (CharUtilities.isBreakableSpace(c) || BREAK_CHARS.indexOf(c) >= 0))); } @@ -296,10 +296,10 @@ public class TextLayoutManager extends AbstractLayoutManager { } - /* Start of this "word", plus any non-suppressed leading space. + /* Start of this TextArea, 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. + * Add up other leading space which is counted in the TextArea IPD. */ SpaceSpecifier pendingSpace = new SpaceSpecifier(false); @@ -375,7 +375,7 @@ public class TextLayoutManager extends AbstractLayoutManager { char c = chars[iNextStart]; if ((c == NEWLINE) || // Include any breakable white-space as break char // even if fixed width - (textInfo.bWrap && (CharUtilities.isSpace(c) + (textInfo.bWrap && (CharUtilities.isBreakableSpace(c) || BREAK_CHARS.indexOf(c) >= 0))) { iFlags |= BreakPoss.CAN_BREAK_AFTER; if (c != SPACE) { @@ -464,7 +464,7 @@ public class TextLayoutManager extends AbstractLayoutManager { /** * Generate and add areas to parent area. - * This can either generate an area for each "word" and each space, or + * This can either generate an area for each TextArea and each space, or * an area containing all text with a parameter controlling the size of * the word space. The latter is most efficient for PDF generation. * Set size of each area. @@ -474,7 +474,7 @@ public class TextLayoutManager extends AbstractLayoutManager { */ public void addAreas(PositionIterator posIter, LayoutContext context) { // Add word areas - AreaInfo ai = null ; + AreaInfo ai = null; int iStart = -1; int iWScount = 0; @@ -508,24 +508,25 @@ public class TextLayoutManager extends AbstractLayoutManager { iAdjust = (int)((double)(ai.ipdArea.opt - ai.ipdArea.min) * dSpaceAdjust); } - // System.err.println("Text adjustment factor = " + dSpaceAdjust + - // " total=" + iAdjust); +// System.err.println("\nText adjustment factor = " + dSpaceAdjust + +// " total=" + iAdjust + "; breakIndex = " + ai.iBreakIndex); // Make an area containing all characters between start and end. InlineArea word = null; int adjust = 0; - // ingnore newline character + + // ignore newline character if (chars[ai.iBreakIndex - 1] == NEWLINE) { adjust = 1; } String str = new String(chars, iStart, ai.iBreakIndex - iStart - adjust); + if (" ".equals(str)) { word = new Space(); word.setWidth(ai.ipdArea.opt + iAdjust); } else { - TextArea t = createText( - str, - ai.ipdArea.opt + iAdjust, context.getBaseline()); + TextArea t = createTextArea(str, ai.ipdArea.opt + iAdjust, + context.getBaseline()); if (iWScount > 0) { //getLogger().error("Adjustment per word-space= " + // iAdjust / iWScount); @@ -560,27 +561,27 @@ public class TextLayoutManager extends AbstractLayoutManager { /** * Create an inline word area. - * This creates a Word and sets up the various attributes. + * This creates a TextArea and sets up the various attributes. * - * @param str the string for the word - * @param width the width that the word uses + * @param str the string for the TextArea + * @param width the width that the TextArea uses * @param base the baseline position * @return the new word area */ - protected TextArea createText(String str, int width, int base) { - TextArea curWordArea = new TextArea(); - curWordArea.setWidth(width); - curWordArea.setHeight(textInfo.fs.getAscender() + protected TextArea createTextArea(String str, int width, int base) { + TextArea textArea = new TextArea(); + textArea.setWidth(width); + textArea.setHeight(textInfo.fs.getAscender() - textInfo.fs.getDescender()); - curWordArea.setOffset(textInfo.fs.getAscender()); - curWordArea.setOffset(base); + textArea.setOffset(textInfo.fs.getAscender()); + textArea.setOffset(base); - curWordArea.setTextArea(str); - curWordArea.addTrait(Trait.FONT_NAME, textInfo.fs.getFontName()); - curWordArea.addTrait(Trait.FONT_SIZE, + textArea.setTextArea(str); + textArea.addTrait(Trait.FONT_NAME, textInfo.fs.getFontName()); + textArea.addTrait(Trait.FONT_SIZE, new Integer(textInfo.fs.getFontSize())); - curWordArea.addTrait(Trait.COLOR, this.textInfo.color); - return curWordArea; + textArea.addTrait(Trait.COLOR, this.textInfo.color); + return textArea; } } diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index d15895319..39e18e33b 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -298,15 +298,15 @@ public abstract class AbstractRenderer extends AbstractLogEnabled decision is to have fo:region-body on top, hence it is rendered last here. */ RegionViewport viewport; - viewport = page.getRegion(Region.BEFORE_CODE); + viewport = page.getRegionViewport(Region.BEFORE_CODE); renderRegionViewport(viewport); - viewport = page.getRegion(Region.START_CODE); + viewport = page.getRegionViewport(Region.START_CODE); renderRegionViewport(viewport); - viewport = page.getRegion(Region.END_CODE); + viewport = page.getRegionViewport(Region.END_CODE); renderRegionViewport(viewport); - viewport = page.getRegion(Region.AFTER_CODE); + viewport = page.getRegionViewport(Region.AFTER_CODE); renderRegionViewport(viewport); - viewport = page.getRegion(Region.BODY_CODE); + viewport = page.getRegionViewport(Region.BODY_CODE); renderRegionViewport(viewport); } diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 5fa8ecdcb..d95073372 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -916,12 +916,12 @@ public class PDFRenderer extends PrintRenderer { // where previous line area failed to take up entire allocated space int rx = currentBlockIPPosition + IPMarginOffset; int bl = currentBPPosition + BPMarginOffset + text.getOffset(); - -/* System.out.println("BlockIP Position: " + currentBlockIPPosition + +/* + System.out.println("\nBlockIP Position: " + currentBlockIPPosition + "; currentBPPosition: " + currentBPPosition + "; offset: " + text.getOffset() + - "; Text = " + text.getTextArea()); */ - + "; Text = " + text.getTextArea()); +*/ // Set letterSpacing //float ls = fs.getLetterSpacing() / this.currentFontSize; //pdf.append(ls).append(" Tc\n"); diff --git a/src/java/org/apache/fop/tools/AreaTreeBuilder.java b/src/java/org/apache/fop/tools/AreaTreeBuilder.java index d0fe8f973..2259f2f5b 100644 --- a/src/java/org/apache/fop/tools/AreaTreeBuilder.java +++ b/src/java/org/apache/fop/tools/AreaTreeBuilder.java @@ -383,19 +383,19 @@ class TreeLoader extends AbstractLogEnabled { Node obj = childs.item(i); if (obj.getNodeName().equals("regionBefore")) { reg.setRegion(readRegion((Element) obj, Region.BEFORE_CODE)); - page.setRegion(Region.BEFORE_CODE, reg); + page.setRegionViewport(Region.BEFORE_CODE, reg); } else if (obj.getNodeName().equals("regionStart")) { reg.setRegion(readRegion((Element) obj, Region.START_CODE)); - page.setRegion(Region.START_CODE, reg); + page.setRegionViewport(Region.START_CODE, reg); } else if (obj.getNodeName().equals("regionBody")) { reg.setRegion(readRegion((Element) obj, Region.BODY_CODE)); - page.setRegion(Region.BODY_CODE, reg); + page.setRegionViewport(Region.BODY_CODE, reg); } else if (obj.getNodeName().equals("regionEnd")) { reg.setRegion(readRegion((Element) obj, Region.END_CODE)); - page.setRegion(Region.END_CODE, reg); + page.setRegionViewport(Region.END_CODE, reg); } else if (obj.getNodeName().equals("regionAfter")) { reg.setRegion(readRegion((Element) obj, Region.AFTER_CODE)); - page.setRegion(Region.AFTER_CODE, reg); + page.setRegionViewport(Region.AFTER_CODE, reg); } } diff --git a/src/java/org/apache/fop/traits/MinOptMax.java b/src/java/org/apache/fop/traits/MinOptMax.java index 114c4e03f..d748628a7 100644 --- a/src/java/org/apache/fop/traits/MinOptMax.java +++ b/src/java/org/apache/fop/traits/MinOptMax.java @@ -157,5 +157,8 @@ public class MinOptMax implements java.io.Serializable, Cloneable { max -= op.min; } + public String toString() { + return "MinOptMax: min=" + min + "; opt=" + opt + "; max=" + max; + } } diff --git a/src/java/org/apache/fop/util/CharUtilities.java b/src/java/org/apache/fop/util/CharUtilities.java index c03c407ba..c1ceb7c78 100644 --- a/src/java/org/apache/fop/util/CharUtilities.java +++ b/src/java/org/apache/fop/util/CharUtilities.java @@ -111,12 +111,12 @@ public class CharUtilities { /** * Helper method to determine if the character is a - * space with normal behaviour. Normal behaviour means that + * space with normal behavior. Normal behavior means that * it's not non-breaking. * @param c character to inspect * @return True if the character is a normal space */ - public static boolean isSpace(char c) { + public static boolean isBreakableSpace(char c) { return (c == ' ' || (c >= '\u2000' && c <= '\u200B')); // c == '\u2000' // en quad @@ -139,7 +139,7 @@ public class CharUtilities { * @param c character to check * @return True if the character is a nbsp */ - public static boolean isNBSP(char c) { + public static boolean isNonBreakableSpace(char c) { return (c == '\u00A0' // no-break space || c == '\u202F' // narrow no-break space @@ -153,7 +153,7 @@ public class CharUtilities { * @return True if the character represents any kind of space */ public static boolean isAnySpace(char c) { - boolean ret = (isSpace(c) || isNBSP(c)); + boolean ret = (isBreakableSpace(c) || isNonBreakableSpace(c)); return ret; } } -- 2.39.5