diff --git a/cpdf.ml b/cpdf.ml index b29d492..1aedef9 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -3157,7 +3157,7 @@ let output_xmp_info encoding pdf = \end{verbatim} *) -let blacktext_ops pdf resources content = +let blacktext_ops (r, g, b) pdf resources content = let not_text = function | Pdfops.Op_Tj _ | Pdfops.Op_TJ _ | Pdfops.Op_' _ | Pdfops.Op_'' (_, _, _) @@ -3181,7 +3181,7 @@ let blacktext_ops pdf resources content = | Pdfops.Op_BT::more -> incr textlevel; remove_colourops - (Pdfops.Op_g 0.::Pdfops.Op_BT::prev) + (Pdfops.Op_rg (r, g, b)::Pdfops.Op_BT::prev) more | Pdfops.Op_ET::more -> decr textlevel; @@ -3253,25 +3253,25 @@ let process_xobjects pdf page f = elts | _ -> () -let blacktext range pdf = +let blacktext (r, g, b) range pdf = let blacktext_page _ page = let content' = - blacktext_ops pdf page.Pdfpage.resources page.Pdfpage.content + blacktext_ops (r, g, b) pdf page.Pdfpage.resources page.Pdfpage.content in - process_xobjects pdf page blacktext_ops; + process_xobjects pdf page (blacktext_ops (r, g, b)); {page with Pdfpage.content = content'} in process_pages blacktext_page pdf range (* \section{Blacken lines} *) -let blacklines_ops pdf resources content = +let blacklines_ops (r, g, b) pdf resources content = let rec blacken_strokeops prev = function | [] -> rev prev | Pdfops.Op_CS _::t -> - blacken_strokeops (Pdfops.Op_CS "/DeviceGray"::prev) t + blacken_strokeops (Pdfops.Op_CS "/DeviceRGB"::prev) t | (Pdfops.Op_SC _ | Pdfops.Op_SCN _ | Pdfops.Op_SCNName _ | Pdfops.Op_G _ | Pdfops.Op_RG _ | Pdfops.Op_K _)::t -> - blacken_strokeops (Pdfops.Op_G 0.::prev) t + blacken_strokeops (Pdfops.Op_RG (r, g, b)::prev) t | h::t -> blacken_strokeops (h::prev) t and operators = Pdfops.parse_operators pdf resources content @@ -3279,25 +3279,25 @@ let blacklines_ops pdf resources content = let operators' = blacken_strokeops [] operators in [Pdfops.stream_of_ops operators'] -let blacklines range pdf = +let blacklines (r, g, b) range pdf = let blacklines_page _ page = let content' = - blacklines_ops pdf page.Pdfpage.resources page.Pdfpage.content + blacklines_ops (r, g, b) pdf page.Pdfpage.resources page.Pdfpage.content in - process_xobjects pdf page blacklines_ops; + process_xobjects pdf page (blacklines_ops (r, g, b)); {page with Pdfpage.content = content'} in process_pages blacklines_page pdf range (* \section{Blacken Fills} *) -let blackfills_ops pdf resources content = +let blackfills_ops (r, g, b) pdf resources content = let rec blacken_fillops prev = function | [] -> rev prev | Pdfops.Op_cs _::t -> - blacken_fillops (Pdfops.Op_cs "/DeviceGray"::prev) t + blacken_fillops (Pdfops.Op_cs "/DeviceRGB"::prev) t | (Pdfops.Op_sc _ | Pdfops.Op_scn _ | Pdfops.Op_scnName _ | Pdfops.Op_g _ | Pdfops.Op_rg _ | Pdfops.Op_k _)::t -> - blacken_fillops (Pdfops.Op_g 0.::prev) t + blacken_fillops (Pdfops.Op_rg (r, g, b)::prev) t | h::t -> blacken_fillops (h::prev) t and operators = Pdfops.parse_operators pdf resources content @@ -3305,12 +3305,12 @@ let blackfills_ops pdf resources content = let operators' = blacken_fillops [] operators in [Pdfops.stream_of_ops operators'] -let blackfills range pdf = +let blackfills (r, g, b) range pdf = let blackfills_page _ page = let content' = - blackfills_ops pdf page.Pdfpage.resources page.Pdfpage.content + blackfills_ops (r, g, b) pdf page.Pdfpage.resources page.Pdfpage.content in - process_xobjects pdf page blackfills_ops; + process_xobjects pdf page (blackfills_ops (r, g, b)); {page with Pdfpage.content = content'} in process_pages blackfills_page pdf range diff --git a/cpdf.mli b/cpdf.mli index 3c6f088..d3aa0f0 100644 --- a/cpdf.mli +++ b/cpdf.mli @@ -459,13 +459,13 @@ val add_page_labels : val thinlines : int list -> float -> Pdf.t -> Pdf.t (** Make all text on certain pages black. *) -val blacktext : int list -> Pdf.t -> Pdf.t +val blacktext : float * float * float -> int list -> Pdf.t -> Pdf.t (** Make all lines on certain pages black. *) -val blacklines : int list -> Pdf.t -> Pdf.t +val blacklines : float * float * float -> int list -> Pdf.t -> Pdf.t (** Make all fills on certain pages black. *) -val blackfills : int list -> Pdf.t -> Pdf.t +val blackfills : float * float * float -> int list -> Pdf.t -> Pdf.t (** Remove images from a PDF, optionally adding crossed boxes. *) val draft : bool -> int list -> Pdf.t -> Pdf.t diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 62483af..a29f97a 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -166,6 +166,7 @@ type op = | RemoveDictEntry of string | ListSpotColours | RemoveClipping + | ChangeFontSize of float let string_of_op = function | CopyFont _ -> "CopyFont" @@ -270,6 +271,7 @@ let string_of_op = function | RemoveDictEntry _ -> "RemoveDictEntry" | ListSpotColours -> "ListSpotColours" | RemoveClipping -> "RemoveClipping" + | ChangeFontSize _ -> "ChangeFontSize" (* Inputs: filename, pagespec. *) type input_kind = @@ -379,7 +381,8 @@ type args = mutable was_decrypted_with_owner : bool; mutable creator : string option; mutable producer : string option; - mutable embedfonts : bool} + mutable embedfonts : bool; + mutable change_font_size_shift : string} let args = {op = None; @@ -462,7 +465,8 @@ let args = was_decrypted_with_owner = false; producer = None; creator = None; - embedfonts = true} + embedfonts = true; + change_font_size_shift = "0 0"} let reset_arguments () = args.op <- None; @@ -610,7 +614,7 @@ let banned banlist = function AddText _|ScaleContents _|AttachFile _|CopyAnnotations _|SetMetadata _| ThinLines _|SetAuthor _|SetTitle _|SetSubject _|SetKeywords _|SetCreate _| SetModify _|SetCreator _|SetProducer _|SetVersion _|RemoveDictEntry _ | - RemoveClipping -> + RemoveClipping | ChangeFontSize _ -> mem Pdfcrypt.NoEdit banlist let operation_allowed pdf banlist op = @@ -1522,6 +1526,12 @@ let setstayonerror () = let setnoembedfont () = args.embedfonts <- false +let setchangefontsizeto i = + args.op <- Some (ChangeFontSize i) + +let setchangefontsizeshift s = + args.change_font_size_shift <- s + (* Parse a control file, make an argv, and then make Arg parse it. *) let rec make_control_argv_and_parse filename = control_args := !control_args @ parse_control_file filename @@ -2066,7 +2076,9 @@ and specs = ("-debug", Arg.Unit setdebug, ""); ("-debug-crypt", Arg.Unit setdebugcrypt, ""); ("-fix-prince", Arg.Unit (setop RemoveUnusedResources), ""); - ("-extract-text", Arg.Unit (setop ExtractText), "")] + ("-extract-text", Arg.Unit (setop ExtractText), ""); + ("-change-font-size-to", Arg.Float setchangefontsizeto, ""); + ("-change-font-size-shift", Arg.String setchangefontsizeshift, "")] and usage_msg = "Syntax: cpdf [-o ] \n\n\ @@ -3161,7 +3173,14 @@ let list_spot_colours pdf = | _ -> ()) pdf -let remove_clipping_ops pdf resources content = content +let remove_clipping_ops pdf resources content = + let ops = Pdfops.parse_operators pdf resources content in + let rec process a = function + Pdfops.Op_W::Pdfops.Op_n::t -> process (Pdfops.Op_n::a) t + | h::t -> process (h::a) t + | [] -> rev a + in + [Pdfops.stream_of_ops (process [] ops)] let remove_clipping pdf range = let remove_clipping_page _ page = @@ -3173,6 +3192,9 @@ let remove_clipping pdf range = in Cpdf.process_pages remove_clipping_page pdf range +let change_font_size pdf range dx dy target_size = + pdf + (* Main function *) let go () = match args.op with @@ -3633,15 +3655,15 @@ let go () = | Some BlackText -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in - write_pdf false (Cpdf.blacktext range pdf) + write_pdf false (Cpdf.blacktext args.color range pdf) | Some BlackLines -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in - write_pdf false (Cpdf.blacklines range pdf) + write_pdf false (Cpdf.blacklines args.color range pdf) | Some BlackFills -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in - write_pdf false (Cpdf.blackfills range pdf) + write_pdf false (Cpdf.blackfills args.color range pdf) | Some RemoveAnnotations -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in @@ -3923,6 +3945,11 @@ let go () = let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in write_pdf false (remove_clipping pdf range) + | Some (ChangeFontSize target_size) -> + let pdf = get_single_pdf args.op false in + let range = parse_pagespec pdf (get_pagespec ()) in + let dx, dy = parse_coordinate pdf args.coord in + write_pdf false (change_font_size pdf range dx dy target_size) let parse_argv () = if args.debug then diff --git a/cpdfmanual.pdf b/cpdfmanual.pdf index 75891ad..6cd9fd9 100644 Binary files a/cpdfmanual.pdf and b/cpdfmanual.pdf differ diff --git a/cpdfmanual.tex b/cpdfmanual.tex index 2cfbba4..30b80eb 100644 --- a/cpdfmanual.tex +++ b/cpdfmanual.tex @@ -2141,6 +2141,9 @@ recommended when file size is the sole consideration. \vspace{1.5mm} \noindent\verb!cpdf -remove-dict-entry in.pdf -o out.pdf! + + \vspace{1.5mm} + \noindent\verb!cpdf -remove-clipping in.pdf -o out.pdf! \end{framed}} \section{Draft Documents} \index{draft} @@ -2183,6 +2186,8 @@ which is part of a form. \small\verb!cpdf -blackfills in.pdf -o out.pdf! \end{framed} +\noindent Contrary to their names, all these operations can use another color, if specified with \texttt{-color}. + \section{Hairline Removal} \index{hairline removal} Quite often, applications will use very thin lines, or even the value of 0, @@ -2269,6 +2274,19 @@ This is for editing data within the PDF's internal representation. Use with caut \end{framed} +\section{Remove Clipping} + + +The \texttt{-remove-clipping} operation removes any clipping paths from the file. + + \begin{framed} + \small\noindent\verb!cpdf -remove-clipping in.pdf -o out.pdf! + + \vspace{2.5mm} + \noindent Remove every clipping path in \texttt{in.pdf}, writing to \texttt{out.pdf}. + \end{framed} + + \appendix \chapter{Dates} \label{dates}