]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3219: Remove space generated by wrapper
authorSimon Steiner <ssteiner@apache.org>
Fri, 15 Nov 2024 12:02:56 +0000 (12:02 +0000)
committerSimon Steiner <ssteiner@apache.org>
Fri, 15 Nov 2024 12:02:56 +0000 (12:02 +0000)
12 files changed:
fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java
fop/test/layoutengine/standard-testcases/table-cell_height2.xml
fop/test/layoutengine/standard-testcases/wrapper_block_id2.xml [new file with mode: 0644]
fop/test/layoutengine/standard-testcases/wrapper_block_id2_legacy.xml [new file with mode: 0644]

index 149af5c908974c2b23e3d228e815f6eaf41def32..bdaf0c023442d683b6dd3b9f6f4d05abe5588585 100644 (file)
@@ -855,4 +855,8 @@ public class FOUserAgent {
     public boolean isLegacyLastPageChangeIPD() {
         return factory.isLegacyLastPageChangeIPD();
     }
+
+    public boolean isLegacyFoWrapper() {
+        return factory.isLegacyFoWrapper();
+    }
 }
index d3344ff77225d11d834b7ea339715b52d1c1314e..d4f993705dbaf698c2b56c859167e18f6fa8fbe7 100644 (file)
@@ -61,8 +61,9 @@ public class FopConfParser {
     private static final String SKIP_PAGE_POSITION_ONLY_ALLOWED = "skip-page-position-only-allowed";
     private static final String LEGACY_SKIP_PAGE_POSITION_ONLY = "legacy-skip-page-position-only";
     private static final String LEGACY_LAST_PAGE_CHANGE_IPD = "legacy-last-page-change-ipd";
+    private static final String LEGACY_FO_WRAPPER = "legacy-fo-wrapper";
 
-    private final Log log = LogFactory.getLog(FopConfParser.class);
+    private static final Log LOG = LogFactory.getLog(FopConfParser.class);
 
     private final FopFactoryBuilder fopFactoryBuilder;
 
@@ -169,8 +170,8 @@ public class FopConfParser {
 
     private void configure(final URI baseURI, final ResourceResolver resourceResolver,
             Configuration cfg) throws FOPException {
-        if (log.isDebugEnabled()) {
-            log.debug("Initializing FopFactory Configuration");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Initializing FopFactory Configuration");
         }
 
         // strict fo validation
@@ -179,7 +180,7 @@ public class FopConfParser {
                 boolean strict = cfg.getChild("strict-validation").getValueAsBoolean();
                 fopFactoryBuilder.setStrictFOValidation(strict);
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -189,7 +190,7 @@ public class FopConfParser {
                 strict = cfg.getChild("strict-configuration").getValueAsBoolean();
                 fopFactoryBuilder.setStrictUserConfigValidation(strict);
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -199,7 +200,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setKeepEmptyTags(
                         cfg.getChild("accessibility").getAttributeAsBoolean(Accessibility.KEEP_EMPTY_TAGS, true));
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -209,7 +210,7 @@ public class FopConfParser {
                 URI confUri = InternalResourceResolver.getBaseURI(cfg.getChild("base").getValue(null));
                 fopFactoryBuilder.setBaseURI(baseURI.resolve(confUri));
             } catch (URISyntaxException use) {
-                LogUtil.handleException(log, use, strict);
+                LogUtil.handleException(LOG, use, strict);
             }
         }
 
@@ -218,16 +219,16 @@ public class FopConfParser {
             float srcRes = cfg.getChild("source-resolution").getValueAsFloat(
                     FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION);
             fopFactoryBuilder.setSourceResolution(srcRes);
-            if (log.isDebugEnabled()) {
-                log.debug("source-resolution set to: " + srcRes + "dpi");
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("source-resolution set to: " + srcRes + "dpi");
             }
         }
         if (cfg.getChild("target-resolution", false) != null) {
             float targetRes = cfg.getChild("target-resolution").getValueAsFloat(
                     FopFactoryConfig.DEFAULT_TARGET_RESOLUTION);
             fopFactoryBuilder.setTargetResolution(targetRes);
-            if (log.isDebugEnabled()) {
-                log.debug("target-resolution set to: " + targetRes + "dpi");
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("target-resolution set to: " + targetRes + "dpi");
             }
         }
         if (cfg.getChild("break-indent-inheritance", false) != null) {
@@ -235,7 +236,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(
                              cfg.getChild("break-indent-inheritance").getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, strict);
+                LogUtil.handleException(LOG, e, strict);
             }
         }
         Configuration pageConfig = cfg.getChild("default-page-settings");
@@ -243,16 +244,16 @@ public class FopConfParser {
             String pageHeight = pageConfig.getAttribute("height",
                     FopFactoryConfig.DEFAULT_PAGE_HEIGHT);
             fopFactoryBuilder.setPageHeight(pageHeight);
-            if (log.isInfoEnabled()) {
-                log.info("Default page-height set to: " + pageHeight);
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Default page-height set to: " + pageHeight);
             }
         }
         if (pageConfig.getAttribute("width", null) != null) {
             String pageWidth = pageConfig.getAttribute("width",
                     FopFactoryConfig.DEFAULT_PAGE_WIDTH);
             fopFactoryBuilder.setPageWidth(pageWidth);
-            if (log.isInfoEnabled()) {
-                log.info("Default page-width set to: " + pageWidth);
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Default page-width set to: " + pageWidth);
             }
         }
 
@@ -271,7 +272,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setPreferRenderer(
                              cfg.getChild(PREFER_RENDERER).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, strict);
+                LogUtil.handleException(LOG, e, strict);
             }
         }
 
@@ -280,7 +281,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setTableBorderOverpaint(
                         cfg.getChild(TABLE_BORDER_OVERPAINT).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -289,7 +290,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setSimpleLineBreaking(
                         cfg.getChild(SIMPLE_LINE_BREAKING).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -298,7 +299,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setSkipPagePositionOnlyAllowed(
                         cfg.getChild(SKIP_PAGE_POSITION_ONLY_ALLOWED).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
         if (cfg.getChild(LEGACY_SKIP_PAGE_POSITION_ONLY, false) != null) {
@@ -306,7 +307,7 @@ public class FopConfParser {
                 fopFactoryBuilder.setLegacySkipPagePositionOnly(
                         cfg.getChild(LEGACY_SKIP_PAGE_POSITION_ONLY).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
             }
         }
         if (cfg.getChild(LEGACY_LAST_PAGE_CHANGE_IPD, false) != null) {
@@ -314,7 +315,15 @@ public class FopConfParser {
                 fopFactoryBuilder.setLegacyLastPageChangeIPD(
                         cfg.getChild(LEGACY_LAST_PAGE_CHANGE_IPD).getValueAsBoolean());
             } catch (ConfigurationException e) {
-                LogUtil.handleException(log, e, false);
+                LogUtil.handleException(LOG, e, false);
+            }
+        }
+        if (cfg.getChild(LEGACY_FO_WRAPPER, false) != null) {
+            try {
+                fopFactoryBuilder.setLegacyFoWrapper(
+                        cfg.getChild(LEGACY_FO_WRAPPER).getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(LOG, e, false);
             }
         }
 
@@ -336,7 +345,7 @@ public class FopConfParser {
                         ResourceResolverFactory.createInternalResourceResolver(
                                 baseURI.resolve(fontBase), resourceResolver));
             } catch (URISyntaxException use) {
-                LogUtil.handleException(log, use, true);
+                LogUtil.handleException(LOG, use, true);
             }
         } else {
             fopFactoryBuilder.setHyphenBaseResourceResolver(
@@ -388,7 +397,7 @@ public class FopConfParser {
                 }
 
                 if (error.length() != 0) {
-                    LogUtil.handleError(log, error.toString(), strict);
+                    LogUtil.handleError(LOG, error.toString(), strict);
                     continue;
                 }
 
@@ -402,8 +411,8 @@ public class FopConfParser {
                 } else {
                     hyphPatNames.put(llccKey, filename);
                 }
-                if (log.isDebugEnabled()) {
-                    log.debug("Using hyphenation pattern filename " + filename
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Using hyphenation pattern filename " + filename
                             + " for lang=\"" + lang + "\""
                             + (country != null ? ", country=\"" + country + "\"" : ""));
                 }
@@ -436,7 +445,7 @@ public class FopConfParser {
                     try {
                         p = Penalty.toPenalty(Integer.parseInt(value));
                     } catch (NumberFormatException nfe) {
-                        LogUtil.handleException(log, nfe, strict);
+                        LogUtil.handleException(LOG, nfe, strict);
                     }
                 }
                 if (p != null) {
@@ -444,7 +453,7 @@ public class FopConfParser {
                 }
             }
         } catch (ConfigurationException e) {
-            LogUtil.handleException(log, e, strict);
+            LogUtil.handleException(LOG, e, strict);
         }
     }
 
index bdf789bf143ed86c486a27920ff180849acf7785..7f89b854c46286d6a1a765fff9a28ff258ff6227 100644 (file)
@@ -252,6 +252,10 @@ public final class FopFactory implements ImageContext {
         return config.isLegacyLastPageChangeIPD();
     }
 
+    boolean isLegacyFoWrapper() {
+        return config.isLegacyFoWrapper();
+    }
+
     /**
      * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
      * instance. Use this factory method if your output type requires an output stream.
index ebb176c03a4375ee4586a6b4ce16091fe1c5c0d6..68c2dc3ebd51a1ba754400b1dcf3a3a238690ab5 100644 (file)
@@ -365,6 +365,11 @@ public final class FopFactoryBuilder {
         return this;
     }
 
+    public FopFactoryBuilder setLegacyFoWrapper(boolean b) {
+        fopFactoryConfigBuilder.setLegacyFoWrapper(b);
+        return this;
+    }
+
     public static class FopFactoryConfigImpl implements FopFactoryConfig {
 
         private final EnvironmentProfile enviro;
@@ -415,6 +420,8 @@ public final class FopFactoryBuilder {
 
         private boolean legacyLastPageChangeIPD;
 
+        private boolean legacyFoWrapper;
+
         private static final class ImageContextImpl implements ImageContext {
 
             private final FopFactoryConfig config;
@@ -551,6 +558,10 @@ public final class FopFactoryBuilder {
             return legacyLastPageChangeIPD;
         }
 
+        public boolean isLegacyFoWrapper() {
+            return legacyFoWrapper;
+        }
+
         public Map<String, String> getHyphenationPatternNames() {
             return hyphPatNames;
         }
@@ -606,6 +617,8 @@ public final class FopFactoryBuilder {
         void setLegacySkipPagePositionOnly(boolean b);
 
         void setLegacyLastPageChangeIPD(boolean b);
+
+        void setLegacyFoWrapper(boolean b);
     }
 
     private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -709,6 +722,10 @@ public final class FopFactoryBuilder {
         public void setLegacyLastPageChangeIPD(boolean b) {
             throwIllegalStateException();
         }
+
+        public void setLegacyFoWrapper(boolean b) {
+            throwIllegalStateException();
+        }
     }
 
     private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -813,6 +830,10 @@ public final class FopFactoryBuilder {
         public void setLegacyLastPageChangeIPD(boolean b) {
             config.legacyLastPageChangeIPD = b;
         }
+
+        public void setLegacyFoWrapper(boolean b) {
+            config.legacyFoWrapper = b;
+        }
     }
 
 }
index 55dbb8671ee6af5519bfe8c16301d8dc50fbd4c3..586966dc4fbc98638fa2d66aa71508f6624462bc 100644 (file)
@@ -173,6 +173,8 @@ public interface FopFactoryConfig {
 
     boolean isLegacyLastPageChangeIPD();
 
+    boolean isLegacyFoWrapper();
+
     /** @return the hyphenation pattern names */
     Map<String, String> getHyphenationPatternNames();
 
index f8ef59e4c5863de4db6bc863a4a651dd42c70055..ce35a38eeda7fb9f7cf3aeb83fa027b8ed0a8f54 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.layoutmgr.AbstractLayoutManager;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
+import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthGlue;
 import org.apache.fop.layoutmgr.KnuthPenalty;
 import org.apache.fop.layoutmgr.KnuthSequence;
@@ -278,8 +279,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
 
         addKnuthElementsForBorderPaddingStart(seq);
 
-        seq.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), alignmentContext,
-                                    notifyPos(new LeafPosition(this, 0)), false));
+        seq.add(makeBox());
 
         addKnuthElementsForBorderPaddingEnd(seq);
 
@@ -287,6 +287,11 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
         return Collections.singletonList(seq);
     }
 
