Tscope5
graphics.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // __ ______
4 // / /_______________ ____ ___ / ____/
5 // / __/ ___/ ___/ __ \/ __ \/ _ \ /___ )
6 // / /_(__ ) /__/ /_/ / /_/ / __/ ____/ /
7 // \__/____/\___/\____/ .___/\___/ /_____/
8 // /_/
9 //
10 /// \file graphics.c
11 /// Definitions of graphics parameter functions.
12 /// \example graphics01.c
13 /// \example graphics02.c
14 /// \example graphics03.c
15 /// \example graphics04.c
16 /// \example graphics05.c
17 /// \example graphics06.c
18 /// \example graphics07.c
19 /// \example graphics08.c
20 /// \example graphics09.c
21 /// \example graphics10.c
22 ////////////////////////////////////////////////////////////////////////////////
23 
24 
25 #include "../include/tscope5/graphics.h"
26 #include "../include/tscope5/graphics_internal.h"
27 #include "../include/tscope5/system_internal.h"
28 #include "../include/tscope5/textio_internal.h"
29 
30 #include <allegro5/allegro_color.h>
31 
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// @name Coordinate functions
35 /// There are two coordinate systems and two coordinate scales
36 /// available in Tscope5.
37 ///
38 /// - There is a Display coordinate system,
39 /// with the origin (0,0) in the upper left corner of the display,
40 /// with increasing coordinate values to the right of and below the origin.
41 /// - There is also a Cartesian system,
42 /// with the origin (0,0) in the center of the display,
43 /// increasing coordinate values to the right and above the origin
44 /// and decreasing (negative) values to the left and below the origin.
45 /// - Default is the Cartesian system.
46 ///
47 /// - There is an absolute coordinate scale where coordinates are
48 /// interpreted as pixel values.
49 /// - There is a relative coordinate scale where coordinates are
50 /// interpreted relative to the display size.
51 /// - The default is the absolute system.
52 ///
53 /// Some helper functions that (can help you) convert between
54 /// the coordinate scales/systems are available,
55 /// but most of the time you will only need to choose the coordinate
56 /// system/scale and Tscop5 will automatically do the transormations
57 /// that are necessary.
58 //@{
59 ////////////////////////////////////////////////////////////////////////////////
60 
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Set the coordinate system.
64 ///
65 /// \param coordinate_system Coordinate system to be used.
66 /// Can be TS5_CARTESIAN_COORDINATES and TS5_DISPLAY_COORDINATES.
67 /// Default is TS5_CARTESIAN_COORDINATES.
68 ///
69 /// \return The previous coordinate system.
70 ///
71 /// The TS5_DISPLAY_COORDINATES system
72 /// has the origin (0,0) in the upper left corner of the display
73 /// and increasing coordinate values to the left of and below the origin.
74 ///
75 /// The TS5_CARTESIAN_COORDINATES system
76 /// has the origin (0,0) in the center of the display,
77 /// increasing coordinate values to the left of and above the origin
78 /// and decreasing (negative) values to the right of and below the origin.
79 /// This is the default coordinate system.
80 ////////////////////////////////////////////////////////////////////////////////
81 int ts5_set_coordinate_system(const int coordinate_system)
82 {
83  ts5_check_graphics("ts5_set_coordinate_system");
84  ts5_log(TS5_LOGLEVEL_4, "ts5_set_coordinate_system(%d)\n",
85  coordinate_system);
86 
87  int retval = _ts5_status.graphics.coordinate_system;
88 
89  if (coordinate_system != TS5_CARTESIAN_COORDINATES
90  && coordinate_system != TS5_DISPLAY_COORDINATES) {
91 
92  ts5_fatal("%s: %s (is %d)\n", "ts5_set_coordinate_system",
93  "coordinate_system should be 0 or 1",
94  coordinate_system);
95  }
96 
97  _ts5_status.graphics.coordinate_system = coordinate_system;
98 
99  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n",
100  "ts5_set_coordinate_system",
101  "set coordinate_system for next display to",
102  _ts5_status.graphics.coordinate_system, retval);
103 
104  return retval;
105 }
106 
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Get the coordinate system.
110 ///
111 /// \return The coordinate system.
112 ////////////////////////////////////////////////////////////////////////////////
114 {
115  ts5_check_graphics("ts5_get_coordinate_system");
116  ts5_log(TS5_LOGLEVEL_4, "ts5_get_coordinate_system()\n");
117 
118  return _ts5_status.graphics.coordinate_system;
119 }
120 
121 
122 ////////////////////////////////////////////////////////////////////////////////
123 /// Set the coordinate scale.
124 ///
125 /// \param coordinate_scale Coordinate scale to be used.
126 /// Can be TS5_RELATIVE_COORDINATES and TS5_ABSOLUTE_COORDINATES.
127 /// Default is TS5_ABSOLUTE_COORDINATES.
128 ///
129 /// \return The previous coordinate scale.
130 ///
131 /// In the TS5_ABSOLUTE_COORDINATES scale coordinates
132 /// are absolute pixel values. This is the default coordinate scale.
133 ///
134 /// In the TS5_RELATIVE_COORDINATES scale coordinates vary
135 /// between -1.0 and 1.0 in the TS5_CARTESIAN_COORDINATES system
136 /// and between 0.0 abd 1.0 in the TS5_DISPLAY_COORDINATES system.
137 ///
138 /// Using the TS5_RELATIVE_COORDINATES scale has an influence on position
139 /// but also on sizes:
140 /// - Display sizes are computed relative to the display adapter.
141 /// - Bitmap sizes are computed relative to the active display.
142 /// - Circle diameters are computed relative to the x axis.
143 /// - Font size and drawing thickness are always set in pixels.
144 /// - When querying the size of the display (adapter), drawing target or
145 /// a bitmap the size in pixels is returned.
146 ////////////////////////////////////////////////////////////////////////////////
147 int ts5_set_coordinate_scale(const int coordinate_scale)
148 {
149  ts5_check_graphics("ts5_set_coordinate_scale");
150  ts5_log(TS5_LOGLEVEL_4, "ts5_set_coordinate_scale(%d)\n", coordinate_scale);
151 
152  int retval = _ts5_status.graphics.coordinate_scale;
153 
154  if (coordinate_scale != TS5_RELATIVE_COORDINATES
155  && coordinate_scale != TS5_ABSOLUTE_COORDINATES) {
156  ts5_fatal("%s: %s (is %d)\n", "ts5_set_coordinate_scale",
157  "coordinate_scale should be 0 or 1", coordinate_scale);
158  }
159 
160  _ts5_status.graphics.coordinate_scale = coordinate_scale;
161 
162  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n", "ts5_set_coordinate_scale",
163  "set coordinate_scale for next display to",
164  _ts5_status.graphics.coordinate_scale, retval);
165 
166  return retval;
167 }
168 
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Get the coordinate scale.
172 ///
173 /// \return The coordinate scale.
174 ////////////////////////////////////////////////////////////////////////////////
176 {
177  ts5_check_graphics("ts5_get_coordinate_scale");
178  ts5_log(TS5_LOGLEVEL_4, "ts5_get_coordinate_scale()\n");
179 
180  return _ts5_status.graphics.coordinate_scale;
181 }
182 
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// Convert a relative horizontal coordinate into an
186 /// absolute horizontal coordinate.
187 ///
188 /// This function can be called using the macro ax(x)
189 ///
190 /// \param x Horizontal coordinate value as a proportion.
191 ///
192 /// \return Horizontal coordinate value in pixels.
193 ///
194 /// Its behavior depends on the coordinate system used.
195 /// - With the Cartesian system x=0 refers to the center of the display,
196 /// x=1 refers the to right-hand side border and
197 /// x=-1 refers to the left-hand side border.
198 /// - With the display system x=0 refers to the right-hand side border and
199 /// x=1 refers to the left-hand side border.
200 ///
201 /// It is possible to call this function as a parameter to a drawing function
202 /// (e.g.: when using the Cartesian coordinate system,
203 /// ts5_putpixel (ts5_relative_to_absolute_coordinate_x(.5), 0);
204 /// writes a pixel 80 pixels to the right of the center
205 /// in the case of a 320x240 sized display,
206 /// or 160 pixels to the right in the case of a 640x480 sized display).
207 ////////////////////////////////////////////////////////////////////////////////
209 {
210  ts5_check_graphics("ts5_relative_to_absolute_coordinate_x");
211  ts5_log(TS5_LOGLEVEL_6, "ts5_relative_to_absolute_coordinate_x(%f)\n", x);
212 
213  double retval;
214 
215  if (_ts5_status.graphics.coordinate_system
216  == TS5_CARTESIAN_COORDINATES) {
217  retval = (x * (_ts5_status.graphics.target_width) / 2.0);
218  }
219  else {
220  retval = (x * _ts5_status.graphics.target_width);
221  }
222 
223  return retval;
224 }
225 
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Convert a relative vertical coordinate into an
229 /// absolute vertical coordinate.
230 ///
231 /// This function can be called using the macro ay(y)
232 ///
233 /// \param y Vertical coordinate value as a proportion.
234 ///
235 /// \return Vertical coordinate value in pixels.
236 ///
237 /// Its behaviour completely parallells that of
238 /// ts5_relative_to_absolute_coordinate_x().
239 ////////////////////////////////////////////////////////////////////////////////
241 {
242  ts5_check_graphics("ts5_relative_to_absolute_coordinate_y");
243  ts5_log(TS5_LOGLEVEL_6, "ts5_relative_to_absolute_coordinate_y(%f)\n", y);
244 
245  double retval;
246 
247  if (_ts5_status.graphics.coordinate_system
248  == TS5_CARTESIAN_COORDINATES) {
249  retval = (y * (_ts5_status.graphics.target_height) / 2.0);
250  }
251  else {
252  retval = (y * _ts5_status.graphics.target_height);
253  }
254 
255  return retval;
256 }
257 
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Convert an absolute horizontal coordinate into a
261 /// relative horizontal coordinate.
262 ///
263 /// This function can be called using the macro rx(x)
264 ///
265 /// \param x Horizontal coordinate value in pixels.
266 ///
267 /// \return Horizontal coordinate value as a proportion.
268 ///
269 /// Mainly for internal use by Tscope5 itself.
270 ////////////////////////////////////////////////////////////////////////////////
272 {
273  ts5_check_graphics("ts5_absolute_to_relative_coordinate_x");
274  ts5_log(TS5_LOGLEVEL_6, "ts5_absolute_to_relative_coordinate_x(%f)\n", x);
275 
276  double retval;
277 
278  if (_ts5_status.graphics.coordinate_system
279  == TS5_CARTESIAN_COORDINATES) {
280  retval = (x / (_ts5_status.graphics.target_width) * 2.0);
281  }
282  else {
283  retval = (x / _ts5_status.graphics.target_width);
284  }
285 
286  return retval;
287 }
288 
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Convert an absolute vertical coordinate into a
292 /// relative vertical coordinate.
293 ///
294 /// This function can be called using the macro ry(y)
295 ///
296 /// \param y Vertical coordinate value in pixels.
297 ///
298 /// \return Vertical coordinate value as a proportion.
299 ///
300 /// Mainly for internal use by Tscope5 itself.
301 ////////////////////////////////////////////////////////////////////////////////
303 {
304  ts5_check_graphics("ts5_absolute_to_relative_coordinate_y");
305  ts5_log(TS5_LOGLEVEL_6, "ts5_absolute_to_relative_coordinate_y(%f)\n", y);
306 
307  double retval;
308 
309  if (_ts5_status.graphics.coordinate_system
310  == TS5_CARTESIAN_COORDINATES) {
311  retval = (y / (_ts5_status.graphics.target_height) * 2.0);
312  }
313  else {
314  retval = (y / _ts5_status.graphics.target_height);
315  }
316 
317  return retval;
318 }
319 
320 
321 ////////////////////////////////////////////////////////////////////////////////
322 /// Convert a horizontal Cartesian coordinate into a
323 /// horizontal display coordinate.
324 ///
325 /// This function can be called using the macro dx(x)
326 ///
327 /// \param x Horizontal coordinate value in the Cartesian coordinate system.
328 ///
329 /// \return The coordinate value in the display coordinate system.
330 ///
331 /// Mainly for internal use by Tscope5 itself.
332 ////////////////////////////////////////////////////////////////////////////////
334 {
335  ts5_check_graphics("ts5_cartesian_to_display_coordinate_x");
336  ts5_log(TS5_LOGLEVEL_6, "ts5_cartesian_to_display_coordinate_x(%f)\n", x);
337 
338  return (_ts5_status.graphics.target_width) / 2.0 + x;
339 }
340 
341 
342 ////////////////////////////////////////////////////////////////////////////////
343 /// Convert a vertical Cartesian coordinate into a
344 /// vertical display coordinate.
345 ///
346 /// This function can be called using the macro dy(y)
347 ///
348 /// \param y Vertical coordinate value in the Cartesian coordinate system.
349 ///
350 /// \return The coordinate value in the display coordinate system.
351 ///
352 /// Mainly for internal use by Tscope5 itself.
353 ////////////////////////////////////////////////////////////////////////////////
355 {
356  ts5_check_graphics("ts5_cartesian_to_display_coordinate_y");
357  ts5_log(TS5_LOGLEVEL_6, "ts5_cartesian_to_display_coordinate_y(%f)\n", y);
358 
359  return (_ts5_status.graphics.target_height) / 2.0 - y;
360 }
361 
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /// Convert a horizontal display coordinate into a
365 /// horizontal Cartisian coordinate.
366 ///
367 /// This function can be called using the macro cx(x)
368 ///
369 /// \param x Horizontal coordinate value in the display coordinate system.
370 ///
371 /// \return The coordinate value in the Cartesian coordinate system.
372 ///
373 /// Mainly for internal use by Tscope5 itself.
374 ////////////////////////////////////////////////////////////////////////////////
376 {
377  ts5_check_graphics("ts5_display_to_cartesian_coordinate_x");
378  ts5_log(TS5_LOGLEVEL_6, "ts5_display_to_cartesian_coordinate_x(%f)\n", x);
379 
380  return x - (_ts5_status.graphics.target_width) / 2.0;
381 }
382 
383 
384 ////////////////////////////////////////////////////////////////////////////////
385 /// Convert a vertical display coordinate into a
386 /// vertical Cartisian coordinate.
387 ///
388 /// This function can be called using the macro cy(y)
389 ///
390 /// \param y Vertical coordinate value in the display coordinate system.
391 ///
392 /// \return The coordinate value in the Cartesian coordinate system.
393 ///
394 /// Mainly for internal use by Tscope5 itself.
395 ////////////////////////////////////////////////////////////////////////////////
397 {
398  ts5_check_graphics("ts5_display_to_cartesian_coordinate_y");
399  ts5_log(TS5_LOGLEVEL_6, "ts5_display_to_cartesian_coordinate_y(%f)\n", y);
400 
401  return (_ts5_status.graphics.target_height) / 2.0 - y;
402 }
403 
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 //@}
407 ////////////////////////////////////////////////////////////////////////////////
408 
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// @name Color definitions
412 /// Tscope5 describes colors in a structure (TS5_COLOR) containing red (r),
413 /// green (g), blue (b) and alpha (a, transparency) values between 0.0 and 1.0.
414 ///
415 /// The functions below generate such a color structure using
416 /// the RGB, HSL or HSV color specification or using the w3c naming system.
417 ///
418 /// Please note that the color structure is a structure, not a variable
419 /// (they can only be assigned at the moment of declaration, not afterwards).
420 /// See the examples for instructions on how to use them.
421 //@{
422 ////////////////////////////////////////////////////////////////////////////////
423 
424 
425 ////////////////////////////////////////////////////////////////////////////////
426 /// Generate a color specification based on an RGB triplet
427 /// plus an alpha channel.
428 ///
429 /// \param r Red. Range from 0.0 to 1.0.
430 /// \param g Green. Range from 0.0 to 1.0.
431 /// \param b Blue. Range from 0.0 to 1.0.
432 /// \param a Alpha. 0.0 is completely transparant and 1.0 is completely opaque.
433 ///
434 /// \return TS5_COLOR structure.
435 ////////////////////////////////////////////////////////////////////////////////
436 TS5_COLOR ts5_make_rgb_color(const double r, const double g, const double b,
437  const double a)
438 {
439  ts5_check_graphics("ts5_make_rgb_color");
440  ts5_log(TS5_LOGLEVEL_5, "ts5_make_rgb_color(%f,%f,%f,%f)\n", r, g, b, a);
441 
442  if (r < 0.0|| g < 0.0 || b < 0.0 || a < 0.0
443  || r > 1.0 || g > 1.0 || b > 1.0 || a > 1.0) {
444  ts5_fatal("%s: %s\n", "ts5_make_rgb_color",
445  "color values must be between 0.0 and 1.0");
446  }
447 
448  return al_map_rgba_f(r, g, b, a);
449 }
450 
451 
452 ////////////////////////////////////////////////////////////////////////////////
453 /// Generate a color specification based on an HSL triplet
454 /// plus an alpha channel.
455 ///
456 /// \param h Hue. Range from 0.0 to 360.0.
457 /// \param s Saturation. Range from 0.0 to 1.0.
458 /// \param l Lightness. Range from 0.0 to 1.0.
459 /// \param a Alpha. 0.0 is completely transparant and 1.0 is completely opaque.
460 ///
461 /// \return TS5_COLOR sctructure.
462 ////////////////////////////////////////////////////////////////////////////////
463 TS5_COLOR ts5_make_hsl_color(const double h, const double s, const double l,
464  const double a)
465 {
466  ts5_check_graphics("ts5_make_hsl_color");
467  ts5_log(TS5_LOGLEVEL_5, "ts5_make_hsl_color(%f,%f,%f,%f)\n", h, s, l, a);
468 
469  if (h < 0.0 || s < 0.0 || l < 0.0 || a < 0.0
470  || h > 360.0 || s > 1.0 || l > 1.0 || a > 1.0) {
471  ts5_fatal("%s: %s\n", "ts5_make_hsl_color",
472  "h:0.0-360.0, s:0.0-1.0, l:0.0-1.0, a:0.0-1.0");
473  }
474 
475  float r, g, b;
476  al_color_hsl_to_rgb(h, s, l, &r, &g, &b);
477 
478  return al_map_rgba_f(r, g, b, a);
479 }
480 
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Generate a color specification based on an HSV triplet
484 /// plus an alpha channel.
485 ///
486 /// \param h Hue. Range from 0.0 to 360.0.
487 /// \param s Saturation. Range from 0.0 to 1.0.
488 /// \param v Value Range from 0.0 to 1.0.
489 /// \param a Alpha. 0.0 is completely transparant and 1.0 is completely opaque.
490 ///
491 /// \return TS5_COLOR sctructure.
492 ////////////////////////////////////////////////////////////////////////////////
493 TS5_COLOR ts5_make_hsv_color(const double h, const double s, const double v,
494  const double a)
495 {
496  ts5_check_graphics("ts5_make_hsv_color");
497  ts5_log(TS5_LOGLEVEL_5, "ts5_make_hsv_color(%f,%f,%f,%f)\n", h, s, v, a);
498 
499  if (h < 0.0 || s < 0.0 || v < 0.0 || a < 0.0
500  || h > 360.0 || s > 1.0 || v > 1.0 || a > 1.0) {
501  ts5_fatal("%s: %s\n", "ts5_make_hsv_color",
502  "h:0.0-360.0, s:0.0-1.0, v:0.0-1.0, a:0.0-1.0");
503  }
504 
505  float r, g, b;
506  al_color_hsv_to_rgb(h, s, v, &r, &g, &b);
507 
508  return al_map_rgba_f(r, g, b, a);
509 }
510 
511 
512 ////////////////////////////////////////////////////////////////////////////////
513 /// Return a color that corresponds to name.
514 ///
515 /// \param name Name of the color.
516 /// \param a Alpha. 0.0 is completely transparant and 1.0 is completely opaque.
517 ///
518 /// \return TS5_COLOR sctructure.
519 ///
520 /// There recognized names are: aliceblue, antiquewhite, aqua, aquamarine,
521 /// azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown,
522 /// burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue,
523 /// cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray,
524 /// darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange,
525 /// darkorchid, darkred, darksalmon, darkseagreen, darkslateblue,
526 /// darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray,
527 /// dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro,
528 /// ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink,
529 /// indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen,
530 /// lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow,
531 /// lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue,
532 /// lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen,
533 /// magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple,
534 /// mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,
535 /// mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite,
536 /// navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod,
537 /// palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink,
538 /// plum, powderblue, purple, purwablue, red, rosybrown, royalblue,
539 /// saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver,
540 /// skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal,
541 /// thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow and
542 /// yellowgreen.
543 ///
544 /// Colors are taken from
545 /// http://www.w3.org/TR/2010/PR-css3-color-20101028/#svg-color.
546 ///
547 /// If the color is not found then black is returned.
548 ////////////////////////////////////////////////////////////////////////////////
549 TS5_COLOR ts5_make_named_color(const char *name, const double a)
550 {
551  ts5_check_graphics("ts5_make_named_color");
552  ts5_log(TS5_LOGLEVEL_5, "ts5_make_named_color(%s,%f)\n", name, a);
553 
554  float r, g, b;
555 
556  if (!al_color_name_to_rgb(name, &r, &g, &b)) {
557  ts5_fatal("ts5_make_named_color: color name %s not found\n", name);
558  }
559 
560  return al_map_rgba_f(r, g, b, a);
561 }
562 
563 
564 ////////////////////////////////////////////////////////////////////////////////
565 //@}
566 ////////////////////////////////////////////////////////////////////////////////
567 
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 /// @name Graphics parameter functions
571 /// This part contains functions to change the graphics parameters
572 /// of the text output and primitives drawing functions.
573 /// - By default, text appears 20pt Courier Bold.
574 /// - Primitives are not filled, and drawn with hairline thickness.
575 /// - All drawing is done in white against a black background.
576 ///
577 /// The text and drawing functions do not have arguments to alter
578 /// the graphics parameters.
579 /// This is done with the parameter functions below.
580 /// They all change one parameter, e.g. the foreground color.
581 /// Once a parameter value is changed, that value is used for
582 /// all further drawing until it is changed again.
583 ///
584 /// The parameter functions all return the previous parameter setting.
585 /// This can be useful when you want to change some parameters
586 /// in one part of a program,
587 /// do some drawing and set the previous parameters again
588 /// without causing undesired parameter changes to other parts of the program.
589 //@{
590 ////////////////////////////////////////////////////////////////////////////////
591 
592 
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Set the foreground color.
595 ///
596 /// \param foreground_color TS5_COLOR color specification.
597 ///
598 /// \return The previous foreground color.
599 ///
600 /// Changes the drawing color of all subsequent drawing operations.
601 /// The default color is white. Once a color is set,
602 /// it remains active until another color is set.
603 ///
604 /// Tscope5 represents colors in an opaque structure (TS5_COLOR).
605 /// Several functions exist for generating such a color definition (see above).
606 ////////////////////////////////////////////////////////////////////////////////
607 TS5_COLOR ts5_set_foreground_color(const TS5_COLOR foreground_color)
608 {
609  ts5_check_graphics("ts5_set_foreground_color");
610  ts5_log(TS5_LOGLEVEL_4, "ts5_set_foreground_color((%f,%f,%f,%f))\n",
611  foreground_color.r, foreground_color.g, foreground_color.b,
612  foreground_color.a);
613 
614  TS5_COLOR oldcolor = _ts5_status.graphics.foreground_color;
615  _ts5_status.graphics.foreground_color = foreground_color;
616 
617  unsigned char r, g, b, a;
618  al_unmap_rgba(foreground_color, &r, &g, &b, &a);
619 
620  ts5_log(TS5_LOGLEVEL_4, "%s: r:%f, g:%f, b:%f, alpha:%f\n",
621  "ts5_set_foreground_color", r/256, g/256, b/256, a/256);
622 
623  return oldcolor;
624 }
625 
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 /// Get the foreground color.
629 ///
630 /// \return The foreground color.
631 ////////////////////////////////////////////////////////////////////////////////
633 {
634  ts5_check_graphics("ts5_get_foreground_color");
635  ts5_log(TS5_LOGLEVEL_4, "ts5_get_foreground_color()\n");
636 
637  return _ts5_status.graphics.foreground_color;
638 }
639 
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// Set the background color.
643 ///
644 /// \param background_color TS5_COLOR color specification.
645 ///
646 /// \return The previous background color.
647 ///
648 /// Changes the background color of all new drawing targets or when a
649 /// drawing target is cleared.
650 ///
651 /// The default color is black.
652 /// Once a color is set, it remains active until another color is set.
653 ////////////////////////////////////////////////////////////////////////////////
654 TS5_COLOR ts5_set_background_color(const TS5_COLOR background_color)
655 {
656  ts5_check_graphics("ts5_set_background_color");
657  ts5_log(TS5_LOGLEVEL_4, "ts5_set_background_color((%f,%f,%f,%f))\n",
658  background_color.r, background_color.g, background_color.b,
659  background_color.a);
660 
661  TS5_COLOR oldcolor = _ts5_status.graphics.background_color;
662  _ts5_status.graphics.background_color = background_color;
663 
664  unsigned char r, g, b, a;
665  al_unmap_rgba(background_color, &r, &g, &b, &a);
666  ts5_log(TS5_LOGLEVEL_4, "%s: r:%f, g:%f, b:%f, alpha:%f\n",
667  "ts5_set_background_color", r/256, g/256, b/256, a/256);
668 
669  return oldcolor;
670 }
671 
672 
673 ////////////////////////////////////////////////////////////////////////////////
674 /// Get the background color.
675 ///
676 /// \return The background color.
677 ////////////////////////////////////////////////////////////////////////////////
679 {
680  ts5_check_graphics("ts5_get_background_color");
681  ts5_log(TS5_LOGLEVEL_4, "ts5_get_background_color()\n");
682 
683  return _ts5_status.graphics.background_color;
684 }
685 
686 
687 ////////////////////////////////////////////////////////////////////////////////
688 /// Set the drawing thickness.
689 ///
690 /// \param drawing_thickness Drawing thickness in pixels.
691 ///
692 /// \return The previous thickness.
693 ///
694 /// Changes thickness of lines for all drawing operations.
695 ///
696 /// The default thickness is 0 (hairline).
697 ////////////////////////////////////////////////////////////////////////////////
698 double ts5_set_drawing_thickness(double drawing_thickness)
699 {
700  ts5_check_graphics("ts5_set_drawing_thickness");
701 
702  ts5_log(TS5_LOGLEVEL_4, "ts5_set_drawing_thickness(%f)\n",
703  drawing_thickness);
704 
705  double retval = _ts5_status.graphics.drawing_thickness;
706 
707  if (drawing_thickness < 0.0) {
708  drawing_thickness = -1.0;
709  }
710 
711  _ts5_status.graphics.drawing_thickness = drawing_thickness;
712 
713  ts5_log(TS5_LOGLEVEL_4, "%s: %s %f (was %f)\n",
714  "ts5_set_drawing_thickness", "set drawing_thickness to",
715  _ts5_status.graphics.drawing_thickness, retval);
716 
717  return retval;
718 }
719 
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Get the drawing thickness.
723 ///
724 /// \return The drawing thickness.
725 ////////////////////////////////////////////////////////////////////////////////
727 {
728  ts5_check_graphics("ts5_get_drawing_thickness");
729  ts5_log(TS5_LOGLEVEL_4, "ts5_get_drawing_thickness()\n");
730 
731  return _ts5_status.graphics.drawing_thickness;
732 }
733 
734 
735 ////////////////////////////////////////////////////////////////////////////////
736 /// Set the fill mode.
737 ///
738 /// \param fill_mode Fill mode. Can be TS5_FILL_ON or TS5_FILL_OFF.
739 ///
740 /// \return The previous fill mode.
741 ///
742 /// Changes the fill mode for future drawing operations.
743 ///
744 /// The default fill mode is TS5_FILL_OFF.
745 ////////////////////////////////////////////////////////////////////////////////
746 int ts5_set_fill_mode(const int fill_mode)
747 {
748  ts5_check_graphics("ts5_set_fill_mode");
749  ts5_log(TS5_LOGLEVEL_4, "ts5_set_fill_mode(%d)\n", fill_mode);
750 
751  int retval = _ts5_status.graphics.fill_mode;
752 
753  if (fill_mode != TS5_FILL_ON && fill_mode != TS5_FILL_OFF) {
754  ts5_fatal("%s: %s %s\n", "ts5_set_fill_mode", "fill_mode should be",
755  "TS5_FILL_OFF (off) or TS5_FILL_ON (on)");
756  }
757 
758  _ts5_status.graphics.fill_mode = fill_mode;
759 
760  ts5_log(TS5_LOGLEVEL_4, "ts5_set_fill_mode: set mode to %d (was %d)\n",
761  _ts5_status.graphics.fill_mode, retval);
762 
763  return retval;
764 }
765 
766 
767 ////////////////////////////////////////////////////////////////////////////////
768 /// Get the fill mode.
769 ///
770 /// \return The fill mode.
771 ////////////////////////////////////////////////////////////////////////////////
773 {
774  ts5_check_graphics("ts5_get_fill_mode");
775  ts5_log(TS5_LOGLEVEL_4, "ts5_get_fill_mode()\n");
776 
777  return _ts5_status.graphics.fill_mode;
778 }
779 
780 
781 ////////////////////////////////////////////////////////////////////////////////
782 /// Set the font type.
783 ///
784 /// \param font_type Font type. Can be TS5_COURIER, TS5_ARIAL and TS5_TIMES.
785 ///
786 /// \return The previous font type.
787 ///
788 /// The default font type is TS5_COURIER.
789 ////////////////////////////////////////////////////////////////////////////////
790 int ts5_set_font_type(const int font_type)
791 {
792  ts5_check_graphics("ts5_set_font_type");
793  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_type(%d)\n", font_type);
794 
795  int retval = _ts5_status.graphics.font_type;
796 
797  if (font_type != TS5_COURIER
798  && font_type != TS5_ARIAL
799  && font_type != TS5_TIMES) {
800 
801  ts5_fatal("%s: %s %s\n", "ts5_set_font_type", "font_type should be",
802  "TS5_COURIER, TS5_ARIAL or TS5_TIMES");
803  }
804 
805  _ts5_status.graphics.font_type = font_type;
806 
807  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_type: set font type to %d (was %d)\n",
808  _ts5_status.graphics.font_type, retval);
809 
810  _ts5_status.graphics.font_index =
811  _ts5_status.graphics.font_type * TS5_FONTSTYLES * TS5_FONTSIZES +
812  _ts5_status.graphics.font_style * TS5_FONTSIZES +
813  _ts5_status.graphics.font_size - 8;
814 
815  return retval;
816 }
817 
818 
819 ////////////////////////////////////////////////////////////////////////////////
820 /// Get the font type.
821 ///
822 /// \return The font type.
823 ////////////////////////////////////////////////////////////////////////////////
825 {
826  ts5_check_graphics("ts5_get_font_type");
827  ts5_log(TS5_LOGLEVEL_4, "ts5_get_font_type()\n");
828 
829  return _ts5_status.graphics.font_type;
830 }
831 
832 
833 ////////////////////////////////////////////////////////////////////////////////
834 /// Set the font style.
835 ///
836 /// \param font_style Font style.
837 /// Can be TS5_REGULAR, TS5_BOLD, TS5_ITALIC or TS5_BOLD_ITALIC.
838 ///
839 /// \return The previous font style.
840 ///
841 /// The default font style is TS5_BOLD.
842 ////////////////////////////////////////////////////////////////////////////////
843 int ts5_set_font_style(const int font_style)
844 {
845  ts5_check_graphics("ts5_set_font_style");
846  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_style(%d)\n", font_style);
847 
848  int retval = _ts5_status.graphics.font_style;
849 
850  if (font_style != TS5_REGULAR
851  && font_style != TS5_BOLD
852  && font_style != TS5_ITALIC
853  && font_style != TS5_BOLD_ITALIC) {
854 
855  ts5_fatal("%s: %s %s\n", "ts5_set_font_style", "font_style should be",
856  "TS5_REGULAR, TS5_BOLD, TS5_ITALIC or TS5_BOLD_ITALIC");
857  }
858 
859  _ts5_status.graphics.font_style = font_style;
860 
861  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n",
862  "ts5_set_font_style", "set font style to",
863  _ts5_status.graphics.font_style, retval);
864 
865  _ts5_status.graphics.font_index =
866  _ts5_status.graphics.font_type * TS5_FONTSTYLES * TS5_FONTSIZES +
867  _ts5_status.graphics.font_style * TS5_FONTSIZES +
868  _ts5_status.graphics.font_size - 8;
869 
870  return retval;
871 }
872 
873 
874 ////////////////////////////////////////////////////////////////////////////////
875 /// Get the font style.
876 ///
877 /// \return The font style.
878 ////////////////////////////////////////////////////////////////////////////////
880 {
881  ts5_check_graphics("ts5_get_font_style");
882  ts5_log(TS5_LOGLEVEL_4, "ts5_get_font_style()\n");
883 
884  return _ts5_status.graphics.font_style;
885 }
886 
887 
888 ////////////////////////////////////////////////////////////////////////////////
889 /// Set the font size.
890 ///
891 /// \param font_size Font size. Can be any value between 8 and 107.
892 ///
893 /// \return The previous font size.
894 ///
895 /// The default font size is 20.
896 ////////////////////////////////////////////////////////////////////////////////
897 int ts5_set_font_size(int font_size)
898 {
899  ts5_check_graphics("ts5_set_font_size");
900  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_size(%d)\n", font_size);
901 
902  int retval = _ts5_status.graphics.font_size;
903 
904  if (font_size < 8 || font_size > 107) {
905  ts5_fatal("ts5_set_font_size: font_size should be between 8 and 107\n");
906  }
907 
908  _ts5_status.graphics.font_size = font_size;
909 
910  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_size: set font size to %d (was %d)\n",
911  _ts5_status.graphics.font_size, retval);
912 
913  _ts5_status.graphics.font_index =
914  _ts5_status.graphics.font_type * TS5_FONTSTYLES * TS5_FONTSIZES +
915  _ts5_status.graphics.font_style * TS5_FONTSIZES +
916  _ts5_status.graphics.font_size - 8;
917 
918  return retval;
919 }
920 
921 
922 ////////////////////////////////////////////////////////////////////////////////
923 /// Get the font size.
924 ///
925 /// \return The font size.
926 ////////////////////////////////////////////////////////////////////////////////
928 {
929  ts5_check_graphics("ts5_get_font_size");
930  ts5_check_textio("ts5_get_font_size");
931  ts5_log(TS5_LOGLEVEL_4, "ts5_get_font_size()\n");
932 
933  int size = _ts5_status.graphics.font_size;
934 
935  return size;
936 }
937 
938 
939 ////////////////////////////////////////////////////////////////////////////////
940 /// Set the font index.
941 ///
942 /// \param font_index Font index. Can be any integer between 0 and TS5_NFONTS-1.
943 ///
944 /// \return The previous font index.
945 ///
946 /// Sets the font type, style and width at once.
947 ////////////////////////////////////////////////////////////////////////////////
948 int ts5_set_font_index(const int font_index)
949 {
950  ts5_check_graphics("ts5_set_font_index");
951  ts5_log(TS5_LOGLEVEL_4, "ts5_set_font_index(%d)\n", font_index);
952 
953  int retval = _ts5_status.graphics.font_index;
954 
955  if (font_index < 0 || font_index >= TS5_NFONTS) {
956  ts5_fatal("%s: %s", "ts5_set_font_index",
957  "font_index should be between 0 and TS5_NFONTS-1\n");
958  }
959 
960  _ts5_status.graphics.font_index = font_index;
961 
962  // update size etc.
963  _ts5_status.graphics.font_size =
964  (font_index % TS5_FONTSIZES) + 8;
965 
966  _ts5_status.graphics.font_style =
967  (font_index / TS5_FONTSIZES) % TS5_FONTSTYLES;
968 
969  _ts5_status.graphics.font_type =
970  font_index / (TS5_FONTSIZES * TS5_FONTSTYLES);
971 
972  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n",
973  "ts5_set_font_index", "set font index to",
974  _ts5_status.graphics.font_index, retval);
975 
976  return retval;
977 }
978 
979 
980 ////////////////////////////////////////////////////////////////////////////////
981 /// Get the font index.
982 ///
983 /// \return The font index.
984 ////////////////////////////////////////////////////////////////////////////////
986 {
987  ts5_check_graphics("ts5_get_font_index");
988  ts5_log(TS5_LOGLEVEL_4, "ts5_get_font_index()\n");
989 
990  return _ts5_status.graphics.font_index;
991 }
992 
993 
994 ////////////////////////////////////////////////////////////////////////////////
995 /// Set the alignment of text.
996 ///
997 /// \param text_alignment Text alignment.
998 /// Can be TS5_ALIGN_LEFT, TS5_ALIGN_CENTER or TS5_ALIGN_RIGHT.
999 ///
1000 /// \return The previous alignment setting.
1001 ///
1002 /// The default aligment is TS5_ALIGN_CENTER.
1003 ////////////////////////////////////////////////////////////////////////////////
1004 int ts5_set_text_alignment(const int text_alignment)
1005 {
1006  ts5_check_graphics("ts5_set_text_alignment");
1007  ts5_log(TS5_LOGLEVEL_4, "ts5_set_text_alignment(%d)\n", text_alignment);
1008 
1009  int retval = _ts5_status.graphics.text_alignment;
1010 
1011  if (text_alignment != TS5_ALIGN_LEFT
1012  && text_alignment != TS5_ALIGN_CENTER
1013  && text_alignment != TS5_ALIGN_RIGHT) {
1014 
1015  ts5_fatal("%s: %s %s\n", "ts5_set_text_alignment",
1016  "text_alignment should be",
1017  "TS5_ALIGN_LEFT, TS5_ALIGN_CENTER or TS5_ALIGN_RIGHT");
1018  }
1019 
1020  _ts5_status.graphics.text_alignment = text_alignment;
1021 
1022  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n",
1023  "ts5_set_text_alignment", "set alignment to",
1024  _ts5_status.graphics.text_alignment, retval);
1025 
1026  return retval;
1027 }
1028 
1029 
1030 ////////////////////////////////////////////////////////////////////////////////
1031 /// Get the alignment of text.
1032 ///
1033 /// \return The alignment setting.
1034 ////////////////////////////////////////////////////////////////////////////////
1036 {
1037  ts5_check_graphics("ts5_get_text_alignment");
1038  ts5_log(TS5_LOGLEVEL_4, "ts5_get_text_alignment()\n");
1039 
1040  return _ts5_status.graphics.text_alignment;
1041 }
1042 
1043 
1044 ////////////////////////////////////////////////////////////////////////////////
1045 //@}
1046 ////////////////////////////////////////////////////////////////////////////////
double ts5_display_to_cartesian_coordinate_y(const double y)
Convert a vertical display coordinate into a vertical Cartisian coordinate.
Definition: graphics.c:396
TS5_COLOR ts5_make_named_color(const char *name, const double a)
Return a color that corresponds to name.
Definition: graphics.c:549
int ts5_get_coordinate_scale()
Get the coordinate scale.
Definition: graphics.c:175
int ts5_get_coordinate_system()
Get the coordinate system.
Definition: graphics.c:113
TS5_COLOR ts5_make_hsl_color(const double h, const double s, const double l, const double a)
Generate a color specification based on an HSL triplet plus an alpha channel.
Definition: graphics.c:463
void ts5_check_textio(char *calling_function)
Do some checks at the start of each textio function.
int ts5_set_font_size(int font_size)
Set the font size.
Definition: graphics.c:897
double ts5_display_to_cartesian_coordinate_x(const double x)
Convert a horizontal display coordinate into a horizontal Cartisian coordinate.
Definition: graphics.c:375
int ts5_get_fill_mode()
Get the fill mode.
Definition: graphics.c:772
int ts5_set_fill_mode(const int fill_mode)
Set the fill mode.
Definition: graphics.c:746
void ts5_check_graphics(char *calling_function)
Do some checks at the start of each graphics function.
int ts5_get_text_alignment()
Get the alignment of text.
Definition: graphics.c:1035
TS5_COLOR ts5_set_foreground_color(const TS5_COLOR foreground_color)
Set the foreground color.
Definition: graphics.c:607
int ts5_set_coordinate_scale(const int coordinate_scale)
Set the coordinate scale.
Definition: graphics.c:147
TS5_COLOR ts5_get_foreground_color()
Get the foreground color.
Definition: graphics.c:632
double ts5_get_drawing_thickness()
Get the drawing thickness.
Definition: graphics.c:726
double ts5_relative_to_absolute_coordinate_x(const double x)
Convert a relative horizontal coordinate into an absolute horizontal coordinate.
Definition: graphics.c:208
int ts5_get_font_style()
Get the font style.
Definition: graphics.c:879
double ts5_set_drawing_thickness(double drawing_thickness)
Set the drawing thickness.
Definition: graphics.c:698
int ts5_set_font_style(const int font_style)
Set the font style.
Definition: graphics.c:843
TS5_COLOR ts5_set_background_color(const TS5_COLOR background_color)
Set the background color.
Definition: graphics.c:654
int ts5_set_text_alignment(const int text_alignment)
Set the alignment of text.
Definition: graphics.c:1004
int ts5_get_font_type()
Get the font type.
Definition: graphics.c:824
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
Definition: system.c:45
double ts5_cartesian_to_display_coordinate_x(const double x)
Convert a horizontal Cartesian coordinate into a horizontal display coordinate.
Definition: graphics.c:333
int ts5_set_font_index(const int font_index)
Set the font index.
Definition: graphics.c:948
double ts5_cartesian_to_display_coordinate_y(const double y)
Convert a vertical Cartesian coordinate into a vertical display coordinate.
Definition: graphics.c:354
int ts5_set_font_type(const int font_type)
Set the font type.
Definition: graphics.c:790
TS5_COLOR ts5_make_hsv_color(const double h, const double s, const double v, const double a)
Generate a color specification based on an HSV triplet plus an alpha channel.
Definition: graphics.c:493
double ts5_absolute_to_relative_coordinate_y(const double y)
Convert an absolute vertical coordinate into a relative vertical coordinate.
Definition: graphics.c:302
int ts5_get_font_index()
Get the font index.
Definition: graphics.c:985
TS5_COLOR ts5_make_rgb_color(const double r, const double g, const double b, const double a)
Generate a color specification based on an RGB triplet plus an alpha channel.
Definition: graphics.c:436
double ts5_absolute_to_relative_coordinate_x(const double x)
Convert an absolute horizontal coordinate into a relative horizontal coordinate.
Definition: graphics.c:271
void ts5_fatal(const char *format,...)
Exit safely with an error message.
Definition: system.c:533
double ts5_relative_to_absolute_coordinate_y(const double y)
Convert a relative vertical coordinate into an absolute vertical coordinate.
Definition: graphics.c:240
int ts5_get_font_size()
Get the font size.
Definition: graphics.c:927
int ts5_set_coordinate_system(const int coordinate_system)
Set the coordinate system.
Definition: graphics.c:81
TS5_COLOR ts5_get_background_color()
Get the background color.
Definition: graphics.c:678