Module Hugin_vg_vector.Vector
What the SVG and PDF renderers share: the walk of a picture, numbers written to an accuracy in points, the maps they write, and paths mapped to a frame and cut at a margin around the page. A renderer gives the walk its syntax as a target.
A frame is the coordinate system a renderer writes numbers in: the page (y-down, in points), or the definition of a stamp, which its instances place.
Numbers
val decimals : float -> intdecimals k is the number of decimals that keeps a number of a frame the page magnifies k times within 0.0005 point once rounded: 3 for k <= 1., and one more per power of ten above, at most 17.
val finer : int -> int -> intfiner k d is k decimals more than d, at most 17. Numbers whose errors add up get finer decimals than their frame's, so that the sum stays within the accuracy.
val add_fixed : Stdlib.Buffer.t -> int -> float -> unitadd_fixed b d v adds v rounded to d decimals, without trailing zeros or point, and 0 for a number that rounds to zero, whatever its sign. v is taken within ±1e15, NaN as 1e15, so that what is added is a number of the order of the page's coordinates.
val add_exact : Stdlib.Buffer.t -> float -> unitadd_exact b v adds the shortest decimal that reads back as v, in %g notation, and 0 for zero, whatever its sign. v is finite.
Maps
val unit : Hugin_gg.Affine.t -> Hugin_gg.Affine.tunit m is the linear part of m divided by Affine.stretch m, which scales no length by more than 1..
val is_even : Hugin_gg.Affine.t -> boolis_even m is true iff the linear part of m is a positive multiple of the identity, up to a relative 1e-9.
val is_axial : Hugin_gg.Affine.t -> boolis_axial m is true iff the linear part of m scales the axes by positive factors and turns nothing, up to a relative 1e-9.
Paths and leaves
A frame's cut is the box its geometry is cut at: on the page, a margin around it; in a stamp's definition, Hugin_vg_instances.Instances.everywhere. Coordinates mapped beyond 1e15 are taken at 1e15.
type sink = {- #
move : float -> float -> unit; - #
line : float -> float -> unit; - #
cubic : float -> float -> float -> float -> float -> float -> unit; - #
close : unit -> unit;
}The type for what receives a path. Each subpath starts with move.
val area :
Hugin_gg.Affine.t ->
Hugin_gg.Box2.t ->
Hugin_gg.Path.t ->
sink ->
unitarea m cut q sink gives sink the subpaths of q mapped through m into a frame, each closed, as filling and clipping see them, as Hugin_gg.Path.crop crops them to cut.
val overlaps : Hugin_gg.Box2.t -> float -> float -> float -> float -> booloverlaps cut minx miny maxx maxy is true iff the box of these bounds meets cut, and false if a bound is NaN.
val run_meets :
Hugin_gg.Box2.t ->
Hugin_gg.Affine.t ->
Hugin_font.Run.t ->
boolrun_meets cut m r is true iff the ink of r mapped through m, or its origin if it has none, is finite and meets cut.
val ems : Hugin_font.Font.t -> floatems f is how far, in ems, the outline of a glyph of f reaches from its origin in any direction.
Pens
The type for pens as written: width, dash lengths and dash offset, in a frame.
val dash_decimals : int -> intdash_decimals d is the decimals of dash lengths in a frame of d decimals: three more, since the errors of the lengths add up along a subpath, so that a thousand of them stay within the accuracy.
is_dashed d pen is true iff a dash length of pen is written non-zero with dash_decimals d decimals. A pattern that is not is written solid.
phase pen o is the dash offset of pen moved by o, within the length of its pattern made even.
The walk
What paints a leaf of a kind: its own colour, the colour an enclosing instance sets and the leaf inherits, or a colour an instance drawn in full gives it.
type ctx = {- #
m : Hugin_gg.Affine.t;(*From the picture's coordinates to the frame's.
*) - #
cut : Hugin_gg.Box2.t;(*The frame's cut.
*) - #
mag : float;(*How much the page magnifies the frame's numbers.
*) - #
d : int;(*Decimals of the frame's numbers.
*) - #
fills : paint;(*What paints fills and glyphs.
*) - #
strokes : paint;(*What paints strokes.
*) - #
fill_set : bool;(*An enclosing instance sets the fill colour.
*) - #
stroke_set : bool;(*An enclosing instance sets the stroke colour.
*) - #
pen : float;(*What the lengths of pens are multiplied by.
*) - #
pen_set : bool;(*An enclosing instance sets the pen's lengths.
*)
}The type for where the walk is: its frame and what enclosing instances set.
val page : Hugin_vg.Renderable.t -> ctxpage r is the context of the page of r, cut at a margin of the page's larger side around it.
val box : ctx -> Hugin_vg.Picture.t -> Hugin_gg.Box2.t optionbox ctx p is a box of the frame holding what p paints there, grown by one point and cut by ctx.cut, or None if p paints nothing there.
type stroke = {- #
style : Hugin_gg.Stroke.t; - #
pen : pen;(*The pen as written in the frame.
*) - #
frame : Hugin_gg.Affine.t option;(*The matrix the pen is written under, if the frame stretches it unevenly: the frame's linear part scaled to stretch no more than the page does, its coefficients rounded to 15 decimals.
*) - #
dashed : bool;
}The type for strokes as written.
type image = {- #
pixels : Nx.host Nx.uint8_t;(*All the pixels of the image.
*) - #
window : int * int * int * int;(*The columns
*)c0toc1and rowsr0tor1, exclusive, whose cells may meet the cut. - #
x : float; - #
y : float; - #
w : float; - #
h : float;(*The box of these cells, in the picture's coordinates.
*)
}The type for images cropped to the cut.
type stamp = {- #
picture : Hugin_vg.Picture.t; - #
extent : Hugin_gg.Box2.t;(*The picture's box under the frame's linear part.
*) - #
pens : pen list;(*The distinct pens of the picture as written, if
*)scaled;[]otherwise. - #
decimals : int;(*The decimals that keep the picture's points within the accuracy once an instance's scale is rounded to them.
*) - #
translucent : bool;(*An instance sets a translucent colour.
*) - #
scaled : bool;(*The stamp scales its instances.
*) - #
fills : Hugin_gg.Color.t array option; - #
strokes : Hugin_gg.Color.t array option; - #
rows : int array option;(*The rows of its instances, from a tag.
*)
}The type for stamps as the walk writes them.
scale_decimals ctx s is the decimals of the pen an instance of scale s sets in the frame of ctx.
type ('b, 'd) target = {- #
fill : 'b -> ctx -> Hugin_vg.Picture.rule -> Hugin_gg.Color.t -> Hugin_gg.Path.t -> unit; - #
stroke : 'b -> ctx -> stroke -> Hugin_gg.Color.t -> (piece:(float -> unit) -> sink -> unit) -> unit;(*
*)stroke b ctx s c outlinewrites the strokes.outline ~piece sinkgivessinkits subpaths in the frame, cut at the cut grown by the pen's reach, mapped through the inverse ofs.frame.piece dprecedes each,dthe length before it along the subpath it was cut from:0.unlesss.dashedand the subpath was cut, so that the dashes keep their phase. - #
glyphs : 'b -> ctx -> Hugin_gg.Color.t -> Hugin_gg.P2.t -> Hugin_font.Run.t -> unit; - #
image : 'b -> ctx -> image -> unit; - #
clip : 'b -> ctx -> Hugin_vg.Picture.rule -> Hugin_gg.Path.t -> ('b -> unit) -> unit;(*
*)clip b ctx rule q kwrites whatkwrites, clipped. - #
opacity : 'b -> ctx -> float -> Hugin_vg.Picture.t -> ('b -> unit) -> unit;(*
*)opacity b ctx a p kwrites whatkwrites ofp, faded. - #
tag : 'b -> ctx -> Hugin_vg.Picture.tag -> ('b -> unit) -> unit;(*
*)tag b ctx t kwrites whatkwrites, tagged. A tag of rows on a stamp gives its rows to the stamp's instances and reachestagwithout rows. - #
carry : ctx -> stamp -> float -> float;(*
*)carry ctx st sis the scale an instance of scaleswrites, or NaN if the definition cannot carry it and the instance is drawn in full. It is applied toctxandstonce per stamp. - #
define : ctx -> Hugin_gg.Box2.t -> ('b -> unit) -> 'd;(*
*)define dctx box kis the definition of whatkwrites in the frame ofdctx, withinbox. - #
use : 'b -> ctx -> stamp -> 'd -> int -> Hugin_gg.P2.t -> float -> unit;(*
*)use b ctx st def i at swrites instanceiofdefatat, of scalesas carried. - #
instance : 'b -> stamp -> int -> ('b -> unit) -> unit;(*
*)instance b st i kwrites instanceidrawn in full byk.
}The type for targets: what a renderer writes for each case of a picture, into a 'b, a stamp's definition being a 'd.
val walk : ('b, 'd) target -> ctx -> 'b -> Hugin_vg.Picture.t -> unitwalk t ctx b p writes p into b with t. Transforms compose into ctx, and one with no inverse leaves nothing to write. A stamp is written as one definition that its instances use, except the instances whose scale t.carry does not carry, and all of them if they scale and the picture holds a scaling stamp or strokes of differing pens: those are drawn in full. An instance at a position or scale that is not finite, or of scale 0., paints nothing, and so does one that Hugin_vg_instances.Instances.shows does not show within ctx.cut, with the pens it keeps.