2023-11-15 18:26:43 +01:00
open Pdfutil
open Cpdferror
2023-11-28 17:14:07 +01:00
(* 1. FIXME btt / rtl / columns *)
(* 2. FIXME Test/document how the sharing affects other cpdf operations - especially with -fast! What do we do with fast/slow, and what does it affect, and does -fast need documentation about what happens in general with shared content streams. *)
(* 3. Annotations must be duplicated *)
(* 4. What is the effect on bookmarks and links annotations? *)
(* 5. Any other page meta items? *)
2023-11-16 19:18:11 +01:00
2023-11-20 11:53:51 +01:00
(* Chop a single page into pieces. We prefer the cropbox when available. We set
mediabox only , and delete any other boxes . * )
2023-11-20 15:12:33 +01:00
let get_box pdf page =
match Pdf . lookup_direct pdf " /CropBox " page . Pdfpage . rest with
| Some r -> Pdf . parse_rectangle pdf r
| None -> Pdf . parse_rectangle pdf page . Pdfpage . mediabox
let erase_boxes d =
let f = Pdf . remove_dict_entry in
f ( f ( f ( f d " /CropBox " ) " /BleedBox " ) " /TrimBox " ) " /ArtBox "
2023-11-20 15:42:00 +01:00
let chop_boxes pdf x y columns btt rtl p =
2023-11-20 12:29:17 +01:00
if x < 1 | | y < 1 then Cpdferror . error " chop_boxes bad specification " else
2023-11-20 15:12:33 +01:00
let move_page mx my p w h dx dy =
(* Printf.printf "move_page by %f %f\n" dx dy; *)
let nminx , nminy , nmaxx , nmaxy = ( mx + . dx , my + . dy , mx + . w + . dx , my + . h + . dy ) in
(* Printf.printf "new box: %f, %f, %f, %f\n" nminx nminy nmaxx nmaxy; *)
{ p with
Pdfpage . mediabox = Pdf . Array [ Pdf . Real nminx ; Pdf . Real nminy ; Pdf . Real nmaxx ; Pdf . Real nmaxy ] ;
Pdfpage . rest = erase_boxes p . Pdfpage . rest }
2023-11-20 14:21:44 +01:00
in
2023-11-20 15:12:33 +01:00
let minx , miny , maxx , maxy = get_box pdf p in
(* Printf.printf "minx, miny, maxx, maxy = %f, %f, %f, %f\n" minx miny maxx maxy; *)
2023-11-20 12:29:17 +01:00
let w , h = ( maxx -. minx ) /. float_of_int x , ( maxy -. miny ) /. float_of_int y in
let ps = ref [] in
2023-11-20 15:42:00 +01:00
let move_page = move_page minx miny p w h in
(* columns, btt, rtl *)
for ty = y - 1 downto 0 do for tx = 0 to x - 1 do
ps = | move_page ( w * . float_of_int tx ) ( h * . float_of_int ty )
done done ;
2023-11-20 12:29:17 +01:00
rev ! ps
2023-11-20 11:53:51 +01:00
(* Chop pages in the range into pieces *)
2023-11-20 15:42:00 +01:00
let chop ~ x ~ y ~ columns ~ btt ~ rtl pdf range =
2023-11-20 11:53:51 +01:00
let pages = Pdfpage . pages_of_pagetree pdf in
2023-11-28 17:14:07 +01:00
let pages_out =
2023-11-20 11:53:51 +01:00
flatten
( map2
2023-11-20 15:42:00 +01:00
( fun n p -> if mem n range then chop_boxes pdf x y columns btt rtl p else [ p ] )
2023-11-20 11:53:51 +01:00
( ilist 1 ( Pdfpage . endpage pdf ) )
pages )
in
2023-11-28 17:14:07 +01:00
let changes =
let q = ref 0 in
flatten
( map2
( fun n p ->
if mem n range
then ( q + = 1 ; let r = combine ( many n ( x * y ) ) ( ilist ! q ( ! q + x * y - 1 ) ) in q + = ( x * y - 1 ) ; r )
else ( q + = 1 ; [ ( n , ! q ) ] ) )
( ilist 1 ( Pdfpage . endpage pdf ) )
pages )
in
(* iter ( fun ( a, b ) -> Printf.printf "%i -> %i\n" a b ) changes; *)
Pdfpage . change_pages ~ changes true pdf pages_out