diff --git a/Makefile b/Makefile
index b61d8f8..e9c6302 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# Build the cpdf command line tools and top level
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
diff --git a/cpdf.ml b/cpdf.ml
index 73fe76f..463be48 100644
--- a/cpdf.ml
+++ b/cpdf.ml
@@ -1268,94 +1268,6 @@ let print_fonts pdf =
(* \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. *)
let winansi_of_utf8 s =
@@ -1445,33 +1357,37 @@ let ops longest_w metrics x y rotate hoffset voffset outline linewidth unique_fo
Pdfops.Op_EMC;
Pdfops.Op_Q]
+type justification = LeftJustify | CentreJustify | RightJustify
+
(* Find the h-offset for justification based on the longest width, the current
width, the justification and the position. *)
-let find_justification_offsets longest_w w position = function
- | LeftJustify ->
- begin match position with
- | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> 0.
- | Top _ | PosCentre _ | Bottom _ | Centre -> (longest_w -. w) /. 2.
- | TopRight _ | BottomRight _ | PosRight _ | Right _ -> longest_w -. w
- | Diagonal -> 0.
- | ReverseDiagonal -> 0.
- end
- | RightJustify ->
- begin match position with
- | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> ~-.(longest_w -. w)
- | Top _ | PosCentre _ | Bottom _ | Centre -> ~-.((longest_w -. w) /. 2.)
- | TopRight _ | BottomRight _ | PosRight _ | Right _ -> 0.
- | Diagonal -> 0.
- | ReverseDiagonal -> 0.
- end
- | CentreJustify ->
- begin match position with
- | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> ~-.((longest_w -. w) /. 2.)
- | Top _ | PosCentre _ | Bottom _ | Centre -> 0.
- | TopRight _ | BottomRight _ | PosRight _ | Right _ -> (longest_w -. w) /. 2.
- | Diagonal -> 0.
- | ReverseDiagonal -> 0.
- end
+let find_justification_offsets longest_w w position j =
+ let open Cpdfposition in
+ match j with
+ | LeftJustify ->
+ begin match position with
+ | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> 0.
+ | Top _ | PosCentre _ | Bottom _ | Centre -> (longest_w -. w) /. 2.
+ | TopRight _ | BottomRight _ | PosRight _ | Right _ -> longest_w -. w
+ | Diagonal -> 0.
+ | ReverseDiagonal -> 0.
+ end
+ | RightJustify ->
+ begin match position with
+ | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> ~-.(longest_w -. w)
+ | Top _ | PosCentre _ | Bottom _ | Centre -> ~-.((longest_w -. w) /. 2.)
+ | TopRight _ | BottomRight _ | PosRight _ | Right _ -> 0.
+ | Diagonal -> 0.
+ | ReverseDiagonal -> 0.
+ end
+ | CentreJustify ->
+ begin match position with
+ | TopLeft _ | Left _ | PosLeft _ | BottomLeft _ -> ~-.((longest_w -. w) /. 2.)
+ | Top _ | PosCentre _ | Bottom _ | Centre -> 0.
+ | TopRight _ | BottomRight _ | PosRight _ | Right _ -> (longest_w -. w) /. 2.
+ | Diagonal -> 0.
+ | ReverseDiagonal -> 0.
+ end
(* Lex an integer from the table *)
let extract_num header s =
@@ -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) ""
(map_pages (extract_page_text extract_text_font_size pdf) pdf range)
+
+
let addtext
metrics lines linewidth outline fast colour fontname embed bates batespad fontsize font
underneath position hoffset voffset text pages orientation cropbox opacity
@@ -1696,7 +1614,7 @@ let addtext
else
Pdf.parse_rectangle page.Pdfpage.mediabox
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 =
if position = Diagonal || position = ReverseDiagonal
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 pdf = ref pdf in
let voffset =
+ let open Cpdfposition in
match position with
| Bottom _ | BottomLeft _ | BottomRight _ ->
ref (0. -. (linespacing *. fontsize *. (float (length lines) -. 1.)))
@@ -1824,7 +1743,7 @@ let
iter
(fun line ->
let voff, hoff =
- if orientation = Vertical then 0., -.(!voffset) else !voffset, 0.
+ if orientation = Cpdfposition.Vertical then 0., -.(!voffset) else !voffset, 0.
in
pdf :=
addtext metrics lines linewidth outline fast colour fontname
@@ -2241,20 +2160,21 @@ let stamp_shift_of_position topline midline sw sh w h p =
else if topline then sh
else 0.
in
- match p with
- | PosCentre (ox, oy) -> ox -. half sw, oy -. dy
- | PosLeft (ox, oy) -> ox, oy -. dy
- | PosRight (ox, oy) -> ox -. sw, oy -. dy
- | Top o -> half w -. half sw, h -. o -. sh -. dy
- | TopLeft o -> o, h -. sh -. o -. dy
- | TopRight o -> w -. sw -. o, h -. sh -. o -. dy
- | Left o -> o, half h -. half sh -. dy
- | BottomLeft o -> o, o -. dy
- | Bottom o -> half w -. half sw, o -. dy
- | BottomRight o -> w -. sw -. o, o -. dy
- | Right o -> w -. sw -. o, half h -. half sh -. dy
- | Diagonal | ReverseDiagonal | Centre ->
- half w -. half sw, half h -. half sh -. dy
+ let open Cpdfposition in
+ match p with
+ | PosCentre (ox, oy) -> ox -. half sw, oy -. dy
+ | PosLeft (ox, oy) -> ox, oy -. dy
+ | PosRight (ox, oy) -> ox -. sw, oy -. dy
+ | Top o -> half w -. half sw, h -. o -. sh -. dy
+ | TopLeft o -> o, h -. sh -. o -. dy
+ | TopRight o -> w -. sw -. o, h -. sh -. o -. dy
+ | Left o -> o, half h -. half sh -. dy
+ | BottomLeft o -> o, o -. dy
+ | Bottom o -> half w -. half sw, o -. dy
+ | BottomRight o -> w -. sw -. o, o -. dy
+ | Right o -> w -. sw -. o, half h -. half sh -. dy
+ | Diagonal | ReverseDiagonal | Centre ->
+ half w -. half sw, half h -. half sh -. dy
(* Combine Pdfpage.rest items for two PDFs. For now, we combine /Annots, and
* copy everything else from adict. What else should we combine? *)
@@ -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 trans_x =
match position with
- Left _ -> 0.
- | Right _ -> (x -. (maxx *. scale))
+ Cpdfposition.Left _ -> 0.
+ | Cpdfposition.Right _ -> (x -. (maxx *. scale))
| _ -> (x -. (maxx *. scale)) /. 2.
and trans_y =
match position with
- | Top _ -> (y -. (maxy *. scale))
- | Bottom _ -> 0.
+ | Cpdfposition.Top _ -> (y -. (maxy *. scale))
+ | Cpdfposition.Bottom _ -> 0.
| _ -> (y -. (maxy *. scale)) /. 2.
in
(Pdftransform.matrix_of_transform
@@ -2853,8 +2773,9 @@ let scale_page_contents ?(fast=false) scale position pdf pnum page =
| Some r -> r
| None -> page.Pdfpage.mediabox)
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 open Cpdfposition in
match position with
| Top t -> 0., -.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#"
-(* 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 =
- string_trim
+ String.trim
(fold_left (fun x y -> x ^ (if x <> "" then ", " else "") ^ y) "" strs)
(* Collect all
elements inside a seq, bag, or alt. Combine with commas. If
diff --git a/cpdf.mli b/cpdf.mli
index ea06c35..027cc18 100644
--- a/cpdf.mli
+++ b/cpdf.mli
@@ -14,23 +14,6 @@ exception HardError of string
(** Two exceptions recommended for use with the library, though currently not
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} *)
(** 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
[over] over each page of the PDF. The arguments have the same meaning as in
[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} *)
@@ -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 *)
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 *)
type justification =
| LeftJustify
| CentreJustify
| 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
position linespacing fontsize underneath text pages orientation
relative_to_cropbox midline_adjust topline filename pdf]. For details see cpdfmanual.pdf *)
@@ -234,13 +197,13 @@ val addtexts :
int -> (* bates number *)
int option -> (* bates padding width *)
float * float * float -> (*colour*)
- position -> (*position*)
+ Cpdfposition.position -> (*position*)
float -> (*linespacing*)
float -> (*fontsize*)
bool -> (*underneath*)
string ->(*text*)
int list ->(*page range*)
- orientation ->(*orientation*)
+ Cpdfposition.orientation ->(*orientation*)
bool ->(*relative to cropbox?*)
float ->(*opacity*)
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
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. *)
-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. *)
-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
diff --git a/cpdfcommand.ml b/cpdfcommand.ml
index 938fcc8..78cb56d 100644
--- a/cpdfcommand.ml
+++ b/cpdfcommand.ml
@@ -379,7 +379,7 @@ type args =
mutable fontsize : float;
mutable color : float * float * float;
mutable opacity : float;
- mutable position : Cpdf.position;
+ mutable position : Cpdfposition.position;
mutable underneath : bool;
mutable linespacing : float;
mutable midline : bool;
@@ -388,7 +388,7 @@ type args =
mutable bates : int;
mutable batespad : int option;
mutable prerotate : bool;
- mutable orientation : Cpdf.orientation;
+ mutable orientation : Cpdfposition.orientation;
mutable relative_to_cropbox : bool;
mutable keepversion : bool;
mutable bycolumns : bool;
@@ -483,7 +483,7 @@ let args =
fontsize = 12.;
color = 0., 0., 0.;
opacity = 1.;
- position = Cpdf.TopLeft 100.;
+ position = Cpdfposition.TopLeft 100.;
underneath = false;
linespacing = 1.;
midline = false;
@@ -492,7 +492,7 @@ let args =
bates = 0;
batespad = None;
prerotate = false;
- orientation = Cpdf.Horizontal;
+ orientation = Cpdfposition.Horizontal;
relative_to_cropbox = false;
keepversion = false;
bycolumns = false;
@@ -587,7 +587,7 @@ let reset_arguments () =
args.fontsize <- 12.;
args.color <- 0., 0., 0.;
args.opacity <- 1.;
- args.position <- Cpdf.TopLeft 100.;
+ args.position <- Cpdfposition.TopLeft 100.;
args.underneath <- false;
args.linespacing <- 1.;
args.midline <- false;
@@ -596,7 +596,7 @@ let reset_arguments () =
args.bates <- 0;
args.batespad <- None;
args.prerotate <- false;
- args.orientation <- Cpdf.Horizontal;
+ args.orientation <- Cpdfposition.Horizontal;
args.relative_to_cropbox <- false;
args.keepversion <- false;
args.bycolumns <- false;
@@ -1047,11 +1047,11 @@ let setaddbookmarks s =
let setstampon f =
setop (StampOn f) ();
(* 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 =
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 =
setop (StampAsXObject f) ()
@@ -1061,58 +1061,58 @@ let setcombinepages f =
let setposcenter s =
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 x, y = Cpdfcoord.parse_coordinate empty s in
- args.position <- Cpdf.PosLeft (x, y)
+ args.position <- Cpdfposition.PosLeft (x, y)
let setposright s =
let x, y = Cpdfcoord.parse_coordinate empty s in
- args.position <- Cpdf.PosRight (x, y)
+ args.position <- Cpdfposition.PosRight (x, y)
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
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
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
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
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
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
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
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
let setdiagonal n =
- args.position <- Cpdf.Diagonal;
+ args.position <- Cpdfposition.Diagonal;
args.justification <- Cpdf.CentreJustify
let setreversediagonal n =
- args.position <- Cpdf.ReverseDiagonal;
+ args.position <- Cpdfposition.ReverseDiagonal;
args.justification <- Cpdf.CentreJustify
let setcenter n =
- args.position <- Cpdf.Centre;
+ args.position <- Cpdfposition.Centre;
args.justification <- Cpdf.CentreJustify
let setbatespad n =
@@ -1220,7 +1220,7 @@ let setscaletofitscale f =
let setscalecontents f =
detect_duplicate_op (ScaleContents f);
args.op <- Some (ScaleContents f);
- args.position <- Cpdf.Diagonal (* Will be center *)
+ args.position <- Cpdfposition.Diagonal (* Will be center *)
let setsqueeze () =
args.squeeze <- true;
@@ -1345,10 +1345,10 @@ let setp2ppath p =
args.path_to_p2p <- p
let settextvertical () =
- args.orientation <- Cpdf.Vertical
+ args.orientation <- Cpdfposition.Vertical
let settextverticaldown () =
- args.orientation <- Cpdf.VerticalDown
+ args.orientation <- Cpdfposition.VerticalDown
let setfrombox s =
detect_duplicate_op CopyBox;
@@ -3351,12 +3351,12 @@ let addrectangle
Pdf.parse_rectangle page.Pdfpage.mediabox
in
let x, y, _ =
- Cpdf.calculate_position false w mediabox Cpdf.Horizontal position
+ Cpdfposition.calculate_position false w mediabox Cpdfposition.Horizontal position
in
let x, y =
match position with
- Cpdf.Top _ | Cpdf.TopLeft _ | Cpdf.TopRight _ -> (x, y -. h)
- | Cpdf.Centre | Cpdf.PosCentre _ -> (x, y -. (h /. 2.))
+ Cpdfposition.Top _ | Cpdfposition.TopLeft _ | Cpdfposition.TopRight _ -> (x, y -. h)
+ | Cpdfposition.Centre | Cpdfposition.PosCentre _ -> (x, y -. (h /. 2.))
| _ -> (x, y)
in
let ops =
diff --git a/cpdfposition.ml b/cpdfposition.ml
new file mode 100644
index 0000000..b139603
--- /dev/null
+++ b/cpdfposition.ml
@@ -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
diff --git a/cpdfposition.mli b/cpdfposition.mli
new file mode 100644
index 0000000..a70cfe1
--- /dev/null
+++ b/cpdfposition.mli
@@ -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