cpdf-source/cpdfdraw.ml

111 lines
2.9 KiB
OCaml
Raw Normal View History

2022-12-15 13:41:19 +01:00
open Pdfutil
type drawops_colspec =
NoCol
| RGB of float * float * float
| Grey of float
| CYMK of float * float * float * float
type drawops =
| Rect of float * float * float * float (* x, y, w, h *)
| To of float * float
| Line of float * float
| Fill of drawops_colspec
| Stroke of drawops_colspec
2022-12-15 15:20:41 +01:00
| SetLineThickness of float
| SetLineCap of int
| SetLineJoin of int
| SetMiterLimit of float
| SetDashPattern of float list * float
2022-12-16 13:13:38 +01:00
| Matrix of Pdftransform.transform_matrix
| Push
| Pop
2022-12-15 13:41:19 +01:00
| EndPath
type state =
{mutable fill : drawops_colspec;
mutable stroke : drawops_colspec;
mutable linewidth : float;
mutable linecap : int;
mutable linejoin : int;
mutable miterlimit : float;
mutable dashpattern : float list * float}
2022-12-16 13:13:38 +01:00
let initial_state () =
2022-12-15 13:41:19 +01:00
{fill = NoCol;
stroke = RGB (0., 0., 0.);
linewidth = 1.;
linecap = 0;
linejoin = 0;
miterlimit = 10.;
dashpattern = ([], 0.)}
2022-12-16 13:13:38 +01:00
let state =
ref [initial_state ()]
let currstate () =
match !state with s::_ -> s | [] -> assert false
let pushstate () =
match !state with s::t -> state := {s with fill = s.fill}::s::t | [] -> assert false
let popstate () =
match !state with [s] -> () | s::t -> state := t | [] -> assert false
let cleanstate () =
state := [initial_state ()]
2022-12-15 13:41:19 +01:00
let ops_of_drawop = function
2022-12-16 13:13:38 +01:00
| Push -> pushstate (); [Pdfops.Op_q]
| Pop -> popstate (); [Pdfops.Op_Q]
| Matrix m -> [Pdfops.Op_cm m]
2022-12-15 13:41:19 +01:00
| Rect (x, y, w, h) -> [Pdfops.Op_re (x, y, w, h)]
| To (x, y) -> [Pdfops.Op_m (x, y)]
| Line (x, y) -> [Pdfops.Op_l (x, y)]
| Fill x ->
2022-12-16 13:13:38 +01:00
(currstate ()).fill <- x;
2022-12-15 13:41:19 +01:00
begin match x with
| RGB (r, g, b) -> [Op_rg (r, g, b)]
| Grey g -> [Op_g g]
| CYMK (c, y, m, k) -> [Op_k (c, y, m, k)]
| NoCol -> []
end
| Stroke x ->
2022-12-16 13:13:38 +01:00
(currstate ()).stroke <- x;
2022-12-15 13:41:19 +01:00
begin match x with
| RGB (r, g, b) -> [Op_RG (r, g, b)]
| Grey g -> [Op_G g]
| CYMK (c, y, m, k) -> [Op_K (c, y, m, k)]
| NoCol -> []
end
| EndPath ->
2022-12-16 13:13:38 +01:00
begin match (currstate ()).fill, (currstate ()).stroke with
2022-12-15 13:41:19 +01:00
| NoCol, NoCol -> []
| NoCol, _ -> [Pdfops.Op_S]
| _, NoCol -> [Pdfops.Op_f]
| _, _ -> [Pdfops.Op_B']
end
2022-12-15 15:20:41 +01:00
| SetLineThickness t ->
2022-12-16 13:13:38 +01:00
(currstate ()).linewidth <- t;
2022-12-15 15:20:41 +01:00
[Pdfops.Op_w t]
| SetLineCap c ->
2022-12-16 13:13:38 +01:00
(currstate ()).linecap <- c;
2022-12-15 15:20:41 +01:00
[Pdfops.Op_J c]
| SetLineJoin j ->
2022-12-16 13:13:38 +01:00
(currstate ()).linejoin <- j;
2022-12-15 15:20:41 +01:00
[Pdfops.Op_j j]
| SetMiterLimit m ->
2022-12-16 13:13:38 +01:00
(currstate ()).miterlimit <- m;
2022-12-15 15:20:41 +01:00
[Pdfops.Op_M m]
| SetDashPattern (x, y) ->
2022-12-16 13:13:38 +01:00
(currstate ()).dashpattern <- (x, y);
2022-12-15 15:20:41 +01:00
[Pdfops.Op_d (x, y)]
2022-12-15 13:41:19 +01:00
let ops_of_drawops drawops = flatten (map ops_of_drawop drawops)
(* Draw all the accumulated operators *)
let draw fast range pdf drawops =
let s = Pdfops.string_of_ops (ops_of_drawops drawops) in
2022-12-16 13:13:38 +01:00
cleanstate ();
2022-12-15 13:41:19 +01:00
Cpdftweak.append_page_content s false fast range pdf