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
|