+    protected KnuthBox makeBox() {
+        return new KnuthInlineBox(areaInfo.ipdArea.getOpt(), alignmentContext,
+                notifyPos(new LeafPosition(this, 0)), false);
+    }
+
     /** {@inheritDoc} */
     public List<ListElement> addALetterSpaceTo(List<ListElement> oldList) {
         // return the unchanged elements
index 0dcba3efecf11afb78257649d923db755ce50ead..4f20998dcc4b458a44b91019241be2e2b23ca2bb 100644 (file)
@@ -27,8 +27,10 @@ import org.apache.fop.area.inline.InlineArea;
 import org.apache.fop.fo.flow.Wrapper;
 import org.apache.fop.layoutmgr.BlockLayoutManager;
 import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthSequence;
 import org.apache.fop.layoutmgr.LayoutContext;
+import org.apache.fop.layoutmgr.LeafPosition;
 import org.apache.fop.layoutmgr.PositionIterator;
 import org.apache.fop.layoutmgr.TraitSetter;
 
@@ -98,4 +100,11 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager {
         }
         return list;
     }
+
+    protected KnuthBox makeBox() {
+        if (parentLayoutManager instanceof InlineLayoutManager || fobj.getUserAgent().isLegacyFoWrapper()) {
+            return super.makeBox();
+        }
+        return new KnuthBox(areaInfo.ipdArea.getOpt(), notifyPos(new LeafPosition(this, 0)), false);
+    }
 }
