This is a library to produce PostScript documents using the OCaml. It is distributed under the terms of the GNU Lesser General Public Licence. You can download it here: postscript.ml.
type orientation = [ `Portrait | `Landscape ]
Orientations for the page.
type alignment = [ `Left | `Right | `Center ]
Text alignment
type end_point = [ `Square | `Round | `Projected ]
End point style for lines. With `Square, lines are ended with with a straight stop; with `Round they are ended with a circle; and with `Projected, they are ended bu a square.
type line_join = [ `Square | `Round | `Bevel ]
Join style for lines. With Square, they make an angle; with Round, they are joint by a curve line; and with Bevel, they are joint by une segment.
and color = [ `RGB of float * float * float | `HSB of float * float * float | `Gray of float ]
Color specification, either red/green/blue, hue/saturation/brightness or gray level. All values are between 0.0 and 1.0 except hue, which is between 0.0 and 360.0.
type fill_type = [ `None | `Current | `Color of color ]
Fill styles for closed figures.
type document_state = Pre_init | Post_exit | Dumb | Prolog | Page
Possible states for the PostScript structure generator. You don't need to use that!
type structure_severity = [ `Fatal | `Verbose | `Quiet ]
Severity level in case of structural error. `Fatal raises an exception, `Verbose prints a warning on stderr and `Quiet does nothing.
type font = { ft_name: string }
The (opaque) structure returned by font creation methods.
module Matrix : sig
This module handles affine transformations.
type t = (float * float) * (float * float) * (float * float)
val id : t
The identity transform.
val translation : float -> float -> t
translation x y
The translation of vector (x, y).
val rotation : ?center:float * float -> float -> t
rotation center:(x, y) angle
The rotation of center (x, y) and angle angle. The center defaults to (0, 0).
val homotetie : ?center:float * float -> float -> t
homotetie center:(x, y) ratio
The homotetie of center (x, y) and ratio ratio. The center defaults to (0, 0).
val shear_x : float -> t
The shearing along the x axis:
______ _______ | | / / |______| -> /______/
val shear_y : float -> t
The shearing along the y axis.
val apply : t -> float * float -> float * float
apply matrix vector
Calculates the image of vector by matrix.
val compose : t -> t -> t
compose matr1 matr2
Returns the composed matrix matr1 o matr2.
val dump : t -> string
Dumps a matrix in PostScript syntax.
val dump_up : t -> string
Dumps a matrix in PostScript syntax, using the NICOMP function to take care of vertical inversion. Useful when handling font transforms.
val may : ('a -> 'b) -> 'b -> 'a option -> 'b
may function default option
An useful function to handle option values: if option is None, default is returned, and if it is Some x, function x is evalued.
val split : string -> string list
Splits a string into words.
val ascii85encode : char Stream.t -> (char -> unit) -> unit
ascii85encode input_stream output_function
Encodes input_stream in ASCII-85, and output it using output_function.
val uniq_name : string -> unit -> string
let u = uniq_name "prefix" u (); u ()
Makes functions that generates uniques names starting with prefix.
val state_name : document_state -> string
Converts document_state value in a readable form.
val latin1_encoding : string list
The names of the gliphs in the iso-8859-1 (latin-1) encoding.
val default_charset : string * string list
("latin1", latin1_encoding)
The default charset of the PostScript engine, latin-1.
val procset : string
The procedures set used by the engine.
val quote_string : string -> string
Quotes a string using the convention: characters (, ) and \ are prefixed with a \.
module Font_metrics : sig
This module enables to parse .afm font metrics files. It is very simple.
type character = { name : string; wx : int; xmin : int; ymin : int; xmax : int; ymax : int; }
Information of a character in a font. wx is the horizontal offset.
type t = { chars : character array; }
Metric information about a font.
val read : ?encoding:string list -> string -> t
Read and parse the given .afm font metrics. Very strict about the format.
val string : t -> ?size:float -> string -> float * float * float
let (width, max, min) = string font_metrics "string"
Computes the extents of the given string, max and min define the vertical extents, relative to the current point.
class postscript : ?end_fun:(unit -> unit) -> out_channel -> object
let engine = new postscript end_fun:function output
The PostScript engine object. I use an object because it's possible t want to output several PostScripts at the same time, and because there are side effects. output is the output stream for the PostScript. end_fun will be called when the object is exited. It can be used to automatically close output.
method init : ?unit:float -> ?orientation:orientation -> ?inverted:bool -> ?hmargin:float -> ?vmargin:float -> float -> float -> unit
engine#init width height
Initializes the postScript engine with a page size of width×height. unit is the unit used for all dimensions, in dots; it defaults to 1 dot. If inverted is true, the y coordinates grows downward; if it's false (the default), it grows upwads. hmargin and vmargin are respectivly the left and bottom (or tom, if inverted is true) margins; they default to 0.
method exit : unit -> unit
Flushes the PostScript engine and end the session.
method new_page : unit -> unit
Begin a new page. All drawing properties are reset.
You can use this PostScript engine to produce structured documents, with page information. The resulting documents can be best viewed with softwares like GhostView (at this time, it doesn't conform strictly to Adobe's DSC, but GhostView accepts it). But If you do that, you must take care to define all used resources in the prolog, before starting the first page.
method begin_document : ?unit:float -> ?orientation:orientation -> ?inverted:bool -> ?pages:int -> ?hmargin:float -> ?vmargin:float -> float -> float -> unit
Initialize the PostScript engine, but with document structure information. pages is the total number of pages of the document. For the others arguments, see init.
method end_document : unit -> unit
Ends the document.
method begin_page : string -> unit
engine#begin_page label
Begin a new page, labeled with label (which is usually a number, but that's not necessary).
Warning: all these styles are reset when you start a new page.
method set_color : color -> unit
Sets the color.
method set_line_width : float -> unit
Sets the line width. 0 is the device thinest line.
method set_dash : black:float -> white:float -> unit
Sets the lines to be dashed. black is the length of drawn segments, white is the length of not drawn segments.
method set_dash_full : ofs:float -> len:float list -> unit
Sets the lines to be dashed, in a richer form. ofs is the space before the first dash, len is the length of the dashes.
method set_no_dash : unit -> unit
Sets the lines to be plain.
method set_line_cap : end_point -> unit
Sets the line cap. See the end_point type for more.
method set_line_join : line_join -> unit
Sets the line join. See the line_join type for more.
method line : float -> float -> float -> float -> unit
engine#line x1 y1 x2 y2
Draws a line from (x1, y1) to (x2, y2).
method lines : (float * float) list -> unit
Draws lines between the points whose coordinates are given.
method rectangle : ?fill:fill_type -> float -> float -> w:float -> h:float -> unit
engine#rectangle x y w:width h:height
Draws a rectangle with the lower-left (I supose you don't use an inverted coordinates system) corner at (x, y) whose size is width×height. The rectangle can be filled. See the fill_typetype for more information. I won't speak again of filling.
method circle : ?fill:fill_type -> float -> float -> rad:float -> unit
engine#circle x y radius
Draws a circle. Ellipses are currently unsupported. Sorry.
method polygon : ?fill:fill_type -> (float * float) list -> unit
Draws a polygon. The difference with lines is that the polygon is closed and can be filled.
method arc : float -> float -> rad:float -> a1:float -> a2:float -> unit
engine#arc x y rad:radius a1:start_angle a2:end_angle
Draws a circle arc. Anlges are given in degrees, starting along the x axis.
method angle : ?fill:fill_type -> float -> float -> rad:float -> a1:float -> a2:float -> unit
Draws a circle angle. Unlike arc, this function draws the radius. As it's a closed path, you can fill it.
method curve : s:float * float -> e:float * float -> ts:float * float -> te:float * float -> unit
Draws a Béziers curve between from with tangent vector tfrom to to with tangent vector tto.
method curves : ((float * float) * (float * float)) list -> unit
Like lines but for Béziers curves.
method poly_curve : ?fill:fill_type -> ((float * float) * (float * float)) list -> unit
Like polygon but for Béziers curves.
method create_font : ?charset:string * string list -> string -> float -> font
let font = engine#create_font font_name size
Create a new font.
method create_font_matrix : ?charset:string * string list -> string -> Matrix.t -> font
let font = engine#create_font_matrix font_name matrix
Create a new font, using a transform matrix instead of a sinple size. create_font is equivalent to create_font_matrix with matrix equals to Matrix.homotetie size.
method print : ?align:alignment -> float -> float -> str:string -> unit
engine#print x y string
Prints a string, using the current font.
method set_font : font -> unit
Sets the current font.
method add_charset : string -> string list -> unit
Defines a new character encoding. I think you don't want to use that, consider it's private.
method recode_font : ?charset:string * string list -> string -> string
Changes the character encoding of a font.
method clip : ?reset:bool -> float -> float -> w:float -> h:float -> unit
engine#clip x y w:width h:height
Sets the clipping rectangle. If reset is false, it's intersected with the previous; reset defaults to true.
method change_coordinates : ?definitive:bool -> Matrix.t -> unit
Change the coordinates system, acording to the given matrix. If definitive is true, the old coordinates system can't be restored (but it's always reset on a new page); it defaults to false.
method restore_coordinates : unit -> unit
Restores the previous coordinates system.
method private image_matrix : float -> float -> float -> float -> int -> int -> unit
Outputs the transform matrix, given the image size, position and resolution.
method color_image_from_function : size:float * float -> pos:float * float -> res:int * int -> f:(int -> int -> int * int * int) -> unit
Plots a color bitmap image. pos is coordinates of the lower-left corner of the image. size is the size of the resulting image. res is the number of pixel in each direction. fun is a function that takes the coordinates of the pixel and returns the color (in three RGB 0-255 integers).
method color_image_from_strings : size:float * float -> pos:float * float -> res:int * int -> data:string array -> unit
Plots a color bitmap image. Here, the bitmap data is held by a string array: one string per row, three characters per pixel.
method gray_image_from_function : size:float * float -> pos:float * float -> res:int * int -> f:(int -> int -> int) -> unit
Exactly like above, but for gray-level images.
method gray_image_from_strings : size:float * float -> pos:float * float -> res:int * int -> data:string array -> unit
Exactly like above, but for gray-level images.
method color_image : float -> float -> float -> float -> int -> int -> (unit -> unit) -> unit
The low-level function to plot a color color image.
method gray_image : float -> float -> float -> float -> int -> int -> (unit -> unit) -> unit
The low-level function to plot a gray gray image.
These two functions enables to include JPEG bitmaps in the document in a quite compact form.
method jpeg_image : ?color:bool -> size:float * float -> pos:float * float -> res:int * int -> char Stream.t -> unit
Draws a JPEG bitmap given as a char stream. You have to provide yourself the information on the resolution of the JPEG and wether it is a color or grayscale image. If the y coordinates grows upwards, the image will be vertically inverted, unless you give a nigative vertical size.
method jpeg_image_from_file : ?color:bool -> size:float * float -> pos:float * float -> res:int * int -> string -> unit
As above, but reads in a file.
These functions enables to do more things, but are a bit more difficile to use. Maybe you should have a look at the PostScript internal system.
method ll_newpath : unit -> unit
Begins a new path.
method ll_moveto : ?relative:bool -> float -> float -> unit
Moves the current point.
method ll_lineto : ?relative:bool -> float -> float -> unit
Appends a line between the current point and the given point to the current path.
method ll_arc : ?clockwise:bool -> float * float -> float -> float -> float -> unit
engine#ll_arc (x, y) radius start_angle end_angle
Appends an arc to the current path.
method ll_curveto : ?relative:bool -> float * float -> float * float -> float * float -> unit
engine#curveto first_handle second_handle end_point
Appends a Béziers curve to the current path. Warning: the handle points are not vectors.
method ll_stroke : unit -> unit
Draws the current path.
method ll_clip : unit -> unit
Sets the interior of the current path to be the clipping area.
method ll_closepath : unit -> unit
Closes the current path with a straight line.
method ll_reversepath : unit -> unit
Reverses the current path.
method ll_strokepath : unit -> unit
Replaces the current path by its outline.
method set_severity : structure_severity -> unit
Sets the severity level of the engine, about mistakes in the document structure.
method dirty_write : string -> unit
Write string directly to the PostScript file.
val new_postscript_to_file : string -> postscript
Creates a new PostScript engine, outputing to a file, and automaticaly closing the channel.