diff options
-rw-r--r-- | src/java/org/apache/fop/area/Page.java | 5 | ||||
-rw-r--r-- | src/java/org/apache/fop/area/RegionReference.java | 14 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java | 86 | ||||
-rw-r--r-- | status.xml | 4 | ||||
-rw-r--r-- | test/layoutengine/disabled-testcases.xml | 7 | ||||
-rw-r--r-- | test/layoutengine/standard-testcases/simple-page-master_borders_padding.xml | 136 |
6 files changed, 239 insertions, 13 deletions
diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java index 64a6db576..94a394014 100644 --- a/src/java/org/apache/fop/area/Page.java +++ b/src/java/org/apache/fop/area/Page.java @@ -126,6 +126,10 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { } else { rr = new RegionReference(r, rvp); } + // set borders and padding traits + // (a little extensions wrt what prescribed by the specs at 6.4.14) + TraitSetter.addBorders(rr, r.getCommonBorderPaddingBackground(), false, false, false, false, null); + TraitSetter.addPadding(rr, r.getCommonBorderPaddingBackground(), false, false, false, false, null); setRegionReferencePosition(rr, r, rvp.getViewArea()); rvp.setRegionReference(rr); setRegionViewport(r.getNameId(), rvp); @@ -289,3 +293,4 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable { } + diff --git a/src/java/org/apache/fop/area/RegionReference.java b/src/java/org/apache/fop/area/RegionReference.java index c41de7c7a..467aadd85 100644 --- a/src/java/org/apache/fop/area/RegionReference.java +++ b/src/java/org/apache/fop/area/RegionReference.java @@ -73,6 +73,18 @@ public class RegionReference extends Area implements Cloneable { blocks.add(child); } + /** {@inheritDoc} */ + public int getBPD() { + // subtract bpd of borders and padding before / after + return super.getBPD() - getBorderAndPaddingWidthBefore() - getBorderAndPaddingWidthAfter(); + } + + /** {@inheritDoc} */ + public int getIPD() { + // subtract ipd of borders and padding start / end + return super.getIPD() - getBorderAndPaddingWidthStart() - getBorderAndPaddingWidthEnd(); + } + /** * Set the Coordinate Transformation Matrix which transforms content * coordinates in this region reference area which are specified in @@ -133,7 +145,7 @@ public class RegionReference extends Area implements Cloneable { public void addBlock(Block block) { addChildArea(block); } - + /** * Clone this region. * This is used when cloning the page by the page master. diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index eb0668d8b..a6c08747f 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -38,6 +38,7 @@ import org.apache.fop.area.Block; import org.apache.fop.area.BlockViewport; import org.apache.fop.area.CTM; import org.apache.fop.area.NormalFlow; +import org.apache.fop.area.RegionReference; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.ForeignObject; @@ -96,19 +97,20 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { */ protected void handleRegionTraits(RegionViewport region) { Rectangle2D viewArea = region.getViewArea(); + RegionReference referenceArea = region.getRegionReference(); float startx = (float)(viewArea.getX() / 1000f); float starty = (float)(viewArea.getY() / 1000f); float width = (float)(viewArea.getWidth() / 1000f); float height = (float)(viewArea.getHeight() / 1000f); - if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) { - currentBPPosition = region.getBorderAndPaddingWidthBefore(); - currentIPPosition = region.getBorderAndPaddingWidthStart(); - } - drawBackAndBorders(region, startx, starty, width, height); + // adjust the current position according to region borders and padding + currentBPPosition = referenceArea.getBorderAndPaddingWidthBefore(); + currentIPPosition = referenceArea.getBorderAndPaddingWidthStart(); + // draw background (traits are in the RegionViewport) + // and borders (traits are in the RegionReference) + drawBackAndBorders(region, referenceArea, startx, starty, width, height); } - /** * Draw the background and borders. * This draws the background and border traits for an area given @@ -123,15 +125,57 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { protected void drawBackAndBorders(Area area, float startx, float starty, float width, float height) { + drawBackAndBorders(area, area, startx, starty, width, height); + } + + /** + * Draw the background and borders. + * This draws the background and border traits for an area given + * the position. + * + * @param backgroundArea the area to get the background traits from + * @param borderArea the area to get the border traits from + * @param startx the start x position + * @param starty the start y position + * @param width the width of the area + * @param height the height of the area + */ + protected void drawBackAndBorders(Area backgroundArea, Area borderArea, + float startx, float starty, + float width, float height) { // draw background then border - BorderProps bpsBefore = (BorderProps)area.getTrait(Trait.BORDER_BEFORE); - BorderProps bpsAfter = (BorderProps)area.getTrait(Trait.BORDER_AFTER); - BorderProps bpsStart = (BorderProps)area.getTrait(Trait.BORDER_START); - BorderProps bpsEnd = (BorderProps)area.getTrait(Trait.BORDER_END); + BorderProps bpsBefore = (BorderProps)borderArea.getTrait(Trait.BORDER_BEFORE); + BorderProps bpsAfter = (BorderProps)borderArea.getTrait(Trait.BORDER_AFTER); + BorderProps bpsStart = (BorderProps)borderArea.getTrait(Trait.BORDER_START); + BorderProps bpsEnd = (BorderProps)borderArea.getTrait(Trait.BORDER_END); - Trait.Background back; - back = (Trait.Background)area.getTrait(Trait.BACKGROUND); + drawBackground(startx, starty, width, height, + (Trait.Background) backgroundArea.getTrait(Trait.BACKGROUND), + bpsBefore, bpsAfter, bpsStart, bpsEnd); + drawBorders(startx, starty, width, height, + bpsBefore, bpsAfter, bpsStart, bpsEnd); + } + + /** + * Draw the background. + * This draws the background given the position and the traits. + * + * @param startx the start x position + * @param starty the start y position + * @param width the width of the area + * @param height the height of the area + * @param back the background traits + * @param bpsBefore the border-before traits + * @param bpsAfter the border-after traits + * @param bpsStart the border-start traits + * @param bpsEnd the border-end traits + */ + protected void drawBackground(float startx, float starty, + float width, float height, + Trait.Background back, + BorderProps bpsBefore, BorderProps bpsAfter, + BorderProps bpsStart, BorderProps bpsEnd) { if (back != null) { endTextObject(); @@ -202,7 +246,25 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { restoreGraphicsState(); } } + } + /** + * Draw the borders. + * This draws the border traits given the position and the traits. + * + * @param startx the start x position + * @param starty the start y position + * @param width the width of the area + * @param height the height of the area + * @param bpsBefore the border-before traits + * @param bpsAfter the border-after traits + * @param bpsStart the border-start traits + * @param bpsEnd the border-end traits + */ + protected void drawBorders(float startx, float starty, + float width, float height, + BorderProps bpsBefore, BorderProps bpsAfter, + BorderProps bpsStart, BorderProps bpsEnd) { Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height); drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd); } diff --git a/status.xml b/status.xml index cc345117f..20caa0e1a 100644 --- a/status.xml +++ b/status.xml @@ -53,6 +53,10 @@ <changes> <release version="FOP Trunk" date="TBD"> + <action context="Layout" dev="LF" type="add"> + Allowing non-zero borders and padding on page regions when + relaxed validation is turned on. + </action> <action context="Layout" dev="LF" type="fix"> Fixed an inconsistency in footnote handling that led to unnecessary empty areas in pages whose last normal line contains footnotes diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index ba985bf8d..ca05b156b 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -216,4 +216,11 @@ <description>A soft hyphen should be a preferred as break compared to a normal hyphenation point but is not.</description> </testcase> + <testcase> + <name>Borders and padding on page regions</name> + <file>simple-page-master_borders_padding.xml</file> + <description>Borders and padding on regions are now implemented but + relaxed validation must be switched on, otherwise there is a validation + exception.</description> + </testcase> </disabled-testcases> diff --git a/test/layoutengine/standard-testcases/simple-page-master_borders_padding.xml b/test/layoutengine/standard-testcases/simple-page-master_borders_padding.xml new file mode 100644 index 000000000..8ce6101a3 --- /dev/null +++ b/test/layoutengine/standard-testcases/simple-page-master_borders_padding.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<testcase> + <info> + <p> + This test checks page-masters (all regions). The empty block-containers are used to check that all the base widths are set correctly so + length evaluation using percentages is possible. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg"> + <fo:layout-master-set> + <fo:simple-page-master master-name="master1" page-width="5in" page-height="5in" margin="10pt"> + <fo:region-body background-color="rgb(100%, 100%, 80%)" margin="50pt" border-before-width="1pt" border-color="rgb(50%, 50%, 40%)" border-style="solid" border-end-width="2pt" border-after-width="3pt" border-start-width="4pt" padding-before="9pt" padding-end="8pt" padding-after="7pt" padding-start="6pt"/> + <fo:region-before background-color="rgb(100%, 80%, 80%)" border="solid 5pt rgb(50%, 40%, 40%)" extent="50pt"/> + <fo:region-after background-color="rgb(80%, 80%, 80%)" border="solid 1pt rgb(40%, 40%, 50%)" padding="3pt" extent="50pt" precedence="true" display-align="after"/> + <fo:region-start background-color="rgb(80%, 100%, 80%)" padding="3pt" extent="50pt"/> + <fo:region-end background-color="rgb(80%, 80%, 100%)" extent="50pt" reference-orientation="270"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="master1" white-space-collapse="true" orphans="0" widows="0"> + <fo:static-content flow-name="xsl-region-before"> + <fo:block-container absolute-position="absolute" width="100%" height="100%" top="0pt" left="0pt"> + <fo:block/> + </fo:block-container> + <fo:block>region-before1</fo:block> + </fo:static-content> + <fo:static-content flow-name="xsl-region-after"> + <fo:block-container absolute-position="absolute" width="100%" height="100%" top="0pt" left="0pt"> + <fo:block/> + </fo:block-container> + <fo:block font-size="50%">region-after1 with precedence and display-align="after"</fo:block> + </fo:static-content> + <fo:static-content flow-name="xsl-region-start"> + <fo:block-container absolute-position="absolute" width="100%" height="100%" top="0pt" left="0pt"> + <fo:block/> + </fo:block-container> + <fo:block>region-start1</fo:block> + </fo:static-content> + <fo:static-content flow-name="xsl-region-end"> + <fo:block-container absolute-position="absolute" width="100%" height="100%" top="0pt" left="0pt"> + <fo:block/> + </fo:block-container> + <fo:block>region-end1</fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container absolute-position="absolute" width="100%" height="100%" top="0pt" left="0pt"> + <fo:block/> + </fo:block-container> + <fo:block>testing all-regions1</fo:block> + <fo:block>testing all-regions2</fo:block> + <fo:block>testing all-regions3</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <eval expected="0 0 360000 360000" xpath="//pageViewport/@bounds"/> + + <eval expected="50000" xpath="//regionBefore/@bpda"/> + <eval expected="240000" xpath="//regionBefore/@ipda"/> + <eval expected="40000" xpath="//regionBefore/@bpd"/> + <eval expected="230000" xpath="//regionBefore/@ipd"/> + <eval expected="(solid,#806666,5000)" xpath="//regionBefore/@border-before"/> + <eval expected="(solid,#806666,5000)" xpath="//regionBefore/@border-after"/> + <eval expected="(solid,#806666,5000)" xpath="//regionBefore/@border-start"/> + <eval expected="(solid,#806666,5000)" xpath="//regionBefore/@border-end"/> + <eval expected="40000" xpath="//regionBefore/block[@positioning='absolute']/@bpda"/> + <eval expected="230000" xpath="//regionBefore/block[@positioning='absolute']/@ipda"/> + + <eval expected="50000" xpath="//regionAfter/@bpda"/> + <eval expected="340000" xpath="//regionAfter/@ipda"/> + <eval expected="42000" xpath="//regionAfter/@bpd"/> + <eval expected="332000" xpath="//regionAfter/@ipd"/> + <eval expected="(solid,#666680,1000)" xpath="//regionAfter/@border-before"/> + <eval expected="(solid,#666680,1000)" xpath="//regionAfter/@border-after"/> + <eval expected="(solid,#666680,1000)" xpath="//regionAfter/@border-start"/> + <eval expected="(solid,#666680,1000)" xpath="//regionAfter/@border-end"/> + <eval expected="3000" xpath="//regionAfter/@padding-before"/> + <eval expected="3000" xpath="//regionAfter/@padding-after"/> + <eval expected="3000" xpath="//regionAfter/@padding-start"/> + <eval expected="3000" xpath="//regionAfter/@padding-end"/> + <eval expected="42000" xpath="//regionAfter/block[@positioning='absolute']/@bpda"/> + <eval expected="332000" xpath="//regionAfter/block[@positioning='absolute']/@ipda"/> + + <eval expected="290000" xpath="//regionStart/@bpda"/> + <eval expected="50000" xpath="//regionStart/@ipda"/> + <eval expected="284000" xpath="//regionStart/@bpd"/> + <eval expected="44000" xpath="//regionStart/@ipd"/> + <eval expected="3000" xpath="//regionStart/@padding-before"/> + <eval expected="3000" xpath="//regionStart/@padding-after"/> + <eval expected="3000" xpath="//regionStart/@padding-start"/> + <eval expected="3000" xpath="//regionStart/@padding-end"/> + <eval expected="284000" xpath="//regionStart/block[@positioning='absolute']/@bpda"/> + <eval expected="44000" xpath="//regionStart/block[@positioning='absolute']/@ipda"/> + + <eval expected="50000" xpath="//regionEnd/@bpda"/> + <eval expected="290000" xpath="//regionEnd/@ipda"/> + <eval expected="50000" xpath="//regionEnd/@bpd"/> + <eval expected="290000" xpath="//regionEnd/@ipd"/> + <eval expected="50000" xpath="//regionEnd/block[@positioning='absolute']/@bpda"/> + <eval expected="290000" xpath="//regionEnd/block[@positioning='absolute']/@ipda"/> + + <eval expected="240000" xpath="//regionBody/@bpda"/> + <eval expected="240000" xpath="//regionBody/@ipda"/> + <eval expected="220000" xpath="//regionBody/@bpda"/> + <eval expected="220000" xpath="//regionBody/@ipda"/> + <eval expected="(solid,#808066,1000)" xpath="//regionBody/@border-before"/> + <eval expected="(solid,#808066,3000)" xpath="//regionBody/@border-after"/> + <eval expected="(solid,#808066,4000)" xpath="//regionBody/@border-start"/> + <eval expected="(solid,#808066,2000)" xpath="//regionBody/@border-end"/> + <eval expected="9000" xpath="//regionBody/@padding-before"/> + <eval expected="7000" xpath="//regionBody/@padding-after"/> + <eval expected="6000" xpath="//regionBody/@padding-start"/> + <eval expected="8000" xpath="//regionBody/@padding-end"/> + <eval expected="220000" xpath="//regionBody/mainReference/span/flow/block[@positioning='absolute']/@bpda"/> + <eval expected="220000" xpath="//regionBody/mainReference/span/flow/block[@positioning='absolute']/@ipda"/> + + </checks> +</testcase> |