index 3fcaa4fbcccd69ed687151d7bcf7f8d6390436b1..4cc39dc6e36a76197ad5b6a9403682bf93e0e410 100644 (file)
@@ -153,6 +153,10 @@ public final class MutableConfig implements FopFactoryConfig {
         return delegate.isLegacyLastPageChangeIPD();
     }
 
+    public boolean isLegacyFoWrapper() {
+        return delegate.isLegacyFoWrapper();
+    }
+
     public Map<String, String> getHyphenationPatternNames() {
         return delegate.getHyphenationPatternNames();
     }
index f87905772b757932d29016b557264ccd9b68dceb..66939cfcc2756f1047f819837860f41f0a59b52c 100644 (file)
@@ -128,6 +128,7 @@ public class TestAssistant {
         builder.setSkipPagePositionOnlyAllowed(isSkipPagePositionOnlyAllowed(testDoc));
         builder.setLegacySkipPagePositionOnly(isLegacySkipPagePositionOnly(testDoc));
         builder.setLegacyLastPageChangeIPD(isLegacyLastPageChangeIPD(testDoc));
+        builder.setLegacyFoWrapper(isLegacyFoWrapper(testDoc));
         return builder.build();
     }
 
@@ -199,6 +200,15 @@ public class TestAssistant {
         }
     }
 
