%{
//
dynload "libatsdoc/dynloadall.dats"
#include "utils/atsdoc/DOCUMENT/TUTORIALATS/tutorialatxt.dats"
//
#include "./ATEXT/ats2cairo.dats"
//
%}\
#comment("\n\
The file is automatically generated by [atsdoc] from chap_hello.atxt.\n\
")
#comment("\n\
Time of Generation: #timestamp()\
")
<chapter id="hello_example">
#title("A Simple Example: Hello, world!")

#para("\

The first program we present in this tutorial is given as follows:

#atscode('\
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] *)
')\

")

#para("\
The functions in the cairo package are declared in the following file:
")

#para("\
#ulink1(
"#ATSLANGSRCROOTget()/contrib/cairo/SATS/cairo.sats", "contrib/cairo/SATS/cairo.sats"
)
")

#para("\
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.
")

#para('\

Suppose that the presented program is contained in a file named
#mycodelink("tutprog_hello.dats", "tutprog_hello.dats").  The following
command can be issued to compile the program to generate an executable of
the name #filename("tutprog_hello"):

<informalexample><programlisting>
#command("atscc") -I${PATSHOME}/contrib -o tutprog_hello tutprog_hello.dats `pkg-config cairo --cflags --libs`
</programlisting></informalexample>

')

#para("\

One can now execute #filename("tutprog_hello") to generate a PNG image file
#myimagelink("tutprog_hello.png", "tutprog_hello.png"), which is included
as follows:\

")

#para('\
<inlinemediaobject>
<imageobject>
<imagedata fileref="#MYIMAGEROOTget()/tutprog_hello.png" format="PNG"/>
</imageobject>
</inlinemediaobject>
')

#para("\

One can also use tools such #command("eog") and #command("gthumb") to view
PNG files.

")

#para("\

Let us now go over some brief explanation about the program contained in
#mycodelink("tutprog_hello.dats", "tutprog_hello.dats").

")

#para("\

The following code first creates a cairo surface for drawing:\

#atscode('\
  val sf = // create a surface for drawing
    cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 250, 80)
')

Then a cairo drawing context is created based on the surface:

#atscode('\
  val cr = cairo_create (sf) // create a context for drawing
')

A font face is chosen and the font size is set to 32.0:

#atscode('\
  val () = cairo_select_font_face
    (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
  val () = cairo_set_font_size (cr, 32.0)
')

")

#para('\
Imagine that we are holding a pen. The following code
sets the color of the pen to blue:

#atscode('\
  // 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*))
')

Let us now move the pen to the postion (10.0, 50.0):

#atscode('\
  val () = cairo_move_to (cr, 10.0, 50.0)
')

and use the pen to write down the text "Hello, world!":

#atscode('\
  val () = cairo_show_text (cr, "Hello, world!")
')

')

#para('\

At this point, drawing is finised. The image drawn on the
surface can be stored into a PNG file:

#atscode('\
  val status = cairo_surface_write_to_png (sf, "tutprog_hello.png")
')

Both the context and the surface are destroyed during the cleanup phase:

#atscode('\
  val () = cairo_destroy (cr) // a type error if omitted
  val () = cairo_surface_destroy (sf) // a type error if omitted
')

In case of a failure, it is reported by the following code:

#atscode("\
  // in case of a failure ...
  val () = assert_errmsg (status = CAIRO_STATUS_SUCCESS, \#LOCATION)
")

')

#para("\

ATS is a programming language that distinguishes itself in its practical
and effective support for precise resource management.  While it may seem
that using cairo functions in ATS is nearly identical to using them in C
(modulo syntatical difference), 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:

#atscode("\
  val () = cairo_surface_destroy (sf) // a type error if omitted
")

is removed from the program in

#mycodelink("tutprog_hello.dats", "tutprog_hello.dats"),

then a type-error message is issued at compile-time to indicate that the
resource #code("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.

")

</chapter>#comment("chapter/hello_example")

#comment(" ****** ****** ")

#comment(" end of [chap_hello.atxt] ")

%{
implement main () = fprint_filsub (stdout_ref, "chap_hello_atxt.txt")
%}
