1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
|
%{
//
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_drawrectcirc.atxt.\n\
")
#comment("\n\
Time of Generation: #timestamp()\
")
<chapter id="drawrectcirc">
#title("Drawing Rectangles and Circles")
#para("\
Let us write a program to generate an image showing a white circle inside a
black square:\
")
#para('\
<inlinemediaobject>
<imageobject>
<imagedata fileref="#MYIMAGEROOTget()/tutprog_sqrcirc.png" format="PNG"/>
</imageobject>
</inlinemediaobject>
')
#para("\
The main function for drawing this image is given as follows:\
#atscode('\
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]
')
")
#para("\
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. The following code
draws a rectangle that happens to be a square:\
#atscode("\
val () = cairo_rectangle (cr, ~0.5, ~0.5, 1.0, 1.0)
")
The function #dyncode("cairo_rectangle") is declared as follows in ATS:
#atscode("\
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
#code("width") and #code("height"), respectively, and whose upper left
corner is located at (x, y).\
")
#para("\
The rectangle is then filled with black color:\
#atscode('\
val () = cairo_set_source_rgb (cr, 0.0, 0.0, 0.0) // black color
val () = cairo_fill (cr)
')
The following code draws a circle of radius 0.5 that is centered at (0.0, 0.0):
#atscode("\
val () = cairo_arc (cr, 0.0, 0.0, 0.5, 0.0, 2*PI)
")
The function #dyncode("cairo_arc") is given the following type in ATS:\
#atscode("\
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 #code("radius") and whose center is at (xc, yc). The arc
begins at the angle #code("angle1") and ends at the angle
#code("angle2"), where clockwise rotation is assumed. If
counterclockwise rotation is needed, the following function can be used
instead:
#atscode('\
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, the circle is filled with white color:\
#atscode("\
val () = cairo_set_source_rgb (cr, 1.0, 1.0, 1.0) // white color
val () = cairo_fill (cr)
")
")
#para("\
Let us now make a call to the function #dyncode("draw_sqrcirc") to generate
a PNG file:\
#atscode('\
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 #dyncode("cairo_translate") and #dyncode("cairo_scale") are
given the following types in ATS:
#atscode('\
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, #dyncode("cairo_translate") creates a new coordinate system by
shifting the origin of the current coordinate system to the point (x, y)
and #dyncode("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.\
")
#para("\
For the entirety of the code used in this section, please see
#mycodelink("tutprog_sqrcirc.dats", "tutprog_sqrcirc.dats").
")
#para("\
For a more elaborate example involving circles, please see\
#mycodelink("illucircmot.dats", " illucircmot.dats"), which generates the
following interesting image:\
")
#para('\
<inlinemediaobject>
<imageobject>
<imagedata fileref="#MYIMAGEROOTget()/illucircmot.png" format="PNG"/>
</imageobject>
</inlinemediaobject>
')
#para("\
For a more elabortate example involving squares and circles, please see
#mycodelink("illuwavy.dats", "illuwavy.dats"), which generates the
following interesting image:\
")
#para('\
<inlinemediaobject>
<imageobject>
<imagedata fileref="#MYIMAGEROOTget()/illuwavy.png" format="PNG"/>
</imageobject>
</inlinemediaobject>
')
<!-- ****** ****** -->
</chapter>#comment("chapter/drawrectcirc")
#comment(" ****** ****** ")
#comment(" end of [chap_drawrectcirc.atxt] ")
%{
implement main () = fprint_filsub (stdout_ref, "chap_drawrectcirc_atxt.txt")
%}
|