From 7441aee484ab3405f935420766fdcdbcca8e15da Mon Sep 17 00:00:00 2001 From: John Whitington Date: Thu, 22 Dec 2022 20:42:55 +0000 Subject: [PATCH] more --- cpdfcommand.ml | 25 +++++++++++++++++++++---- cpdfdraw.ml | 44 ++++++++++++++++++++++++++++++++------------ cpdfdraw.mli | 2 +- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 9cff4e4..0020b3e 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -1899,7 +1899,7 @@ let setmrotate s = let setmscale s = match readfloats s with | [a; b; c; d] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.Scale ((a, b), c, d)])) - | _ | exception _ -> error "-mtranslate takes four numbers" + | _ | exception _ -> error "-mscale takes four numbers" let setmshearx s = match readfloats s with @@ -1925,10 +1925,27 @@ let usexobj s = _ -> error (Printf.sprintf "Could not find stashed graphics %s\n" s) let addjpeg n = - let objnum = - 0 + let name, filename = + match String.split_on_char '=' n with + | [name; filename] -> name, filename + | _ -> error "addjpeg: bad file specification" in - addop (Cpdfdraw.ImageXObject (n, objnum)) + try + let data = Pdfio.bytes_of_string (contents_of_file filename) in + let w, h = Pdfjpeg.jpeg_dimensions data in + let d = + ["/Length", Pdf.Integer (Pdfio.bytes_size data); + "/Filter", Pdf.Name "/DCTDecode"; + "/BitsPerComponent", Pdf.Integer 8; + "/ColorSpace", Pdf.Name "/DeviceRGB"; + "/Subtype", Pdf.Name "/Image"; + "/Width", Pdf.Integer w; + "/Height", Pdf.Integer h] + in + let obj = Pdf.Stream {contents = (Pdf.Dictionary d , Pdf.Got data)} in + addop (Cpdfdraw.ImageXObject (name, obj)) + with + _ -> error "addjpeg: could not load JPEG" let addimage s = addop (Cpdfdraw.Image s) diff --git a/cpdfdraw.ml b/cpdfdraw.ml index ea59f0b..f165756 100644 --- a/cpdfdraw.ml +++ b/cpdfdraw.ml @@ -35,15 +35,15 @@ type drawops = | SoftXObject of drawops list | HardXObject of drawops list | Image of string - | ImageXObject of string * int + | ImageXObject of string * Pdf.pdfobject -(* Hash table of (human name, (resources name, object number)) for image xobjects *) +(* Hash table of (human name, (resources name, object)) for image xobjects *) let images = null_hash () (* Fresh XObject names. If we are stamping over another page, manage clashes later. *) let fresh_xobj_name () = "/Img0" -let rec ops_of_drawop = function +let rec ops_of_drawop pdf = function | Push -> [Pdfops.Op_q] | Pop -> [Pdfops.Op_Q] | Matrix m -> [Pdfops.Op_cm m] @@ -79,17 +79,37 @@ let rec ops_of_drawop = function | SetMiterLimit m -> [Pdfops.Op_M m] | SetDashPattern (x, y) -> [Pdfops.Op_d (x, y)] | SoftXObject l | HardXObject l -> - [Pdfops.Op_q] @ ops_of_drawops l @ [Pdfops.Op_Q] + [Pdfops.Op_q] @ ops_of_drawops pdf l @ [Pdfops.Op_Q] | Image s -> [Pdfops.Op_Do (try fst (Hashtbl.find images s) with _ -> Cpdferror.error ("Image not found: " ^ s))] - | ImageXObject (s, i) -> - Hashtbl.add images s (fresh_xobj_name (), i); + | ImageXObject (s, obj) -> + Hashtbl.add images s (fresh_xobj_name (), Pdf.addobj pdf obj); [] -and ops_of_drawops drawops = - flatten (map ops_of_drawop drawops) +and ops_of_drawops pdf drawops = + flatten (map (ops_of_drawop pdf) drawops) -(* Draw all the accumulated operators. FIXME: Manage name clashes in Xobjects etc, -by using something more robust than append_page_content! *) +(* Draw all the accumulated operators. FIXME: Manage name clashes in Xobjects *) let draw fast range pdf drawops = - let s = Pdfops.string_of_ops (ops_of_drawops drawops) in - Cpdftweak.append_page_content s false fast range pdf + let s = Pdfops.string_of_ops (ops_of_drawops pdf drawops) in + let pdf = Cpdftweak.append_page_content s false fast range pdf in + let images = list_of_hashtbl images in + let resources = map (fun (_, (n, o)) -> (n, Pdf.Indirect o)) images in + match images with [] -> pdf | _ -> + let pages = Pdfpage.pages_of_pagetree pdf in + let pages = + map + (fun p -> + let new_resources = + let existing = + begin match Pdf.lookup_direct pdf "/XObject" p.Pdfpage.resources with + | Some (Pdf.Dictionary d) -> d + | _ -> [] + end + in + let new_xobjects = fold_right (fun (k, v) d -> add k v d) resources existing in + Pdf.add_dict_entry p.Pdfpage.resources "/XObject" (Pdf.Dictionary new_xobjects) + in + {p with resources = new_resources}) + pages + in + Pdfpage.change_pages true pdf pages diff --git a/cpdfdraw.mli b/cpdfdraw.mli index 2012abe..78e02e4 100644 --- a/cpdfdraw.mli +++ b/cpdfdraw.mli @@ -33,6 +33,6 @@ type drawops = | SoftXObject of drawops list | HardXObject of drawops list | Image of string - | ImageXObject of string * int + | ImageXObject of string * Pdf.pdfobject val draw : bool -> int list -> Pdf.t -> drawops list -> Pdf.t