cpdfposition
This commit is contained in:
parent
afe80205dd
commit
671a637271
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
# Build the cpdf command line tools and top level
|
# Build the cpdf command line tools and top level
|
||||||
MODS = tjutil tjutf16 tjllist tjparserMonad tjjson xmlm \
|
MODS = tjutil tjutf16 tjllist tjparserMonad tjjson xmlm \
|
||||||
cpdfwriteJSON cpdfstrftime cpdfcoord cpdfpagespec cpdf cpdfcommand
|
cpdfwriteJSON cpdfstrftime cpdfcoord cpdfpagespec cpdfposition cpdf cpdfcommand
|
||||||
|
|
||||||
SOURCES = $(foreach x,$(MODS),$(x).ml $(x).mli) cpdfcommandrun.ml
|
SOURCES = $(foreach x,$(MODS),$(x).ml $(x).mli) cpdfcommandrun.ml
|
||||||
|
|
||||||
|
|
121
cpdf.ml
121
cpdf.ml
|
@ -1268,94 +1268,6 @@ let print_fonts pdf =
|
||||||
|
|
||||||
(* \section{Superimpose text, page numbers etc.} *)
|
(* \section{Superimpose text, page numbers etc.} *)
|
||||||
|
|
||||||
type position =
|
|
||||||
| PosCentre of float * float
|
|
||||||
| PosLeft of float * float
|
|
||||||
| PosRight of float * float
|
|
||||||
| Top of float
|
|
||||||
| TopLeft of float
|
|
||||||
| TopRight of float
|
|
||||||
| Left of float
|
|
||||||
| BottomLeft of float
|
|
||||||
| Bottom of float
|
|
||||||
| BottomRight of float
|
|
||||||
| Right of float
|
|
||||||
| Diagonal
|
|
||||||
| ReverseDiagonal
|
|
||||||
| Centre
|
|
||||||
|
|
||||||
let string_of_position = function
|
|
||||||
| PosCentre (a, b) -> Printf.sprintf "PosCentre %f %f" a b
|
|
||||||
| PosLeft (a, b) -> Printf.sprintf "PosLeft %f %f" a b
|
|
||||||
| PosRight (a, b) -> Printf.sprintf "PosRight %f %f" a b
|
|
||||||
| Top a -> Printf.sprintf "Top %f" a
|
|
||||||
| TopLeft a -> Printf.sprintf "TopLeft %f" a
|
|
||||||
| TopRight a -> Printf.sprintf "TopRight %f" a
|
|
||||||
| Left a -> Printf.sprintf "Left %f" a
|
|
||||||
| BottomLeft a -> Printf.sprintf "BottomLeft %f" a
|
|
||||||
| Bottom a -> Printf.sprintf "Bottom %f" a
|
|
||||||
| BottomRight a -> Printf.sprintf "BottomRight %f" a
|
|
||||||
| Right a -> Printf.sprintf "Right %f" a
|
|
||||||
| Diagonal -> "Diagonal"
|
|
||||||
| ReverseDiagonal -> "Reverse Diagonal"
|
|
||||||
| Centre -> "Centre"
|
|
||||||
|
|
||||||
type orientation =
|
|
||||||
| Horizontal
|
|
||||||
| Vertical
|
|
||||||
| VerticalDown
|
|
||||||
|
|
||||||
type justification = LeftJustify | CentreJustify | RightJustify
|
|
||||||
|
|
||||||
(* Given the mediabox, calculate an absolute position for the text. *)
|
|
||||||
let calculate_position ignore_d w (xmin, ymin, xmax, ymax) orientation pos =
|
|
||||||
let rot = if orientation = VerticalDown then rad_of_deg 270. else 0. in
|
|
||||||
match pos with
|
|
||||||
| Centre ->
|
|
||||||
(xmin +. xmax) /. 2. -. w /. 2.,
|
|
||||||
(ymin +. ymax) /. 2.,
|
|
||||||
rot
|
|
||||||
| Diagonal ->
|
|
||||||
let angle = atan ((ymax -. ymin) /. (xmax -. xmin))
|
|
||||||
in let cx, cy = (xmax +. xmin) /. 2., (ymax +. ymin) /. 2. in
|
|
||||||
let dl = w /. 2. in
|
|
||||||
let dx = dl *. cos angle
|
|
||||||
in let dy = dl *. sin angle in
|
|
||||||
cx -. dx, cy -. dy, angle
|
|
||||||
| ReverseDiagonal ->
|
|
||||||
let angle = atan ((ymax -. ymin) /. (xmax -. xmin))
|
|
||||||
in let cx, cy = (xmax +. xmin) /. 2., (ymax +. ymin) /. 2. in
|
|
||||||
let dl = w /. 2. in
|
|
||||||
let dx = dl *. cos angle
|
|
||||||
in let dy = dl *. sin angle in
|
|
||||||
cx -. dx, (ymax +. ymin) -. (cy -. dy), angle -. ((2. *. pi) -. ((pi -. (2. *. angle)) *. 2.) /. 2.) +. pi
|
|
||||||
| PosLeft (x, y) -> xmin +. x, ymin +. y, rot
|
|
||||||
| PosCentre (x, y) -> xmin +. x -. (w /. 2.), ymin +. y, rot
|
|
||||||
| PosRight (x, y) -> xmin +. x -. w, ymin +. y, rot
|
|
||||||
| Top d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
(xmin +. xmax) /. 2. -. w /. 2., ymax -. d, rot
|
|
||||||
| TopLeft d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmin +. d, ymax -. d, rot
|
|
||||||
| TopRight d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmax -. d -. w, ymax -. d, rot
|
|
||||||
| Left d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmin +. d, (ymax +. ymin) /. 2., rot
|
|
||||||
| BottomLeft d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmin +. d, ymin +. d, rot
|
|
||||||
| Bottom d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
(xmin +. xmax) /. 2. -. w /. 2., ymin +. d, rot
|
|
||||||
| BottomRight d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmax -. d -. w, ymin +. d, rot
|
|
||||||
| Right d ->
|
|
||||||
let d = if ignore_d then 0. else d in
|
|
||||||
xmax -. d -. w, (ymax +. ymin) /. 2., rot
|
|
||||||
|
|
||||||
(* Process UTF8 text to /WinAnsiEncoding string. *)
|
(* Process UTF8 text to /WinAnsiEncoding string. *)
|
||||||
let winansi_of_utf8 s =
|
let winansi_of_utf8 s =
|
||||||
|
@ -1445,9 +1357,13 @@ let ops longest_w metrics x y rotate hoffset voffset outline linewidth unique_fo
|
||||||
Pdfops.Op_EMC;
|
Pdfops.Op_EMC;
|
||||||
Pdfops.Op_Q]
|
Pdfops.Op_Q]
|
||||||
|
|
||||||
|
type justification = LeftJustify | CentreJustify | RightJustify
|
||||||
|
|
||||||
(* Find the h-offset for justification based on the longest width, the current
|
(* Find the h-offset for justification based on the longest width, the current
|
||||||
width, the justification and the position. *)
|
width, the justification and the position. *)
|
||||||
let find_justification_offsets longest_w w position = function
|
let find_justification_offsets longest_w w position j =
|
||||||
|
let open Cpdfposition in
|
||||||
|
match j with
|
||||||
| LeftJustify ->
|
| LeftJustify ->
|
||||||
begin match position with
|
begin match position with
|
||||||
| TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> 0.
|
| TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> 0.
|
||||||
|
@ -1599,6 +1515,8 @@ let extract_text extract_text_font_size pdf range =
|
||||||
fold_left (fun x y -> x ^ (if x <> "" && y <> "" then "\n" else "") ^ y) ""
|
fold_left (fun x y -> x ^ (if x <> "" && y <> "" then "\n" else "") ^ y) ""
|
||||||
(map_pages (extract_page_text extract_text_font_size pdf) pdf range)
|
(map_pages (extract_page_text extract_text_font_size pdf) pdf range)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let addtext
|
let addtext
|
||||||
metrics lines linewidth outline fast colour fontname embed bates batespad fontsize font
|
metrics lines linewidth outline fast colour fontname embed bates batespad fontsize font
|
||||||
underneath position hoffset voffset text pages orientation cropbox opacity
|
underneath position hoffset voffset text pages orientation cropbox opacity
|
||||||
|
@ -1696,7 +1614,7 @@ let addtext
|
||||||
else
|
else
|
||||||
Pdf.parse_rectangle page.Pdfpage.mediabox
|
Pdf.parse_rectangle page.Pdfpage.mediabox
|
||||||
in
|
in
|
||||||
let x, y, rotate = calculate_position false textwidth mediabox orientation position in
|
let x, y, rotate = Cpdfposition.calculate_position false textwidth mediabox orientation position in
|
||||||
let hoffset, voffset =
|
let hoffset, voffset =
|
||||||
if position = Diagonal || position = ReverseDiagonal
|
if position = Diagonal || position = ReverseDiagonal
|
||||||
then -. (cos ((pi /. 2.) -. rotate) *. voffset), sin ((pi /. 2.) -. rotate) *. voffset
|
then -. (cos ((pi /. 2.) -. rotate) *. voffset), sin ((pi /. 2.) -. rotate) *. voffset
|
||||||
|
@ -1785,6 +1703,7 @@ let
|
||||||
let lines = map unescape_string (split_at_newline text) in
|
let lines = map unescape_string (split_at_newline text) in
|
||||||
let pdf = ref pdf in
|
let pdf = ref pdf in
|
||||||
let voffset =
|
let voffset =
|
||||||
|
let open Cpdfposition in
|
||||||
match position with
|
match position with
|
||||||
| Bottom _ | BottomLeft _ | BottomRight _ ->
|
| Bottom _ | BottomLeft _ | BottomRight _ ->
|
||||||
ref (0. -. (linespacing *. fontsize *. (float (length lines) -. 1.)))
|
ref (0. -. (linespacing *. fontsize *. (float (length lines) -. 1.)))
|
||||||
|
@ -1824,7 +1743,7 @@ let
|
||||||
iter
|
iter
|
||||||
(fun line ->
|
(fun line ->
|
||||||
let voff, hoff =
|
let voff, hoff =
|
||||||
if orientation = Vertical then 0., -.(!voffset) else !voffset, 0.
|
if orientation = Cpdfposition.Vertical then 0., -.(!voffset) else !voffset, 0.
|
||||||
in
|
in
|
||||||
pdf :=
|
pdf :=
|
||||||
addtext metrics lines linewidth outline fast colour fontname
|
addtext metrics lines linewidth outline fast colour fontname
|
||||||
|
@ -2241,6 +2160,7 @@ let stamp_shift_of_position topline midline sw sh w h p =
|
||||||
else if topline then sh
|
else if topline then sh
|
||||||
else 0.
|
else 0.
|
||||||
in
|
in
|
||||||
|
let open Cpdfposition in
|
||||||
match p with
|
match p with
|
||||||
| PosCentre (ox, oy) -> ox -. half sw, oy -. dy
|
| PosCentre (ox, oy) -> ox -. half sw, oy -. dy
|
||||||
| PosLeft (ox, oy) -> ox, oy -. dy
|
| PosLeft (ox, oy) -> ox, oy -. dy
|
||||||
|
@ -2819,13 +2739,13 @@ let scale_to_fit_pdf ?(fast=false) position input_scale xylist op pdf range =
|
||||||
let scale = fmin fx fy *. input_scale in
|
let scale = fmin fx fy *. input_scale in
|
||||||
let trans_x =
|
let trans_x =
|
||||||
match position with
|
match position with
|
||||||
Left _ -> 0.
|
Cpdfposition.Left _ -> 0.
|
||||||
| Right _ -> (x -. (maxx *. scale))
|
| Cpdfposition.Right _ -> (x -. (maxx *. scale))
|
||||||
| _ -> (x -. (maxx *. scale)) /. 2.
|
| _ -> (x -. (maxx *. scale)) /. 2.
|
||||||
and trans_y =
|
and trans_y =
|
||||||
match position with
|
match position with
|
||||||
| Top _ -> (y -. (maxy *. scale))
|
| Cpdfposition.Top _ -> (y -. (maxy *. scale))
|
||||||
| Bottom _ -> 0.
|
| Cpdfposition.Bottom _ -> 0.
|
||||||
| _ -> (y -. (maxy *. scale)) /. 2.
|
| _ -> (y -. (maxy *. scale)) /. 2.
|
||||||
in
|
in
|
||||||
(Pdftransform.matrix_of_transform
|
(Pdftransform.matrix_of_transform
|
||||||
|
@ -2853,8 +2773,9 @@ let scale_page_contents ?(fast=false) scale position pdf pnum page =
|
||||||
| Some r -> r
|
| Some r -> r
|
||||||
| None -> page.Pdfpage.mediabox)
|
| None -> page.Pdfpage.mediabox)
|
||||||
in
|
in
|
||||||
let sx, sy, _ = calculate_position true 0. box Horizontal position in
|
let sx, sy, _ = Cpdfposition.calculate_position true 0. box Horizontal position in
|
||||||
let tx, ty =
|
let tx, ty =
|
||||||
|
let open Cpdfposition in
|
||||||
match position with
|
match position with
|
||||||
| Top t -> 0., -.t
|
| Top t -> 0., -.t
|
||||||
| TopLeft t -> t, -.t
|
| TopLeft t -> t, -.t
|
||||||
|
@ -3343,14 +3264,8 @@ let dc = "http://purl.org/dc/elements/1.1/"
|
||||||
|
|
||||||
let rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
let rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
|
||||||
(* For OCaml < 4.00 *)
|
|
||||||
let string_trim s =
|
|
||||||
implode
|
|
||||||
(rev (dropwhile
|
|
||||||
Pdf.is_whitespace (rev (dropwhile Pdf.is_whitespace (explode s)))))
|
|
||||||
|
|
||||||
let combine_with_spaces strs =
|
let combine_with_spaces strs =
|
||||||
string_trim
|
String.trim
|
||||||
(fold_left (fun x y -> x ^ (if x <> "" then ", " else "") ^ y) "" strs)
|
(fold_left (fun x y -> x ^ (if x <> "" then ", " else "") ^ y) "" strs)
|
||||||
|
|
||||||
(* Collect all <li> elements inside a seq, bag, or alt. Combine with commas. If
|
(* Collect all <li> elements inside a seq, bag, or alt. Combine with commas. If
|
||||||
|
|
47
cpdf.mli
47
cpdf.mli
|
@ -14,23 +14,6 @@ exception HardError of string
|
||||||
(** Two exceptions recommended for use with the library, though currently not
|
(** Two exceptions recommended for use with the library, though currently not
|
||||||
raised by any function in this module. Cpdfcommand uses them extensively. *)
|
raised by any function in this module. Cpdfcommand uses them extensively. *)
|
||||||
|
|
||||||
(** Possible positions for adding text and other uses. See cpdfmanual.pdf *)
|
|
||||||
type position =
|
|
||||||
| PosCentre of float * float
|
|
||||||
| PosLeft of float * float
|
|
||||||
| PosRight of float * float
|
|
||||||
| Top of float
|
|
||||||
| TopLeft of float
|
|
||||||
| TopRight of float
|
|
||||||
| Left of float
|
|
||||||
| BottomLeft of float
|
|
||||||
| Bottom of float
|
|
||||||
| BottomRight of float
|
|
||||||
| Right of float
|
|
||||||
| Diagonal
|
|
||||||
| ReverseDiagonal
|
|
||||||
| Centre
|
|
||||||
|
|
||||||
(** {2 Debug} *)
|
(** {2 Debug} *)
|
||||||
|
|
||||||
(** Debug: Print out a PDF in readable form to the terminal *)
|
(** Debug: Print out a PDF in readable form to the terminal *)
|
||||||
|
@ -174,7 +157,7 @@ val combine_pages : bool -> Pdf.t -> Pdf.t -> bool -> bool -> bool -> Pdf.t
|
||||||
(** [stamp relative_to_cropbox position topline midline fast scale_to_fit isover range over pdf] stamps the first page of
|
(** [stamp relative_to_cropbox position topline midline fast scale_to_fit isover range over pdf] stamps the first page of
|
||||||
[over] over each page of the PDF. The arguments have the same meaning as in
|
[over] over each page of the PDF. The arguments have the same meaning as in
|
||||||
[combine_pages]. *)
|
[combine_pages]. *)
|
||||||
val stamp : bool -> position -> bool -> bool -> bool -> bool -> bool -> int list -> Pdf.t -> Pdf.t -> Pdf.t
|
val stamp : bool -> Cpdfposition.position -> bool -> bool -> bool -> bool -> bool -> int list -> Pdf.t -> Pdf.t -> Pdf.t
|
||||||
|
|
||||||
(** {2 Splitting PDFs} *)
|
(** {2 Splitting PDFs} *)
|
||||||
|
|
||||||
|
@ -194,32 +177,12 @@ val list_fonts : Pdf.t -> (int * string * string * string * string) list
|
||||||
(** Expand the string "now" to a PDF date string, ignoring any other string *)
|
(** Expand the string "now" to a PDF date string, ignoring any other string *)
|
||||||
val expand_date : string -> string
|
val expand_date : string -> string
|
||||||
|
|
||||||
|
|
||||||
(** Produce a debug string of a [position] *)
|
|
||||||
val string_of_position : position -> string
|
|
||||||
|
|
||||||
(** Orientation of the string on the page *)
|
|
||||||
type orientation =
|
|
||||||
| Horizontal
|
|
||||||
| Vertical
|
|
||||||
| VerticalDown
|
|
||||||
|
|
||||||
(** Justification of multiline text *)
|
(** Justification of multiline text *)
|
||||||
type justification =
|
type justification =
|
||||||
| LeftJustify
|
| LeftJustify
|
||||||
| CentreJustify
|
| CentreJustify
|
||||||
| RightJustify
|
| RightJustify
|
||||||
|
|
||||||
(** [calculate_position ignore_d w (xmin, ymin, xmax, ymax) orientation pos] calculates
|
|
||||||
the absolute position of text given its width, bounding box, orientation and
|
|
||||||
position. If [ignore_d] is true, the distance from the position (e.g 10 in
|
|
||||||
TopLeft 10) is ignored (considered zero). *)
|
|
||||||
val calculate_position :
|
|
||||||
bool ->
|
|
||||||
float ->
|
|
||||||
float * float * float * float ->
|
|
||||||
orientation -> position -> float * float * float
|
|
||||||
|
|
||||||
(** Call [add_texts metrics linewidth outline fast fontname font bates batespad colour
|
(** Call [add_texts metrics linewidth outline fast fontname font bates batespad colour
|
||||||
position linespacing fontsize underneath text pages orientation
|
position linespacing fontsize underneath text pages orientation
|
||||||
relative_to_cropbox midline_adjust topline filename pdf]. For details see cpdfmanual.pdf *)
|
relative_to_cropbox midline_adjust topline filename pdf]. For details see cpdfmanual.pdf *)
|
||||||
|
@ -234,13 +197,13 @@ val addtexts :
|
||||||
int -> (* bates number *)
|
int -> (* bates number *)
|
||||||
int option -> (* bates padding width *)
|
int option -> (* bates padding width *)
|
||||||
float * float * float -> (*colour*)
|
float * float * float -> (*colour*)
|
||||||
position -> (*position*)
|
Cpdfposition.position -> (*position*)
|
||||||
float -> (*linespacing*)
|
float -> (*linespacing*)
|
||||||
float -> (*fontsize*)
|
float -> (*fontsize*)
|
||||||
bool -> (*underneath*)
|
bool -> (*underneath*)
|
||||||
string ->(*text*)
|
string ->(*text*)
|
||||||
int list ->(*page range*)
|
int list ->(*page range*)
|
||||||
orientation ->(*orientation*)
|
Cpdfposition.orientation ->(*orientation*)
|
||||||
bool ->(*relative to cropbox?*)
|
bool ->(*relative to cropbox?*)
|
||||||
float ->(*opacity*)
|
float ->(*opacity*)
|
||||||
justification ->(*justification*)
|
justification ->(*justification*)
|
||||||
|
@ -323,10 +286,10 @@ val scale_pdf : ?fast:bool -> (float * float) list -> Pdf.t -> int list -> Pdf.t
|
||||||
(** [scale_to_fit_pdf fast position input_scale x y op pdf range] scales a page to fit the
|
(** [scale_to_fit_pdf fast position input_scale x y op pdf range] scales a page to fit the
|
||||||
page size given by (x, y) and by the [input_scale] (e.g 1.0 = scale to fit, 0.9
|
page size given by (x, y) and by the [input_scale] (e.g 1.0 = scale to fit, 0.9
|
||||||
= scale to fit leaving a border etc.). [op] is unused. *)
|
= scale to fit leaving a border etc.). [op] is unused. *)
|
||||||
val scale_to_fit_pdf : ?fast:bool -> position -> float -> (float * float) list -> 'a -> Pdf.t -> int list -> Pdf.t
|
val scale_to_fit_pdf : ?fast:bool -> Cpdfposition.position -> float -> (float * float) list -> 'a -> Pdf.t -> int list -> Pdf.t
|
||||||
|
|
||||||
(** Scale the contents of a page by a given factor centred around a given point in a given range. *)
|
(** Scale the contents of a page by a given factor centred around a given point in a given range. *)
|
||||||
val scale_contents : ?fast:bool -> position -> float -> Pdf.t -> int list -> Pdf.t
|
val scale_contents : ?fast:bool -> Cpdfposition.position -> float -> Pdf.t -> int list -> Pdf.t
|
||||||
|
|
||||||
val trim_marks : ?fast:bool -> Pdf.t -> int list -> Pdf.t
|
val trim_marks : ?fast:bool -> Pdf.t -> int list -> Pdf.t
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,7 @@ type args =
|
||||||
mutable fontsize : float;
|
mutable fontsize : float;
|
||||||
mutable color : float * float * float;
|
mutable color : float * float * float;
|
||||||
mutable opacity : float;
|
mutable opacity : float;
|
||||||
mutable position : Cpdf.position;
|
mutable position : Cpdfposition.position;
|
||||||
mutable underneath : bool;
|
mutable underneath : bool;
|
||||||
mutable linespacing : float;
|
mutable linespacing : float;
|
||||||
mutable midline : bool;
|
mutable midline : bool;
|
||||||
|
@ -388,7 +388,7 @@ type args =
|
||||||
mutable bates : int;
|
mutable bates : int;
|
||||||
mutable batespad : int option;
|
mutable batespad : int option;
|
||||||
mutable prerotate : bool;
|
mutable prerotate : bool;
|
||||||
mutable orientation : Cpdf.orientation;
|
mutable orientation : Cpdfposition.orientation;
|
||||||
mutable relative_to_cropbox : bool;
|
mutable relative_to_cropbox : bool;
|
||||||
mutable keepversion : bool;
|
mutable keepversion : bool;
|
||||||
mutable bycolumns : bool;
|
mutable bycolumns : bool;
|
||||||
|
@ -483,7 +483,7 @@ let args =
|
||||||
fontsize = 12.;
|
fontsize = 12.;
|
||||||
color = 0., 0., 0.;
|
color = 0., 0., 0.;
|
||||||
opacity = 1.;
|
opacity = 1.;
|
||||||
position = Cpdf.TopLeft 100.;
|
position = Cpdfposition.TopLeft 100.;
|
||||||
underneath = false;
|
underneath = false;
|
||||||
linespacing = 1.;
|
linespacing = 1.;
|
||||||
midline = false;
|
midline = false;
|
||||||
|
@ -492,7 +492,7 @@ let args =
|
||||||
bates = 0;
|
bates = 0;
|
||||||
batespad = None;
|
batespad = None;
|
||||||
prerotate = false;
|
prerotate = false;
|
||||||
orientation = Cpdf.Horizontal;
|
orientation = Cpdfposition.Horizontal;
|
||||||
relative_to_cropbox = false;
|
relative_to_cropbox = false;
|
||||||
keepversion = false;
|
keepversion = false;
|
||||||
bycolumns = false;
|
bycolumns = false;
|
||||||
|
@ -587,7 +587,7 @@ let reset_arguments () =
|
||||||
args.fontsize <- 12.;
|
args.fontsize <- 12.;
|
||||||
args.color <- 0., 0., 0.;
|
args.color <- 0., 0., 0.;
|
||||||
args.opacity <- 1.;
|
args.opacity <- 1.;
|
||||||
args.position <- Cpdf.TopLeft 100.;
|
args.position <- Cpdfposition.TopLeft 100.;
|
||||||
args.underneath <- false;
|
args.underneath <- false;
|
||||||
args.linespacing <- 1.;
|
args.linespacing <- 1.;
|
||||||
args.midline <- false;
|
args.midline <- false;
|
||||||
|
@ -596,7 +596,7 @@ let reset_arguments () =
|
||||||
args.bates <- 0;
|
args.bates <- 0;
|
||||||
args.batespad <- None;
|
args.batespad <- None;
|
||||||
args.prerotate <- false;
|
args.prerotate <- false;
|
||||||
args.orientation <- Cpdf.Horizontal;
|
args.orientation <- Cpdfposition.Horizontal;
|
||||||
args.relative_to_cropbox <- false;
|
args.relative_to_cropbox <- false;
|
||||||
args.keepversion <- false;
|
args.keepversion <- false;
|
||||||
args.bycolumns <- false;
|
args.bycolumns <- false;
|
||||||
|
@ -1047,11 +1047,11 @@ let setaddbookmarks s =
|
||||||
let setstampon f =
|
let setstampon f =
|
||||||
setop (StampOn f) ();
|
setop (StampOn f) ();
|
||||||
(* Due to an earlier bad decision (default position), we have this nasty hack *)
|
(* Due to an earlier bad decision (default position), we have this nasty hack *)
|
||||||
if args.position = Cpdf.TopLeft 100. then args.position <- Cpdf.BottomLeft 0.
|
if args.position = Cpdfposition.TopLeft 100. then args.position <- Cpdfposition.BottomLeft 0.
|
||||||
|
|
||||||
let setstampunder f =
|
let setstampunder f =
|
||||||
setop (StampUnder f) ();
|
setop (StampUnder f) ();
|
||||||
if args.position = Cpdf.TopLeft 100. then args.position <- Cpdf.BottomLeft 0.
|
if args.position = Cpdfposition.TopLeft 100. then args.position <- Cpdfposition.BottomLeft 0.
|
||||||
|
|
||||||
let setstampasxobject f =
|
let setstampasxobject f =
|
||||||
setop (StampAsXObject f) ()
|
setop (StampAsXObject f) ()
|
||||||
|
@ -1061,58 +1061,58 @@ let setcombinepages f =
|
||||||
|
|
||||||
let setposcenter s =
|
let setposcenter s =
|
||||||
let x, y = Cpdfcoord.parse_coordinate empty s in
|
let x, y = Cpdfcoord.parse_coordinate empty s in
|
||||||
args.position <- Cpdf.PosCentre (x, y)
|
args.position <- Cpdfposition.PosCentre (x, y)
|
||||||
|
|
||||||
let setposleft s =
|
let setposleft s =
|
||||||
let x, y = Cpdfcoord.parse_coordinate empty s in
|
let x, y = Cpdfcoord.parse_coordinate empty s in
|
||||||
args.position <- Cpdf.PosLeft (x, y)
|
args.position <- Cpdfposition.PosLeft (x, y)
|
||||||
|
|
||||||
let setposright s =
|
let setposright s =
|
||||||
let x, y = Cpdfcoord.parse_coordinate empty s in
|
let x, y = Cpdfcoord.parse_coordinate empty s in
|
||||||
args.position <- Cpdf.PosRight (x, y)
|
args.position <- Cpdfposition.PosRight (x, y)
|
||||||
|
|
||||||
let settop n =
|
let settop n =
|
||||||
args.position <- Cpdf.Top (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.Top (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.CentreJustify
|
args.justification <- Cpdf.CentreJustify
|
||||||
|
|
||||||
let settopleft n =
|
let settopleft n =
|
||||||
args.position <- Cpdf.TopLeft (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.TopLeft (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.LeftJustify
|
args.justification <- Cpdf.LeftJustify
|
||||||
|
|
||||||
let settopright n =
|
let settopright n =
|
||||||
args.position <- Cpdf.TopRight (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.TopRight (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.RightJustify
|
args.justification <- Cpdf.RightJustify
|
||||||
|
|
||||||
let setleft n =
|
let setleft n =
|
||||||
args.position <- Cpdf.Left (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.Left (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.LeftJustify
|
args.justification <- Cpdf.LeftJustify
|
||||||
|
|
||||||
let setbottomleft n =
|
let setbottomleft n =
|
||||||
args.position <- Cpdf.BottomLeft (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.BottomLeft (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.LeftJustify
|
args.justification <- Cpdf.LeftJustify
|
||||||
|
|
||||||
let setbottom n =
|
let setbottom n =
|
||||||
args.position <- Cpdf.Bottom (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.Bottom (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.CentreJustify
|
args.justification <- Cpdf.CentreJustify
|
||||||
|
|
||||||
let setbottomright n =
|
let setbottomright n =
|
||||||
args.position <- Cpdf.BottomRight (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.BottomRight (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.RightJustify
|
args.justification <- Cpdf.RightJustify
|
||||||
|
|
||||||
let setright n =
|
let setright n =
|
||||||
args.position <- Cpdf.Right (Cpdfcoord.parse_single_number empty n);
|
args.position <- Cpdfposition.Right (Cpdfcoord.parse_single_number empty n);
|
||||||
args.justification <- Cpdf.RightJustify
|
args.justification <- Cpdf.RightJustify
|
||||||
|
|
||||||
let setdiagonal n =
|
let setdiagonal n =
|
||||||
args.position <- Cpdf.Diagonal;
|
args.position <- Cpdfposition.Diagonal;
|
||||||
args.justification <- Cpdf.CentreJustify
|
args.justification <- Cpdf.CentreJustify
|
||||||
|
|
||||||
let setreversediagonal n =
|
let setreversediagonal n =
|
||||||
args.position <- Cpdf.ReverseDiagonal;
|
args.position <- Cpdfposition.ReverseDiagonal;
|
||||||
args.justification <- Cpdf.CentreJustify
|
args.justification <- Cpdf.CentreJustify
|
||||||
|
|
||||||
let setcenter n =
|
let setcenter n =
|
||||||
args.position <- Cpdf.Centre;
|
args.position <- Cpdfposition.Centre;
|
||||||
args.justification <- Cpdf.CentreJustify
|
args.justification <- Cpdf.CentreJustify
|
||||||
|
|
||||||
let setbatespad n =
|
let setbatespad n =
|
||||||
|
@ -1220,7 +1220,7 @@ let setscaletofitscale f =
|
||||||
let setscalecontents f =
|
let setscalecontents f =
|
||||||
detect_duplicate_op (ScaleContents f);
|
detect_duplicate_op (ScaleContents f);
|
||||||
args.op <- Some (ScaleContents f);
|
args.op <- Some (ScaleContents f);
|
||||||
args.position <- Cpdf.Diagonal (* Will be center *)
|
args.position <- Cpdfposition.Diagonal (* Will be center *)
|
||||||
|
|
||||||
let setsqueeze () =
|
let setsqueeze () =
|
||||||
args.squeeze <- true;
|
args.squeeze <- true;
|
||||||
|
@ -1345,10 +1345,10 @@ let setp2ppath p =
|
||||||
args.path_to_p2p <- p
|
args.path_to_p2p <- p
|
||||||
|
|
||||||
let settextvertical () =
|
let settextvertical () =
|
||||||
args.orientation <- Cpdf.Vertical
|
args.orientation <- Cpdfposition.Vertical
|
||||||
|
|
||||||
let settextverticaldown () =
|
let settextverticaldown () =
|
||||||
args.orientation <- Cpdf.VerticalDown
|
args.orientation <- Cpdfposition.VerticalDown
|
||||||
|
|
||||||
let setfrombox s =
|
let setfrombox s =
|
||||||
detect_duplicate_op CopyBox;
|
detect_duplicate_op CopyBox;
|
||||||
|
@ -3351,12 +3351,12 @@ let addrectangle
|
||||||
Pdf.parse_rectangle page.Pdfpage.mediabox
|
Pdf.parse_rectangle page.Pdfpage.mediabox
|
||||||
in
|
in
|
||||||
let x, y, _ =
|
let x, y, _ =
|
||||||
Cpdf.calculate_position false w mediabox Cpdf.Horizontal position
|
Cpdfposition.calculate_position false w mediabox Cpdfposition.Horizontal position
|
||||||
in
|
in
|
||||||
let x, y =
|
let x, y =
|
||||||
match position with
|
match position with
|
||||||
Cpdf.Top _ | Cpdf.TopLeft _ | Cpdf.TopRight _ -> (x, y -. h)
|
Cpdfposition.Top _ | Cpdfposition.TopLeft _ | Cpdfposition.TopRight _ -> (x, y -. h)
|
||||||
| Cpdf.Centre | Cpdf.PosCentre _ -> (x, y -. (h /. 2.))
|
| Cpdfposition.Centre | Cpdfposition.PosCentre _ -> (x, y -. (h /. 2.))
|
||||||
| _ -> (x, y)
|
| _ -> (x, y)
|
||||||
in
|
in
|
||||||
let ops =
|
let ops =
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
open Pdfutil
|
||||||
|
|
||||||
|
type position =
|
||||||
|
| PosCentre of float * float
|
||||||
|
| PosLeft of float * float
|
||||||
|
| PosRight of float * float
|
||||||
|
| Top of float
|
||||||
|
| TopLeft of float
|
||||||
|
| TopRight of float
|
||||||
|
| Left of float
|
||||||
|
| BottomLeft of float
|
||||||
|
| Bottom of float
|
||||||
|
| BottomRight of float
|
||||||
|
| Right of float
|
||||||
|
| Diagonal
|
||||||
|
| ReverseDiagonal
|
||||||
|
| Centre
|
||||||
|
|
||||||
|
let string_of_position = function
|
||||||
|
| PosCentre (a, b) -> Printf.sprintf "PosCentre %f %f" a b
|
||||||
|
| PosLeft (a, b) -> Printf.sprintf "PosLeft %f %f" a b
|
||||||
|
| PosRight (a, b) -> Printf.sprintf "PosRight %f %f" a b
|
||||||
|
| Top a -> Printf.sprintf "Top %f" a
|
||||||
|
| TopLeft a -> Printf.sprintf "TopLeft %f" a
|
||||||
|
| TopRight a -> Printf.sprintf "TopRight %f" a
|
||||||
|
| Left a -> Printf.sprintf "Left %f" a
|
||||||
|
| BottomLeft a -> Printf.sprintf "BottomLeft %f" a
|
||||||
|
| Bottom a -> Printf.sprintf "Bottom %f" a
|
||||||
|
| BottomRight a -> Printf.sprintf "BottomRight %f" a
|
||||||
|
| Right a -> Printf.sprintf "Right %f" a
|
||||||
|
| Diagonal -> "Diagonal"
|
||||||
|
| ReverseDiagonal -> "Reverse Diagonal"
|
||||||
|
| Centre -> "Centre"
|
||||||
|
|
||||||
|
type orientation =
|
||||||
|
| Horizontal
|
||||||
|
| Vertical
|
||||||
|
| VerticalDown
|
||||||
|
|
||||||
|
(* Given the mediabox, calculate an absolute position for the text. *)
|
||||||
|
let calculate_position ignore_d w (xmin, ymin, xmax, ymax) orientation pos =
|
||||||
|
let rot = if orientation = VerticalDown then rad_of_deg 270. else 0. in
|
||||||
|
match pos with
|
||||||
|
| Centre ->
|
||||||
|
(xmin +. xmax) /. 2. -. w /. 2.,
|
||||||
|
(ymin +. ymax) /. 2.,
|
||||||
|
rot
|
||||||
|
| Diagonal ->
|
||||||
|
let angle = atan ((ymax -. ymin) /. (xmax -. xmin))
|
||||||
|
in let cx, cy = (xmax +. xmin) /. 2., (ymax +. ymin) /. 2. in
|
||||||
|
let dl = w /. 2. in
|
||||||
|
let dx = dl *. cos angle
|
||||||
|
in let dy = dl *. sin angle in
|
||||||
|
cx -. dx, cy -. dy, angle
|
||||||
|
| ReverseDiagonal ->
|
||||||
|
let angle = atan ((ymax -. ymin) /. (xmax -. xmin))
|
||||||
|
in let cx, cy = (xmax +. xmin) /. 2., (ymax +. ymin) /. 2. in
|
||||||
|
let dl = w /. 2. in
|
||||||
|
let dx = dl *. cos angle
|
||||||
|
in let dy = dl *. sin angle in
|
||||||
|
cx -. dx, (ymax +. ymin) -. (cy -. dy), angle -. ((2. *. pi) -. ((pi -. (2. *. angle)) *. 2.) /. 2.) +. pi
|
||||||
|
| PosLeft (x, y) -> xmin +. x, ymin +. y, rot
|
||||||
|
| PosCentre (x, y) -> xmin +. x -. (w /. 2.), ymin +. y, rot
|
||||||
|
| PosRight (x, y) -> xmin +. x -. w, ymin +. y, rot
|
||||||
|
| Top d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
(xmin +. xmax) /. 2. -. w /. 2., ymax -. d, rot
|
||||||
|
| TopLeft d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmin +. d, ymax -. d, rot
|
||||||
|
| TopRight d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmax -. d -. w, ymax -. d, rot
|
||||||
|
| Left d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmin +. d, (ymax +. ymin) /. 2., rot
|
||||||
|
| BottomLeft d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmin +. d, ymin +. d, rot
|
||||||
|
| Bottom d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
(xmin +. xmax) /. 2. -. w /. 2., ymin +. d, rot
|
||||||
|
| BottomRight d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmax -. d -. w, ymin +. d, rot
|
||||||
|
| Right d ->
|
||||||
|
let d = if ignore_d then 0. else d in
|
||||||
|
xmax -. d -. w, (ymax +. ymin) /. 2., rot
|
|
@ -0,0 +1,32 @@
|
||||||
|
(** Possible positions for adding text and other uses. See cpdfmanual.pdf *)
|
||||||
|
type position =
|
||||||
|
PosCentre of float * float
|
||||||
|
| PosLeft of float * float
|
||||||
|
| PosRight of float * float
|
||||||
|
| Top of float
|
||||||
|
| TopLeft of float
|
||||||
|
| TopRight of float
|
||||||
|
| Left of float
|
||||||
|
| BottomLeft of float
|
||||||
|
| Bottom of float
|
||||||
|
| BottomRight of float
|
||||||
|
| Right of float
|
||||||
|
| Diagonal
|
||||||
|
| ReverseDiagonal
|
||||||
|
| Centre
|
||||||
|
|
||||||
|
(** Produce a debug string of a [position] *)
|
||||||
|
val string_of_position : position -> string
|
||||||
|
|
||||||
|
(** Orientation of the string on the page *)
|
||||||
|
type orientation = Horizontal | Vertical | VerticalDown
|
||||||
|
|
||||||
|
(** [calculate_position ignore_d w (xmin, ymin, xmax, ymax) orientation pos] calculates
|
||||||
|
the absolute position of text given its width, bounding box, orientation and
|
||||||
|
position. If [ignore_d] is true, the distance from the position (e.g 10 in
|
||||||
|
TopLeft 10) is ignored (considered zero). *)
|
||||||
|
val calculate_position :
|
||||||
|
bool ->
|
||||||
|
float ->
|
||||||
|
float * float * float * float ->
|
||||||
|
orientation -> position -> float * float * float
|
Loading…
Reference in New Issue