@flowaccount/pdfmake 1.0.7-staging.3 → 1.0.7-staging.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/pdfmake.js +595 -492
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/package.json +1 -1
- package/src/layoutBuilder.js +121 -15
package/package.json
CHANGED
package/src/layoutBuilder.js
CHANGED
|
@@ -539,13 +539,31 @@ LayoutBuilder.prototype.processNode = function (node) {
|
|
|
539
539
|
startPage: ctx.page,
|
|
540
540
|
availableHeight: ctx.availableHeight,
|
|
541
541
|
itemCount: currentPage ? currentPage.items.length : 0,
|
|
542
|
-
x: ctx.x
|
|
542
|
+
x: ctx.x,
|
|
543
|
+
summaryRenderedPage: null
|
|
543
544
|
};
|
|
544
545
|
}
|
|
545
546
|
|
|
546
547
|
// Process the stack
|
|
547
548
|
self.processVerticalContainer(node);
|
|
548
549
|
|
|
550
|
+
// Track which page summary was rendered on (summary is first item, unbreakable)
|
|
551
|
+
if (preRenderState && node.stack && node.stack[0]) {
|
|
552
|
+
var summaryNode = node.stack[0];
|
|
553
|
+
if (summaryNode.summary || summaryNode.unbreakable) {
|
|
554
|
+
// Summary is unbreakable, check if it was pushed to a new page
|
|
555
|
+
// by comparing its height with available space at startPage
|
|
556
|
+
var summaryHeight = Math.abs(summaryNode._height || 0);
|
|
557
|
+
if (summaryHeight <= preRenderState.availableHeight) {
|
|
558
|
+
// Summary fit on startPage
|
|
559
|
+
preRenderState.summaryRenderedPage = preRenderState.startPage;
|
|
560
|
+
} else {
|
|
561
|
+
// Summary was pushed to next page
|
|
562
|
+
preRenderState.summaryRenderedPage = preRenderState.startPage + 1;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
549
567
|
// Post-render repositioning
|
|
550
568
|
if (footerGapEnabled && preRenderState) {
|
|
551
569
|
var ctx = self.writer.context();
|
|
@@ -726,9 +744,12 @@ LayoutBuilder.prototype.processNode = function (node) {
|
|
|
726
744
|
sItemY = sItem.item.y1;
|
|
727
745
|
} else if (sItem.item && typeof sItem.item.y === 'number') {
|
|
728
746
|
sItemY = sItem.item.y;
|
|
747
|
+
} else if (sItem.item && sItem.item.points && Array.isArray(sItem.item.points) && sItem.item.points.length > 0) {
|
|
748
|
+
// For polylines, use the first point's Y
|
|
749
|
+
sItemY = sItem.item.points[0].y;
|
|
729
750
|
}
|
|
730
751
|
|
|
731
|
-
|
|
752
|
+
// Skip items fully above footer start
|
|
732
753
|
if (sItemY === null || sItemY < startStackStartY) continue;
|
|
733
754
|
|
|
734
755
|
// Move item down
|
|
@@ -827,19 +848,35 @@ LayoutBuilder.prototype.processNode = function (node) {
|
|
|
827
848
|
if (typeof item.item.y2 === 'number' && item.item.y2 > itemBottom) {
|
|
828
849
|
itemBottom = item.item.y2;
|
|
829
850
|
}
|
|
851
|
+
// Handle polylines (points array)
|
|
852
|
+
if (item.item.points && Array.isArray(item.item.points)) {
|
|
853
|
+
for (var pi = 0; pi < item.item.points.length; pi++) {
|
|
854
|
+
if (typeof item.item.points[pi].y === 'number' && item.item.points[pi].y > itemBottom) {
|
|
855
|
+
itemBottom = item.item.points[pi].y;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
830
859
|
}
|
|
831
860
|
if (itemBottom > contentBottom) {
|
|
832
861
|
contentBottom = itemBottom;
|
|
833
862
|
}
|
|
834
863
|
}
|
|
835
864
|
|
|
836
|
-
//
|
|
837
|
-
var
|
|
865
|
+
// Check if summary is on the last page
|
|
866
|
+
var summaryOnLastPage = (preRenderState.summaryRenderedPage === pageIdx);
|
|
838
867
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
//
|
|
868
|
+
var stackStartY;
|
|
869
|
+
if (summaryOnLastPage) {
|
|
870
|
+
// Summary is on this page - move all: summary + remark + footer together
|
|
871
|
+
// Calculate header threshold for this page
|
|
872
|
+
var repeatableHeaderHeight = 0;
|
|
873
|
+
for (var ri = 0; ri < self.writer.repeatables.length; ri++) {
|
|
874
|
+
repeatableHeaderHeight += self.writer.repeatables[ri].height;
|
|
875
|
+
}
|
|
876
|
+
var headerThreshold = pageMargins.top + repeatableHeaderHeight;
|
|
877
|
+
|
|
878
|
+
// Find minimum Y of all items below header threshold
|
|
879
|
+
stackStartY = contentBottom;
|
|
843
880
|
for (var i = 0; i < page.items.length; i++) {
|
|
844
881
|
var item = page.items[i];
|
|
845
882
|
var itemY = null;
|
|
@@ -848,23 +885,92 @@ LayoutBuilder.prototype.processNode = function (node) {
|
|
|
848
885
|
} else if (item.item && typeof item.item.y === 'number') {
|
|
849
886
|
itemY = item.item.y;
|
|
850
887
|
} else if (item.item && item.item.points && Array.isArray(item.item.points) && item.item.points.length > 0) {
|
|
851
|
-
// For polylines, use the first point's Y
|
|
852
888
|
itemY = item.item.points[0].y;
|
|
853
889
|
}
|
|
890
|
+
if (itemY !== null && itemY >= headerThreshold && itemY < stackStartY) {
|
|
891
|
+
stackStartY = itemY;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
854
894
|
|
|
855
|
-
|
|
856
|
-
|
|
895
|
+
// Draw guide lines in the gap area (same as single-page)
|
|
896
|
+
var gapHeightForLines = pageBottom - contentBottom;
|
|
897
|
+
if (gapHeightForLines > 0) {
|
|
898
|
+
var colSpec = node._footerGapOption && node._footerGapOption.columns ? node._footerGapOption.columns : (self._footerGapOption && self._footerGapOption.columns);
|
|
899
|
+
if (colSpec) {
|
|
900
|
+
var rawWidths = colSpec.content && colSpec.content.vLines ? colSpec.content.vLines : [];
|
|
901
|
+
if (rawWidths && rawWidths.length > 1) {
|
|
902
|
+
var style = (colSpec.style || {});
|
|
903
|
+
var lw = style.lineWidth != null ? style.lineWidth : 0.5;
|
|
904
|
+
var lc = style.color || '#000000';
|
|
905
|
+
var dashCfg = style.dash;
|
|
906
|
+
var includeOuter = colSpec.includeOuter !== false;
|
|
907
|
+
var startIndex = includeOuter ? 0 : 1;
|
|
908
|
+
var endIndex = includeOuter ? rawWidths.length : rawWidths.length - 1;
|
|
909
|
+
var pageX = preRenderState.x || pageMargins.left;
|
|
910
|
+
|
|
911
|
+
for (var ci = startIndex; ci < endIndex; ci++) {
|
|
912
|
+
var xGuide = pageX + rawWidths[ci] - 0.25;
|
|
913
|
+
page.items.push({
|
|
914
|
+
type: 'vector',
|
|
915
|
+
item: {
|
|
916
|
+
type: 'line',
|
|
917
|
+
x1: xGuide,
|
|
918
|
+
y1: stackStartY,
|
|
919
|
+
x2: xGuide,
|
|
920
|
+
y2: stackStartY + gapHeightForLines,
|
|
921
|
+
lineWidth: lw,
|
|
922
|
+
lineColor: lc,
|
|
923
|
+
dash: dashCfg ? {
|
|
924
|
+
length: dashCfg.length,
|
|
925
|
+
space: dashCfg.space != null ? dashCfg.space : dashCfg.gap
|
|
926
|
+
} : undefined,
|
|
927
|
+
_footerGuideLine: true
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
} else {
|
|
935
|
+
// Summary is NOT on this page - move only footer
|
|
936
|
+
stackStartY = contentBottom - stackHeight;
|
|
937
|
+
}
|
|
857
938
|
|
|
858
|
-
|
|
859
|
-
|
|
939
|
+
// Calculate gap: how much to move footer stack down
|
|
940
|
+
var gapHeight = pageBottom - contentBottom;
|
|
941
|
+
if (gapHeight > 0) {
|
|
942
|
+
// Calculate header threshold if not already calculated
|
|
943
|
+
if (typeof headerThreshold === 'undefined') {
|
|
860
944
|
var repeatableHeaderHeight = 0;
|
|
861
945
|
for (var ri = 0; ri < self.writer.repeatables.length; ri++) {
|
|
862
946
|
repeatableHeaderHeight += self.writer.repeatables[ri].height;
|
|
863
947
|
}
|
|
864
|
-
|
|
948
|
+
headerThreshold = pageMargins.top + repeatableHeaderHeight;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// Move all items that are part of footer stack (Y >= stackStartY)
|
|
952
|
+
for (var i = 0; i < page.items.length; i++) {
|
|
953
|
+
var item = page.items[i];
|
|
954
|
+
|
|
955
|
+
// Skip guide lines (they're already positioned correctly)
|
|
956
|
+
if (item.item && item.item._footerGuideLine) continue;
|
|
957
|
+
|
|
958
|
+
var itemY = null;
|
|
959
|
+
if (item.item && typeof item.item.y1 === 'number') {
|
|
960
|
+
itemY = item.item.y1;
|
|
961
|
+
} else if (item.item && typeof item.item.y === 'number') {
|
|
962
|
+
itemY = item.item.y;
|
|
963
|
+
} else if (item.item && item.item.points && Array.isArray(item.item.points) && item.item.points.length > 0) {
|
|
964
|
+
itemY = item.item.points[0].y;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// Skip items above footer stack
|
|
968
|
+
if (itemY === null || itemY < stackStartY) continue;
|
|
969
|
+
|
|
970
|
+
// Skip items in header area (repeated headers)
|
|
865
971
|
if (itemY < headerThreshold) continue;
|
|
866
972
|
|
|
867
|
-
// Move footer item down
|
|
973
|
+
// Move footer stack item down
|
|
868
974
|
if (item.item && typeof item.item.y === 'number') {
|
|
869
975
|
item.item.y += gapHeight;
|
|
870
976
|
}
|