We are to generate an image showing a white circle inside a black square:
The main function for drawing this image is given as follows:
fun draw_sqrcirc{l:agz} (cr: !cairo_ref l): void = let val () = cairo_rectangle (cr, ~0.5, ~0.5, 1.0, 1.0) val () = cairo_set_source_rgb (cr, 0.0, 0.0, 0.0) // black color val () = cairo_fill (cr) val () = cairo_arc (cr, 0.0, 0.0, 0.5, 0.0, 2*PI) val () = cairo_set_source_rgb (cr, 1.0, 1.0, 1.0) // white color val () = cairo_fill (cr) in // nothing end // end of [draw_sqrcirc]
At this moment, let us assume that the square is centered at the position (0, 0) and the length of each of its sides is 1. Therefore, the upper left corner of the square is at (-0.5, -0.5) as x-axis and y-axis increase from left to right and from top to bottom, respectively. We first draw as follows a rectangle which happens to be a square:
The function cairo_rectangle is given the following type in ATS:
fun cairo_rectangle {l:agz} ( cr: !cairo_ref l, x: double, y: double, width: double, height: double ) : void // end of [cairo_rectangle]
When called, this function draws a rectangle whose width and height are width and height, respectively, and whose upper left corner is located at (x, y).
We then fill the rectangle with black color:
We next draw a circle of radius 0.5 whose center is at (0.0, 0.0):
The function cairo_arc is given the following type in ATS:
fun cairo_arc {l:agz} ( cr: !cairo_ref l , xc: double, yc: double, rad: double, angle1: double, angle2: double ) : void // end of [cairo_arc]
When called, this function draws an arc that is part of the circle whose radius equals radius and whose center is at (xc, yc). The arc begins at the angle angle1 and ends at the angle angle2, where clockwise rotation is assumed. If counterclockwise rotation is needed, the following function can be used instead:
fun cairo_arc_negative {l:agz} ( cr: !cairo_ref l , xc: double, yc: double, rad: double, angle1: double, angle2: double ) : void // end of [cairo_arc_negative]
Lastly, we fill the circle with white color:
We can now make a call to the function draw_sqrcirc to generate a PNG file:
implement main0 () = () where { // val W = 250 and H = 250 // val surface = // create a surface for drawing cairo_image_surface_create (CAIRO_FORMAT_ARGB32, W, H) val cr = cairo_create (surface) // val WH = min (W, H) val WH = double_of (WH) val (pf0 | ()) = cairo_save (cr) val () = cairo_translate (cr, WH/2, WH/2) val () = cairo_scale (cr, WH, WH) val () = draw_sqrcirc (cr) val () = cairo_restore (pf0 | cr) // val status = cairo_surface_write_to_png (surface, "tutprog_sqrcirc.png") val () = cairo_surface_destroy (surface) // a type error if omitted val () = cairo_destroy (cr) // a type error if omitted // // in case of a failure ... val () = assert_errmsg (status = CAIRO_STATUS_SUCCESS, #LOCATION) } (* end of [main0] *)
The functions cairo_translate and cairo_scale are given the following types in ATS:
fun cairo_translate {l:agz} (cr: !cairo_ref l, x: double, y: double): void // end of [cairo_translate] fun cairo_scale {l:agz} (cr: !cairo_ref l, sx: double, sy: double): void // end of [cairo_scale]
When called, cairo_translate creates a new coordinate system by shifting the origin of the current coordinate system to the point (x, y) and cairo_scale creates a new coordinate system whose x-unit and y-unit are sx and sy times the x-unit and y-unit of the current system, respectively.
For the entirety of the code used in this section, please see tutprog_sqrcirc.dats
For a more elaborate example involving circles, please see illucircmot.dats, which generates the following interesting image:
For a more elabortate example involving squares and circles, please see illuwavy.dats, which generates the following interesting image: