more
This commit is contained in:
parent
d16c7c284a
commit
dc2380298a
108
cpdfcommand.ml
108
cpdfcommand.ml
|
@ -1746,9 +1746,18 @@ let whingemalformed () =
|
||||||
prerr_string "Command line must be of exactly the form\ncpdf <infile> -gs <path> -gs-malformed-force -o <outfile>\n";
|
prerr_string "Command line must be of exactly the form\ncpdf <infile> -gs <path> -gs-malformed-force -o <outfile>\n";
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
(* Drawing operations. Just the parsed command line ops. We convert to actual PDF operations later. *)
|
(* Drawing operations. FIXME: Clear this around ANDs? *)
|
||||||
|
let drawops =
|
||||||
|
let t = Hashtbl.create 10 in
|
||||||
|
Hashtbl.add t "_" [];
|
||||||
|
t
|
||||||
|
|
||||||
let drawops = ref []
|
(* For now, re-using a save name is undefined, and nesting them is undefined too. To fix in both cases. *)
|
||||||
|
let currstash = ref "_"
|
||||||
|
|
||||||
|
let addop o =
|
||||||
|
let v = Hashtbl.find drawops !currstash in
|
||||||
|
Hashtbl.replace drawops !currstash (o::v)
|
||||||
|
|
||||||
let col_of_string s =
|
let col_of_string s =
|
||||||
match parse_color s with
|
match parse_color s with
|
||||||
|
@ -1758,44 +1767,44 @@ let col_of_string s =
|
||||||
| exception _ -> Cpdfdraw.NoCol
|
| exception _ -> Cpdfdraw.NoCol
|
||||||
|
|
||||||
let setstroke s =
|
let setstroke s =
|
||||||
drawops := Cpdfdraw.SetStroke (col_of_string s)::!drawops
|
addop (Cpdfdraw.SetStroke (col_of_string s))
|
||||||
|
|
||||||
let setfill s =
|
let setfill s =
|
||||||
drawops := Cpdfdraw.SetFill (col_of_string s)::!drawops
|
addop (Cpdfdraw.SetFill (col_of_string s))
|
||||||
|
|
||||||
let addrect s =
|
let addrect s =
|
||||||
let x, y, w, h = Cpdfcoord.parse_rectangle (Pdf.empty ()) s in
|
let x, y, w, h = Cpdfcoord.parse_rectangle (Pdf.empty ()) s in
|
||||||
drawops := Cpdfdraw.Rect (x, y, w, h)::!drawops
|
addop (Cpdfdraw.Rect (x, y, w, h))
|
||||||
|
|
||||||
let addto s =
|
let addto s =
|
||||||
let x, y = Cpdfcoord.parse_coordinate (Pdf.empty ()) s in
|
let x, y = Cpdfcoord.parse_coordinate (Pdf.empty ()) s in
|
||||||
drawops := Cpdfdraw.To (x, y)::!drawops
|
addop (Cpdfdraw.To (x, y))
|
||||||
|
|
||||||
let addline s =
|
let addline s =
|
||||||
let x, y = Cpdfcoord.parse_coordinate (Pdf.empty ()) s in
|
let x, y = Cpdfcoord.parse_coordinate (Pdf.empty ()) s in
|
||||||
drawops := Cpdfdraw.Line (x, y)::!drawops
|
addop (Cpdfdraw.Line (x, y))
|
||||||
|
|
||||||
let stroke () =
|
let stroke () =
|
||||||
drawops := Cpdfdraw.Stroke::!drawops
|
addop Cpdfdraw.Stroke
|
||||||
|
|
||||||
let fill () =
|
let fill () =
|
||||||
drawops := Cpdfdraw.Fill::!drawops
|
addop Cpdfdraw.Fill
|
||||||
|
|
||||||
let fillevenodd () =
|
let fillevenodd () =
|
||||||
drawops := Cpdfdraw.FillEvenOdd::!drawops
|
addop Cpdfdraw.FillEvenOdd
|
||||||
|
|
||||||
let strokefill () =
|
let strokefill () =
|
||||||
drawops := Cpdfdraw.FillStroke::!drawops
|
addop Cpdfdraw.FillStroke
|
||||||
|
|
||||||
let strokefillevenodd () =
|
let strokefillevenodd () =
|
||||||
drawops := Cpdfdraw.FillStrokeEvenOdd::!drawops
|
addop Cpdfdraw.FillStrokeEvenOdd
|
||||||
|
|
||||||
let closepath () =
|
let closepath () =
|
||||||
drawops := Cpdfdraw.ClosePath::!drawops
|
addop Cpdfdraw.ClosePath
|
||||||
|
|
||||||
let setthickness s =
|
let setthickness s =
|
||||||
try
|
try
|
||||||
drawops := Cpdfdraw.SetLineThickness (float_of_string s)::!drawops
|
addop (Cpdfdraw.SetLineThickness (float_of_string s))
|
||||||
with
|
with
|
||||||
_ -> error "Thickness must be a number"
|
_ -> error "Thickness must be a number"
|
||||||
|
|
||||||
|
@ -1807,7 +1816,7 @@ let setcap s =
|
||||||
| "square" -> 2
|
| "square" -> 2
|
||||||
| _ -> error "Unknown cap type"
|
| _ -> error "Unknown cap type"
|
||||||
in
|
in
|
||||||
drawops := Cpdfdraw.SetLineCap num::!drawops
|
addop (Cpdfdraw.SetLineCap num)
|
||||||
|
|
||||||
let setjoin s =
|
let setjoin s =
|
||||||
let num =
|
let num =
|
||||||
|
@ -1817,38 +1826,77 @@ let setjoin s =
|
||||||
| "bevel" -> 2
|
| "bevel" -> 2
|
||||||
| _ -> error "Unknown join type"
|
| _ -> error "Unknown join type"
|
||||||
in
|
in
|
||||||
drawops := Cpdfdraw.SetLineJoin num::!drawops
|
addop (Cpdfdraw.SetLineJoin num)
|
||||||
|
|
||||||
let setmiter s =
|
let setmiter s =
|
||||||
try
|
try
|
||||||
drawops := Cpdfdraw.SetMiterLimit (float_of_string s)::!drawops
|
addop (Cpdfdraw.SetMiterLimit (float_of_string s))
|
||||||
with
|
with
|
||||||
_ -> error "Miter limit must be a number"
|
_ -> error "Miter limit must be a number"
|
||||||
|
|
||||||
|
let readfloats s = map float_of_string (String.split_on_char ' ' s)
|
||||||
|
|
||||||
let setdash s =
|
let setdash s =
|
||||||
try
|
try
|
||||||
let x, y =
|
let x, y =
|
||||||
let nums = map float_of_string (String.split_on_char ' ' s) in
|
let nums = readfloats s in all_but_last nums, last nums
|
||||||
all_but_last nums, last nums
|
|
||||||
in
|
in
|
||||||
drawops := Cpdfdraw.SetDashPattern (x, y)::!drawops
|
addop (Cpdfdraw.SetDashPattern (x, y))
|
||||||
with
|
with
|
||||||
_ -> error "Dash pattern elements must one or more numbers"
|
_ -> error "Dash pattern elements must one or more numbers"
|
||||||
|
|
||||||
let push () =
|
let push () =
|
||||||
drawops := Cpdfdraw.Push::!drawops
|
addop Cpdfdraw.Push
|
||||||
|
|
||||||
let pop () =
|
let pop () =
|
||||||
drawops := Cpdfdraw.Pop::!drawops
|
addop Cpdfdraw.Pop
|
||||||
|
|
||||||
let setmatrix s =
|
let setmatrix s =
|
||||||
match map float_of_string (String.split_on_char ' ' s) with
|
match readfloats s with
|
||||||
| [a; b; c; d; e; f] ->
|
| [a; b; c; d; e; f] ->
|
||||||
drawops := Cpdfdraw.Matrix {Pdftransform.a = a; Pdftransform.b = b; Pdftransform.c = c;
|
addop (Cpdfdraw.Matrix {Pdftransform.a = a; Pdftransform.b = b; Pdftransform.c = c;
|
||||||
Pdftransform.d = d; Pdftransform.e = e; Pdftransform.f = f}::!drawops
|
Pdftransform.d = d; Pdftransform.e = e; Pdftransform.f = f})
|
||||||
| _ -> error "Matrix must have six numbers"
|
| _ -> error "Matrix must have six numbers"
|
||||||
| exception _ -> error "Matrix elements must be numbers"
|
| exception _ -> error "Matrix elements must be numbers"
|
||||||
|
|
||||||
|
let setmtranslate s =
|
||||||
|
match readfloats s with
|
||||||
|
| [a; b] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.Translate (a, b)]))
|
||||||
|
| _ | exception _ -> error "-mtranslate takes two numbers"
|
||||||
|
|
||||||
|
let setmrotate s =
|
||||||
|
match readfloats s with
|
||||||
|
| [a; b; c] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.Rotate ((a, b), c)]))
|
||||||
|
| _ | exception _ -> error "-mrotate takes three numbers"
|
||||||
|
|
||||||
|
let setmscale s =
|
||||||
|
match readfloats s with
|
||||||
|
| [a; b; c; d] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.Scale ((a, b), c, d)]))
|
||||||
|
| _ | exception _ -> error "-mtranslate takes four numbers"
|
||||||
|
|
||||||
|
let setmshearx s =
|
||||||
|
match readfloats s with
|
||||||
|
| [a; b; c] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.ShearX ((a, b), c)]))
|
||||||
|
| _ | exception _ -> error "-mshearx takes three numbers"
|
||||||
|
|
||||||
|
let setmsheary s =
|
||||||
|
match readfloats s with
|
||||||
|
| [a; b; c] -> addop (Cpdfdraw.Matrix (Pdftransform.matrix_of_transform [Pdftransform.ShearY ((a, b), c)]))
|
||||||
|
| _ | exception _ -> error "-msheary takes three numbers"
|
||||||
|
|
||||||
|
let savexobj s =
|
||||||
|
Hashtbl.add drawops s [];
|
||||||
|
currstash := s
|
||||||
|
|
||||||
|
let endsave s =
|
||||||
|
currstash := "_"
|
||||||
|
|
||||||
|
let usexobj s =
|
||||||
|
try
|
||||||
|
addop (Cpdfdraw.SoftXObject (rev (Hashtbl.find drawops s)))
|
||||||
|
with
|
||||||
|
_ -> error (Printf.sprintf "Could not find stashed graphics %s\n" s)
|
||||||
|
|
||||||
(* Parse a control file, make an argv, and then make Arg parse it. *)
|
(* Parse a control file, make an argv, and then make Arg parse it. *)
|
||||||
let rec make_control_argv_and_parse filename =
|
let rec make_control_argv_and_parse filename =
|
||||||
control_args := !control_args @ parse_control_file filename
|
control_args := !control_args @ parse_control_file filename
|
||||||
|
@ -2647,6 +2695,14 @@ and specs =
|
||||||
("-push", Arg.Unit push, " Push graphics stack");
|
("-push", Arg.Unit push, " Push graphics stack");
|
||||||
("-pop", Arg.Unit pop, " Pop graphics stack");
|
("-pop", Arg.Unit pop, " Pop graphics stack");
|
||||||
("-matrix", Arg.String setmatrix, " Append to graphics matrix");
|
("-matrix", Arg.String setmatrix, " Append to graphics matrix");
|
||||||
|
("-mtrans", Arg.String setmtranslate, " Translate the graphics matrix");
|
||||||
|
("-mrot", Arg.String setmrotate, " Rotate the graphics matrix");
|
||||||
|
("-mscale", Arg.String setmscale, " Scale the graphics matrix");
|
||||||
|
("-mshearx", Arg.String setmshearx, " Shear the graphics matrix in X");
|
||||||
|
("-msheary", Arg.String setmshearx, " Shear the graphics matrix in Y");
|
||||||
|
("-save", Arg.String savexobj, " Begin to save graphics operators");
|
||||||
|
("-endsave", Arg.String endsave, " End saving of graphics operators");
|
||||||
|
("-use", Arg.String usexobj, " Use a saved sequence of graphics operators");
|
||||||
(* These items are undocumented *)
|
(* These items are undocumented *)
|
||||||
("-remove-unused-resources", Arg.Unit (setop RemoveUnusedResources), "");
|
("-remove-unused-resources", Arg.Unit (setop RemoveUnusedResources), "");
|
||||||
("-stay-on-error", Arg.Unit setstayonerror, "");
|
("-stay-on-error", Arg.Unit setstayonerror, "");
|
||||||
|
@ -4147,7 +4203,7 @@ let go () =
|
||||||
| Some Draw ->
|
| Some Draw ->
|
||||||
let pdf = get_single_pdf args.op false in
|
let pdf = get_single_pdf args.op false in
|
||||||
let range = parse_pagespec_allow_empty pdf (get_pagespec ()) in
|
let range = parse_pagespec_allow_empty pdf (get_pagespec ()) in
|
||||||
write_pdf false (Cpdfdraw.draw args.fast range pdf (rev !drawops))
|
write_pdf false (Cpdfdraw.draw args.fast range pdf (rev (Hashtbl.find drawops "_")))
|
||||||
|
|
||||||
(* Advise the user if a combination of command line flags makes little sense,
|
(* Advise the user if a combination of command line flags makes little sense,
|
||||||
or error out if it make no sense at all. *)
|
or error out if it make no sense at all. *)
|
||||||
|
|
|
@ -26,8 +26,10 @@ type drawops =
|
||||||
| Stroke
|
| Stroke
|
||||||
| FillStroke
|
| FillStroke
|
||||||
| FillStrokeEvenOdd
|
| FillStrokeEvenOdd
|
||||||
|
| SoftXObject of drawops list
|
||||||
|
| HardXObject of drawops list
|
||||||
|
|
||||||
let ops_of_drawop = function
|
let rec ops_of_drawop = function
|
||||||
| Push -> [Pdfops.Op_q]
|
| Push -> [Pdfops.Op_q]
|
||||||
| Pop -> [Pdfops.Op_Q]
|
| Pop -> [Pdfops.Op_Q]
|
||||||
| Matrix m -> [Pdfops.Op_cm m]
|
| Matrix m -> [Pdfops.Op_cm m]
|
||||||
|
@ -59,8 +61,11 @@ let ops_of_drawop = function
|
||||||
| SetLineJoin j -> [Pdfops.Op_j j]
|
| SetLineJoin j -> [Pdfops.Op_j j]
|
||||||
| SetMiterLimit m -> [Pdfops.Op_M m]
|
| SetMiterLimit m -> [Pdfops.Op_M m]
|
||||||
| SetDashPattern (x, y) -> [Pdfops.Op_d (x, y)]
|
| SetDashPattern (x, y) -> [Pdfops.Op_d (x, y)]
|
||||||
|
| SoftXObject l | HardXObject l ->
|
||||||
|
[Pdfops.Op_q] @ ops_of_drawops l @ [Pdfops.Op_Q]
|
||||||
|
|
||||||
let ops_of_drawops drawops = flatten (map ops_of_drawop drawops)
|
and ops_of_drawops drawops =
|
||||||
|
flatten (map ops_of_drawop drawops)
|
||||||
|
|
||||||
(* Draw all the accumulated operators *)
|
(* Draw all the accumulated operators *)
|
||||||
let draw fast range pdf drawops =
|
let draw fast range pdf drawops =
|
||||||
|
|
|
@ -24,5 +24,7 @@ type drawops =
|
||||||
| Stroke
|
| Stroke
|
||||||
| FillStroke
|
| FillStroke
|
||||||
| FillStrokeEvenOdd
|
| FillStrokeEvenOdd
|
||||||
|
| SoftXObject of drawops list
|
||||||
|
| HardXObject of drawops list
|
||||||
|
|
||||||
val draw : bool -> int list -> Pdf.t -> drawops list -> Pdf.t
|
val draw : bool -> int list -> Pdf.t -> drawops list -> Pdf.t
|
||||||
|
|
Loading…
Reference in New Issue