+    private boolean isLegacyFoWrapper(Document testDoc) {
+        try {
+            String s = eval(testDoc, "/testcase/cfg/legacy-fo-wrapper");
+            return "true".equalsIgnoreCase(s);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * Loads a test case into a DOM document.
      * @param testFile the test file
index ad4bd30bb180e1937e6bba2e19a8192202211533..9d0c2671cbb6a560de3aa49440e5d0796179f7cb 100644 (file)
@@ -69,6 +69,7 @@
     </fo:root>
   </fo>
   <checks>
-    <eval expected="11100" xpath="//lineArea/@bpd"/>
+    <eval expected="0" xpath="//lineArea/@bpd"/>
+    <eval expected="14173" xpath="//block/@bpd"/>
   </checks>
 </testcase>
diff --git a/fop/test/layoutengine/standard-testcases/wrapper_block_id2.xml b/fop/test/layoutengine/standard-testcases/wrapper_block_id2.xml
new file mode 100644 (file)
index 0000000..8ba3455
--- /dev/null
@@ -0,0 +1,51 @@
+<?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 fo:wrapper surrounding block-level content with an ID.
+    </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="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 id="B0">
+            <fo:wrapper id="B1">
+              <fo:block font-size="0">
+                <fo:external-graphic content-width="5in" content-height="5in" src="../resources/images/box1.png"/>
+              </fo:block>
+            </fo:wrapper>
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <true xpath="boolean(//*[@prod-id='B0'])"/>
+    <true xpath="boolean(//*[@prod-id='B1'])"/>
+    <eval expected="1" xpath="count(//pageViewport)"/>
+    <eval expected="0" xpath="//lineArea/@bpd"/>
+  </checks>
+</testcase>
diff --git a/fop/test/layoutengine/standard-testcases/wrapper_block_id2_legacy.xml b/fop/test/layoutengine/standard-testcases/wrapper_block_id2_legacy.xml
new file mode 100644 (file)
index 0000000..8f636cd
--- /dev/null
@@ -0,0 +1,54 @@
+<?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 fo:wrapper surrounding block-level content with an ID.
+    </p>
+  </info>
+  <cfg>
+    <legacy-fo-wrapper>true</legacy-fo-wrapper>
+  </cfg>  
+  <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="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 id="B0">
+            <fo:wrapper id="B1">
+              <fo:block font-size="0">
+                <fo:external-graphic content-width="5in" content-height="5in" src="../resources/images/box1.png"/>
+              </fo:block>
+            </fo:wrapper>
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <true xpath="boolean(//*[@prod-id='B0'])"/>
+    <true xpath="boolean(//*[@prod-id='B1'])"/>
+    <eval expected="2" xpath="count(//pageViewport)"/>
+    <eval expected="11100" xpath="//lineArea/@bpd"/>
+  </checks>
+</testcase>