cpdf-source/cpdfposition.ml
2023-04-07 15:31:21 +01:00

88 lines
3.2 KiB
OCaml

open Pdfutil
type position =
| PosCentre of float * float
| PosLeft of float * float
| PosRight of float * float
| Top of float
| TopLeft of float * float
| TopRight of float * float
| Left of float
| BottomLeft of float * float
| Bottom of float
| BottomRight of float * 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, b) -> Printf.sprintf "TopLeft %f %f" a b
| TopRight (a, b) -> Printf.sprintf "TopRight %f %f" a b
| Left a -> Printf.sprintf "Left %f" a
| BottomLeft (a, b) -> Printf.sprintf "BottomLeft %f %f" a b
| Bottom a -> Printf.sprintf "Bottom %f" a
| BottomRight (a, b) -> Printf.sprintf "BottomRight %f %f" a b
| Right a -> Printf.sprintf "Right %f" a
| Diagonal -> "Diagonal"
| ReverseDiagonal -> "Reverse Diagonal"
| Centre -> "Centre"
(* Given the mediabox, calculate an absolute position for the text. *)
let calculate_position ignore_d w (xmin, ymin, xmax, ymax) pos =
let rot = 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 (a, b) ->
let a = if ignore_d then 0. else a in
let b = if ignore_d then 0. else b in
xmin +. a, ymax -. b, rot
| TopRight (a, b) ->
let a = if ignore_d then 0. else a in
let b = if ignore_d then 0. else b in
xmax -. a -. w, ymax -. b, rot
| Left d ->
let d = if ignore_d then 0. else d in
xmin +. d, (ymax +. ymin) /. 2., rot
| BottomLeft (a, b) ->
let a = if ignore_d then 0. else a in
let b = if ignore_d then 0. else b in
xmin +. a, ymin +. b, rot
| Bottom d ->
let d = if ignore_d then 0. else d in
(xmin +. xmax) /. 2. -. w /. 2., ymin +. d, rot
| BottomRight (a, b) ->
let a = if ignore_d then 0. else a in
let b = if ignore_d then 0. else b in
xmax -. a -. w, ymin +. b, rot
| Right d ->
let d = if ignore_d then 0. else d in
xmax -. d -. w, (ymax +. ymin) /. 2., rot