diff options
9 files changed, 266 insertions, 52 deletions
diff --git a/src/java/org/apache/fop/area/Block.java b/src/java/org/apache/fop/area/Block.java index 264a9e690..21fa7c49d 100644 --- a/src/java/org/apache/fop/area/Block.java +++ b/src/java/org/apache/fop/area/Block.java @@ -19,7 +19,6 @@ package org.apache.fop.area; -import java.util.ArrayList; // block areas hold either more block areas or line // areas can also be used as a block spacer @@ -59,6 +58,8 @@ public class Block extends BlockParent { private int stacking = TB; private int positioning = STACK; + protected transient boolean allowBPDUpdate = true; + // a block with may contain the dominant styling info in // terms of most lines or blocks with info @@ -78,7 +79,7 @@ public class Block extends BlockParent { * @param autoHeight increase the height of the block. */ public void addBlock(Block block, boolean autoHeight) { - if (autoHeight) { + if (autoHeight && allowBPDUpdate) { bpd += block.getAllocBPD(); } addChildArea(block); @@ -113,12 +114,20 @@ public class Block extends BlockParent { } /** + * Indicates whether this block is stacked, rather than absolutely positioned. + * @return true if it is stacked + */ + public boolean isStacked() { + return (getPositioning() == Block.STACK || getPositioning() == Block.RELATIVE); + } + + /** * @return the start-indent trait */ public int getStartIndent() { Integer startIndent = (Integer)getTrait(Trait.START_INDENT); return (startIndent != null ? startIndent.intValue() : 0); } - + } diff --git a/src/java/org/apache/fop/area/BlockViewport.java b/src/java/org/apache/fop/area/BlockViewport.java index af994afd4..167e7c5b3 100644 --- a/src/java/org/apache/fop/area/BlockViewport.java +++ b/src/java/org/apache/fop/area/BlockViewport.java @@ -34,6 +34,15 @@ public class BlockViewport extends Block { * Create a new block viewport area. */ public BlockViewport() { + this(false); + } + + /** + * Create a new block viewport area. + * @param allowBPDUpdate true allows the BPD to be updated when children are added + */ + public BlockViewport(boolean allowBPDUpdate) { + this.allowBPDUpdate = allowBPDUpdate; } /** diff --git a/src/java/org/apache/fop/area/NormalFlow.java b/src/java/org/apache/fop/area/NormalFlow.java index 715a61cb0..c9fc8380a 100644 --- a/src/java/org/apache/fop/area/NormalFlow.java +++ b/src/java/org/apache/fop/area/NormalFlow.java @@ -37,7 +37,9 @@ public class NormalFlow extends BlockParent { /** {@inheritDoc} */ public void addBlock(Block block) { super.addBlock(block); - bpd += block.getAllocBPD(); + if (block.isStacked()) { + bpd += block.getAllocBPD(); + } } } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index 3d9076efd..fc60b561e 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -65,7 +65,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager private int vpContentBPD; // When viewport should grow with the content. - private boolean autoHeight = true; + private boolean autoHeight = true; + private boolean inlineElementList = false; /* holds the (one-time use) fo:block space-before and -after properties. Large fo:blocks are split @@ -196,6 +197,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager return getNextKnuthElementsAbsolute(context, alignment); } + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); autoHeight = false; //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); int maxbpd = context.getStackLimit().opt; @@ -203,9 +206,13 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager if (height.getEnum() == EN_AUTO || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) { //auto height when height="auto" or "if that dimension is not specified explicitly - //(i.e., it depends on content's blockprogression-dimension)" (XSL 1.0, 7.14.1) + //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1) allocBPD = maxbpd; autoHeight = true; + if (getBlockContainerFO().getReferenceOrientation() == 0) { + //Cannot easily inline element list when ref-or="180" + inlineElementList = true; + } } else { allocBPD = height.getValue(this); //this is the content-height allocBPD += getBPIndents(); @@ -229,19 +236,14 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager contentRectOffsetY += getBlockContainerFO() .getCommonBorderPaddingBackground().getPaddingBefore(false, this); - Rectangle2D rect = new Rectangle2D.Double( - contentRectOffsetX, contentRectOffsetY, - getContentAreaIPD(), getContentAreaBPD()); - relDims = new FODimension(0, 0); - absoluteCTM = CTM.getCTMandRelDims(getBlockContainerFO().getReferenceOrientation(), - getBlockContainerFO().getWritingMode(), rect, relDims); + updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight); int availableIPD = referenceIPD - getIPIndents(); - if (rect.getWidth() > availableIPD) { + if (getContentAreaIPD() > availableIPD) { log.warn(FONode.decorateWithContextInfo( "The extent in inline-progression-direction (width) of a block-container is" + " bigger than the available space (" - + rect.getWidth() + "mpt > " + context.getRefIPD() + "mpt)", + + getContentAreaIPD() + "mpt > " + context.getRefIPD() + "mpt)", getBlockContainerFO())); } @@ -268,7 +270,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); firstVisibleMarkServed = true; - if (autoHeight) { + if (autoHeight && inlineElementList) { //Spaces, border and padding to be repeated at each break addPendingMarks(context); @@ -356,6 +358,16 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); breaker.doLayout(relDims.bpd, autoHeight); boolean contentOverflows = breaker.isOverflow(); + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.totalWidth; + if (switchedProgressionDirection) { + setContentAreaIPD(newHeight); + } else { + vpContentBPD = newHeight; + } + updateRelDims(contentRectOffsetX, contentRectOffsetY, false); + } Position bcPosition = new BlockContainerPosition(this, breaker); returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false)); @@ -385,6 +397,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager private LinkedList getNextKnuthElementsAbsolute(LayoutContext context, int alignment) { autoHeight = false; + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); Point offset = getAbsOffset(); int allocBPD, allocIPD; if (height.getEnum() == EN_AUTO @@ -432,7 +446,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } else { int maxbpd = context.getStackLimit().opt; allocBPD = maxbpd; - autoHeight = true; + if (!switchedProgressionDirection) { + autoHeight = true; + } } } else { allocBPD = height.getValue(this); //this is the content-height @@ -474,6 +490,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager */ allocIPD = 0; } + if (switchedProgressionDirection) { + autoHeight = true; + } } } else { allocIPD = width.getValue(this); //this is the content-width @@ -483,29 +502,29 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager vpContentBPD = allocBPD - getBPIndents(); setContentAreaIPD(allocIPD - getIPIndents()); - double contentRectOffsetX = 0; - double contentRectOffsetY = 0; - - Rectangle2D rect = new Rectangle2D.Double( - contentRectOffsetX, contentRectOffsetY, - getContentAreaIPD(), vpContentBPD); - relDims = new FODimension(0, 0); - absoluteCTM = CTM.getCTMandRelDims( - getBlockContainerFO().getReferenceOrientation(), - getBlockContainerFO().getWritingMode(), - rect, relDims); + updateRelDims(0, 0, autoHeight); MinOptMax range = new MinOptMax(relDims.ipd); BlockContainerBreaker breaker = new BlockContainerBreaker(this, range); breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight); boolean contentOverflows = breaker.isOverflow(); + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.totalWidth; + if (switchedProgressionDirection) { + setContentAreaIPD(newHeight); + } else { + vpContentBPD = newHeight; + } + updateRelDims(0, 0, false); + } LinkedList returnList = new LinkedList(); if (!breaker.isEmpty()) { Position bcPosition = new BlockContainerPosition(this, breaker); returnList.add(new KnuthBox(0, notifyPos(bcPosition), false)); //TODO Maybe check for page overflow when autoHeight=true - if (!autoHeight & (contentOverflows/*usedBPD > relDims.bpd*/)) { + if (!autoHeight & (contentOverflows)) { log.warn("Contents overflow block-container viewport: clipping"); if (getBlockContainerFO().getOverflow() == EN_ERROR_IF_OVERFLOW) { //TODO Throw layout exception @@ -516,6 +535,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager setFinished(true); return returnList; } + + private void updateRelDims(double xOffset, double yOffset, boolean skipAutoHeight) { + Rectangle2D rect = new Rectangle2D.Double( + xOffset, yOffset, + getContentAreaIPD(), + this.vpContentBPD); + relDims = new FODimension(0, 0); + absoluteCTM = CTM.getCTMandRelDims( + getBlockContainerFO().getReferenceOrientation(), + getBlockContainerFO().getWritingMode(), + rect, relDims); + } private class BlockContainerPosition extends NonLeafPosition { @@ -854,13 +885,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager */ public Area getParentArea(Area childArea) { if (referenceArea == null) { - viewportBlockArea = new BlockViewport(); + boolean switchedProgressionDirection + = (getBlockContainerFO().getReferenceOrientation() % 180 != 0); + boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection; + + viewportBlockArea = new BlockViewport(allowBPDUpdate); viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + viewportBlockArea.setIPD(getContentAreaIPD()); - if (autoHeight) { + if (allowBPDUpdate) { viewportBlockArea.setBPD(0); } else { - viewportBlockArea.setBPD(getContentAreaBPD()); + viewportBlockArea.setBPD(this.vpContentBPD); } transferForeignAttributes(viewportBlockArea); @@ -941,16 +977,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager getBlockContainerFO().getCommonBorderPaddingBackground(), this); - // Fake a 0 height for absolute positioned blocks. - int saveBPD = viewportBlockArea.getBPD(); - if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) { - viewportBlockArea.setBPD(0); - } super.flush(); - // Restore the right height. - if (viewportBlockArea.getPositioning() == Block.ABSOLUTE) { - viewportBlockArea.setBPD(saveBPD); - } } /** {@inheritDoc} */ diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 5f5672ae7..15ac8aa48 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -27,13 +27,6 @@ nominal line.</description> </testcase> <testcase> - <name>Bugzilla #36391: reference-orientation</name> - <file>block-container_reference-orientation_bug36391.xml</file> - <description>There's a problem involving nested block-containers - and reference-orientation 180/-180.</description> - <reference>http://issues.apache.org/bugzilla/show_bug.cgi?id=36391</reference> - </testcase> - <testcase> <name>Auto-height block-containers produce fences</name> <file>block-container_space-before_space-after_3.xml</file> <description>Block-containers with no height currently don't diff --git a/test/layoutengine/standard-testcases/block-container_absolute-position_display-align.xml b/test/layoutengine/standard-testcases/block-container_absolute-position_display-align.xml index 667d2a37c..42aaee529 100644 --- a/test/layoutengine/standard-testcases/block-container_absolute-position_display-align.xml +++ b/test/layoutengine/standard-testcases/block-container_absolute-position_display-align.xml @@ -56,6 +56,8 @@ </fo:root> </fo> <checks> + <eval expected="0" xpath="//flow/@bpd"/> <!-- all blocks are absolutely positioned --> + <!-- first block-container --> <true xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@is-viewport-area"/> <eval expected="[1.0 0.0 0.0 1.0 0.0 0.0]" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ctm"/> diff --git a/test/layoutengine/standard-testcases/block-container_absolute-position_no-height_2.xml b/test/layoutengine/standard-testcases/block-container_absolute-position_no-height_2.xml new file mode 100644 index 000000000..3c987fec8 --- /dev/null +++ b/test/layoutengine/standard-testcases/block-container_absolute-position_no-height_2.xml @@ -0,0 +1,84 @@ +<?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 absolutely positioned block-containers where the content-bpd isn't specified. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="normal"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container id="bc0" width="80pt" absolute-position="absolute" left="10pt" top="10pt" overflow="visible" + reference-orientation="0" background-color="lightgray"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block-container id="bc90" width="80pt" absolute-position="absolute" left="10pt" top="120pt" overflow="visible" + reference-orientation="90" background-color="lightgray"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block-container id="bc180" width="80pt" absolute-position="absolute" left="120pt" top="10pt" overflow="visible" + reference-orientation="180" background-color="lightgray"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block-container id="bc270" width="80pt" absolute-position="absolute" left="120pt" top="240pt" overflow="visible" + reference-orientation="270" background-color="lightgray"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <!-- 0 --> + <eval expected="80000" xpath="//block[@prod-id='bc0' and boolean(@is-viewport-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc0' and boolean(@is-viewport-area)]/@bpd"/> + <eval expected="80000" xpath="//block[@prod-id='bc0' and boolean(@is-reference-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc0' and boolean(@is-reference-area)]/@bpd"/> + <eval expected="[1.0 0.0 0.0 1.0 0.0 0.0]" xpath="//block[@prod-id='bc0' and boolean(@is-viewport-area)]/@ctm"/> + <!-- 90 --> + <eval expected="43200" xpath="//block[@prod-id='bc90' and boolean(@is-viewport-area)]/@ipd"/> + <eval expected="80000" xpath="//block[@prod-id='bc90' and boolean(@is-viewport-area)]/@bpd"/> + <eval expected="80000" xpath="//block[@prod-id='bc90' and boolean(@is-reference-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc90' and boolean(@is-reference-area)]/@bpd"/> + <eval expected="[0.0 -1.0 1.0 0.0 0.0 80000.0]" xpath="//block[@prod-id='bc90' and boolean(@is-viewport-area)]/@ctm"/> + <!-- 180 --> + <eval expected="80000" xpath="//block[@prod-id='bc180' and boolean(@is-viewport-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc180' and boolean(@is-viewport-area)]/@bpd"/> + <eval expected="80000" xpath="//block[@prod-id='bc180' and boolean(@is-reference-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc180' and boolean(@is-reference-area)]/@bpd"/> + <eval expected="[-1.0 -0.0 0.0 -1.0 80000.0 43200.0]" xpath="//block[@prod-id='bc180' and boolean(@is-viewport-area)]/@ctm"/> + <!-- 270 --> + <eval expected="43200" xpath="//block[@prod-id='bc270' and boolean(@is-viewport-area)]/@ipd"/> + <eval expected="80000" xpath="//block[@prod-id='bc270' and boolean(@is-viewport-area)]/@bpd"/> + <eval expected="80000" xpath="//block[@prod-id='bc270' and boolean(@is-reference-area)]/@ipd"/> + <eval expected="43200" xpath="//block[@prod-id='bc270' and boolean(@is-reference-area)]/@bpd"/> + <eval expected="[0.0 1.0 -1.0 0.0 43200.0 0.0]" xpath="//block[@prod-id='bc270' and boolean(@is-viewport-area)]/@ctm"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/block-container_reference-orientation_2.xml b/test/layoutengine/standard-testcases/block-container_reference-orientation_2.xml new file mode 100644 index 000000000..60400410d --- /dev/null +++ b/test/layoutengine/standard-testcases/block-container_reference-orientation_2.xml @@ -0,0 +1,91 @@ +<?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 the element lists of in-flow block-containers with reference orientation. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence id="bc0" master-reference="normal"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container width="60pt" reference-orientation="0"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block>EOPS</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence id="bc90" master-reference="normal"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container width="60pt" reference-orientation="90"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block>EOPS</fo:block> + </fo:flow> + </fo:page-sequence> + <fo:page-sequence id="bc180" master-reference="normal"> + <fo:flow flow-name="xsl-region-body"> + <fo:block-container width="60pt" reference-orientation="180" background-color="yellow"> + <fo:block>ABC</fo:block> + <fo:block font-size="200%">ABC</fo:block> + </fo:block-container> + <fo:block>EOPS</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker" id="bc0"> + <!-- content is inlined --> + <box w="14400"/> + <penalty w="0" p="0"/> + <box w="28800"/> + <penalty w="0" p="0"/> + <box w="14400"/> + + <skip>3</skip> + </element-list> + <element-list category="breaker" id="bc90"> + <!-- one box with the length of the rotated content-width --> + <box w="60000"/> + <penalty w="0" p="0"/> + <box w="14400"/> + + <skip>3</skip> + </element-list> + <element-list category="breaker" id="bc180"> + <!-- one box with the length of the effective content-height (auto-heigth) --> + <!-- Maybe the element list could be reversed somehow so the b-c can still be broken + correctly, even if ref-or="180". But we leave that be for the time being. --> + <box w="43200"/> + <penalty w="0" p="0"/> + <box w="14400"/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/block-container_reference-orientation_bug36391.xml b/test/layoutengine/standard-testcases/block-container_reference-orientation_bug36391.xml index 615fb28e1..7b1bfc793 100644 --- a/test/layoutengine/standard-testcases/block-container_reference-orientation_bug36391.xml +++ b/test/layoutengine/standard-testcases/block-container_reference-orientation_bug36391.xml @@ -90,13 +90,10 @@ <eval expected="[0.0 -1.0 1.0 0.0 0.0 31000.0]" xpath="//mainReference/span/flow[1]/block[6]/block[1]/block[1]/@ctm"/>
<!-- 180 -->
<eval expected="[1.0 0.0 0.0 1.0 0.0 1000.0]" xpath="//mainReference/span/flow[2]/block[2]/@ctm"/>
- <!-- The following currently fails since the BCLM doesn't check the effective content BPD.
- Another problem could probably arise if a BC with this ref-orientation is broken at the page end.
- I'm pretty sure the element list is wrong in this case. It would need to be reversed I think. -->
- <eval expected="[-1.0 -0.0 0.0 -1.0 30000.0 14400.0]" xpath="//mainReference/span/flow[2]/block[2]/block[1]/block[1]/@ctm"/>
+ <eval expected="[-1.0 -0.0 0.0 -1.0 30000.0 15400.0]" xpath="//mainReference/span/flow[2]/block[2]/block[1]/block[1]/@ctm"/>
<!-- -180 -->
<eval expected="[1.0 0.0 0.0 1.0 0.0 1000.0]" xpath="//mainReference/span/flow[2]/block[4]/@ctm"/>
- <eval expected="[-1.0 -0.0 0.0 -1.0 30000.0 14400.0]" xpath="//mainReference/span/flow[2]/block[4]/block[1]/block[1]/@ctm"/>
+ <eval expected="[-1.0 -0.0 0.0 -1.0 30000.0 15400.0]" xpath="//mainReference/span/flow[2]/block[4]/block[1]/block[1]/@ctm"/>
<!-- 270 -->
<eval expected="[1.0 0.0 0.0 1.0 0.0 1000.0]" xpath="//mainReference/span/flow[2]/block[6]/@ctm"/>
<eval expected="[0.0 1.0 -1.0 0.0 90000.0 1000.0]" xpath="//mainReference/span/flow[2]/block[6]/block[1]/block[1]/@ctm"/>
|