mirror of
https://github.com/johnwhitington/cpdf-source.git
synced 2025-04-19 04:27:33 +02:00
Extending attachment functions
This commit is contained in:
parent
82cb349e92
commit
a68136c6c2
154
cpdf.ml
154
cpdf.ml
@ -673,89 +673,91 @@ let presentation range t d h i dir effect_dur pdf =
|
|||||||
Pdfpage.change_pages true pdf pages'
|
Pdfpage.change_pages true pdf pages'
|
||||||
|
|
||||||
(* Attaching files *)
|
(* Attaching files *)
|
||||||
let make_filestream file =
|
let attach_file ?memory keepversion topage pdf file =
|
||||||
let data =
|
let data =
|
||||||
let ch = open_in_bin file in
|
match memory with
|
||||||
let len = in_channel_length ch in
|
Some data -> data
|
||||||
let stream = mkbytes len in
|
| None ->
|
||||||
let i = input_of_channel ch in
|
let ch = open_in_bin file in
|
||||||
setinit i stream 0 len;
|
let len = in_channel_length ch in
|
||||||
close_in ch;
|
let stream = mkbytes len in
|
||||||
stream
|
let i = input_of_channel ch in
|
||||||
|
setinit i stream 0 len;
|
||||||
|
close_in ch;
|
||||||
|
stream
|
||||||
in
|
in
|
||||||
Pdf.Stream
|
let filestream =
|
||||||
(ref (Pdf.Dictionary
|
Pdf.Stream
|
||||||
[("/Length", Pdf.Integer (bytes_size data));
|
(ref (Pdf.Dictionary
|
||||||
("/Type", Pdf.Name "/EmbeddedFile")],
|
[("/Length", Pdf.Integer (bytes_size data));
|
||||||
Pdf.Got data))
|
("/Type", Pdf.Name "/EmbeddedFile")],
|
||||||
|
Pdf.Got data))
|
||||||
let attach_file keepversion topage pdf file =
|
in
|
||||||
let filestream = make_filestream file in
|
let filestream_num = Pdf.addobj pdf filestream in
|
||||||
let filestream_num = Pdf.addobj pdf filestream in
|
let filespec =
|
||||||
let filespec =
|
Pdf.Dictionary
|
||||||
Pdf.Dictionary
|
[("/EF", Pdf.Dictionary ["/F", Pdf.Indirect filestream_num]);
|
||||||
[("/EF", Pdf.Dictionary ["/F", Pdf.Indirect filestream_num]);
|
("/F", Pdf.String (Filename.basename file));
|
||||||
("/F", Pdf.String (Filename.basename file));
|
("/Type", Pdf.Name "/F")]
|
||||||
("/Type", Pdf.Name "/F")]
|
in
|
||||||
in
|
match topage with
|
||||||
match topage with
|
| None ->
|
||||||
| None ->
|
(* Look up /Names and /EmbeddedFiles and /Names. *)
|
||||||
(* Look up /Names and /EmbeddedFiles and /Names. *)
|
let rootdict = Pdf.lookup_obj pdf pdf.Pdf.root in
|
||||||
let rootdict = Pdf.lookup_obj pdf pdf.Pdf.root in
|
let namedict =
|
||||||
let namedict =
|
match Pdf.lookup_direct pdf "/Names" rootdict with
|
||||||
match Pdf.lookup_direct pdf "/Names" rootdict with
|
|
||||||
| None -> Pdf.Dictionary []
|
|
||||||
| Some namedict -> namedict
|
|
||||||
in
|
|
||||||
let embeddednamedict =
|
|
||||||
match Pdf.lookup_direct pdf "/EmbeddedFiles" namedict with
|
|
||||||
| None -> Pdf.Dictionary []
|
| None -> Pdf.Dictionary []
|
||||||
| Some embeddednamedict -> embeddednamedict
|
| Some namedict -> namedict
|
||||||
in
|
in
|
||||||
let elts =
|
let embeddednamedict =
|
||||||
match Pdf.lookup_direct pdf "/Names" embeddednamedict with
|
match Pdf.lookup_direct pdf "/EmbeddedFiles" namedict with
|
||||||
| Some (Pdf.Array elts) -> elts
|
| None -> Pdf.Dictionary []
|
||||||
| _ -> []
|
| Some embeddednamedict -> embeddednamedict
|
||||||
in
|
in
|
||||||
let names' = Pdf.Array (elts @ [Pdf.String (Filename.basename file); filespec]) in
|
let elts =
|
||||||
let embeddednamedict' = Pdf.add_dict_entry embeddednamedict "/Names" names' in
|
match Pdf.lookup_direct pdf "/Names" embeddednamedict with
|
||||||
let namedict' = Pdf.add_dict_entry namedict "/EmbeddedFiles" embeddednamedict' in
|
| Some (Pdf.Array elts) -> elts
|
||||||
let rootdict' = Pdf.add_dict_entry rootdict "/Names" namedict' in
|
| _ -> []
|
||||||
let rootnum = Pdf.addobj pdf rootdict' in
|
|
||||||
{pdf with
|
|
||||||
Pdf.minor = if keepversion then pdf.Pdf.minor else max pdf.Pdf.minor 4;
|
|
||||||
Pdf.root = rootnum;
|
|
||||||
Pdf.trailerdict =
|
|
||||||
Pdf.add_dict_entry
|
|
||||||
pdf.Pdf.trailerdict "/Root" (Pdf.Indirect rootnum)}
|
|
||||||
| Some pagenumber ->
|
|
||||||
let pages = Pdfpage.pages_of_pagetree pdf in
|
|
||||||
if pagenumber < 0 || pagenumber > length pages then error "attach_file: Page not found" else
|
|
||||||
let page = select pagenumber pages in
|
|
||||||
let annots =
|
|
||||||
match Pdf.lookup_direct pdf "/Annots" page.Pdfpage.rest with
|
|
||||||
| Some (Pdf.Array annots) -> annots
|
|
||||||
| _ -> []
|
|
||||||
in
|
|
||||||
let rect =
|
|
||||||
let minx, miny, maxx, maxy = Pdf.parse_rectangle page.Pdfpage.mediabox in
|
|
||||||
Pdf.Array [Pdf.Real 18.; Pdf.Real (maxy -. 45.); Pdf.Real 45.; Pdf.Real (maxy -. 18.)]
|
|
||||||
in
|
in
|
||||||
let annot =
|
let names' = Pdf.Array (elts @ [Pdf.String (Filename.basename file); filespec]) in
|
||||||
Pdf.Dictionary
|
let embeddednamedict' = Pdf.add_dict_entry embeddednamedict "/Names" names' in
|
||||||
[("/FS", filespec);
|
let namedict' = Pdf.add_dict_entry namedict "/EmbeddedFiles" embeddednamedict' in
|
||||||
("/Subtype", Pdf.Name "/FileAttachment");
|
let rootdict' = Pdf.add_dict_entry rootdict "/Names" namedict' in
|
||||||
("/Contents", Pdf.String (Filename.basename file));
|
let rootnum = Pdf.addobj pdf rootdict' in
|
||||||
("/Rect", rect)]
|
{pdf with
|
||||||
|
Pdf.minor = if keepversion then pdf.Pdf.minor else max pdf.Pdf.minor 4;
|
||||||
|
Pdf.root = rootnum;
|
||||||
|
Pdf.trailerdict =
|
||||||
|
Pdf.add_dict_entry
|
||||||
|
pdf.Pdf.trailerdict "/Root" (Pdf.Indirect rootnum)}
|
||||||
|
| Some pagenumber ->
|
||||||
|
let pages = Pdfpage.pages_of_pagetree pdf in
|
||||||
|
if pagenumber < 0 || pagenumber > length pages then error "attach_file: Page not found" else
|
||||||
|
let page = select pagenumber pages in
|
||||||
|
let annots =
|
||||||
|
match Pdf.lookup_direct pdf "/Annots" page.Pdfpage.rest with
|
||||||
|
| Some (Pdf.Array annots) -> annots
|
||||||
|
| _ -> []
|
||||||
|
in
|
||||||
|
let rect =
|
||||||
|
let minx, miny, maxx, maxy = Pdf.parse_rectangle page.Pdfpage.mediabox in
|
||||||
|
Pdf.Array [Pdf.Real 18.; Pdf.Real (maxy -. 45.); Pdf.Real 45.; Pdf.Real (maxy -. 18.)]
|
||||||
in
|
in
|
||||||
let annots' = Pdf.Array (annot::annots) in
|
let annot =
|
||||||
let page' =
|
Pdf.Dictionary
|
||||||
{page with Pdfpage.rest = Pdf.add_dict_entry page.Pdfpage.rest "/Annots" annots'}
|
[("/FS", filespec);
|
||||||
in
|
("/Subtype", Pdf.Name "/FileAttachment");
|
||||||
let pages' = replace_number pagenumber page' pages in
|
("/Contents", Pdf.String (Filename.basename file));
|
||||||
let pdf = Pdfpage.change_pages false pdf pages' in
|
("/Rect", rect)]
|
||||||
{pdf with
|
in
|
||||||
Pdf.minor = if keepversion then pdf.Pdf.minor else max pdf.Pdf.minor 4}
|
let annots' = Pdf.Array (annot::annots) in
|
||||||
|
let page' =
|
||||||
|
{page with Pdfpage.rest = Pdf.add_dict_entry page.Pdfpage.rest "/Annots" annots'}
|
||||||
|
in
|
||||||
|
let pages' = replace_number pagenumber page' pages in
|
||||||
|
let pdf = Pdfpage.change_pages false pdf pages' in
|
||||||
|
{pdf with
|
||||||
|
Pdf.minor = if keepversion then pdf.Pdf.minor else max pdf.Pdf.minor 4}
|
||||||
|
|
||||||
let list_attached_files pdf =
|
let list_attached_files pdf =
|
||||||
let toplevel =
|
let toplevel =
|
||||||
|
2
cpdf.mli
2
cpdf.mli
@ -149,7 +149,7 @@ val presentation : int list -> string option ->
|
|||||||
|
|
||||||
(** {2 File Attachments} *)
|
(** {2 File Attachments} *)
|
||||||
(** [attach_file keepversion topage pdf filename] attaches the file in [filename] to the pdf, optionally to a page (rather than document-level). If keepversion is true, the PDF version number won't be altered. *)
|
(** [attach_file keepversion topage pdf filename] attaches the file in [filename] to the pdf, optionally to a page (rather than document-level). If keepversion is true, the PDF version number won't be altered. *)
|
||||||
val attach_file : bool -> int option -> Pdf.t -> string -> Pdf.t
|
val attach_file : ?memory:Pdfio.bytes -> bool -> int option -> Pdf.t -> string -> Pdf.t
|
||||||
|
|
||||||
(** Remove attached files. *)
|
(** Remove attached files. *)
|
||||||
val remove_attached_files : Pdf.t -> Pdf.t
|
val remove_attached_files : Pdf.t -> Pdf.t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user