Chapter 2. Types for Some Objects in Cairo

The type for cairo drawing contexts in ATS is declared as follows:

absvtype cairo_ref (l:addr) // = cairo_t*

The type cairo_ref(null) is just for a null pointer. Given an address L that is not null, the type cairo_ref(L) is for a reference to a cairo context located at L. We introduce an abbreviation cairo_ref1 as follows:

vtypedef cairo_ref1 = [l:addr | l > null] cairo_ref l

Therefore, cairo_ref1 essentially represents a type cairo_ref(L) for some unknown L that is not null. Similarly, we have the following types in ATS for objects representing cairo surfaces, cairo patterns, and cairo font faces:

absvtype cairo_surface_ref (l:addr) // = cairo_surface_t*

absvtype cairo_pattern_ref (l:addr) // = cairo_pattern_t*
vtypedef cairo_pattern_ref1 = [l:addr | l > null] cairo_pattern_ref l

absvtype cairo_font_face_ref (l:addr) // = cairo_font_face_t*
vtypedef cairo_font_face_ref1 = [l:addr | l > null] cairo_font_face_ref l

The above types for objects in cairo are all reference-counted. In other words, there is a reference count in each object that is assgined one of these types. When such an object is created, the initial count is 1. This count can increase or decrease depending on operations performed on the object, and the object is freed once the count drops to 0. In ATS, we can employ linear types to track reference counts. Compared to various other APIs for cairo, the ability to track reference counts statically, that is, at compile-time, is arguably the greatest benefit one receives when programming with ATS/Cairo.