@@ -244,11 +244,13 @@ private static void copyTo(PdfDocument destDocument, int insertBeforePage, Map<P
244244 * @param page2page association between original page and copied page.
245245 * @param copyFromDestDocument indicates if <code>page2page</code> keys and values represent pages from {@code destDocument}.
246246 */
247- private static void copyTo (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page , PdfDocument callingDocument , boolean copyFromDestDocument ) {
247+ private static void copyTo (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page , PdfDocument callingDocument
248+ , boolean copyFromDestDocument ) {
248249 copyTo (destDocument , page2page , callingDocument , copyFromDestDocument , -1 );
249250 }
250251
251- private static void copyTo (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page , PdfDocument callingDocument , boolean copyFromDestDocument , int insertIndex ) {
252+ private static void copyTo (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page , PdfDocument callingDocument
253+ , boolean copyFromDestDocument , int insertIndex ) {
252254 CopyStructureResult copiedStructure = copyStructure (destDocument , page2page , callingDocument , copyFromDestDocument );
253255 PdfStructTreeRoot destStructTreeRoot = destDocument .getStructTreeRoot ();
254256 destStructTreeRoot .makeIndirect (destDocument );
@@ -283,7 +285,8 @@ private static void copyTo(PdfDocument destDocument, Map<PdfPage, PdfPage> page2
283285 }
284286 }
285287
286- private static CopyStructureResult copyStructure (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page , PdfDocument callingDocument , boolean copyFromDestDocument ) {
288+ private static CopyStructureResult copyStructure (PdfDocument destDocument , Map <PdfPage , PdfPage > page2page
289+ , PdfDocument callingDocument , boolean copyFromDestDocument ) {
287290 PdfDocument fromDocument = copyFromDestDocument ? destDocument : callingDocument ;
288291 Map <PdfDictionary , PdfDictionary > topsToFirstDestPage = new HashMap <>();
289292 Set <PdfObject > objectsToCopy = new HashSet <>();
@@ -380,16 +383,23 @@ private static PdfDictionary copyObject(PdfDictionary source, PdfDictionary dest
380383 }
381384
382385 PdfObject k = source .get (PdfName .K );
386+ PdfDictionary lastCopiedTrPage = null ;
383387 if (k != null ) {
384388 if (k .isArray ()) {
385389 PdfArray kArr = (PdfArray ) k ;
386390 PdfArray newArr = new PdfArray ();
387391 for (int i = 0 ; i < kArr .size (); i ++) {
388- PdfObject copiedKid = copyObjectKid (kArr .get (i ), copied , destPage , parentChangePg , copyingParams );
392+ PdfObject copiedKid = copyObjectKid (kArr .get (i ), copied , destPage , parentChangePg , copyingParams
393+ , lastCopiedTrPage );
389394 if (copiedKid != null ) {
390395 newArr .add (copiedKid );
396+ if (copiedKid instanceof PdfDictionary
397+ && PdfName .TR .equals (((PdfDictionary ) copiedKid ).getAsName (PdfName .S ))) {
398+ lastCopiedTrPage = destPage ;
399+ }
391400 }
392401 }
402+
393403 if (!newArr .isEmpty ()) {
394404 if (newArr .size () == 1 ) {
395405 copied .put (PdfName .K , newArr .get (0 ));
@@ -398,7 +408,8 @@ private static PdfDictionary copyObject(PdfDictionary source, PdfDictionary dest
398408 }
399409 }
400410 } else {
401- PdfObject copiedKid = copyObjectKid (k , copied , destPage , parentChangePg , copyingParams );
411+ PdfObject copiedKid = copyObjectKid (k , copied , destPage , parentChangePg , copyingParams
412+ , lastCopiedTrPage );
402413 if (copiedKid != null ) {
403414 copied .put (PdfName .K , copiedKid );
404415 }
@@ -407,7 +418,9 @@ private static PdfDictionary copyObject(PdfDictionary source, PdfDictionary dest
407418 return copied ;
408419 }
409420
410- private static PdfObject copyObjectKid (PdfObject kid , PdfDictionary copiedParent , PdfDictionary destPage , boolean parentChangePg , StructElemCopyingParams copyingParams ) {
421+ private static PdfObject copyObjectKid (PdfObject kid , PdfDictionary copiedParent , PdfDictionary destPage ,
422+ boolean parentChangePg , StructElemCopyingParams copyingParams ,
423+ PdfDictionary lastCopiedTrPage ) {
411424 if (kid .isNumber ()) {
412425 if (!parentChangePg ) {
413426 copyingParams .getToDocument ().getStructTreeRoot ().getParentTreeHandler ()
@@ -416,11 +429,27 @@ private static PdfObject copyObjectKid(PdfObject kid, PdfDictionary copiedParent
416429 }
417430 } else if (kid .isDictionary ()) {
418431 PdfDictionary kidAsDict = (PdfDictionary ) kid ;
419- // if element is TD and its parent is TR which was copied, then we copy it in any case
432+ //if element is TD and its parent is TR which was copied, then we copy it in any case
420433 if (copyingParams .getObjectsToCopy ().contains (kidAsDict ) ||
421434 shouldTableElementBeCopied (kidAsDict , copiedParent )) {
435+ //if TR element is not connected to any page,
436+ //it should be copied to the same page as the last copied TR which connected to page
437+ PdfDictionary destination = destPage ;
438+ if (PdfName .TR .equals (kidAsDict .getAsName (PdfName .S ))
439+ && !copyingParams .getObjectsToCopy ().contains (kidAsDict )) {
440+ if (McrCheckUtil .isTrContainsMcr (kidAsDict )){
441+ return null ;
442+ }
443+
444+ if (lastCopiedTrPage == null ) {
445+ return null ;
446+ } else {
447+ destination = lastCopiedTrPage ;
448+ }
449+ }
422450 boolean hasParent = kidAsDict .containsKey (PdfName .P );
423- PdfDictionary copiedKid = copyObject (kidAsDict , destPage , parentChangePg , copyingParams );
451+ PdfDictionary copiedKid = copyObject (kidAsDict , destination , parentChangePg , copyingParams );
452+
424453 if (hasParent ) {
425454 copiedKid .put (PdfName .P , copiedParent );
426455 } else {
@@ -446,8 +475,9 @@ private static PdfObject copyObjectKid(PdfObject kid, PdfDictionary copiedParent
446475 }
447476
448477 static boolean shouldTableElementBeCopied (PdfDictionary obj , PdfDictionary parent ) {
449- return (PdfName .TD .equals (obj .get (PdfName .S )) || PdfName .TH .equals (obj .get (PdfName .S )))
450- && PdfName .TR .equals (parent .get (PdfName .S ));
478+ PdfName role = obj .getAsName (PdfName .S );
479+ return ((PdfName .TD .equals (role ) || PdfName .TH .equals (role )) && PdfName .TR .equals (parent .get (PdfName .S )))
480+ || PdfName .TR .equals (role );
451481 }
452482
453483 private static PdfDictionary copyNamespaceDict (PdfDictionary srcNsDict , StructElemCopyingParams copyingParams ) {
0 commit comments