diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java
index 8ae6a0cab..71b638f13 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java
@@ -103,6 +103,7 @@ public class IdentValue implements FSDerivedValue {
public final static IdentValue FONT_WEIGHT_900 = addValue("900");
public final static IdentValue FS_CONTENT_PLACEHOLDER = addValue("-fs-content-placeholder");
public final static IdentValue FS_INITIAL_VALUE = addValue("-fs-initial-value");
+ public final static IdentValue FS_TABLE_PAGINATE_REPEATED_VISIBLE = addValue("-fs-table-paginate-repeated-visible");
public final static IdentValue GEORGIAN = addValue("georgian");
public final static IdentValue GROOVE = addValue("groove");
public final static IdentValue HEBREW = addValue("hebrew");
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java
index 9f4592f99..a9b71374a 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java
@@ -1515,10 +1515,11 @@ protected BitSet getAllowed() {
}
public static class Visibility extends SingleIdent {
- // visible | hidden | collapse | inherit
+ // visible | hidden | collapse | inherit | -fs-table-paginate-repeated-visible
private static final BitSet ALLOWED = setFor(
new IdentValue[] {
- IdentValue.VISIBLE, IdentValue.HIDDEN, IdentValue.COLLAPSE });
+ IdentValue.VISIBLE, IdentValue.HIDDEN, IdentValue.COLLAPSE,
+ IdentValue.FS_TABLE_PAGINATE_REPEATED_VISIBLE });
protected BitSet getAllowed() {
return ALLOWED;
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java
index 08a3930ce..33b3a58bb 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java
@@ -43,8 +43,11 @@
import com.openhtmltopdf.css.style.derived.NumberValue;
import com.openhtmltopdf.css.style.derived.RectPropertySet;
import com.openhtmltopdf.css.value.FontSpecification;
+import com.openhtmltopdf.newtable.TableBox;
+import com.openhtmltopdf.render.Box;
import com.openhtmltopdf.render.FSFont;
import com.openhtmltopdf.render.FSFontMetrics;
+import com.openhtmltopdf.render.RenderingContext;
import com.openhtmltopdf.util.XRLog;
import com.openhtmltopdf.util.XRRuntimeException;
@@ -1026,8 +1029,42 @@ public boolean isListItem() {
return isIdent(CSSName.DISPLAY, IdentValue.LIST_ITEM);
}
- public boolean isVisible() {
- return isIdent(CSSName.VISIBILITY, IdentValue.VISIBLE);
+ /**
+ * Determine if the element is visible. This is normaly the case
+ * if visibility == visible. Only when visibilty is
+ * -fs-table-paginate-repeated-visible and we are in a repeated table header
+ * the element will also be visible. This allows to only show an element in the table header
+ * after a page break.
+ * @param renderingContext null or the current renderingContext. If null,
+ * then the -fs-table-paginate-repeated-visible logic
+ * will not work.
+ * @param thisElement the element for which the visibility should be determined. Only required if
+ * -fs-table-paginate-repeated-visible is specified.
+ * @return true if the element is visible
+ */
+ public boolean isVisible(RenderingContext renderingContext, Box thisElement) {
+ IdentValue val = getIdent(CSSName.VISIBILITY);
+ if (val == IdentValue.VISIBLE)
+ return true;
+ if (renderingContext != null) {
+ if (val == IdentValue.FS_TABLE_PAGINATE_REPEATED_VISIBLE) {
+ /*
+ * We need to find the parent TableBox which has a
+ * ContentLimitContainer and can be repeated.
+ */
+ Box parentElement = thisElement.getParent();
+ while (parentElement != null
+ && !(parentElement.getStyle().isTable()
+ && ((TableBox) parentElement).hasContentLimitContainer()))
+ parentElement = parentElement.getDocumentParent();
+
+ if (parentElement != null) {
+ TableBox tableBox = (TableBox) parentElement;
+ return !tableBox.isTableRenderedOnFirstPage(renderingContext);
+ }
+ }
+ }
+ return false;
}
public boolean isForcePageBreakBefore() {
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableBox.java
index 9f8aa309c..aece4c0ed 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableBox.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableBox.java
@@ -398,7 +398,7 @@ public void analyzePageBreaks(LayoutContext c, ContentLimitContainer container)
public void paintBackground(RenderingContext c) {
if (_contentLimitContainer == null) {
super.paintBackground(c);
- } else if (getStyle().isVisible()) {
+ } else if (getStyle().isVisible(c, this)) {
c.getOutputDevice().paintBackground(
c, getStyle(), getContentLimitedBorderEdge(c), getPaintingBorderEdge(c),
getStyle().getBorder(c));
@@ -408,7 +408,7 @@ c, getStyle(), getContentLimitedBorderEdge(c), getPaintingBorderEdge(c),
public void paintBorder(RenderingContext c) {
if (_contentLimitContainer == null) {
super.paintBorder(c);
- } else if (getStyle().isVisible()) {
+ } else if (getStyle().isVisible(c, this)) {
c.getOutputDevice().paintBorder(c, getStyle(), getContentLimitedBorderEdge(c), getBorderSides());
}
}
@@ -866,6 +866,13 @@ public boolean hasContentLimitContainer() {
return _contentLimitContainer != null;
}
+ /**
+ * @return true if the table is rendered on its first page. false if the table is rendered after a page break
+ */
+ public boolean isTableRenderedOnFirstPage(RenderingContext context){
+ return hasContentLimitContainer() && _contentLimitContainer.getInitialPageNo() == context.getPageNo();
+ }
+
public int getExtraSpaceTop() {
return _extraSpaceTop;
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableCellBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableCellBox.java
index 56238814d..f6fa42878 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableCellBox.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/newtable/TableCellBox.java
@@ -260,7 +260,7 @@ private boolean isPaintBackgroundsAndBorders() {
}
public void paintBackground(RenderingContext c) {
- if (isPaintBackgroundsAndBorders() && getStyle().isVisible()) {
+ if (isPaintBackgroundsAndBorders() && getStyle().isVisible(c, this)) {
Rectangle bounds;
if (c.isPrint() && getTable().getStyle().isPaginateTable()) {
bounds = getContentLimitedBorderEdge(c);
@@ -315,7 +315,7 @@ bounds, getTable().getColumnBounds(c, getCol()),
public void paintBorder(RenderingContext c) {
if (isPaintBackgroundsAndBorders() && ! hasCollapsedPaintingBorder()) {
// Collapsed table borders are painted separately
- if (c.isPrint() && getTable().getStyle().isPaginateTable() && getStyle().isVisible()) {
+ if (c.isPrint() && getTable().getStyle().isPaginateTable() && getStyle().isVisible(c, this)) {
Rectangle bounds = getContentLimitedBorderEdge(c);
if (bounds != null) {
c.getOutputDevice().paintBorder(c, getStyle(), bounds, getBorderSides());
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/AbstractOutputDevice.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/AbstractOutputDevice.java
index 07ed7591f..485c955d8 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/AbstractOutputDevice.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/AbstractOutputDevice.java
@@ -167,7 +167,7 @@ public void paintCollapsedBorder(
}
public void paintBorder(RenderingContext c, Box box) {
- if (! box.getStyle().isVisible()) {
+ if (! box.getStyle().isVisible(c, box)) {
return;
}
@@ -200,7 +200,7 @@ public void paintBackground(
}
public void paintBackground(RenderingContext c, Box box) {
- if (! box.getStyle().isVisible()) {
+ if (! box.getStyle().isVisible(c, box)) {
return;
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java
index 76f1940f7..5f3dccb31 100755
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java
@@ -256,7 +256,7 @@ public String dump(LayoutContext c, String indent, int which) {
}
public void paintListMarker(RenderingContext c) {
- if (! getStyle().isVisible()) {
+ if (! getStyle().isVisible(c, this)) {
return;
}
@@ -281,7 +281,7 @@ public Rectangle getPaintingClipEdge(CssContext cssCtx) {
}
public void paintInline(RenderingContext c) {
- if (! getStyle().isVisible()) {
+ if (! getStyle().isVisible(c, this)) {
return;
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/Box.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/Box.java
index 6807eb5e2..649784392 100755
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/Box.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/Box.java
@@ -691,7 +691,7 @@ public Box find(CssContext cssCtx, int absX, int absY, boolean findAnonymous) {
}
Rectangle edge = getContentAreaEdge(getAbsX(), getAbsY(), cssCtx);
- return edge.contains(absX, absY) && getStyle().isVisible() ? this : null;
+ return edge.contains(absX, absY) && getStyle().isVisible(null, this) ? this : null;
}
public boolean isRoot() {
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineLayoutBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineLayoutBox.java
index c1e316dbf..b9403e31d 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineLayoutBox.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineLayoutBox.java
@@ -251,7 +251,7 @@ public void paintSelection(RenderingContext c) {
}
public void paintInline(RenderingContext c) {
- if (! getStyle().isVisible()) {
+ if (! getStyle().isVisible(c, this)) {
return;
}
@@ -785,7 +785,7 @@ public Box find(CssContext cssCtx, int absX, int absY, boolean findAnonymous) {
}
Rectangle edge = getContentAreaEdge(getAbsX(), getAbsY(), cssCtx);
- result = edge.contains(absX, absY) && getStyle().isVisible() ? this : null;
+ result = edge.contains(absX, absY) && getStyle().isVisible(null, this) ? this : null;
if (! findAnonymous && result != null && getElement() == null) {
return getParent().getParent();
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/LineBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/LineBox.java
index 485d68fb9..867fc62c9 100755
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/LineBox.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/LineBox.java
@@ -109,7 +109,7 @@ public Rectangle getMarginEdge(CssContext cssCtx, int tx, int ty) {
}
public void paintInline(RenderingContext c) {
- if (! getParent().getStyle().isVisible()) {
+ if (! getParent().getStyle().isVisible(c, this)) {
return;
}