aboutsummaryrefslogtreecommitdiffstats
path: root/fop-core/src/main/java/org/apache/fop
diff options
context:
space:
mode:
authorJoao Goncalves <jgoncalves@smartcommunications.com>2025-07-23 18:45:26 -0500
committerJoao Goncalves <jgoncalves@smartcommunications.com>2025-07-25 17:47:35 -0500
commit35a432760efcacd9a50e381020420ea58e7f5efc (patch)
tree55af138edfa650d588af30bb6dd556bd1025e182 /fop-core/src/main/java/org/apache/fop
parentb077abbad95b14b8880b4ca34f8e49690a890416 (diff)
downloadxmlgraphics-fop-main.tar.gz
xmlgraphics-fop-main.zip
FOP-3181 Prevent page duplication when ipd changesHEADmain
Diffstat (limited to 'fop-core/src/main/java/org/apache/fop')
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java10
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java9
-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.java24
-rw-r--r--fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java7
-rw-r--r--fop-core/src/main/java/org/apache/fop/layoutmgr/RestartAtLM.java8
6 files changed, 60 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 4c6b2c100..32d11475f 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
@@ -540,6 +540,16 @@ public class FOUserAgent {
}
/**
+ * Are invalid positions to be allowed when breaking text?
+ *
+ * @return if invalid break positions are to be allowed
+ * @see FopFactory#isLegacyInvalidBreakPosition()
+ */
+ public boolean isLegacyInvalidBreakPosition() {
+ return factory.isLegacyInvalidBreakPosition();
+ }
+
+ /**
* @return true if the indent inheritance should be broken when crossing reference area
* boundaries (for more info, see the javadoc for the relative member variable)
* @see FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()
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 abc3a4edb..c610f766a 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
@@ -63,6 +63,7 @@ public class FopConfParser {
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 static final String LEGACY_INVALID_BREAK_POSITION = "legacy-invalid-break-position";
private static final Log LOG = LogFactory.getLog(FopConfParser.class);
private static final String ACCESSIBILITY = "accessibility";
@@ -330,6 +331,14 @@ public class FopConfParser {
LogUtil.handleException(LOG, e, false);
}
}
+ if (cfg.getChild(LEGACY_INVALID_BREAK_POSITION, false) != null) {
+ try {
+ fopFactoryBuilder.setLegacyInvalidBreakPosition(
+ cfg.getChild(LEGACY_INVALID_BREAK_POSITION).getValueAsBoolean());
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, strict);
+ }
+ }
// configure font manager
new FontManagerConfigurator(cfg, baseURI, fopFactoryBuilder.getBaseURI(), resourceResolver)
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 46ec3ceb1..7befef58d 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
@@ -256,6 +256,10 @@ public final class FopFactory implements ImageContext {
return config.isLegacyFoWrapper();
}
+ public boolean isLegacyInvalidBreakPosition() {
+ return config.isLegacyInvalidBreakPosition();
+ }
+
/**
* 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 e89021412..243bc8570 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
@@ -375,6 +375,11 @@ public final class FopFactoryBuilder {
return this;
}
+ public FopFactoryBuilder setLegacyInvalidBreakPosition(boolean value) {
+ fopFactoryConfigBuilder.setLegacyInvalidBreakPosition(value);
+ return this;
+ }
+
public static class FopFactoryConfigImpl implements FopFactoryConfig {
private final EnvironmentProfile enviro;
@@ -429,6 +434,8 @@ public final class FopFactoryBuilder {
private boolean legacyFoWrapper;
+ private boolean legacyInvalidBreakPosition = FopFactoryConfig.DEFAULT_LEGACY_INVALID_BREAK_POSITION;
+
private static final class ImageContextImpl implements ImageContext {
private final FopFactoryConfig config;
@@ -573,6 +580,10 @@ public final class FopFactoryBuilder {
return legacyFoWrapper;
}
+ public boolean isLegacyInvalidBreakPosition() {
+ return legacyInvalidBreakPosition;
+ }
+
public Map<String, String> getHyphenationPatternNames() {
return hyphPatNames;
}
@@ -600,6 +611,8 @@ public final class FopFactoryBuilder {
void setStrictUserConfigValidation(boolean validateStrictly);
+ void setLegacyInvalidBreakPosition(boolean invalidBreakPosition);
+
void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value);
void setSourceResolution(float dpi);
@@ -677,6 +690,10 @@ public final class FopFactoryBuilder {
throwIllegalStateException();
}
+ public void setLegacyInvalidBreakPosition(boolean ignoreInvalidBreakPosition) {
+ throwIllegalStateException();
+ }
+
public void setBreakIndentInheritanceOnReferenceAreaBoundary(
boolean value) {
throwIllegalStateException();
@@ -788,8 +805,7 @@ public final class FopFactoryBuilder {
config.hasStrictUserValidation = validateStrictly;
}
- public void setBreakIndentInheritanceOnReferenceAreaBoundary(
- boolean value) {
+ public void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value) {
config.breakIndentInheritanceOnReferenceBoundary = value;
}
@@ -857,6 +873,10 @@ public final class FopFactoryBuilder {
public void setLegacyFoWrapper(boolean b) {
config.legacyFoWrapper = b;
}
+
+ public void setLegacyInvalidBreakPosition(boolean legacyInvalidBreakPosition) {
+ config.legacyInvalidBreakPosition = legacyInvalidBreakPosition;
+ }
}
}
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 190a6f556..6f62f17e3 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
@@ -40,6 +40,11 @@ import org.apache.fop.layoutmgr.LayoutManagerMaker;
// part of the API. Why would a user care how the internal objects are passed around? They shouldn't.
public interface FopFactoryConfig {
+ /**
+ * Defines if FOP should allow breaks at positions deemed invalid
+ */
+ boolean DEFAULT_LEGACY_INVALID_BREAK_POSITION = false;
+
/** Defines if FOP should use an alternative rule to determine text indents */
boolean DEFAULT_BREAK_INDENT_INHERITANCE = false;
@@ -178,6 +183,8 @@ public interface FopFactoryConfig {
boolean isLegacyFoWrapper();
+ boolean isLegacyInvalidBreakPosition();
+
/** @return the hyphenation pattern names */
Map<String, String> getHyphenationPatternNames();
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/RestartAtLM.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/RestartAtLM.java
index 4a0fcd885..647c9968f 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/RestartAtLM.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/RestartAtLM.java
@@ -100,10 +100,18 @@ class RestartAtLM {
position = position.getPosition();
}
if (position.getPosition() == null) {
+ if (!breaker.getPageProvider().foUserAgent.isLegacyInvalidBreakPosition()) {
+ breaker.firstElementsForRestart = new LinkedList<>();
+ breaker.positionAtBreak = new LeafPosition(surroundingLM, positionIndex + 1);
+
+ return surroundingLM;
+ }
+
if (!position.getLM().getFObj().isForceKeepTogether()) {
position.getLM().getFObj().setForceKeepTogether(true);
invalidPosition = true;
}
+
return null;
}
restartAtLM = position.getPosition().getLM();