1 /* Graphics_utils.cpp
2 *
3 * Copyright (C) 1992-2007,2009-2012,2015-2020 Paul Boersma
4 *
5 * This code is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This code is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this work. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "GraphicsP.h"
20
21 /***** UTILITIES: *****/
22 /***** THESE ROUINTES OUTPUT TO CURRENT GRAPHICS BY CALLING PRIMITIVES. *****/
23 /***** THE TWO UTILITIES "Graphics_grey" AND "Graphics_altitude" *****/
24 /***** ARE IN DIFFERENT FILES BECAUSE THEY NEED LOCAL SUBROUTINES. *****/
25
26 /********** Utility functions. **********/
27
28 /********** Drawing into margins. **********/
29
Graphics_drawInnerBox(Graphics me)30 void Graphics_drawInnerBox (Graphics me) {
31 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
32 const int original_lineType = my lineType;
33 const double original_lineWidth = my lineWidth;
34 const MelderColour original_colour = my colour;
35
36 Graphics_setInner (me);
37 Graphics_setWindow (me, 0.0, 1.0, 0.0, 1.0);
38 Graphics_setLineType (me, Graphics_DRAWN);
39 Graphics_setLineWidth (me, 2.0 * original_lineWidth);
40 Graphics_setColour (me, Melder_BLACK);
41 Graphics_rectangle (me, 0.0, 1.0, 0.0, 1.0);
42 Graphics_unsetInner (me);
43
44 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
45 Graphics_setLineType (me, original_lineType);
46 Graphics_setLineWidth (me, original_lineWidth);
47 Graphics_setColour (me, original_colour);
48 }
49
Graphics_textLeft(Graphics me,bool farr,conststring32 text)50 void Graphics_textLeft (Graphics me, bool farr, conststring32 text) {
51 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
52 const int vert = ( farr ? Graphics_TOP : Graphics_BOTTOM );
53 const MelderColour original_colour = my colour;
54
55 Graphics_setColour (me, Melder_BLACK);
56 Graphics_setWindow (me, 0.0, 1.0, 0.0, 1.0);
57 Graphics_setTextRotation (me, 90.0);
58 Graphics_setTextAlignment (me, Graphics_CENTRE, vert);
59 if (! farr)
60 Graphics_setInner (me);
61 Graphics_text (me, 0.0, 0.5, text);
62 if (! farr)
63 Graphics_unsetInner (me);
64
65 Graphics_setTextRotation (me, 0.0);
66 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
67 Graphics_setColour (me, original_colour);
68 }
69
Graphics_textRight(Graphics me,bool farr,conststring32 text)70 void Graphics_textRight (Graphics me, bool farr, conststring32 text) {
71 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
72 const int vert = ( farr ? Graphics_TOP : Graphics_BOTTOM );
73 const MelderColour original_colour = my colour;
74
75 Graphics_setWindow (me, 0.0, 1.0, 0.0, 1.0);
76 Graphics_setColour (me, Melder_BLACK);
77 Graphics_setTextAlignment (me, Graphics_CENTRE, vert);
78 Graphics_setTextRotation (me, 270.0);
79 if (! farr)
80 Graphics_setInner (me);
81 Graphics_text (me, 1.0, 0.5, text);
82 if (! farr)
83 Graphics_unsetInner (me);
84
85 Graphics_setTextRotation (me, 0.0);
86 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
87 Graphics_setColour (me, original_colour);
88 }
89
Graphics_textBottom(Graphics me,bool farr,conststring32 text)90 void Graphics_textBottom (Graphics me, bool farr, conststring32 text) {
91 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
92 const MelderColour original_colour = my colour;
93
94 Graphics_setWindow (me, 0.0, 1.0, 0.0, 1.0);
95 Graphics_setColour (me, Melder_BLACK);
96 if (farr) {
97 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
98 Graphics_text (me, 0.5, 0.0, text);
99 } else {
100 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
101 Graphics_setInner (me);
102 Graphics_text (me, 0.5, - my vertTick, text);
103 Graphics_unsetInner (me);
104 }
105
106 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
107 Graphics_setColour (me, original_colour);
108 }
109
Graphics_textTop(Graphics me,bool farr,conststring32 text)110 void Graphics_textTop (Graphics me, bool farr, conststring32 text) {
111 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
112 const MelderColour original_colour = my colour;
113
114 Graphics_setWindow (me, 0.0, 1.0, 0.0, 1.0);
115 Graphics_setColour (me, Melder_BLACK);
116 if (farr) {
117 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
118 Graphics_text (me, 0.5, 1.0, text);
119 } else {
120 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
121 Graphics_setInner (me);
122 Graphics_text (me, 0.5, 1.0 + my vertTick, text);
123 Graphics_unsetInner (me);
124 }
125
126 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
127 Graphics_setColour (me, original_colour);
128 }
129
Graphics_marksLeft(Graphics me,int numberOfMarks,bool haveNumbers,bool haveTicks,bool haveDottedLines)130 void Graphics_marksLeft (Graphics me, int numberOfMarks, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
131 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
132 const int original_lineType = my lineType;
133 const double original_lineWidth = my lineWidth;
134 const MelderColour original_colour = my colour;
135 if (numberOfMarks < 2)
136 return;
137
138 Graphics_setWindow (me, 0.0, 1.0, original_y1WC, original_y2WC);
139 Graphics_setColour (me, Melder_BLACK);
140 Graphics_setTextAlignment (me, Graphics_RIGHT, Graphics_HALF);
141 Graphics_setInner (me);
142 if (haveTicks) {
143 Graphics_setLineType (me, Graphics_DRAWN);
144 Graphics_setLineWidth (me, 2.0 * original_lineWidth);
145 }
146 for (int i = 1; i <= numberOfMarks; i ++) {
147 const double f = (i - 1.0) / (numberOfMarks - 1);
148 const double yWC = original_y1WC + (original_y2WC - original_y1WC) * f;
149 if (haveNumbers)
150 Graphics_text (me, - my horTick, yWC, Melder_float (Melder_half (yWC)));
151 if (haveTicks)
152 Graphics_line (me, - my horTick, yWC, 0, yWC);
153 }
154 if (haveTicks)
155 Graphics_setLineWidth (me, original_lineWidth);
156 if (haveDottedLines && numberOfMarks > 2) {
157 Graphics_setLineType (me, Graphics_DOTTED);
158 Graphics_setLineWidth (me, 0.67 * original_lineWidth);
159 for (int i = 2; i < numberOfMarks; i ++) {
160 const double f = (i - 1.0) / (numberOfMarks - 1);
161 const double yWC = original_y1WC + (original_y2WC - original_y1WC) * f;
162 Graphics_line (me, 0.0, yWC, 1.0, yWC);
163 }
164 Graphics_setLineWidth (me, original_lineWidth);
165 }
166 Graphics_unsetInner (me);
167
168 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
169 Graphics_setLineType (me, original_lineType);
170 Graphics_setColour (me, original_colour);
171 }
172
Graphics_marksRight(Graphics me,int numberOfMarks,bool haveNumbers,bool haveTicks,bool haveDottedLines)173 void Graphics_marksRight (Graphics me, int numberOfMarks, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
174 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
175 const int original_lineType = my lineType;
176 const double original_lineWidth = my lineWidth;
177 const MelderColour original_colour = my colour;
178 if (numberOfMarks < 2)
179 return;
180
181 Graphics_setWindow (me, 0.0, 1.0, original_y1WC, original_y2WC);
182 Graphics_setColour (me, Melder_BLACK);
183 Graphics_setTextAlignment (me, Graphics_LEFT, Graphics_HALF);
184 Graphics_setInner (me);
185 if (haveTicks) {
186 Graphics_setLineType (me, Graphics_DRAWN);
187 Graphics_setLineWidth (me, 2.0 * original_lineWidth);
188 }
189 for (int i = 1; i <= numberOfMarks; i ++) {
190 const double f = (i - 1.0) / (numberOfMarks - 1);
191 const double yWC = original_y1WC + (original_y2WC - original_y1WC) * f;
192 if (haveNumbers)
193 Graphics_text (me, 1.0 + my horTick, yWC, Melder_float (Melder_half (yWC)));
194 if (haveTicks)
195 Graphics_line (me, 1.0, yWC, 1.0 + my horTick, yWC);
196 }
197 if (haveTicks)
198 Graphics_setLineWidth (me, original_lineWidth);
199 if (haveDottedLines && numberOfMarks > 2) {
200 Graphics_setLineType (me, Graphics_DOTTED);
201 Graphics_setLineWidth (me, 0.67 * original_lineWidth);
202 for (int i = 2; i < numberOfMarks; i ++) {
203 const double f = (i - 1.0) / (numberOfMarks - 1);
204 const double yWC = original_y1WC + (original_y2WC - original_y1WC) * f;
205 Graphics_line (me, 0.0, yWC, 1.0, yWC);
206 }
207 Graphics_setLineWidth (me, original_lineWidth);
208 }
209 Graphics_unsetInner (me);
210
211 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
212 Graphics_setLineType (me, original_lineType);
213 Graphics_setColour (me, original_colour);
214 }
215
Graphics_marksBottom(Graphics me,int numberOfMarks,bool haveNumbers,bool haveTicks,bool haveDottedLines)216 void Graphics_marksBottom (Graphics me, int numberOfMarks, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
217 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
218 int original_lineType = my lineType;
219 const double original_lineWidth = my lineWidth;
220 const MelderColour original_colour = my colour;
221 if (numberOfMarks < 2)
222 return;
223
224 Graphics_setWindow (me, original_x1WC, original_x2WC, 0.0, 1.0);
225 Graphics_setColour (me, Melder_BLACK);
226 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
227 Graphics_setInner (me);
228 if (haveTicks) {
229 Graphics_setLineType (me, Graphics_DRAWN);
230 Graphics_setLineWidth (me, 2.0 * original_lineWidth);
231 }
232 for (int i = 1; i <= numberOfMarks; i ++) {
233 const double f = (i - 1.0) / (numberOfMarks - 1);
234 const double xWC = original_x1WC + (original_x2WC - original_x1WC) * f;
235 if (haveNumbers)
236 Graphics_text (me, xWC, - my vertTick, Melder_float (Melder_half (xWC)));
237 if (haveTicks)
238 Graphics_line (me, xWC, - my vertTick, xWC, 0);
239 }
240 if (haveTicks)
241 Graphics_setLineWidth (me, original_lineWidth);
242 if (haveDottedLines && numberOfMarks > 2) {
243 Graphics_setLineType (me, Graphics_DOTTED);
244 Graphics_setLineWidth (me, 0.67 * original_lineWidth);
245 for (int i = 2; i < numberOfMarks; i ++) {
246 const double f = (i - 1.0) / (numberOfMarks - 1);
247 const double xWC = original_x1WC + (original_x2WC - original_x1WC) * f;
248 Graphics_line (me, xWC, 0.0, xWC, 1.0);
249 }
250 Graphics_setLineWidth (me, original_lineWidth);
251 }
252 Graphics_unsetInner (me);
253
254 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
255 Graphics_setLineType (me, original_lineType);
256 Graphics_setColour (me, original_colour);
257 }
258
Graphics_marksTop(Graphics me,int numberOfMarks,bool haveNumbers,bool haveTicks,bool haveDottedLines)259 void Graphics_marksTop (Graphics me, int numberOfMarks, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
260 const double original_x1WC = my d_x1WC, original_x2WC = my d_x2WC, original_y1WC = my d_y1WC, original_y2WC = my d_y2WC;
261 const int original_lineType = my lineType;
262 const double original_lineWidth = my lineWidth;
263 const MelderColour original_colour = my colour;
264 if (numberOfMarks < 2)
265 return;
266
267 Graphics_setWindow (me, original_x1WC, original_x2WC, 0.0, 1.0);
268 Graphics_setColour (me, Melder_BLACK);
269 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
270 Graphics_setInner (me);
271 if (haveTicks) {
272 Graphics_setLineType (me, Graphics_DRAWN);
273 Graphics_setLineWidth (me, 2.0 * original_lineWidth);
274 }
275 for (int i = 1; i <= numberOfMarks; i ++) {
276 const double f = (i - 1.0) / (numberOfMarks - 1);
277 const double xWC = original_x1WC + (original_x2WC - original_x1WC) * f;
278 if (haveNumbers)
279 Graphics_text (me, xWC, 1.0 + my vertTick, Melder_float (Melder_half (xWC)));
280 if (haveTicks)
281 Graphics_line (me, xWC, 1.0, xWC, 1.0 + my vertTick);
282 }
283 if (haveTicks)
284 Graphics_setLineWidth (me, original_lineWidth);
285 if (haveDottedLines && numberOfMarks > 2) {
286 Graphics_setLineType (me, Graphics_DOTTED);
287 Graphics_setLineWidth (me, 0.67 * original_lineWidth);
288 for (int i = 2; i < numberOfMarks; i ++) {
289 const double f = (i - 1.0) / (numberOfMarks - 1);
290 const double xWC = original_x1WC + (original_x2WC - original_x1WC) * f;
291 Graphics_line (me, xWC, 0.0, xWC, 1.0);
292 }
293 Graphics_setLineWidth (me, original_lineWidth);
294 }
295 Graphics_unsetInner (me);
296
297 Graphics_setWindow (me, original_x1WC, original_x2WC, original_y1WC, original_y2WC);
298 Graphics_setLineType (me, original_lineType);
299 Graphics_setColour (me, original_colour);
300 }
301
302 #define MAXNUM_MARKS_PER_DECADE 7
303 static double decade_y [1 + MAXNUM_MARKS_PER_DECADE] [1 + MAXNUM_MARKS_PER_DECADE] = {
304 { 0 },
305 { 0, 10 },
306 { 0, 10, 30 },
307 { 0, 10, 20, 50 },
308 { 0, 10, 20, 30, 50 },
309 { 0, 10, 20, 30, 50, 70 },
310 { 0, 10, 15, 20, 30, 50, 70 },
311 { 0, 10, 15, 20, 30, 40, 50, 70 }
312 };
313
Graphics_marksLeftLogarithmic(Graphics me,int numberOfMarksPerDecade,bool haveNumbers,bool haveTicks,bool haveDottedLines)314 void Graphics_marksLeftLogarithmic (Graphics me, int numberOfMarksPerDecade, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
315 const double x1 = my d_x1WC, x2 = my d_x2WC, y1 = my d_y1WC, y2 = my d_y2WC;
316 const int lineType = my lineType;
317 const double lineWidth = my lineWidth;
318 const MelderColour colour = my colour;
319 Melder_clip (1, & numberOfMarksPerDecade, MAXNUM_MARKS_PER_DECADE);
320 if (y1 > 300.0 || y2 > 300.0)
321 return;
322
323 const double py1 = pow (10.0, y1 + ( y1 < y2 ? -1e-6 : 1e-6 ));
324 const double py2 = pow (10.0, y2 + ( y1 < y2 ? 1e-6 : -1e-6 ));
325 Graphics_setWindow (me, 0, 1, y1, y2);
326 Graphics_setColour (me, Melder_BLACK);
327 Graphics_setTextAlignment (me, Graphics_RIGHT, Graphics_HALF);
328 Graphics_setInner (me);
329 for (int i = 1; i <= numberOfMarksPerDecade; i ++) {
330 double y = decade_y [numberOfMarksPerDecade] [i];
331 while (y < (y1<y2?py1:py2))
332 y *= 10.0;
333 while (y >= (y1<y2?py1:py2))
334 y /= 10.0;
335 for (y *= 10.0; y <= (y1<y2?py2:py1); y *= 10.0) {
336 if (haveNumbers)
337 Graphics_text (me, - my horTick, log10 (y), Melder_float (Melder_half (y)));
338 if (haveTicks) {
339 Graphics_setLineWidth (me, 2.0 * lineWidth);
340 Graphics_setLineType (me, Graphics_DRAWN);
341 Graphics_line (me, - my horTick, log10 (y), 0, log10 (y));
342 Graphics_setLineWidth (me, lineWidth);
343 }
344 if (haveDottedLines) {
345 Graphics_setLineType (me, Graphics_DOTTED);
346 Graphics_setLineWidth (me, 0.67 * lineWidth);
347 Graphics_line (me, 0.0, log10 (y), 1.0, log10 (y));
348 Graphics_setLineType (me, lineType);
349 Graphics_setLineWidth (me, lineWidth);
350 }
351 }
352 }
353 Graphics_unsetInner (me);
354
355 Graphics_setWindow (me, x1, x2, y1, y2);
356 Graphics_setColour (me, colour);
357 }
358
Graphics_marksRightLogarithmic(Graphics me,int numberOfMarksPerDecade,bool haveNumbers,bool haveTicks,bool haveDottedLines)359 void Graphics_marksRightLogarithmic (Graphics me, int numberOfMarksPerDecade, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
360 const double x1 = my d_x1WC, x2 = my d_x2WC, y1 = my d_y1WC, y2 = my d_y2WC;
361 const int lineType = my lineType;
362 const double lineWidth = my lineWidth;
363 const MelderColour colour = my colour;
364 Melder_clip (1, & numberOfMarksPerDecade, MAXNUM_MARKS_PER_DECADE);
365 if (y1 > 300.0 || y2 > 300.0)
366 return;
367
368 const double py1 = pow (10.0, y1 + ( y1 < y2 ? -1e-6 : 1e-6 ));
369 const double py2 = pow (10.0, y2 + ( y1 < y2 ? 1e-6 : -1e-6 ));
370 Graphics_setWindow (me, 0.0, 1.0, y1, y2);
371 Graphics_setColour (me, Melder_BLACK);
372 Graphics_setTextAlignment (me, Graphics_LEFT, Graphics_HALF);
373 Graphics_setInner (me);
374 for (int i = 1; i <= numberOfMarksPerDecade; i ++) {
375 double y = decade_y [numberOfMarksPerDecade] [i];
376 while (y < (y1<y2?py1:py2))
377 y *= 10.0;
378 while (y >= (y1<y2?py1:py2))
379 y /= 10.0;
380 for (y *= 10.0; y <= (y1<y2?py2:py1); y *= 10.0) {
381 if (haveNumbers)
382 Graphics_text (me, 1.0 + my horTick, log10 (y), Melder_float (Melder_half (y)));
383 if (haveTicks) {
384 Graphics_setLineWidth (me, 2.0 * lineWidth);
385 Graphics_setLineType (me, Graphics_DRAWN);
386 Graphics_line (me, 1.0, log10 (y), 1.0 + my horTick, log10 (y));
387 Graphics_setLineWidth (me, lineWidth);
388 }
389 if (haveDottedLines) {
390 Graphics_setLineType (me, Graphics_DOTTED);
391 Graphics_setLineWidth (me, 0.67 * lineWidth);
392 Graphics_line (me, 0.0, log10 (y), 1.0, log10 (y));
393 Graphics_setLineType (me, lineType);
394 Graphics_setLineWidth (me, lineWidth);
395 }
396 }
397 }
398 Graphics_unsetInner (me);
399
400 Graphics_setWindow (me, x1, x2, y1, y2);
401 Graphics_setColour (me, colour);
402 }
403
Graphics_marksTopLogarithmic(Graphics me,int numberOfMarksPerDecade,bool haveNumbers,bool haveTicks,bool haveDottedLines)404 void Graphics_marksTopLogarithmic (Graphics me, int numberOfMarksPerDecade, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
405 const double x1 = my d_x1WC, x2 = my d_x2WC, y1 = my d_y1WC, y2 = my d_y2WC;
406 const int lineType = my lineType;
407 const double lineWidth = my lineWidth;
408 const MelderColour colour = my colour;
409 Melder_clip (1, & numberOfMarksPerDecade, MAXNUM_MARKS_PER_DECADE);
410 if (x1 > 300.0 || x2 > 300.0)
411 return;
412
413 const double px1 = pow (10.0, x1 + ( x1 < x2 ? -1e-6 : 1e-6 ));
414 const double px2 = pow (10.0, x2 + ( x1 < x2 ? 1e-6 : -1e-6 ));
415 Graphics_setWindow (me, x1, x2, 0.0, 1.0);
416 Graphics_setColour (me, Melder_BLACK);
417 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
418 Graphics_setInner (me);
419 for (int i = 1; i <= numberOfMarksPerDecade; i ++) {
420 double x = decade_y [numberOfMarksPerDecade] [i];
421 while (x < (x1<x2?px1:px2))
422 x *= 10.0;
423 while (x >= (x1<x2?px1:px2))
424 x /= 10.0;
425 for (x *= 10.0; x <= (x1<x2?px2:px1); x *= 10.0) {
426 if (haveNumbers)
427 Graphics_text (me, log10 (x), 1.0 + my vertTick, Melder_float (Melder_half (x)));
428 if (haveTicks) {
429 Graphics_setLineWidth (me, 2.0 * lineWidth);
430 Graphics_setLineType (me, Graphics_DRAWN);
431 Graphics_line (me, log10 (x), 1.0, log10 (x), 1.0 + my vertTick);
432 Graphics_setLineWidth (me, lineWidth);
433 }
434 if (haveDottedLines) {
435 Graphics_setLineType (me, Graphics_DOTTED);
436 Graphics_setLineWidth (me, 0.67 * lineWidth);
437 Graphics_line (me, log10 (x), 0.0, log10 (x), 1.0);
438 Graphics_setLineType (me, lineType);
439 Graphics_setLineWidth (me, lineWidth);
440 }
441 }
442 }
443 Graphics_unsetInner (me);
444
445 Graphics_setWindow (me, x1, x2, y1, y2);
446 Graphics_setColour (me, colour);
447 }
448
Graphics_marksBottomLogarithmic(Graphics me,int numberOfMarksPerDecade,bool haveNumbers,bool haveTicks,bool haveDottedLines)449 void Graphics_marksBottomLogarithmic (Graphics me, int numberOfMarksPerDecade, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
450 const double x1 = my d_x1WC, x2 = my d_x2WC, y1 = my d_y1WC, y2 = my d_y2WC;
451 const int lineType = my lineType;
452 const double lineWidth = my lineWidth;
453 const MelderColour colour = my colour;
454 Melder_clip (1, & numberOfMarksPerDecade, MAXNUM_MARKS_PER_DECADE);
455 if (x1 > 300.0 || x2 > 300.0)
456 return;
457
458 const double px1 = pow (10.0, x1 + ( x1 < x2 ? -1e-6 : 1e-6 ));
459 const double px2 = pow (10.0, x2 + ( x1 < x2 ? 1e-6 : -1e-6 ));
460 Graphics_setWindow (me, x1, x2, 0, 1);
461 Graphics_setColour (me, Melder_BLACK);
462 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
463 Graphics_setInner (me);
464 for (int i = 1; i <= numberOfMarksPerDecade; i ++) {
465 double x = decade_y [numberOfMarksPerDecade] [i];
466 while (x < (x1<x2?px1:px2))
467 x *= 10.0;
468 while (x >= (x1<x2?px1:px2))
469 x /= 10.0;
470 for (x *= 10.0; x <= (x1<x2?px2:px1); x *= 10.0) {
471 if (haveNumbers)
472 Graphics_text (me, log10 (x), - my vertTick, Melder_float (Melder_half (x)));
473 if (haveTicks) {
474 Graphics_setLineWidth (me, 2.0 * lineWidth);
475 Graphics_setLineType (me, Graphics_DRAWN);
476 Graphics_line (me, log10 (x), - my vertTick, log10 (x), 0.0);
477 Graphics_setLineWidth (me, lineWidth);
478 }
479 if (haveDottedLines) {
480 Graphics_setLineType (me, Graphics_DOTTED);
481 Graphics_setLineWidth (me, 0.67 * lineWidth);
482 Graphics_line (me, log10 (x), 0.0, log10 (x), 1.0);
483 Graphics_setLineType (me, lineType);
484 Graphics_setLineWidth (me, lineWidth);
485 }
486 }
487 }
488 Graphics_unsetInner (me);
489
490 Graphics_setWindow (me, x1, x2, y1, y2);
491 Graphics_setColour (me, colour);
492 }
493
Graphics_markLeft(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)494 void Graphics_markLeft (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
495 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
496 const int lineType = my lineType;
497 const double lineWidth = my lineWidth;
498 const MelderColour colour = my colour;
499
500 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
501 Graphics_setColour (me, Melder_BLACK);
502 Graphics_setTextAlignment (me, Graphics_RIGHT, Graphics_HALF);
503 Graphics_setInner (me);
504 if (hasNumber)
505 Graphics_text (me, - my horTick, position, Melder_float (Melder_half (position)));
506 if (hasTick) {
507 Graphics_setLineType (me, Graphics_DRAWN);
508 Graphics_setLineWidth (me, 2.0 * lineWidth);
509 Graphics_line (me, - my horTick, position, 0.0, position);
510 Graphics_setLineWidth (me, lineWidth);
511 }
512 if (hasDottedLine) {
513 Graphics_setLineType (me, Graphics_DOTTED);
514 Graphics_setLineWidth (me, 0.67 * lineWidth);
515 Graphics_line (me, 0.0, position, 1.0, position);
516 Graphics_setLineWidth (me, lineWidth);
517 }
518 if (text && text [0])
519 Graphics_text (me, - my horTick, position, text); // 'text' has to stay valid until here; no Graphics is allowed to use the cat buffer!
520 Graphics_unsetInner (me);
521
522 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
523 Graphics_setLineType (me, lineType);
524 Graphics_setColour (me, colour);
525 }
526
Graphics_markRight(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)527 void Graphics_markRight (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
528 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
529 const int lineType = my lineType;
530 const double lineWidth = my lineWidth;
531 const MelderColour colour = my colour;
532
533 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
534 Graphics_setColour (me, Melder_BLACK);
535 Graphics_setTextAlignment (me, Graphics_LEFT, Graphics_HALF);
536 Graphics_setInner (me);
537 if (hasNumber)
538 Graphics_text (me, 1.0 + my horTick, position, Melder_float (Melder_half (position)));
539 if (hasTick) {
540 Graphics_setLineType (me, Graphics_DRAWN);
541 Graphics_setLineWidth (me, 2.0 * lineWidth);
542 Graphics_line (me, 1.0, position, 1.0 + my horTick, position);
543 Graphics_setLineWidth (me, lineWidth);
544 }
545 if (hasDottedLine) {
546 Graphics_setLineType (me, Graphics_DOTTED);
547 Graphics_setLineWidth (me, 0.67 * lineWidth);
548 Graphics_line (me, 0.0, position, 1.0, position);
549 Graphics_setLineWidth (me, lineWidth);
550 }
551 if (text && text [0])
552 Graphics_text (me, 1.0 + my horTick, position, text);
553 Graphics_unsetInner (me);
554
555 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
556 Graphics_setLineType (me, lineType);
557 Graphics_setColour (me, colour);
558 }
559
Graphics_markTop(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)560 void Graphics_markTop (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
561 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
562 const int lineType = my lineType;
563 const double lineWidth = my lineWidth;
564 const MelderColour colour = my colour;
565
566 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
567 Graphics_setColour (me, Melder_BLACK);
568 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
569 Graphics_setInner (me);
570 if (hasNumber)
571 Graphics_text (me, position, 1.0 + my vertTick, Melder_float (Melder_single (position)));
572 if (hasTick) {
573 Graphics_setLineType (me, Graphics_DRAWN);
574 Graphics_setLineWidth (me, 2.0 * lineWidth);
575 Graphics_line (me, position, 1.0, position, 1.0 + my vertTick);
576 Graphics_setLineWidth (me, lineWidth);
577 }
578 if (hasDottedLine) {
579 Graphics_setLineType (me, Graphics_DOTTED);
580 Graphics_setLineWidth (me, 0.67 * lineWidth);
581 Graphics_line (me, position, 0.0, position, 1.0);
582 Graphics_setLineWidth (me, lineWidth);
583 }
584 if (text && text [0])
585 Graphics_text (me, position, 1.0 + my vertTick, text);
586 Graphics_unsetInner (me);
587
588 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
589 Graphics_setLineType (me, lineType);
590 Graphics_setColour (me, colour);
591 }
592
Graphics_markBottom(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)593 void Graphics_markBottom (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
594 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
595 const int lineType = my lineType;
596 const double lineWidth = my lineWidth;
597 const MelderColour colour = my colour;
598
599 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
600 Graphics_setColour (me, Melder_BLACK);
601 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
602 Graphics_setInner (me);
603 if (hasNumber)
604 Graphics_text (me, position, - my vertTick, Melder_float (Melder_single (position)));
605 if (hasTick) {
606 Graphics_setLineType (me, Graphics_DRAWN);
607 Graphics_setLineWidth (me, 2.0 * lineWidth);
608 Graphics_line (me, position, - my vertTick, position, 0.0);
609 Graphics_setLineWidth (me, lineWidth);
610 }
611 if (hasDottedLine) {
612 Graphics_setLineType (me, Graphics_DOTTED);
613 Graphics_setLineWidth (me, 0.67 * lineWidth);
614 Graphics_line (me, position, 0.0, position, 1.0);
615 Graphics_setLineWidth (me, lineWidth);
616 }
617 if (text && text [0])
618 Graphics_text (me, position, - my vertTick, text);
619 Graphics_unsetInner (me);
620
621 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
622 Graphics_setLineType (me, lineType);
623 Graphics_setColour (me, colour);
624 }
625
Graphics_markLeftLogarithmic(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)626 void Graphics_markLeftLogarithmic (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
627 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
628 const int lineType = my lineType;
629 const double lineWidth = my lineWidth;
630 const MelderColour colour = my colour;
631 if (position <= 0.0)
632 return;
633
634 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
635 Graphics_setColour (me, Melder_BLACK);
636 Graphics_setTextAlignment (me, Graphics_RIGHT, Graphics_HALF);
637 Graphics_setInner (me);
638 if (hasNumber)
639 Graphics_text (me, - my horTick, log10 (position), Melder_float (Melder_half (position)));
640 if (hasTick) {
641 Graphics_setLineType (me, Graphics_DRAWN);
642 Graphics_setLineWidth (me, 2.0 * lineWidth);
643 Graphics_line (me, - my horTick, log10 (position), 0.0, log10 (position));
644 Graphics_setLineWidth (me, lineWidth);
645 }
646 if (hasDottedLine) {
647 Graphics_setLineType (me, Graphics_DOTTED);
648 Graphics_setLineWidth (me, 0.67 * lineWidth);
649 Graphics_line (me, 0.0, log10 (position), 1.0, log10 (position));
650 Graphics_setLineWidth (me, lineWidth);
651 }
652 if (text && text [0])
653 Graphics_text (me, - my horTick, log10 (position), text);
654 Graphics_unsetInner (me);
655
656 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
657 Graphics_setLineType (me, lineType);
658 Graphics_setColour (me, colour);
659 }
660
Graphics_markRightLogarithmic(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)661 void Graphics_markRightLogarithmic (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
662 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
663 const int lineType = my lineType;
664 const double lineWidth = my lineWidth;
665 const MelderColour colour = my colour;
666 if (position <= 0.0)
667 return;
668
669 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
670 Graphics_setColour (me, Melder_BLACK);
671 Graphics_setTextAlignment (me, Graphics_LEFT, Graphics_HALF);
672 Graphics_setInner (me);
673 if (hasNumber)
674 Graphics_text (me, 1.0 + my horTick, log10 (position), Melder_float (Melder_half (position)));
675 if (hasTick) {
676 Graphics_setLineType (me, Graphics_DRAWN);
677 Graphics_setLineWidth (me, 2.0 * lineWidth);
678 Graphics_line (me, 1.0, log10 (position), 1.0 + my horTick, log10 (position));
679 Graphics_setLineWidth (me, lineWidth);
680 }
681 if (hasDottedLine) {
682 Graphics_setLineType (me, Graphics_DOTTED);
683 Graphics_setLineWidth (me, 0.67 * lineWidth);
684 Graphics_line (me, 0.0, log10 (position), 1.0, log10 (position));
685 Graphics_setLineWidth (me, lineWidth);
686 }
687 if (text && text [0])
688 Graphics_text (me, 1.0 + my horTick, log10 (position), text);
689 Graphics_unsetInner (me);
690
691 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
692 Graphics_setLineType (me, lineType);
693 Graphics_setColour (me, colour);
694 }
695
Graphics_markTopLogarithmic(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)696 void Graphics_markTopLogarithmic (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
697 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
698 const int lineType = my lineType;
699 const double lineWidth = my lineWidth;
700 const MelderColour colour = my colour;
701 if (position <= 0.0)
702 return;
703
704 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
705 Graphics_setColour (me, Melder_BLACK);
706 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
707 Graphics_setInner (me);
708 if (hasNumber)
709 Graphics_text (me, log10 (position), 1.0 + my vertTick, Melder_float (Melder_half (position)));
710 if (hasTick) {
711 Graphics_setLineType (me, Graphics_DRAWN);
712 Graphics_setLineWidth (me, 2.0 * lineWidth);
713 Graphics_line (me, log10 (position), 1.0, log10 (position), 1.0 + my vertTick);
714 Graphics_setLineWidth (me, lineWidth);
715 }
716 if (hasDottedLine) {
717 Graphics_setLineType (me, Graphics_DOTTED);
718 Graphics_setLineWidth (me, 0.67 * lineWidth);
719 Graphics_line (me, log10 (position), 0.0, log10 (position), 1.0);
720 Graphics_setLineWidth (me, lineWidth);
721 }
722 if (text && text [0])
723 Graphics_text (me, log10 (position), 1.0 + my vertTick, text);
724 Graphics_unsetInner (me);
725
726 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
727 Graphics_setLineType (me, lineType);
728 Graphics_setColour (me, colour);
729 }
730
Graphics_markBottomLogarithmic(Graphics me,double position,bool hasNumber,bool hasTick,bool hasDottedLine,conststring32 text)731 void Graphics_markBottomLogarithmic (Graphics me, double position, bool hasNumber, bool hasTick, bool hasDottedLine, conststring32 text /* cattable */) {
732 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
733 const int lineType = my lineType;
734 const double lineWidth = my lineWidth;
735 const MelderColour colour = my colour;
736 if (position <= 0.0)
737 return;
738
739 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
740 Graphics_setColour (me, Melder_BLACK);
741 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
742 Graphics_setInner (me);
743 if (hasNumber)
744 Graphics_text (me, log10 (position), - my vertTick, Melder_float (Melder_half (position)));
745 if (hasTick) {
746 Graphics_setLineType (me, Graphics_DRAWN);
747 Graphics_setLineWidth (me, 2.0 * lineWidth);
748 Graphics_line (me, log10 (position), - my vertTick, log10 (position), 0.0);
749 Graphics_setLineWidth (me, lineWidth);
750 }
751 if (hasDottedLine) {
752 Graphics_setLineType (me, Graphics_DOTTED);
753 Graphics_setLineWidth (me, 0.67 * lineWidth);
754 Graphics_line (me, log10 (position), 0.0, log10 (position), 1.0);
755 Graphics_setLineWidth (me, lineWidth);
756 }
757 if (text && text [0])
758 Graphics_text (me, log10 (position), - my vertTick, text);
759 Graphics_unsetInner (me);
760
761 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
762 Graphics_setLineType (me, lineType);
763 Graphics_setColour (me, colour);
764 }
765
Graphics_marksLeftEvery(Graphics me,double units,double distance,bool haveNumbers,bool haveTicks,bool haveDottedLines)766 void Graphics_marksLeftEvery (Graphics me, double units, double distance, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
767 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
768 const int lineType = my lineType;
769 const double lineWidth = my lineWidth;
770 const MelderColour colour = my colour;
771 distance *= units;
772
773 const integer first = Melder_iceiling (( y1WC < y2WC ? y1WC : y2WC ) / distance - 1e-5);
774 const integer last = Melder_ifloor (( y1WC < y2WC ? y2WC : y1WC ) / distance + 1e-5);
775 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
776 Graphics_setColour (me, Melder_BLACK);
777 Graphics_setTextAlignment (me, Graphics_RIGHT, Graphics_HALF);
778 Graphics_setInner (me);
779 if (haveTicks) {
780 Graphics_setLineType (me, Graphics_DRAWN);
781 Graphics_setLineWidth (me, 2.0 * lineWidth);
782 }
783 for (integer i = first; i <= last; i ++) {
784 const double yWC = i * distance;
785 if (haveNumbers)
786 Graphics_text (me, - my horTick, yWC, Melder_float (Melder_half (yWC / units)));
787 if (haveTicks)
788 Graphics_line (me, - my horTick, yWC, 0.0, yWC);
789 }
790 if (haveTicks)
791 Graphics_setLineWidth (me, lineWidth);
792 if (haveDottedLines) {
793 Graphics_setLineType (me, Graphics_DOTTED);
794 Graphics_setLineWidth (me, 0.67 * lineWidth);
795 for (integer i = first; i <= last; i ++) {
796 const double yWC = i * distance;
797 Graphics_line (me, 0.0, yWC, 1.0, yWC);
798 }
799 Graphics_setLineWidth (me, lineWidth);
800 }
801 Graphics_unsetInner (me);
802
803 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
804 Graphics_setLineType (me, lineType);
805 Graphics_setColour (me, colour);
806 }
807
Graphics_marksRightEvery(Graphics me,double units,double distance,bool haveNumbers,bool haveTicks,bool haveDottedLines)808 void Graphics_marksRightEvery (Graphics me, double units, double distance, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
809 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
810 const int lineType = my lineType;
811 const double lineWidth = my lineWidth;
812 const MelderColour colour = my colour;
813 distance *= units;
814
815 const integer first = Melder_iceiling (( y1WC < y2WC ? y1WC : y2WC ) / distance - 1e-5);
816 const integer last = Melder_ifloor (( y1WC < y2WC ? y2WC : y1WC ) / distance + 1e-5);
817 if (first > last)
818 return; // TODO: describe why this is. ppgb 2020-10-01
819 Graphics_setWindow (me, 0.0, 1.0, y1WC, y2WC);
820 Graphics_setColour (me, Melder_BLACK);
821 Graphics_setTextAlignment (me, Graphics_LEFT, Graphics_HALF);
822 Graphics_setInner (me);
823 if (haveTicks) {
824 Graphics_setLineType (me, Graphics_DRAWN);
825 Graphics_setLineWidth (me, 2.0 * lineWidth);
826 }
827 for (integer i = first; i <= last; i ++) {
828 const double yWC = i * distance;
829 if (haveNumbers)
830 Graphics_text (me, 1.0 + my horTick, yWC, Melder_float (Melder_half (yWC / units)));
831 if (haveTicks)
832 Graphics_line (me, 1.0, yWC, 1.0 + my horTick, yWC);
833 }
834 if (haveTicks)
835 Graphics_setLineWidth (me, lineWidth);
836 if (haveDottedLines) {
837 Graphics_setLineType (me, Graphics_DOTTED);
838 Graphics_setLineWidth (me, 0.67 * lineWidth);
839 for (integer i = first; i <= last; i ++) {
840 const double yWC = i * distance;
841 Graphics_line (me, 0.0, yWC, 1.0, yWC);
842 }
843 Graphics_setLineWidth (me, lineWidth);
844 }
845 Graphics_unsetInner (me);
846
847 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
848 Graphics_setLineType (me, lineType);
849 Graphics_setColour (me, colour);
850 }
851
Graphics_marksBottomEvery(Graphics me,double units,double distance,bool haveNumbers,bool haveTicks,bool haveDottedLines)852 void Graphics_marksBottomEvery (Graphics me, double units, double distance, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
853 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
854 const int lineType = my lineType;
855 const double lineWidth = my lineWidth;
856 const MelderColour colour = my colour;
857 distance *= units;
858
859 const integer first = Melder_iceiling (( x1WC < x2WC ? x1WC : x2WC ) / distance - 1e-5);
860 const integer last = Melder_ifloor (( x1WC < x2WC ? x2WC : x1WC ) / distance + 1e-5);
861 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
862 Graphics_setColour (me, Melder_BLACK);
863 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_TOP);
864 Graphics_setInner (me);
865 if (haveTicks) {
866 Graphics_setLineType (me, Graphics_DRAWN);
867 Graphics_setLineWidth (me, 2.0 * lineWidth);
868 }
869 for (integer i = first; i <= last; i ++) {
870 const double xWC = i * distance;
871 if (haveNumbers)
872 Graphics_text (me, xWC, - my vertTick, Melder_float (Melder_half (xWC / units)));
873 if (haveTicks)
874 Graphics_line (me, xWC, - my vertTick, xWC, 0.0);
875 }
876 if (haveTicks)
877 Graphics_setLineWidth (me, lineWidth);
878 if (haveDottedLines) {
879 Graphics_setLineType (me, Graphics_DOTTED);
880 Graphics_setLineWidth (me, 0.67 * lineWidth);
881 for (integer i = first; i <= last; i ++) {
882 const double xWC = i * distance;
883 Graphics_line (me, xWC, 0.0, xWC, 1.0);
884 }
885 Graphics_setLineWidth (me, lineWidth);
886 }
887 Graphics_unsetInner (me);
888
889 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
890 Graphics_setLineType (me, lineType);
891 Graphics_setColour (me, colour);
892 }
893
Graphics_marksTopEvery(Graphics me,double units,double distance,bool haveNumbers,bool haveTicks,bool haveDottedLines)894 void Graphics_marksTopEvery (Graphics me, double units, double distance, bool haveNumbers, bool haveTicks, bool haveDottedLines) {
895 const double x1WC = my d_x1WC, x2WC = my d_x2WC, y1WC = my d_y1WC, y2WC = my d_y2WC;
896 const int lineType = my lineType;
897 const double lineWidth = my lineWidth;
898 const MelderColour colour = my colour;
899 distance *= units;
900
901 const integer first = Melder_iceiling (( x1WC < x2WC ? x1WC : x2WC ) / distance - 1e-5);
902 const integer last = Melder_ifloor (( x1WC < x2WC ? x2WC : x1WC ) / distance + 1e-5);
903 Graphics_setWindow (me, x1WC, x2WC, 0.0, 1.0);
904 Graphics_setColour (me, Melder_BLACK);
905 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_BOTTOM);
906 Graphics_setInner (me);
907 if (haveTicks) {
908 Graphics_setLineType (me, Graphics_DRAWN);
909 Graphics_setLineWidth (me, 2.0 * lineWidth);
910 }
911 for (integer i = first; i <= last; i ++) {
912 const double xWC = i * distance;
913 if (haveNumbers)
914 Graphics_text (me, xWC, 1.0 + my vertTick, Melder_float (Melder_half (xWC / units)));
915 if (haveTicks)
916 Graphics_line (me, xWC, 1.0, xWC, 1.0 + my vertTick);
917 }
918 if (haveTicks)
919 Graphics_setLineWidth (me, lineWidth);
920 if (haveDottedLines) {
921 Graphics_setLineType (me, Graphics_DOTTED);
922 Graphics_setLineWidth (me, 0.67 * lineWidth);
923 for (integer i = first; i <= last; i ++) {
924 const double xWC = i * distance;
925 Graphics_line (me, xWC, 0.0, xWC, 1.0);
926 }
927 Graphics_setLineWidth (me, lineWidth);
928 }
929 Graphics_unsetInner (me);
930
931 Graphics_setWindow (me, x1WC, x2WC, y1WC, y2WC);
932 Graphics_setLineType (me, lineType);
933 Graphics_setColour (me, colour);
934 }
935
Graphics_mark(Graphics me,double x,double y,double size_mm,conststring32 markString)936 void Graphics_mark (Graphics me, double x, double y, double size_mm, conststring32 markString /* cattable */) {
937 int mark;
938 if (! markString || ! markString [0])
939 mark = 0;
940 else if (! markString [1]) {
941 if (markString [0] == '+')
942 mark = 1;
943 else if (markString [0] == 'x')
944 mark = 2;
945 else if (markString [0] == 'o')
946 mark = 3;
947 else if (markString [0] == '.')
948 mark = 0;
949 else
950 mark = -1;
951 } else
952 mark = -1;
953 if (mark == -1) {
954 const double oldSize = my fontSize;
955 const int oldHorizontalAlignment = my horizontalTextAlignment;
956 const int oldVerticalAlignment = my verticalTextAlignment;
957 Graphics_setFontSize (me, size_mm * 72.0 / 25.4);
958 Graphics_setTextAlignment (me, Graphics_CENTRE, Graphics_HALF);
959 Graphics_text (me, x, y, markString);
960 Graphics_setFontSize (me, oldSize);
961 Graphics_setTextAlignment (me, (kGraphics_horizontalAlignment) oldHorizontalAlignment, oldVerticalAlignment);
962 } else if (mark == 0) {
963 Graphics_fillCircle_mm (me, x, y, size_mm);
964 } else if (mark == 1) {
965 const double dx = 0.5 * Graphics_dxMMtoWC (me, size_mm);
966 const double dy = 0.5 * Graphics_dyMMtoWC (me, size_mm);
967 Graphics_line (me, x - dx, y, x + dx, y);
968 Graphics_line (me, x, y - dy, x, y + dy);
969 } else if (mark == 2) {
970 const double dx = 0.4 * Graphics_dxMMtoWC (me, size_mm);
971 const double dy = 0.4 * Graphics_dyMMtoWC (me, size_mm);
972 Graphics_line (me, x - dx, y - dy, x + dx, y + dy);
973 Graphics_line (me, x + dx, y - dy, x - dx, y + dy);
974 } else {
975 Graphics_circle_mm (me, x, y, size_mm);
976 }
977 }
978
Graphics_setTextRotation_vector(Graphics me,double dx,double dy)979 void Graphics_setTextRotation_vector (Graphics me, double dx, double dy) {
980 double angle;
981 if (dy == 0.0) {
982 angle = ( dx >= 0.0 ? 0.0 : 180.0 );
983 } else if (dx == 0.0) {
984 angle = ( dy > 0.0 ? 90.0 : 270.0 );
985 } else {
986 const double dxDC = dx * my scaleX;
987 const double dyDC = ( my yIsZeroAtTheTop ? -dy * my scaleY : dy * my scaleY );
988 angle = atan2 (dyDC, dxDC) * (180.0 / NUMpi);
989 }
990 Graphics_setTextRotation (me, angle);
991 }
992
993 /* End of file Graphics_utils.cpp */
994