The first program we present in this tutorial is given as follows:
implement main0 () = () where { // // create a surface for drawing // val sf = // create a surface for drawing cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 250, 80) // val cr = cairo_create (sf) // create a context for drawing // val () = cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD) val () = cairo_set_font_size (cr, 32.0) // // the call [cairo_set_source_rgb] sets the color to blue // val () = cairo_set_source_rgb (cr, 0.0(*r*), 0.0(*g*), 1.0(*b*)) val () = cairo_move_to (cr, 10.0, 50.0) val () = cairo_show_text (cr, "Hello, world!") // val status = cairo_surface_write_to_png (sf, "tutprog_hello.png") val () = cairo_destroy (cr) // a type error if omitted val () = cairo_surface_destroy (sf) // a type error if omitted // // in case of a failure ... // val () = assertloc (status = CAIRO_STATUS_SUCCESS) // } (* end of [main0] *)
The functions in the cairo package are declared in the following file:
Note that in this tutorial, a file name, if relative, is always relative to the ATS home directory (stored in the environment variable ATSHOME) unless it is specified otherwise.
Suppose that the presented program is contained in a file named tutprog_hello.dats. The following command can be issued to compile the program to generate an executable of the name tutprog_hello:
One can now execute tutprog_hello to generate a PNG image file tutprog_hello.png, which is included as follows:
One can also use tools such eog and gthumb to view PNG files.
Let us now go over some brief explanation about the program contained in tutprog_hello.dats.
The following code first creates a cairo surface for drawing:
Then a cairo drawing context is created based on the surface: A font face is chosen and the font size is set to 32.0:val () = cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD) val () = cairo_set_font_size (cr, 32.0)
Imagine that we are holding a pen. The following code sets the color of the pen to blue:
// the call [cairo_set_source_rgb] sets the color to blue val () = cairo_set_source_rgb (cr, 0.0(*r*), 0.0(*g*), 1.0(*b*))
At this point, drawing is finised. The image drawn on the surface can be stored into a PNG file:
Both the context and the surface are destroyed during the cleanup phase:val () = cairo_destroy (cr) // a type error if omitted val () = cairo_surface_destroy (sf) // a type error if omitted
It may seem that using cairo functions in ATS is nearly identical to using them in C (modulo syntatical difference). However, what happens at the level of typechecking in ATS is far more sophisticated than in C. In particular, linear types are assigned to cairo objects (such as contexts, surfaces, patterns, font faces, etc.) in ATS to allow them to be tracked statically, that is, at compile-time, preventing potential mismanagement of such objects. For instance, if the following line:
is removed from the program in tutprog_hello.dats, then a type-error message is issued at compile-time to indicate that the resource sf is not properly freed. A message as such can be of great value in practice for correcting potential memory leaks that may otherwise readily go unnoticed. ATS is a programming language that distinguishes itself in its practical and effective support for precise resource management.