aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2022-09-14 08:53:04 +0000
committerSimon Steiner <ssteiner@apache.org>2022-09-14 08:53:04 +0000
commit3f35111f4c780b42f1e8d3ec78228d3528cdb7f0 (patch)
treef6450d0b947f3b2028e2d415c87489def029023f
parent142ae43d6333de7bbd17aa98d6a3107a02c759c8 (diff)
downloadxmlgraphics-fop-3f35111f4c780b42f1e8d3ec78228d3528cdb7f0.tar.gz
xmlgraphics-fop-3f35111f4c780b42f1e8d3ec78228d3528cdb7f0.zip
FOP-2860: Add light weight line breaking option
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1904062 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java4
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java10
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopFactory.java4
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java20
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java2
-rw-r--r--fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java8
-rw-r--r--fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java4
-rw-r--r--fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java10
-rw-r--r--fop/test/layoutengine/standard-testcases/simple-line-breaking.xml49
9 files changed, 109 insertions, 2 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java b/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
index 159efe4aa..3ab871dfc 100644
--- a/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
+++ b/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
@@ -835,4 +835,8 @@ public class FOUserAgent {
public boolean isTableBorderOverpaint() {
return factory.isTableBorderOverpaint();
}
+
+ public boolean isSimpleLineBreaking() {
+ return factory.isSimpleLineBreaking();
+ }
}
diff --git a/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java b/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
index 019250c17..7e41de624 100644
--- a/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
+++ b/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
@@ -57,6 +57,7 @@ public class FopConfParser {
private static final String PREFER_RENDERER = "prefer-renderer";
private static final String TABLE_BORDER_OVERPAINT = "table-border-overpaint";
+ private static final String SIMPLE_LINE_BREAKING = "simple-line-breaking";
private final Log log = LogFactory.getLog(FopConfParser.class);
@@ -280,6 +281,15 @@ public class FopConfParser {
}
}
+ if (cfg.getChild(SIMPLE_LINE_BREAKING, false) != null) {
+ try {
+ fopFactoryBuilder.setSimpleLineBreaking(
+ cfg.getChild(SIMPLE_LINE_BREAKING).getValueAsBoolean());
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, false);
+ }
+ }
+
// configure font manager
new FontManagerConfigurator(cfg, baseURI, fopFactoryBuilder.getBaseURI(), resourceResolver)
.configure(fopFactoryBuilder.getFontManager(), strict);
diff --git a/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java b/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
index 2685fe021..8bcbf01fd 100644
--- a/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
+++ b/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
@@ -219,6 +219,10 @@ public final class FopFactory implements ImageContext {
return config.isTableBorderOverpaint();
}
+ boolean isSimpleLineBreaking() {
+ return config.isSimpleLineBreaking();
+ }
+
/**
* 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.
diff --git a/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java b/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
index aa8c74116..848454e7f 100644
--- a/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
+++ b/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
@@ -345,6 +345,11 @@ public final class FopFactoryBuilder {
return this;
}
+ public FopFactoryBuilder setSimpleLineBreaking(boolean b) {
+ fopFactoryConfigBuilder.setSimpleLineBreaking(b);
+ return this;
+ }
+
public static class FopFactoryConfigImpl implements FopFactoryConfig {
private final EnvironmentProfile enviro;
@@ -387,6 +392,7 @@ public final class FopFactoryBuilder {
private Map<String, String> hyphPatNames;
private boolean tableBorderOverpaint;
+ private boolean simpleLineBreaking;
private static final class ImageContextImpl implements ImageContext {
@@ -508,6 +514,10 @@ public final class FopFactoryBuilder {
return tableBorderOverpaint;
}
+ public boolean isSimpleLineBreaking() {
+ return simpleLineBreaking;
+ }
+
public Map<String, String> getHyphenationPatternNames() {
return hyphPatNames;
}
@@ -555,6 +565,8 @@ public final class FopFactoryBuilder {
void setHyphPatNames(Map<String, String> hyphPatNames);
void setTableBorderOverpaint(boolean b);
+
+ void setSimpleLineBreaking(boolean b);
}
private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -642,6 +654,10 @@ public final class FopFactoryBuilder {
public void setTableBorderOverpaint(boolean b) {
throwIllegalStateException();
}
+
+ public void setSimpleLineBreaking(boolean b) {
+ throwIllegalStateException();
+ }
}
private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -730,6 +746,10 @@ public final class FopFactoryBuilder {
public void setTableBorderOverpaint(boolean b) {
config.tableBorderOverpaint = b;
}
+
+ public void setSimpleLineBreaking(boolean b) {
+ config.simpleLineBreaking = b;
+ }
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java b/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
index cda0d2c10..c9495afb8 100644
--- a/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
+++ b/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
@@ -165,6 +165,8 @@ public interface FopFactoryConfig {
boolean isTableBorderOverpaint();
+ boolean isSimpleLineBreaking();
+
/** @return the hyphenation pattern names */
Map<String, String> getHyphenationPatternNames();
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 260c01c4e..d19642ab5 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -887,12 +887,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// now try something different
log.debug("Hyphenation possible? " + canHyphenate);
+ boolean simpleLineBreaking = fobj.getUserAgent().isSimpleLineBreaking();
+
// Note: if allowedBreaks is guaranteed to be unchanged by alg.findBreakingPoints(),
// the below check can be simplified to 'if (canHyphenate) ...'
if (canHyphenate && allowedBreaks != BreakingAlgorithm.ONLY_FORCED_BREAKS) {
// consider every hyphenation point as a legal break
allowedBreaks = BreakingAlgorithm.ALL_BREAKS;
- } else {
+ } else if (!simpleLineBreaking) {
// try with a higher threshold
maxAdjustment = 5;
}
@@ -905,7 +907,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager
log.debug("No set of breaking points found with maxAdjustment = "
+ maxAdjustment + (canHyphenate ? " and hyphenation" : ""));
}
- maxAdjustment = 20;
+ if (!simpleLineBreaking) {
+ maxAdjustment = 20;
+ }
alg.findBreakingPoints(currPar, maxAdjustment, true, allowedBreaks);
}
diff --git a/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java b/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
index 04b760e74..6f1a18752 100644
--- a/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
+++ b/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
@@ -137,6 +137,10 @@ public final class MutableConfig implements FopFactoryConfig {
return delegate.isTableBorderOverpaint();
}
+ public boolean isSimpleLineBreaking() {
+ return delegate.isSimpleLineBreaking();
+ }
+
public Map<String, String> getHyphenationPatternNames() {
return delegate.getHyphenationPatternNames();
}
diff --git a/fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java b/fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java
index 901bef2e6..7048a9fd9 100644
--- a/fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java
+++ b/fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java
@@ -124,6 +124,7 @@ public class TestAssistant {
builder.setStrictFOValidation(isStrictValidation(testDoc));
builder.getFontManager().setBase14KerningEnabled(isBase14KerningEnabled(testDoc));
builder.setTableBorderOverpaint(isTableBorderOverpaint(testDoc));
+ builder.setSimpleLineBreaking(isSimpleLineBreaking(testDoc));
return builder.build();
}
@@ -159,6 +160,15 @@ public class TestAssistant {
return (String) xPath.compile(xpath).evaluate(doc, XPathConstants.STRING);
}
+ private boolean isSimpleLineBreaking(Document testDoc) {
+ try {
+ String s = eval(testDoc, "/testcase/cfg/simple-line-breaking");
+ return "true".equalsIgnoreCase(s);
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException("Error while evaluating XPath expression", e);
+ }
+ }
+
/**
* Loads a test case into a DOM document.
* @param testFile the test file
diff --git a/fop/test/layoutengine/standard-testcases/simple-line-breaking.xml b/fop/test/layoutengine/standard-testcases/simple-line-breaking.xml
new file mode 100644
index 000000000..ec6e9cd86
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/simple-line-breaking.xml
@@ -0,0 +1,49 @@
+<?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 if simple line breaking is enabled
+ </p>
+ </info>
+ <cfg>
+ <simple-line-breaking>true</simple-line-breaking>
+ </cfg>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="body">
+ <fo:region-body margin="15mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="body">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Libero, expedita voluptatem, dolorem totam eos ex, quas quaerat architecto reprehenderit sit illo voluptatum. Molestias, fuga assumenda quis. Libero est vero voluptatum iusto sint repudiandae deserunt nisi neque quidem veritatis, asperiores eos, consectetur cupiditate repellat culpa, error architecto pariatur voluptates hic alias itaque esse quod totam labore. Officia assumenda incidunt quisquam. Voluptatibus est sequi non eaque, animi illum ea itaque beatae vel voluptas odio autem, cum ducimus ut? Dolores ipsum voluptate, dicta. Omnis veniam deserunt obcaecati, eligendi nobis enim reiciendis laudantium magnam officiis deleniti necessitatibus illo, laboriosam inventore iusto ullam beatae maiores. Ex libero, explicabo nemo modi. Iure officia, cumque itaque delectus beatae natus totam quibusdam vitae voluptatibus. Commodi excepturi, accusantium mollitia minus, debitis ut doloribus voluptate sequi tempora dolorem amet assumenda. Expedita corporis neque id iusto, ipsa nesciunt. Soluta fuga laudantium possimus eveniet harum quo impedit iure modi iste cumque nihil error delectus explicabo perspiciatis aliquam, repellat assumenda hic provident deleniti nisi rem, vitae? Tempore ullam sit similique ratione possimus, cumque hic corrupti rerum molestiae inventore libero, porro placeat distinctio neque aliquid veritatis tenetur magni ab debitis saepe, unde ea. Ut inventore ratione consequuntur blanditiis, possimus qui iste autem, aspernatur in illum distinctio magni nostrum obcaecati harum neque dolorum excepturi, culpa ipsa laboriosam est. Facilis at quaerat repudiandae impedit vero explicabo quod aspernatur, voluptates quis cum, consequuntur expedita eius laboriosam architecto obcaecati officia autem commodi quae velit alias odio a mollitia soluta labore? Officia dolores magni voluptatum odio dolor officiis aperiam blanditiis eaque quasi nulla nihil exercitationem dolorum reprehenderit aliquam fugit totam est amet error cum porro, fugiat vitae reiciendis dicta. Corrupti eos ducimus at. Asperiores dolor, in placeat, reprehenderit repellendus inventore, similique magni id quo officiis unde doloribus minima quibusdam quasi odio labore? Illum ea possimus dolores dolore repellendus nobis similique aut libero eaque, vitae, natus, facilis illo! Corrupti quos consectetur mollitia maiores doloribus repudiandae, aperiam quam officia vel facilis molestias accusamus voluptas eligendi libero nemo quae cupiditate perferendis accusantium aspernatur expedita. Tenetur ipsa impedit qui, dolorum sequi, labore quas pariatur quidem officia, amet temporibus iste. Nobis, delectus, iusto. Suscipit corporis sapiente accusamus eveniet? Expedita vel illum harum iste vitae magnam aspernatur soluta, illo vero at sed officia neque eaque! Ipsa necessitatibus totam, placeat modi provident nihil atque fugiat saepe voluptatibus sint explicabo repellendus magnam dignissimos enim illum debitis, eveniet in animi officia omnis excepturi dolores velit vero. Consectetur recusandae magnam ea eveniet hic tempore reprehenderit, suscipit dolore a officiis nesciunt vero aut quod atque et voluptates ipsa, praesentium obcaecati labore aliquid doloremque ullam. Dolores, delectus consequuntur quasi ullam, architecto, at enim fugit voluptatibus harum quisquam sequi assumenda aspernatur! Quidem atque dolores, rem dignissimos provident et beatae sit reprehenderit ipsam tenetur alias facere aliquam numquam iusto eos enim expedita aliquid. Vel sit amet minus voluptatum, inventore officia, atque facilis possimus quisquam. Incidunt esse ea nesciunt ullam perferendis quisquam ipsam autem. Ipsam eligendi temporibus, nulla odio corporis qui sequi ducimus excepturi perspiciatis doloribus tenetur laborum corrupti pariatur illum sunt ipsum, itaque nesciunt mollitia aliquid eaque sint cumque atque blanditiis molestias in! Esse quidem soluta ducimus dolore aliquam repudiandae quae ipsa asperiores perferendis voluptate. Harum ad placeat necessitatibus assumenda omnis laudantium, commodi repudiandae laborum in asperiores nisi esse reprehenderit autem deserunt nihil velit sit quo earum odit vitae quaerat mollitia. Dolores non ducimus consectetur eos voluptatum excepturi nostrum at veritatis sapiente saepe, eaque minima iste, praesentium aspernatur, earum debitis commodi maiores possimus, impedit culpa inventore. Quidem hic iusto totam praesentium quia odit ut blanditiis provident inventore odio aperiam nulla, sed iste ratione, laboriosam dolore itaque dolorem, consequuntur voluptas facere. Labore dolor consequuntur numquam earum iure quae consequatur, eius fugiat repudiandae accusamus magnam? Quis fuga laboriosam alias quia inventore doloribus nam omnis veniam deserunt harum eveniet ducimus magnam voluptas enim ipsam non fugit, perspiciatis repellendus. Voluptatem illo, corporis, ut quas quo velit nostrum libero! Incidunt quam quisquam expedita debitis dolore nam sequi ullam, soluta ipsa esse, quo amet tenetur commodi maiores hic. Non ex illo nostrum explicabo dolorem ut nihil, dignissimos aliquid maxime. Iusto beatae, veritatis obcaecati voluptate, excepturi eveniet. Voluptates pariatur saepe, enim a, minima laboriosam, eveniet omnis non eaque ea doloribus dolorum ex tenetur earum qui voluptatibus. Velit, sequi, inventore! Id est at quia sunt voluptatum odio dignissimos illo quam enim quod nulla tempore veritatis commodi dolor, sint quaerat, beatae, reiciendis! Iste neque obcaecati rem nulla, sit reprehenderit et eaque nihil culpa repudiandae. Unde placeat totam voluptatem impedit maxime expedita eos error reiciendis similique eligendi ullam quam, doloremque nostrum quod consectetur animi doloribus ipsa neque, quas minima porro nihil exercitationem. Obcaecati, rerum, illo. Quisquam nam iusto tempore odio mollitia ad perferendis tempora explicabo veniam dignissimos quaerat libero illo at vel dolorem nisi ipsa deleniti enim, ex voluptas quo qui molestias nostrum similique. Tenetur amet excepturi fuga error totam aliquid optio illum, possimus laboriosam quos dolorum quo provident assumenda dolore recusandae iure quibusdam tempora! Debitis rem totam eveniet nesciunt harum natus atque vitae corrupti ea et illum impedit illo aliquid ipsa tempora dolore a, doloribus ullam dignissimos placeat. Quae explicabo sed at autem deleniti enim beatae vel quaerat amet, quibusdam quisquam. Quidem natus nostrum quo modi tempora, incidunt obcaecati. Quidem recusandae quisquam neque amet corrupti? Dolores voluptas cupiditate doloribus odio quam, ipsam magni facilis corporis molestias fugiat incidunt harum aperiam fuga quas sequi quisquam ipsum illo illum! Eum, corporis aliquid sequi libero laboriosam nobis, velit nihil, beatae voluptas laudantium nam quas omnis voluptatem temporibus repellendus molestias? Tempore minus corrupti tenetur, praesentium sed iusto illum nulla aperiam sapiente enim natus quod vero fuga consectetur quisquam culpa, hic tempora, error dignissimos voluptatibus itaque amet pariatur. Ullam quo neque, rerum necessitatibus, laboriosam quaerat officia est perspiciatis quisquam cupiditate velit dolor accusantium repudiandae, esse dolores laudantium! Nihil omnis, rerum. Nulla veniam minima est nemo nihil tenetur repudiandae dolor laborum dolores, reprehenderit corporis esse porro voluptates vero odio saepe dolorum,</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="973" xpath="count(//word)"/>
+ <eval expected="80" xpath="count(//lineArea)"/>
+ <eval expected="2" xpath="count(//pageViewport)"/>
+ <eval expected="Lorem" xpath="//pageViewport[1]//word"/>
+ <eval expected="consequuntur" xpath="//pageViewport[2]//word"/>
+ </checks>
+</testcase>