File: chap_drawrectcirc.atxt

package info (click to toggle)
ats2-lang 0.4.2-1.1
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 40,436 kB
  • sloc: ansic: 389,898; makefile: 7,136; javascript: 1,852; lisp: 812; sh: 657; php: 573; python: 387; perl: 365
file content (234 lines) | stat: -rw-r--r-- 5,743 bytes parent folder | download | duplicates (4)
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")
%}