1 /* @source cirdna application
2 **
3 ** Draws circular maps of DNA constructs
4 ** @author Copyright (C) Nicolas Tourasse (tourasse@biotek.uio.no),
5 ** Biotechnology Centre of Oslo, Norway.
6 ** @@
7 **
8 ** This program is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License
10 ** as published by the Free Software Foundation; either version 2
11 ** of the License, or (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ******************************************************************************/
22
23 #include "emboss.h"
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29
30
31
32 static AjBool cirdna_ReadInput(AjPFile infile,
33 float *Start, float *End);
34 static AjPStr cirdna_ReadGroup(AjPFile infile, ajint maxlabels,
35 float* From, float *To,
36 AjPStr *Name2, char *FromSymbol,
37 char *ToSymbol, AjPStr *Style2,
38 ajint *NumLabels, ajint *NumNames,
39 ajint *Colour);
40 static float cirdna_TextGroup(float TextHeight, float TextLength,
41 AjPStr const *Name2, ajint NumLabels,
42 const ajint *NumNames,
43 AjPStr const *Style2,
44 const float* From,
45 const float* To,
46 const AjPStr PosTicks);
47 static float cirdna_TextGroupStr(AjPStr const *Name2, ajint NumLabels,
48 const ajint *NumNames,
49 float TextCoef, AjPStr const *Style2,
50 const float* From,
51 const float* To,
52 const AjPStr PosTicks);
53 static float cirdna_HeightGroup(float postext,
54 float TickHeight, float BlockHeight,
55 float RangeHeight,
56 AjPStr const *Style2, ajint NumLabels,
57 const AjPStr PosTicks,
58 const AjPStr PosBlocks, ajint Adjust);
59 static ajint cirdna_OverlapTextGroup(AjPStr const *Name2,
60 AjPStr const *Style2,
61 ajint NumLabels,
62 const float* From, const float* To,
63 float Start, float End,
64 const AjPStr PosTicks, ajint *Adjust);
65 static AjBool cirdna_OverlapTickRuler(ajint NumGroups, const ajint *NumLabels,
66 float* const * From,
67 const AjPStr PosTicks,
68 ajint RulerTick);
69 static void cirdna_DrawGroup(float xDraw, float yDraw, float posblock,
70 float posrange, float postext, float TickHeight,
71 float BlockHeight, float RangeHeight,
72 float RealLength, float Radius, float RadiusMax,
73 const float* From, const float* To,
74 AjPStr const *Name2,
75 const char *FromSymbol, const char *ToSymbol,
76 AjPStr const *Style2, AjBool InterSymbol,
77 AjBool InterTicks, ajint NumLabels,
78 float OriginAngle,
79 const ajint *NumNames, const AjPStr PosTicks,
80 const AjPStr PosBlocks, const ajint *Adjust,
81 ajint InterColour, const ajint *Colour,
82 const AjPStr BlockType);
83 static float cirdna_TextRuler(float Start, float End, ajint GapSize,
84 float TextLength, float TextHeight,
85 const AjPStr PosTicks, ajint NumGroups,
86 const ajint *NumLabels);
87 static float cirdna_TextRulerStr(float Start, float End, ajint GapSize,
88 float TextCoef, const AjPStr PosTicks,
89 ajint NumGroups, const ajint *NumLabels);
90 static float cirdna_HeightRuler(float Start, float End, ajint GapSize,
91 float postext, float TickHeight,
92 const AjPStr PosTicks, ajint NumGroups,
93 const ajint *NumLabels);
94 static void cirdna_DrawRuler(float xDraw, float yDraw, float Start, float End,
95 float RealLength, float Radius, float TickHeight,
96 float OriginAngle, ajint GapSize,
97 AjBool TickLines, float postext,
98 ajint NumGroups, const ajint *NumLabels,
99 float* const * From,
100 const AjPStr PosTicks, ajint Colour);
101 static void cirdna_DrawTicks(float xDraw, float yDraw, float RealLength,
102 float Radius, float TickHeight, float From,
103 const AjPStr Name2, float OriginAngle,
104 float postext,
105 const AjPStr PosTicks,
106 ajint NumNames, ajint Adjust,
107 ajint Colour);
108 static void cirdna_DrawBlocks(float xDraw, float yDraw, float RealLength,
109 float Radius, ajint BlockHeight, float From,
110 float To, const AjPStr Name2,
111 float postext, float OriginAngle,
112 const AjPStr PosBlocks, ajint NumNames,
113 ajint Adjust,
114 ajint Colour, const AjPStr BlockType);
115 static void cirdna_DrawRanges(float xDraw, float yDraw, float RealLength,
116 float Radius, float RangeHeight, float From,
117 float To, char FromSymbol,
118 char ToSymbol, const AjPStr Name2,
119 float OriginAngle,
120 ajint NumNames, float postext, ajint Adjust,
121 ajint Colour);
122 static void cirdna_InterBlocks(float xDraw, float yDraw, float RealLength,
123 float Radius, float BlockHeight, float From,
124 float To, float OriginAngle,
125 AjBool InterSymbol, ajint Colour);
126 static void cirdna_DrawArrowHeadsOncurve(float xDraw, float yDraw,
127 float RealLength, float Height,
128 float Length, float Radius,
129 float Angle, ajint Way);
130 static void cirdna_DrawBracketsOncurve(float xDraw, float yDraw,
131 float RealLength, float Height,
132 float Length, float Radius,
133 float Angle, ajint Way);
134 static void cirdna_DrawBarsOncurve(float xDraw, float yDraw,
135 float Height, float Radius,
136 float Angle);
137 static void cirdna_HorTextPile(float x, float y, float Radius,
138 float StartAngle, float EndAngle,
139 const AjPStr Name2,
140 float postext, ajint NumNames);
141 static float cirdna_HorTextPileHeight(float postext, ajint NumNames);
142 static float cirdna_HorTextPileLengthMax(const AjPStr Name2, ajint NumNames);
143 static float cirdna_ComputeAngle(float RealLength, float Length,
144 float OriginAngle);
145 static float cirdna_ComputeArc(float RealLength, float Length);
146
147
148
149 static AjPStr** Style=NULL;
150 static AjPStr** Name=NULL;
151 /*static AjPStr Style[MAXGROUPS][MAXLABELS]; */
152 /*static AjPStr Name[MAXGROUPS][MAXLABELS];*/
153
154 static ajint cirdnaMaxinter=0;
155 static ajint* cirdnaInter=NULL;
156 /*ajint Inter[MAXLABELS];*/
157
158
159 static float* cirdnaFromText=NULL;
160 static float* cirdnaToText=NULL;
161 /* float FromText[MAXLABELS];*/
162 /* float ToText[MAXLABELS];*/
163
164
165
166
167 /* @prog cirdna ***************************************************************
168 **
169 ** Draws circular maps of DNA constructs
170 **
171 ******************************************************************************/
172
main(int argc,char ** argv)173 int main(int argc, char **argv)
174 {
175 AjPGraph graph;
176 ajint i;
177 ajint j;
178 ajint GapSize;
179 ajint* NumLabels;
180 ajint** NumNames;
181 /* ajint NumNames[MAXGROUPS][MAXLABELS];*/
182 ajint NumGroups;
183 ajint InterColour;
184 ajint** Colour;
185 ajint** Adjust;
186 ajint* AdjustMax=NULL;
187 char** FromSymbol=NULL;
188 char** ToSymbol=NULL;
189 /* ajint Colour[MAXGROUPS][MAXLABELS];*/
190 /* ajint Adjust[MAXGROUPS][MAXLABELS];*/
191 /* ajint AdjustMax[MAXGROUPS];*/
192 /* char FromSymbol[MAXGROUPS][MAXLABELS];*/
193 /* char ToSymbol[MAXGROUPS][MAXLABELS];*/
194 float xDraw;
195 float yDraw;
196 float Radius;
197 float RadiusMax;
198 float DrawRadius;
199 float OriginAngle;
200 float** From=NULL;
201 float** To=NULL;
202 /* float From[MAXGROUPS][MAXLABELS];*/
203 /* float To[MAXGROUPS][MAXLABELS];*/
204 float TotalHeight;
205 float* GroupHeight=NULL;
206 /* float GroupHeight[MAXGROUPS];*/
207 float RulerHeight;
208 float Width;
209 float Height;
210 float Border;
211 float Start;
212 float End;
213 float DrawLength;
214 float RealLength;
215 float TickHeight;
216 float BlockHeight;
217 float RangeHeight;
218 float TextLength;
219 float TextHeight;
220 float GapGroup;
221 float posblock;
222 float posrange;
223 float postext;
224 AjPFile infile;
225 AjPStr line;
226 AjPStr* GroupName=NULL;
227 /* AjPStr GroupName[MAXGROUPS];*/
228 AjBool Ruler;
229 AjBool InterSymbol;
230 AjBool InterTicks;
231 AjPStr PosTicks;
232 AjBool TickLines;
233 AjPStr BlockType;
234 AjPStr PosBlocks;
235 float charsize;
236 float minsize;
237 ajint maxgroups;
238 ajint maxlabels;
239
240 /* read the ACD file for graphical programs */
241 embInit("cirdna", argc, argv);
242
243 /* array size limits */
244 maxgroups = ajAcdGetInt("maxgroups");
245 maxlabels = ajAcdGetInt("maxlabels");
246
247 /* to draw or not to draw the ruler */
248 Ruler = ajAcdGetBoolean("ruler");
249
250 /* get the type of blocks */
251 BlockType = ajAcdGetListSingle("blocktype");
252
253 /* get the angle of the molecule's origin */
254 OriginAngle = ajAcdGetFloat("originangle");
255
256 /* get the position of the ticks */
257 PosTicks = ajAcdGetSelectSingle("posticks");
258
259 /* get the position of the text for blocks */
260 PosBlocks = ajAcdGetSelectSingle("posblocks");
261
262 /* to draw or not to draw junctions to link blocks */
263 InterSymbol = ajAcdGetBoolean("intersymbol");
264 /* get the colour of junctions used to link blocks */
265 InterColour = ajAcdGetInt("intercolour");
266
267 /* to draw or not to draw junctions between ticks */
268 InterTicks = ajAcdGetBoolean("interticks");
269
270 /* get the size of the intervals between the ruler's ticks */
271 GapSize = ajAcdGetInt("gapsize");
272 /* to draw or not to draw vertical lines at ruler's ticks */
273 TickLines = ajAcdGetBoolean("ticklines");
274
275
276 /* set the output graphical context */
277 graph = ajAcdGetGraph("graphout");
278
279 /* get the input file */
280 infile = ajAcdGetInfile("infile");
281
282 /* Allocate memory for the old fixed-length arrays */
283
284 AJCNEW0(Style, maxgroups);
285 AJCNEW0(Name, maxgroups);
286 AJCNEW0(NumNames, maxgroups);
287 AJCNEW0(NumLabels, maxgroups);
288 AJCNEW0(Colour, maxgroups);
289 AJCNEW0(Adjust, maxgroups);
290 AJCNEW0(AdjustMax, maxgroups);
291 AJCNEW0(FromSymbol, maxgroups);
292 AJCNEW0(ToSymbol, maxgroups);
293 AJCNEW0(From, maxgroups);
294 AJCNEW0(To, maxgroups);
295 AJCNEW0(GroupHeight, maxgroups);
296 AJCNEW0(GroupName, maxgroups);
297
298 /* length and height of text */
299 /*TextHeight = 10;
300 TextLength = TextHeight+25;*/
301 TextHeight = 2*ajAcdGetFloat("textheight");
302 TextLength = 7*ajAcdGetFloat("textlength");
303
304
305 /* read the start and end positions */
306 if(!cirdna_ReadInput(infile, &Start, &End))
307 ajFatal("Error processing input file");
308
309 /* compute the real length of the molecule */
310 RealLength = (End - Start) + 1;
311
312 /* height of a tick, a block, and a range */
313 TickHeight = 3*ajAcdGetFloat("tickheight");
314 if( ajStrMatchCaseC(PosBlocks, "Out") )
315 BlockHeight = 3*ajAcdGetFloat("blockheight");
316 else
317 {
318 BlockHeight = (TextHeight+3)*ajAcdGetFloat("blockheight");
319 if(BlockHeight<(TextHeight+3) )
320 BlockHeight = (TextHeight+3);
321 }
322 RangeHeight = 3*ajAcdGetFloat("rangeheight");
323
324 /* set the relative positions of elements of a group */
325 posblock = 0;
326 posrange = 0;
327 GapGroup = 3*ajAcdGetFloat("gapgroup");
328
329 ajGraphAppendTitleS(graph, ajFileGetPrintnameS(infile));
330
331 /* open the window in which the graphics will be drawn */
332 ajGraphOpenMm(graph, &Width, &Height);
333
334 Border = (float) 2.0 * (TickHeight+TextLength);
335 DrawLength = Height - 2*Border;
336
337 /* coordinates of the circle's center */
338 xDraw = Width/(float)2.0;
339 yDraw = Height/(float)2.0;
340
341 /* radius of the outermost circle */
342 Radius = RadiusMax = DrawLength/(float)2.0;
343
344 /* read the contents of the groups */
345 line = ajStrNew();
346 ajFileSeek(infile, 0L, 0);
347 i = 0;
348 while( ajReadlineTrim(infile, &line) )
349 {
350 if( ajStrPrefixC(line, "group") )
351 {
352 if (i == maxgroups)
353 ajWarn("Too many groups (maxgroups=%d) in input", maxgroups);
354 if (i < maxgroups)
355 {
356 AJCNEW0(Style[i], maxlabels);
357 AJCNEW0(Name[i], maxlabels);
358 AJCNEW0(NumNames[i], maxlabels);
359 AJCNEW0(Colour[i], maxlabels);
360 AJCNEW0(Adjust[i], maxlabels);
361 AJCNEW0(FromSymbol[i], maxlabels);
362 AJCNEW0(ToSymbol[i], maxlabels);
363 AJCNEW0(From[i], maxlabels);
364 AJCNEW0(To[i], maxlabels);
365
366 GroupName[i] = cirdna_ReadGroup(infile, maxlabels,
367 From[i], To[i],
368 Name[i],
369 FromSymbol[i], ToSymbol[i],
370 Style[i], &NumLabels[i],
371 NumNames[i], Colour[i]);
372 j = NumLabels[i];
373 AJCRESIZE(Style[i], j);
374 AJCRESIZE(Name[i], j);
375 AJCRESIZE(NumNames[i], j);
376 AJCRESIZE(Colour[i], j);
377 AJCRESIZE(Adjust[i], j);
378 AJCRESIZE(FromSymbol[i], j);
379 AJCRESIZE(ToSymbol[i], j);
380 AJCRESIZE(From[i], j);
381 AJCRESIZE(To[i], j);
382 }
383 i++;
384 }
385 }
386 NumGroups = i;
387
388 AJCRESIZE(Style, i);
389 AJCRESIZE(Name, i);
390 AJCRESIZE(NumNames, i);
391 AJCRESIZE(NumLabels, i);
392 AJCRESIZE(Colour, i);
393 AJCRESIZE(Adjust, i);
394 AJCRESIZE(AdjustMax, i);
395 AJCRESIZE(FromSymbol, i);
396 AJCRESIZE(ToSymbol, i);
397 AJCRESIZE(From, i);
398 AJCRESIZE(To, i);
399 AJCRESIZE(GroupHeight, i);
400 AJCRESIZE(GroupName, i);
401
402 /* remove the beginning of the molecule in case it doesn't begin at 1 */
403 if (Start != 1)
404 {
405 for(i=0; i<NumGroups; i++)
406 for(j=0; j<NumLabels[i]; j++)
407 {
408 From[i][j] -= (Start-1);
409 To[i][j] -= (Start-1);
410 }
411 }
412
413 /* compute the character size that fits all groups, including the ruler */
414 minsize = 100.0;
415 charsize = cirdna_TextRuler(Start, End, GapSize, TextLength, TextHeight,
416 PosTicks, NumGroups, NumLabels);
417 if( charsize<minsize ) minsize = charsize;
418 ajDebug("Calculated charsize: %f minsize:%f\n", charsize, minsize);
419 for(i=0; i<NumGroups; i++)
420 {
421 charsize = cirdna_TextGroup(TextHeight, TextLength, Name[i],
422 NumLabels[i], NumNames[i],
423 Style[i], From[i], To[i],
424 PosTicks);
425 if( charsize<minsize )
426 minsize = charsize;
427 }
428 ajGraphicsSetDefcharsize(minsize);
429 ajDebug("Initial charsize: %f\n", minsize);
430
431
432 /* find whether horizontal text strings overlap within a group */
433 postext = (ajGraphicsCalcTextheight()+1)*ajAcdGetFloat("postext");
434 for(i=0; i<NumGroups; i++)
435 AdjustMax[i] = cirdna_OverlapTextGroup(Name[i], Style[i], NumLabels[i],
436 From[i], To[i], Start, End,
437 PosTicks, Adjust[i]);
438
439
440 /* compute the height of the ruler */
441 RulerHeight = cirdna_HeightRuler(Start, End, GapSize, postext, TickHeight,
442 PosTicks, NumGroups, NumLabels);
443 if(!RulerHeight)
444 ajDebug("Err: Ruler height");
445
446 /* compute the height of the groups */
447 TotalHeight = 0.0;
448 for(i=0; i<NumGroups; i++)
449 {
450 GroupHeight[i] = cirdna_HeightGroup(postext,
451 TickHeight, BlockHeight,
452 RangeHeight, Style[i],
453 NumLabels[i],
454 PosTicks, PosBlocks, AdjustMax[i]);
455 TotalHeight += (GroupHeight[i]+GapGroup);
456 }
457
458 /*
459 ** decrease the radius such that the innermost group is not
460 ** compressed in the centre of the circle
461 */
462 DrawRadius = Radius - (TotalHeight/NumGroups);
463
464 /*
465 ** if the groups are too big, resize them such that they fit in the
466 ** window
467 */
468 if(TotalHeight<DrawRadius)
469 TotalHeight = DrawRadius;
470 TickHeight/=(TotalHeight/DrawRadius);
471 BlockHeight/=(TotalHeight/DrawRadius);
472 RangeHeight/=(TotalHeight/DrawRadius);
473 TextHeight/=(TotalHeight/DrawRadius);
474 TextLength/=(TotalHeight/DrawRadius);
475 postext/=(TotalHeight/DrawRadius);
476 posblock/=(TotalHeight/DrawRadius);
477 posrange/=(TotalHeight/DrawRadius);
478 GapGroup/=(TotalHeight/DrawRadius);
479
480 /*
481 ** the groups having been resized, recompute the character size that
482 ** fits all groups, including the ruler
483 */
484 minsize = 100.0;
485 charsize = cirdna_TextRulerStr(Start, End, GapSize,
486 (TotalHeight/DrawRadius),
487 PosTicks, NumGroups, NumLabels);
488 ajDebug("Resized calculated charsize: %f minsize:%f\n", charsize, minsize);
489 if(charsize<minsize)
490 minsize = charsize;
491 for(i=0; i<NumGroups; i++)
492 {
493 charsize = cirdna_TextGroupStr(Name[i], NumLabels[i], NumNames[i],
494 (TotalHeight/DrawRadius),
495 Style[i], From[i], To[i],
496 PosTicks);
497 if(charsize<minsize)
498 minsize = charsize;
499 }
500 ajGraphicsSetDefcharsize(minsize);
501 ajDebug("Resized charsize: %f\n", minsize);
502
503
504 /* the ruler having been resized, recompute its height */
505 RulerHeight = cirdna_HeightRuler(Start, End, GapSize, postext, TickHeight,
506 PosTicks, NumGroups, NumLabels);
507 /* the groups having been resized, recompute their height */
508 TotalHeight = 0.0;
509 for(i=0; i<NumGroups; i++)
510 {
511 GroupHeight[i] = cirdna_HeightGroup(postext,
512 TickHeight, BlockHeight,
513 RangeHeight,
514 Style[i], NumLabels[i],
515 PosTicks, PosBlocks,
516 AdjustMax[i]);
517 TotalHeight += (GroupHeight[i]+GapGroup);
518 }
519
520 /* draw the ruler */
521 if(Ruler)
522 cirdna_DrawRuler(xDraw, yDraw, Start, End,
523 RealLength, Radius, TickHeight,
524 OriginAngle, GapSize, TickLines,
525 postext, NumGroups, NumLabels,
526 From, PosTicks, 1);
527
528 /* draw the groups */
529 for(i=0; i<NumGroups; i++)
530 {
531 Radius -= (GroupHeight[i]+GapGroup);
532 cirdna_DrawGroup(xDraw, yDraw, posblock, posrange, postext, TickHeight,
533 BlockHeight, RangeHeight, RealLength,
534 Radius, RadiusMax, From[i], To[i],
535 Name[i], FromSymbol[i], ToSymbol[i], Style[i],
536 InterSymbol, InterTicks, NumLabels[i],
537 OriginAngle, NumNames[i], PosTicks, PosBlocks,
538 Adjust[i], InterColour, Colour[i], BlockType);
539 ajStrDel(&GroupName[i]);
540 }
541
542
543 /* close the input file */
544 ajFileClose(&infile);
545 ajStrDel(&line);
546
547 ajStrDel(&PosTicks);
548 ajStrDel(&PosBlocks);
549 ajStrDel(&BlockType);
550
551 /* close the graphical window */
552 ajGraphicsClose();
553 ajGraphxyDel(&graph);
554
555 for(i=0;i<NumGroups;i++)
556 {
557 for(j=0;j<NumLabels[i];j++)
558 {
559 ajStrDel(&Style[i][j]);
560 ajStrDel(&Name[i][j]);
561 }
562 ajStrDel(&GroupName[i]);
563 AJFREE(NumNames[i]);
564 AJFREE(Colour[i]);
565 AJFREE(Adjust[i]);
566 AJFREE(FromSymbol[i]);
567 AJFREE(ToSymbol[i]);
568 AJFREE(From[i]);
569 AJFREE(To[i]);
570 AJFREE(Name[i]);
571 AJFREE(Style[i]);
572 }
573 AJFREE(AdjustMax);
574 AJFREE(GroupHeight);
575 AJFREE(NumLabels);
576 AJFREE(GroupName);
577 AJFREE(NumNames);
578 AJFREE(Style);
579 AJFREE(Name);
580 AJFREE(Colour);
581 AJFREE(Adjust);
582 AJFREE(FromSymbol);
583 AJFREE(ToSymbol);
584 AJFREE(From);
585 AJFREE(To);
586 AJFREE(cirdnaInter);
587 AJFREE(cirdnaFromText);
588 AJFREE(cirdnaToText);
589
590 embExit();
591
592 return 0;
593 }
594
595
596
597
598 /* @funcstatic cirdna_TextRuler ***********************************************
599 **
600 ** Compute the character size that fits all elements of the ruler
601 ** provided that the height and the length of all strings are at
602 ** most TextHeight and TextLength, respectively
603 **
604 ** @param [r] Start [float] Undocumented
605 ** @param [r] End [float] Undocumented
606 ** @param [r] GapSize [ajint] Undocumented
607 ** @param [r] TextLength [float] Undocumented
608 ** @param [r] TextHeight [float] Undocumented
609 ** @param [r] PosTicks [const AjPStr] Undocumented
610 ** @param [r] NumGroups [ajint] Undocumented
611 ** @param [r] NumLabels [const ajint*] Undocumented
612 ** @return [float] Undocumented
613 ** @@
614 ******************************************************************************/
615
cirdna_TextRuler(float Start,float End,ajint GapSize,float TextLength,float TextHeight,const AjPStr PosTicks,ajint NumGroups,const ajint * NumLabels)616 static float cirdna_TextRuler(float Start, float End, ajint GapSize,
617 float TextLength, float TextHeight,
618 const AjPStr PosTicks, ajint NumGroups,
619 const ajint *NumLabels)
620 {
621 ajint i;
622 ajint j;
623 const AjPStr token;
624 AjPStr string;
625 float charsize;
626 float minsize = 100.0;
627
628 string = ajStrNew();
629
630 ajStrFromInt(&string, (ajint)Start);
631 charsize = ajGraphicsCalcCharsize(0, 0, TextLength, TextLength,
632 ajStrGetPtr(string), TextHeight );
633 if(charsize < minsize)
634 minsize = charsize;
635
636 for(i=GapSize; i<End; i+=GapSize)
637 if(i>Start)
638 {
639 ajStrFromInt(&string, i);
640 charsize = ajGraphicsCalcCharsize(0, 0, TextLength, TextLength,
641 ajStrGetPtr(string), TextHeight );
642 if(charsize < minsize)
643 minsize = charsize;
644 }
645
646 for(i=0; i<NumGroups; i++)
647 for(j=0; j<NumLabels[i]; j++)
648 if(ajStrMatchCaseC(Style[i][j], "Tick") &&
649 ajStrMatchCaseC(PosTicks, "Out") )
650 {
651 token = ajStrParseC(Name[i][j], ";");
652 charsize = ajGraphicsCalcCharsize( 0, 0, TextLength,
653 TextLength,
654 ajStrGetPtr(token),
655 TextHeight );
656 if(charsize < minsize)
657 minsize = charsize;
658 }
659
660 ajStrDel(&string);
661
662 return minsize;
663 }
664
665
666
667
668 /* @funcstatic cirdna_TextRulerStr ********************************************
669 **
670 ** compute the character size that fits all elements of the ruler provided
671 ** that the height and the length of all strings are multiplied by TextCoef
672 **
673 ** @param [r] Start [float] Undocumented
674 ** @param [r] End [float] Undocumented
675 ** @param [r] GapSize [ajint] Undocumented
676 ** @param [r] TextCoef [float] Undocumented
677 ** @param [r] PosTicks [const AjPStr] Undocumented
678 ** @param [r] NumGroups [ajint] Undocumented
679 ** @param [r] NumLabels [const ajint*] Undocumented
680 ** @return [float] Undocumented
681 ** @@
682 ******************************************************************************/
683
cirdna_TextRulerStr(float Start,float End,ajint GapSize,float TextCoef,const AjPStr PosTicks,ajint NumGroups,const ajint * NumLabels)684 static float cirdna_TextRulerStr(float Start, float End, ajint GapSize,
685 float TextCoef, const AjPStr PosTicks,
686 ajint NumGroups, const ajint *NumLabels)
687 {
688 ajint i;
689 ajint j;
690 const AjPStr token;
691 AjPStr string;
692 float charsize;
693 float minsize = 100.0;
694 float stringLength;
695 float stringHeight;
696
697 string = ajStrNew();
698
699 ajStrFromInt(&string, (ajint)Start);
700 stringLength = ajGraphicsCalcTextlengthS(string);
701 stringHeight = ajGraphicsCalcTextheight();
702 charsize = ajGraphicsCalcCharsize(0, 0, stringLength/TextCoef,
703 stringLength/TextCoef,
704 ajStrGetPtr(string),
705 stringHeight/TextCoef );
706 if( charsize < minsize ) minsize = charsize;
707
708 for(i=GapSize; i<End; i+=GapSize)
709 if(i>Start)
710 {
711 ajStrFromInt(&string, i);
712 stringLength = ajGraphicsCalcTextlengthS(string);
713 stringHeight = ajGraphicsCalcTextheight();
714 charsize = ajGraphicsCalcCharsize(0, 0, stringLength/TextCoef,
715 stringLength/TextCoef,
716 ajStrGetPtr(string),
717 stringHeight/TextCoef);
718 if(charsize < minsize)
719 minsize = charsize;
720 }
721
722 for(i=0; i<NumGroups; i++)
723 for(j=0; j<NumLabels[i]; j++)
724 {
725 if( ajStrMatchCaseC(Style[i][j], "Tick") &&
726 ajStrMatchCaseC(PosTicks, "Out") )
727 {
728 token = ajStrParseC(Name[i][j], ";");
729 stringLength = ajGraphicsCalcTextlengthS(token);
730 stringHeight = ajGraphicsCalcTextheight();
731 charsize = ajGraphicsCalcCharsize(0, 0, stringLength/TextCoef,
732 stringLength/TextCoef,
733 ajStrGetPtr(token),
734 stringHeight/TextCoef );
735 if(charsize < minsize)
736 minsize = charsize;
737 }
738 }
739
740 ajStrDel(&string);
741
742 return minsize;
743 }
744
745
746
747
748 /* @funcstatic cirdna_HeightRuler *********************************************
749 **
750 ** compute the ruler's height
751 **
752 ** @param [r] Start [float] Undocumented
753 ** @param [r] End [float] Undocumented
754 ** @param [r] GapSize [ajint] Undocumented
755 ** @param [r] postext [float] Undocumented
756 ** @param [r] TickHeight [float] Undocumented
757 ** @param [r] PosTicks [const AjPStr] Undocumented
758 ** @param [r] NumGroups [ajint] Undocumented
759 ** @param [r] NumLabels [const ajint*] Undocumented
760 ** @return [float] Undocumented
761 ** @@
762 ******************************************************************************/
763
cirdna_HeightRuler(float Start,float End,ajint GapSize,float postext,float TickHeight,const AjPStr PosTicks,ajint NumGroups,const ajint * NumLabels)764 static float cirdna_HeightRuler(float Start, float End, ajint GapSize,
765 float postext, float TickHeight,
766 const AjPStr PosTicks, ajint NumGroups,
767 const ajint *NumLabels)
768 {
769 ajint i;
770 ajint j;
771 float RulerHeight;
772 float stringLength;
773 float maxLength = 0.0;
774 const AjPStr token;
775 AjPStr string;
776
777 string = ajStrNew();
778
779 RulerHeight = TickHeight+postext;
780
781 ajStrFromInt(&string, (ajint)Start);
782 stringLength = ajGraphicsCalcTextlengthS(string);
783 if(stringLength>maxLength)
784 maxLength = stringLength;
785
786 for(i=GapSize; i<End; i+=GapSize)
787 if(i>Start)
788 {
789 ajStrFromInt(&string, i);
790 stringLength = ajGraphicsCalcTextlengthS(string);
791 if(stringLength>maxLength)
792 maxLength = stringLength;
793 }
794
795 for(i=0; i<NumGroups; i++)
796 for(j=0; j<NumLabels[i]; j++)
797 if(ajStrMatchCaseC(Style[i][j], "Tick") &&
798 ajStrMatchCaseC(PosTicks, "Out") )
799 {
800 token = ajStrParseC(Name[i][j], ";");
801 stringLength = ajGraphicsCalcTextlengthS(token);
802 if( stringLength>maxLength )
803 maxLength = stringLength;
804 }
805
806 RulerHeight += maxLength;
807
808 ajStrDel(&string);
809
810 return RulerHeight;
811 }
812
813
814
815
816 /* @funcstatic cirdna_DrawRuler ***********************************************
817 **
818 ** draw a ruler
819 **
820 ** @param [r] xDraw [float] Undocumented
821 ** @param [r] yDraw [float] Undocumented
822 ** @param [r] Start [float] Undocumented
823 ** @param [r] End [float] Undocumented
824 ** @param [r] RealLength [float] Undocumented
825 ** @param [r] Radius [float] Undocumented
826 ** @param [r] TickHeight [float] Undocumented
827 ** @param [r] OriginAngle [float] Undocumented
828 ** @param [r] GapSize [ajint] Undocumented
829 ** @param [r] TickLines [AjBool] Undocumented
830 ** @param [r] postext [float] Undocumented
831 ** @param [r] NumGroups [ajint] Undocumented
832 ** @param [r] NumLabels [const ajint*] Undocumented
833 ** @param [r] From [float* const *] Undocumented
834 ** @param [r] PosTicks [const AjPStr] Undocumented
835 ** @param [r] Colour [ajint] Undocumented
836 ** @@
837 ******************************************************************************/
838
cirdna_DrawRuler(float xDraw,float yDraw,float Start,float End,float RealLength,float Radius,float TickHeight,float OriginAngle,ajint GapSize,AjBool TickLines,float postext,ajint NumGroups,const ajint * NumLabels,float * const * From,const AjPStr PosTicks,ajint Colour)839 static void cirdna_DrawRuler(float xDraw, float yDraw, float Start, float End,
840 float RealLength, float Radius, float TickHeight,
841 float OriginAngle, ajint GapSize,
842 AjBool TickLines, float postext,
843 ajint NumGroups, const ajint *NumLabels,
844 float* const * From,
845 const AjPStr PosTicks, ajint Colour)
846 {
847 ajint i;
848 AjPStr string;
849 AjPStr posticks;
850 float *xy;
851 float Angle;
852
853 string = ajStrNew();
854 posticks = ajStrNew();
855
856 ajGraphicsSetFgcolour(Colour);
857
858 ajGraphicsDrawposCircle( xDraw, yDraw, Radius );
859
860 ajStrAssignEmptyC(&posticks, "Out");
861
862 /* set the circle's origin */
863 ajStrFromInt(&string, (ajint)Start);
864 if(TickLines)
865 {
866 Angle = cirdna_ComputeAngle(RealLength, 0, OriginAngle);
867 xy = ajGraphicsCalcCoord(xDraw, yDraw, Radius, Angle);
868 ajGraphicsDrawposLine(xDraw, yDraw, xy[0], xy[1]);
869 AJFREE(xy);
870 }
871
872 if(!cirdna_OverlapTickRuler(NumGroups, NumLabels, From, PosTicks,
873 (ajint)Start) )
874 cirdna_DrawTicks(xDraw, yDraw, RealLength, Radius, TickHeight, 0,
875 string, OriginAngle, postext,
876 posticks, 1, 0, Colour);
877
878 /* draw the ruler's ticks */
879 for(i=GapSize; i<End; i+=GapSize)
880 if(i>Start)
881 {
882 ajStrFromInt(&string, i);
883 if( TickLines )
884 {
885 Angle = cirdna_ComputeAngle(RealLength, i-Start, OriginAngle);
886 xy = ajGraphicsCalcCoord(xDraw, yDraw, Radius, Angle);
887 ajGraphicsDrawposLine(xDraw, yDraw, xy[0], xy[1]);
888 AJFREE(xy);
889 }
890 if(!cirdna_OverlapTickRuler(NumGroups, NumLabels, From, PosTicks,
891 i))
892 cirdna_DrawTicks(xDraw, yDraw, RealLength, Radius, TickHeight,
893 i-Start, string, OriginAngle,
894 postext, posticks, 1, 0, Colour);
895 }
896
897 ajStrDel(&string);
898 ajStrDel(&posticks);
899
900 return;
901 }
902
903
904
905
906 /* @funcstatic cirdna_DrawTicks ***********************************************
907 **
908 ** draw a Tick
909 **
910 ** @param [r] xDraw [float] Undocumented
911 ** @param [r] yDraw [float] Undocumented
912 ** @param [r] RealLength [float] Undocumented
913 ** @param [r] Radius [float] Undocumented
914 ** @param [r] TickHeight [float] Undocumented
915 ** @param [r] From [float] Undocumented
916 ** @param [r] Name2 [const AjPStr] Undocumented
917 ** @param [r] OriginAngle [float] Undocumented
918 ** @param [r] postext [float] Undocumented
919 ** @param [r] PosTicks [const AjPStr] Undocumented
920 ** @param [r] NumNames [ajint] Undocumented
921 ** @param [r] Adjust [ajint] Undocumented
922 ** @param [r] Colour [ajint] Undocumented
923 ** @@
924 ******************************************************************************/
925
cirdna_DrawTicks(float xDraw,float yDraw,float RealLength,float Radius,float TickHeight,float From,const AjPStr Name2,float OriginAngle,float postext,const AjPStr PosTicks,ajint NumNames,ajint Adjust,ajint Colour)926 static void cirdna_DrawTicks(float xDraw, float yDraw, float RealLength,
927 float Radius, float TickHeight, float From,
928 const AjPStr Name2, float OriginAngle,
929 float postext,
930 const AjPStr PosTicks,
931 ajint NumNames, ajint Adjust,
932 ajint Colour)
933 {
934 float Angle;
935 float StartAngle;
936 float EndAngle;
937 float *xy1;
938 float *xy2;
939 float *xy3;
940 float stringLength;
941 float r1Ticks = Radius;
942 float r2Ticks = r1Ticks+TickHeight;
943 const AjPStr token;
944 float mmtolen;
945
946 /* radius is 2pi*radius in mm, RealLength in bases */
947 mmtolen = RealLength/(Radius * (float) 2.0 * (float) 3.1416);
948
949 ajGraphicsSetFgcolour(Colour);
950
951 Angle = cirdna_ComputeAngle(RealLength, From, OriginAngle);
952
953 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, r1Ticks, Angle);
954 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, r2Ticks, Angle);
955 ajGraphicsDrawposLine(xy1[0], xy1[1], xy2[0], xy2[1] );
956 AJFREE(xy1);
957 AJFREE(xy2);
958
959 if(ajStrMatchCaseC(PosTicks, "In") )
960 {
961 stringLength = mmtolen * cirdna_HorTextPileLengthMax(Name2, NumNames);
962 StartAngle = cirdna_ComputeAngle(RealLength, From+stringLength/2,
963 OriginAngle);
964 EndAngle = cirdna_ComputeAngle(RealLength, From-stringLength/2,
965 OriginAngle);
966 cirdna_HorTextPile(xDraw, yDraw, r2Ticks+(Adjust*postext), StartAngle,
967 EndAngle, Name2, postext, 1);
968 }
969 else
970 {
971 token = ajStrParseC(Name2, ";");
972 /*ajStrExchangeCC(&Name2, ";", " ");*/
973 stringLength = mmtolen * ajGraphicsCalcTextlengthS(token);
974 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, r2Ticks+postext, Angle);
975 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, r2Ticks+postext+stringLength,
976 Angle);
977 xy3 = ajGraphicsCalcCoord(xDraw, yDraw, r2Ticks+postext-stringLength,
978 Angle);
979 if((Angle>=0.0 && Angle<=90.0) || (Angle>=270.0 && Angle<=360.0) ||
980 (Angle>=360.0 && Angle<=450.0) || (Angle>=630.0 && Angle<=720.0) )
981 ajGraphicsDrawposTextAtlineJustify( xy1[0], xy1[1], xy2[0], xy2[1],
982 ajStrGetPtr(token), 0.0 );
983 else
984 ajGraphicsDrawposTextAtlineJustify( xy1[0], xy1[1], xy3[0], xy3[1],
985 ajStrGetPtr(token), 1.0 );
986 AJFREE(xy1);
987 AJFREE(xy2);
988 AJFREE(xy3);
989 }
990
991 return;
992 }
993
994
995
996
997 /* @funcstatic cirdna_DrawBlocks **********************************************
998 **
999 ** draw a Block
1000 **
1001 ** @param [r] xDraw [float] Undocumented
1002 ** @param [r] yDraw [float] Undocumented
1003 ** @param [r] RealLength [float] Undocumented
1004 ** @param [r] Radius [float] Undocumented
1005 ** @param [r] BlockHeight [ajint] Undocumented
1006 ** @param [r] From [float] Undocumented
1007 ** @param [r] To [float] Undocumented
1008 ** @param [r] Name2 [const AjPStr] Undocumented
1009 ** @param [r] postext [float] Undocumented
1010 ** @param [r] OriginAngle [float] Undocumented
1011 ** @param [r] PosBlocks [const AjPStr] Undocumented
1012 ** @param [r] NumNames [ajint] Undocumented
1013 ** @param [r] Adjust [ajint] Undocumented
1014 ** @param [r] Colour [ajint] Undocumented
1015 ** @param [r] BlockType [const AjPStr] Undocumented
1016 ** @@
1017 ******************************************************************************/
1018
cirdna_DrawBlocks(float xDraw,float yDraw,float RealLength,float Radius,ajint BlockHeight,float From,float To,const AjPStr Name2,float postext,float OriginAngle,const AjPStr PosBlocks,ajint NumNames,ajint Adjust,ajint Colour,const AjPStr BlockType)1019 static void cirdna_DrawBlocks(float xDraw, float yDraw, float RealLength,
1020 float Radius, ajint BlockHeight, float From,
1021 float To, const AjPStr Name2, float postext,
1022 float OriginAngle, const AjPStr PosBlocks,
1023 ajint NumNames, ajint Adjust, ajint Colour,
1024 const AjPStr BlockType)
1025 {
1026 float StartAngle;
1027 float EndAngle;
1028 float stringLength;
1029 float stringHeight;
1030 float r1Blocks;
1031 float r2Blocks;
1032 float mmtolen;
1033
1034 /* radius is 2pi*radius in mm, RealLength in bases */
1035 mmtolen = RealLength/(Radius * (float) 2.0 * (float) 3.1416);
1036
1037 r1Blocks = Radius+((float)1.0*BlockHeight/(float)2);
1038 r2Blocks = r1Blocks-BlockHeight;
1039
1040 StartAngle = cirdna_ComputeAngle(RealLength, From, OriginAngle);
1041 EndAngle = cirdna_ComputeAngle(RealLength, To, OriginAngle);
1042
1043 ajGraphicsSetFgcolour(Colour);
1044 if(ajCharCmpCase(ajStrGetPtr(BlockType), "Open")==0 )
1045 ajGraphicsDrawarcRect(xDraw, yDraw, r2Blocks,
1046 StartAngle, EndAngle, (float)BlockHeight);
1047 else if( ajCharCmpCase(ajStrGetPtr(BlockType), "Filled")==0 )
1048 ajGraphicsDrawarcRectFill(xDraw, yDraw, r2Blocks,
1049 StartAngle, EndAngle, (float)BlockHeight);
1050 else
1051 {
1052 ajGraphicsDrawarcRectFill(xDraw, yDraw, r2Blocks,
1053 StartAngle, EndAngle, (float)BlockHeight);
1054 ajGraphicsSetFgcolour(0);
1055 ajGraphicsDrawarcRect(xDraw, yDraw, r2Blocks,
1056 StartAngle, EndAngle, (float)BlockHeight);
1057 ajGraphicsSetFgcolour(Colour);
1058 }
1059
1060 stringLength = mmtolen * cirdna_HorTextPileLengthMax(Name2, NumNames);
1061 stringHeight = ajGraphicsCalcTextheight();
1062 StartAngle = cirdna_ComputeAngle(RealLength,
1063 (To+From)/2 + stringLength/2,
1064 OriginAngle);
1065 EndAngle = cirdna_ComputeAngle(RealLength,
1066 (To+From)/2 - stringLength/2,
1067 OriginAngle);
1068
1069 if(ajStrMatchCaseC(PosBlocks, "Out") )
1070 cirdna_HorTextPile(xDraw, yDraw, r1Blocks+Adjust*postext, StartAngle,
1071 EndAngle, Name2, postext, 1);
1072 else
1073 cirdna_HorTextPile(xDraw, yDraw,
1074 (r1Blocks+r2Blocks)/2-(stringHeight/2)-postext,
1075 StartAngle, EndAngle, Name2, postext, 1);
1076
1077 return;
1078 }
1079
1080
1081
1082
1083 /* @funcstatic cirdna_DrawRanges **********************************************
1084 **
1085 ** draw a Range
1086 **
1087 ** @param [r] xDraw [float] Undocumented
1088 ** @param [r] yDraw [float] Undocumented
1089 ** @param [r] RealLength [float] Undocumented
1090 ** @param [r] Radius [float] Undocumented
1091 ** @param [r] RangeHeight [float] Undocumented
1092 ** @param [r] From [float] Undocumented
1093 ** @param [r] To [float] Undocumented
1094 ** @param [r] FromSymbol [char] Undocumented
1095 ** @param [r] ToSymbol [char] Undocumented
1096 ** @param [r] Name2 [const AjPStr] Undocumented
1097 ** @param [r] OriginAngle [float] Undocumented
1098 ** @param [r] NumNames [ajint] Undocumented
1099 ** @param [r] postext [float] Undocumented
1100 ** @param [r] Adjust [ajint] Undocumented
1101 ** @param [r] Colour [ajint] Undocumented
1102 ** @@
1103 ******************************************************************************/
1104
cirdna_DrawRanges(float xDraw,float yDraw,float RealLength,float Radius,float RangeHeight,float From,float To,char FromSymbol,char ToSymbol,const AjPStr Name2,float OriginAngle,ajint NumNames,float postext,ajint Adjust,ajint Colour)1105 static void cirdna_DrawRanges(float xDraw, float yDraw, float RealLength,
1106 float Radius, float RangeHeight, float From,
1107 float To, char FromSymbol, char ToSymbol,
1108 const AjPStr Name2, float OriginAngle,
1109 ajint NumNames, float postext, ajint Adjust,
1110 ajint Colour)
1111 {
1112 float StartAngle;
1113 float EndAngle;
1114 float stringLength;
1115 float rRanges = Radius;
1116 float rupper;
1117 float BoundaryLength;
1118 float mmtolen;
1119
1120 /* radius is 2pi*radius in mm, RealLength in bases */
1121 mmtolen = RealLength/(Radius * (float) 2.0 * (float) 3.1416);
1122
1123 rupper = rRanges+((float)1.0*RangeHeight/(float)2);
1124
1125 ajGraphicsSetFgcolour(Colour);
1126
1127 StartAngle = cirdna_ComputeAngle(RealLength, From, OriginAngle);
1128 EndAngle = cirdna_ComputeAngle(RealLength, To, OriginAngle);
1129 ajGraphicsDrawarcArc(xDraw, yDraw, rRanges, StartAngle, EndAngle);
1130
1131 if( RangeHeight>(From-To)/3 )
1132 BoundaryLength = (From-To)/3;
1133 else
1134 BoundaryLength = RangeHeight;
1135
1136 if(FromSymbol=='<')
1137 cirdna_DrawArrowHeadsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1138 BoundaryLength, rRanges, StartAngle,
1139 +1);
1140 if(FromSymbol=='>')
1141 cirdna_DrawArrowHeadsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1142 BoundaryLength, rRanges, StartAngle,
1143 -1);
1144 if(FromSymbol=='[')
1145 cirdna_DrawBracketsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1146 BoundaryLength, rRanges, StartAngle,
1147 +1);
1148 if(FromSymbol==']')
1149 cirdna_DrawBracketsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1150 BoundaryLength, rRanges, StartAngle,
1151 -1);
1152 if(FromSymbol=='|')
1153 cirdna_DrawBarsOncurve(xDraw, yDraw, RangeHeight,
1154 rRanges, StartAngle);
1155
1156 if(ToSymbol=='<')
1157 cirdna_DrawArrowHeadsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1158 BoundaryLength, rRanges, EndAngle,
1159 +1);
1160 if(ToSymbol=='>')
1161 cirdna_DrawArrowHeadsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1162 BoundaryLength, rRanges, EndAngle,
1163 -1);
1164 if(ToSymbol=='[')
1165 cirdna_DrawBracketsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1166 BoundaryLength, rRanges, EndAngle,
1167 +1);
1168 if(ToSymbol==']')
1169 cirdna_DrawBracketsOncurve(xDraw, yDraw, RealLength, RangeHeight,
1170 BoundaryLength, rRanges, EndAngle,
1171 -1);
1172 if(ToSymbol=='|')
1173 cirdna_DrawBarsOncurve(xDraw, yDraw, RangeHeight,
1174 rRanges, EndAngle);
1175
1176 stringLength = mmtolen * cirdna_HorTextPileLengthMax(Name2, NumNames);
1177 StartAngle = cirdna_ComputeAngle(RealLength, (To+From)/2+stringLength/2,
1178 OriginAngle);
1179 EndAngle = cirdna_ComputeAngle(RealLength, (To+From)/2-stringLength/2,
1180 OriginAngle);
1181 cirdna_HorTextPile(xDraw, yDraw, rupper+(Adjust*postext), StartAngle,
1182 EndAngle, Name2, postext, 1);
1183
1184 return;
1185 }
1186
1187
1188
1189
1190 /* @funcstatic cirdna_InterBlocks *********************************************
1191 **
1192 ** draw an InterBlock
1193 **
1194 ** @param [r] xDraw [float] Undocumented
1195 ** @param [r] yDraw [float] Undocumented
1196 ** @param [r] RealLength [float] Undocumented
1197 ** @param [r] Radius [float] Undocumented
1198 ** @param [r] BlockHeight [float] Undocumented
1199 ** @param [r] From [float] Undocumented
1200 ** @param [r] To [float] Undocumented
1201 ** @param [r] OriginAngle [float] Undocumented
1202 ** @param [r] InterSymbol [AjBool] Undocumented
1203 ** @param [r] Colour [ajint] Undocumented
1204 ** @@
1205 ******************************************************************************/
1206
cirdna_InterBlocks(float xDraw,float yDraw,float RealLength,float Radius,float BlockHeight,float From,float To,float OriginAngle,AjBool InterSymbol,ajint Colour)1207 static void cirdna_InterBlocks(float xDraw, float yDraw, float RealLength,
1208 float Radius, float BlockHeight, float From,
1209 float To, float OriginAngle,
1210 AjBool InterSymbol, ajint Colour)
1211 {
1212 float StartAngle;
1213 float EndAngle;
1214 float r1Inter;
1215 float r2Inter;
1216
1217
1218 r1Inter = Radius+((float)1.0*BlockHeight/(float)2);
1219 r2Inter = r1Inter-BlockHeight;
1220
1221 ajGraphicsSetFgcolour(Colour);
1222
1223 StartAngle = cirdna_ComputeAngle(RealLength, To, OriginAngle);
1224 EndAngle = cirdna_ComputeAngle(RealLength, From, OriginAngle);
1225
1226 if(InterSymbol)
1227 ajGraphicsDrawarcArc(xDraw, yDraw, (r1Inter+r2Inter)/2, StartAngle,
1228 EndAngle);
1229
1230 return;
1231 }
1232
1233
1234
1235
1236 /* @funcstatic cirdna_ComputeAngle ********************************************
1237 **
1238 ** compute the angle at the Length position
1239 **
1240 ** @param [r] RealLength [float] Undocumented
1241 ** @param [r] Length [float] Undocumented
1242 ** @param [r] OriginAngle [float] Undocumented
1243 ** @return [float] Undocumented
1244 ** @@
1245 ******************************************************************************/
1246
cirdna_ComputeAngle(float RealLength,float Length,float OriginAngle)1247 static float cirdna_ComputeAngle(float RealLength, float Length,
1248 float OriginAngle)
1249 {
1250 float i;
1251 float j;
1252
1253 i = Length/RealLength;
1254 j = i * 360 - OriginAngle;
1255
1256 return 360-j;
1257 }
1258
1259
1260
1261
1262 /* @funcstatic cirdna_ComputeArc ********************************************
1263 **
1264 ** compute the angle covering the length as a fraction of the real length
1265 **
1266 ** @param [r] RealLength [float] Undocumented
1267 ** @param [r] Length [float] Undocumented
1268 ** @return [float] Undocumented
1269 ** @@
1270 ******************************************************************************/
1271
cirdna_ComputeArc(float RealLength,float Length)1272 static float cirdna_ComputeArc(float RealLength, float Length)
1273 {
1274 float i;
1275 float j;
1276
1277 i = Length/RealLength;
1278 j = i * 360;
1279
1280 return j;
1281 }
1282
1283
1284
1285
1286 /* @funcstatic cirdna_DrawArrowHeadsOncurve ***********************************
1287 **
1288 ** draw arrowheads on a curve
1289 **
1290 ** @param [r] xDraw [float] Undocumented
1291 ** @param [r] yDraw [float] Undocumented
1292 ** @param [r] RealLength [float] Undocumented
1293 ** @param [r] Height [float] Undocumented
1294 ** @param [r] Length [float] Undocumented
1295 ** @param [r] Radius [float] Undocumented
1296 ** @param [r] Angle [float] Undocumented
1297 ** @param [r] Way [ajint] Undocumented
1298 ** @@
1299 ******************************************************************************/
1300
cirdna_DrawArrowHeadsOncurve(float xDraw,float yDraw,float RealLength,float Height,float Length,float Radius,float Angle,ajint Way)1301 static void cirdna_DrawArrowHeadsOncurve(float xDraw, float yDraw,
1302 float RealLength, float Height,
1303 float Length, float Radius,
1304 float Angle, ajint Way)
1305 {
1306 float *xy1;
1307 float *xy2;
1308 float pos;
1309 float middle;
1310
1311
1312 middle = (float)1.0*Height/(float)2;
1313
1314 pos = cirdna_ComputeArc(RealLength, Length);
1315 if(pos < 1.0)
1316 pos = 1.0;
1317
1318 if(Way==1)
1319 {
1320 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius, Angle);
1321 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius+middle, Angle+pos);
1322 ajGraphicsDrawposLine( xy1[0], xy1[1], xy2[0], xy2[1] );
1323 AJFREE(xy2);
1324 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius-middle, Angle+pos);
1325 ajGraphicsDrawposLine( xy1[0], xy1[1], xy2[0], xy2[1] );
1326 AJFREE(xy1);
1327 AJFREE(xy2);
1328 }
1329
1330 if(Way==-1)
1331 {
1332 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius+middle, Angle-pos);
1333 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius, Angle);
1334 ajGraphicsDrawposLine( xy1[0], xy1[1], xy2[0], xy2[1] );
1335 AJFREE(xy1);
1336 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius-middle, Angle-pos);
1337 ajGraphicsDrawposLine( xy1[0], xy1[1], xy2[0], xy2[1] );
1338 AJFREE(xy1);
1339 AJFREE(xy2);
1340 }
1341
1342 return;
1343 }
1344
1345
1346
1347
1348 /* @funcstatic cirdna_DrawBracketsOncurve *************************************
1349 **
1350 ** draw brackets on a curve
1351 **
1352 ** @param [r] xDraw [float] Undocumented
1353 ** @param [r] yDraw [float] Undocumented
1354 ** @param [r] RealLength [float] Undocumented
1355 ** @param [r] Height [float] Undocumented
1356 ** @param [r] Length [float] Undocumented
1357 ** @param [r] Radius [float] Undocumented
1358 ** @param [r] Angle [float] Undocumented
1359 ** @param [r] Way [ajint] Undocumented
1360 ** @@
1361 ******************************************************************************/
1362
cirdna_DrawBracketsOncurve(float xDraw,float yDraw,float RealLength,float Height,float Length,float Radius,float Angle,ajint Way)1363 static void cirdna_DrawBracketsOncurve(float xDraw, float yDraw,
1364 float RealLength, float Height,
1365 float Length, float Radius,
1366 float Angle, ajint Way)
1367 {
1368 float *xy1;
1369 float *xy2;
1370 float pos;
1371 float middle;
1372
1373 middle = (float)1.0*Height/(float)2;
1374
1375 pos = cirdna_ComputeArc(RealLength, Length);
1376 if(pos < 1.0)
1377 pos = 1.0;
1378
1379 if(Way==1)
1380 {
1381 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius+middle, Angle);
1382 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius-middle, Angle);
1383 ajGraphicsDrawposLine(xy1[0], xy1[1], xy2[0], xy2[1]);
1384 AJFREE(xy1);
1385 AJFREE(xy2);
1386
1387 ajGraphicsDrawarcArc(xDraw, yDraw, Radius+middle, Angle-pos, Angle);
1388 ajGraphicsDrawarcArc(xDraw, yDraw, Radius-middle, Angle-pos, Angle);
1389 }
1390
1391 if(Way==-1)
1392 {
1393 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius+middle, Angle);
1394 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius-middle, Angle);
1395 ajGraphicsDrawposLine(xy1[0], xy1[1], xy2[0], xy2[1]);
1396 AJFREE(xy1);
1397 AJFREE(xy2);
1398 ajGraphicsDrawarcArc(xDraw, yDraw, Radius+middle, Angle, Angle+pos);
1399 ajGraphicsDrawarcArc(xDraw, yDraw, Radius-middle, Angle, Angle+pos);
1400 }
1401
1402 return;
1403 }
1404
1405
1406
1407
1408 /* @funcstatic cirdna_DrawBarsOncurve *****************************************
1409 **
1410 ** draw bars on a curve
1411 **
1412 ** @param [r] xDraw [float] Undocumented
1413 ** @param [r] yDraw [float] Undocumented
1414 ** @param [r] Height [float] Undocumented
1415 ** @param [r] Radius [float] Undocumented
1416 ** @param [r] Angle [float] Undocumented
1417 ** @return [void]
1418 ** @@
1419 ******************************************************************************/
1420
cirdna_DrawBarsOncurve(float xDraw,float yDraw,float Height,float Radius,float Angle)1421 static void cirdna_DrawBarsOncurve(float xDraw, float yDraw,
1422 float Height, float Radius,
1423 float Angle)
1424 {
1425 float *xy1;
1426 float *xy2;
1427 float middle;
1428
1429 middle = (float)1.0*Height/(float)2;
1430
1431 xy1 = ajGraphicsCalcCoord(xDraw, yDraw, Radius+middle, Angle);
1432 xy2 = ajGraphicsCalcCoord(xDraw, yDraw, Radius-middle, Angle);
1433 ajGraphicsDrawposLine( xy1[0], xy1[1], xy2[0], xy2[1] );
1434 AJFREE(xy1);
1435 AJFREE(xy2);
1436
1437 return;
1438 }
1439
1440
1441
1442
1443 /* @funcstatic cirdna_HorTextPile *********************************************
1444 **
1445 ** write a pile of horizontal text strings
1446 **
1447 ** @param [r] x [float] Undocumented
1448 ** @param [r] y [float] Undocumented
1449 ** @param [r] Radius [float] Undocumented
1450 ** @param [r] StartAngle [float] Undocumented
1451 ** @param [r] EndAngle [float] Undocumented
1452 ** @param [r] Name2 [const AjPStr] Undocumented
1453 ** @param [r] postext [float] Undocumented
1454 ** @param [r] NumNames [ajint] Undocumented
1455 ** @@
1456 ******************************************************************************/
1457
cirdna_HorTextPile(float x,float y,float Radius,float StartAngle,float EndAngle,const AjPStr Name2,float postext,ajint NumNames)1458 static void cirdna_HorTextPile(float x, float y, float Radius,
1459 float StartAngle, float EndAngle,
1460 const AjPStr Name2, float postext,
1461 ajint NumNames)
1462 {
1463 float rupper;
1464 float stringHeight;
1465 float totalHeight;
1466 const AjPStr token;
1467 ajint i;
1468
1469 totalHeight = Radius+postext;
1470 for(i=0; i<NumNames; i++)
1471 {
1472 if(i==0)
1473 token = ajStrParseC(Name2, ";");
1474 else
1475 token = ajStrParseC(NULL, ";");
1476 stringHeight = ajGraphicsCalcTextheight();
1477 rupper = totalHeight+stringHeight;
1478 if(token && ajStrGetPtr(token))
1479 ajGraphicsDrawarcTextJustify(x, y,
1480 (totalHeight+rupper)/2, StartAngle,
1481 EndAngle, ajStrGetPtr(token), 0.5);
1482 totalHeight+=(stringHeight+postext);
1483 }
1484
1485 return;
1486 }
1487
1488
1489
1490
1491 /* @funcstatic cirdna_HorTextPileHeight ***************************************
1492 **
1493 ** compute the height of a pile of horizontal text strings
1494 **
1495 ** @param [r] postext [float] Undocumented
1496 ** @param [r] NumNames [ajint] Undocumented
1497 ** @return [float] Undocumented
1498 ** @@
1499 ******************************************************************************/
1500
cirdna_HorTextPileHeight(float postext,ajint NumNames)1501 static float cirdna_HorTextPileHeight(float postext, ajint NumNames)
1502 {
1503 float stringHeight;
1504 float totalHeight;
1505 ajint i;
1506
1507 totalHeight = 0.0;
1508 for(i=0; i<NumNames; i++)
1509 {
1510 stringHeight = ajGraphicsCalcTextheight();
1511 totalHeight += (stringHeight+postext);
1512 }
1513
1514 return totalHeight;
1515 }
1516
1517
1518
1519
1520 /* @funcstatic cirdna_HorTextPileLengthMax ************************************
1521 **
1522 ** compute the maximum length of a pile of horizontal text strings
1523 ** (this is the length of the longest string)
1524 **
1525 ** @param [r] Name2 [const AjPStr] Undocumented
1526 ** @param [r] NumNames [ajint] Undocumented
1527 ** @return [float] Undocumented
1528 ** @@
1529 ******************************************************************************/
1530
cirdna_HorTextPileLengthMax(const AjPStr Name2,ajint NumNames)1531 static float cirdna_HorTextPileLengthMax(const AjPStr Name2, ajint NumNames)
1532 {
1533 float stringLength;
1534 float maxLength;
1535 ajint i;
1536 const AjPStr token;
1537
1538 maxLength = 0.0;
1539 for(i=0; i<NumNames; i++)
1540 {
1541 if(i==0)
1542 token = ajStrParseC(Name2, ";");
1543 else
1544 token = ajStrParseC(NULL, ";");
1545 stringLength = ajGraphicsCalcTextlengthS(token);
1546
1547 if(stringLength>maxLength)
1548 maxLength = stringLength;
1549 }
1550
1551 return maxLength;
1552 }
1553
1554
1555
1556
1557 /* @funcstatic cirdna_ReadInput ***********************************************
1558 **
1559 ** read the beginning of the input file
1560 **
1561 ** @param [u] infile [AjPFile] Undocumented
1562 ** @param [w] Start [float*] Undocumented
1563 ** @param [w] End [float*] Undocumented
1564 ** @return [AjBool] True if input file is valid
1565 ** @@
1566 ******************************************************************************/
1567
cirdna_ReadInput(AjPFile infile,float * Start,float * End)1568 static AjBool cirdna_ReadInput(AjPFile infile,
1569 float *Start, float *End)
1570 {
1571 AjPStr line;
1572
1573 AjBool foundstart = ajFalse;
1574 AjBool foundend = ajFalse;
1575
1576 line = ajStrNew();
1577 while(ajReadlineTrim(infile, &line))
1578 {
1579 /* read the start and end positions */
1580 if(ajStrPrefixC(line, "Start"))
1581 {
1582 foundstart = ajTrue;
1583 if(sscanf(ajStrGetPtr(line), "%*s%f", Start) != 1)
1584 return ajFalse;
1585 }
1586
1587 if(ajStrPrefixC(line, "End"))
1588 {
1589 foundend = ajTrue;
1590 if(sscanf(ajStrGetPtr(line), "%*s%f", End) != 1)
1591 {
1592 ajStrDel(&line);
1593 return ajFalse;
1594 }
1595 }
1596 }
1597
1598 ajStrDel(&line);
1599
1600 if(!foundstart || !foundend)
1601 {
1602 ajWarn("Missing Start and/or End line(s) in input file");
1603 return ajFalse;
1604 }
1605
1606
1607 return ajTrue;;
1608 }
1609
1610
1611
1612
1613 /* @funcstatic cirdna_ReadGroup ***********************************************
1614 **
1615 ** read a group
1616 **
1617 ** @param [u] infile [AjPFile] Undocumented
1618 ** @param [r] maxlabels [ajint] Undocumented
1619 ** @param [w] From [float*] From position array
1620 ** @param [w] To [float*] To position array
1621 ** @param [w] Name2 [AjPStr*] Array of sequence names
1622 ** @param [w] FromSymbol [char*] Undocumented
1623 ** @param [w] ToSymbol [char*] Undocumented
1624 ** @param [w] Style2 [AjPStr *] Undocumented
1625 ** @param [w] NumLabels [ajint*] Undocumented
1626 ** @param [w] NumNames [ajint*] Array of ajints
1627 ** @param [w] Colour [ajint*] Array of colour codes
1628 ** @return [AjPStr] Undocumented
1629 ******************************************************************************/
1630
1631
cirdna_ReadGroup(AjPFile infile,ajint maxlabels,float * From,float * To,AjPStr * Name2,char * FromSymbol,char * ToSymbol,AjPStr * Style2,ajint * NumLabels,ajint * NumNames,ajint * Colour)1632 static AjPStr cirdna_ReadGroup(AjPFile infile, ajint maxlabels,
1633 float* From, float* To,
1634 AjPStr *Name2, char *FromSymbol,
1635 char *ToSymbol, AjPStr *Style2,
1636 ajint *NumLabels, ajint *NumNames,
1637 ajint *Colour)
1638 {
1639 ajint i;
1640 ajint j;
1641 AjPStr GroupName;
1642 AjPStr line;
1643 const AjPStr token;
1644 char *style;
1645 ajlong pos;
1646
1647 line = ajStrNew();
1648 GroupName = ajStrNew();
1649
1650 style = (char *)AJALLOC( 10*sizeof(char) );
1651
1652 /* read the group's name */
1653 pos = ajFileResetPos(infile);
1654 while(ajReadlineTrim(infile, &GroupName))
1655 {
1656 token = ajStrParseC(GroupName, " \n\t\r\f");
1657 if(ajStrGetLen(token)!=0)
1658 {
1659 if(ajStrMatchCaseC(GroupName, "label") ||
1660 ajStrMatchCaseC(GroupName, "endgroup"))
1661 ajStrAssignC(&GroupName, " ");
1662
1663 if(ajStrGetLen(GroupName)>20)
1664 ajStrCutRange( &GroupName, 20, ajStrGetLen(GroupName)-1 );
1665 break;
1666 }
1667 }
1668
1669 i = 0;
1670 ajFileSeek(infile, pos, 0);
1671 while(ajReadlineTrim(infile, &line))
1672 {
1673 token = ajStrParseC(line, " \n\t\r\f");
1674 if(ajStrGetLen(token)!=0)
1675 {
1676 if(ajStrPrefixC(line, "endgroup"))
1677 break;
1678 else
1679 {
1680 /* read the group's label(s) */
1681 if(ajStrPrefixC(line, "label"))
1682 {
1683 while(ajReadlineTrim(infile, &line))
1684 {
1685 if (i == maxlabels)
1686 ajWarn("Too many labels (maxlabels=%d) in input",
1687 maxlabels);
1688 token = ajStrParseC(line, " \n\t\r\f");
1689 if(ajStrGetLen(token)!=0)
1690 {
1691 if (i < maxlabels)
1692 {
1693 FromSymbol[i] = '<';
1694 ToSymbol[i] = '>';
1695 sscanf( ajStrGetPtr(line), "%s", style );
1696 if(ajCharMatchCaseC(style, "Tick"))
1697 sscanf( ajStrGetPtr(line), "%*s %f %d %*c",
1698 &From[i], &Colour[i] );
1699 if(ajCharMatchCaseC(style, "Block"))
1700 sscanf( ajStrGetPtr(line), "%*s %f %f %d %*c",
1701 &To[i], &From[i], &Colour[i] );
1702 if(ajCharMatchCaseC(style, "Range"))
1703 sscanf( ajStrGetPtr(line),
1704 "%*s %f %f %c %c %d %*c",
1705 &To[i], &From[i],
1706 &FromSymbol[i], &ToSymbol[i],
1707 &Colour[i] );
1708 ajStrAssignC(&Style2[i], style);
1709 }
1710 break;
1711 }
1712 }
1713
1714 j = 0;
1715
1716 /* read the label's name(s) */
1717 while(ajReadlineTrim(infile, &line))
1718 {
1719 token = ajStrParseC(line, " \n\t\r\f");
1720 if(ajStrGetLen(token)!=0)
1721 {
1722 if(ajStrPrefixC(line, "endlabel"))
1723 break;
1724 else
1725 {
1726 if (i < maxlabels)
1727 {
1728 ajStrAppendS(&Name2[i], line);
1729 ajStrAppendC(&Name2[i], ";");
1730 j++;
1731 }
1732 }
1733 }
1734 }
1735 if (i < maxlabels)
1736 NumNames[i] = j;
1737 i++;
1738 }
1739 }
1740 }
1741 }
1742 if (i < maxlabels)
1743 *NumLabels = i;
1744 else
1745 *NumLabels = maxlabels;
1746
1747 AJFREE(style);
1748 ajStrDel(&line);
1749
1750 return GroupName;
1751 }
1752
1753
1754
1755
1756 /* @funcstatic cirdna_TextGroup ***********************************************
1757 **
1758 ** compute the character size that fits all elements of a group
1759 ** provided that the height and the length of all strings are at most
1760 ** TextHeight and TextLength, respectively
1761 **
1762 ** @param [r] TextHeight [float] Undocumented
1763 ** @param [r] TextLength [float] Undocumented
1764 ** @param [r] Name2 [AjPStr const *] Undocumented
1765 ** @param [r] NumLabels [ajint] Undocumented
1766 ** @param [r] NumNames [const ajint*] Undocumented
1767 ** @param [r] Style2 [AjPStr const *] Undocumented
1768 ** @param [r] From [const float*] Undocumented
1769 ** @param [r] To [const float*] Undocumented
1770 ** @param [r] PosTicks [const AjPStr] Undocumented
1771 ** @return [float] Undocumented
1772 ******************************************************************************/
cirdna_TextGroup(float TextHeight,float TextLength,AjPStr const * Name2,ajint NumLabels,const ajint * NumNames,AjPStr const * Style2,const float * From,const float * To,const AjPStr PosTicks)1773 static float cirdna_TextGroup(float TextHeight, float TextLength,
1774 AjPStr const *Name2, ajint NumLabels,
1775 const ajint *NumNames,
1776 AjPStr const *Style2,
1777 const float* From,
1778 const float* To,
1779 const AjPStr PosTicks)
1780 {
1781 ajint i;
1782 ajint j;
1783 float charsize;
1784 float minsize = 100.0;
1785 const AjPStr token;
1786
1787 for(i=0; i<NumLabels; i++)
1788 {
1789 for(j=0; j<NumNames[i]; j++)
1790 {
1791 if(!(ajStrMatchCaseC(Style2[i], "Tick") &&
1792 ajStrMatchCaseC(PosTicks, "Out")))
1793 {
1794 if(j==0)
1795 token = ajStrParseC(Name2[i], ";");
1796 else
1797 token = ajStrParseC(NULL, ";");
1798 if(ajStrMatchCaseC(Style2[i], "Block") &&
1799 ((From[i]-To[i])<TextLength))
1800 charsize = ajGraphicsCalcCharsize(0, 0, From[i]-To[i],
1801 From[i]-To[i],
1802 ajStrGetPtr(token),
1803 TextHeight);
1804 else
1805 charsize = ajGraphicsCalcCharsize(0, 0, TextLength,
1806 TextLength,
1807 ajStrGetPtr(token),
1808 TextHeight);
1809 if(charsize < minsize)
1810 minsize = charsize;
1811 }
1812 }
1813 }
1814
1815 return minsize;
1816 }
1817
1818
1819
1820
1821 /* @funcstatic cirdna_TextGroupStr ********************************************
1822 **
1823 ** compute the character size that fits all elements of a group provided that
1824 ** the height and the length of all strings are multiplied by TextCoef
1825 **
1826 ** @param [r] Name2 [AjPStr const *] Undocumented
1827 ** @param [r] NumLabels [ajint] Undocumented
1828 ** @param [r] NumNames [const ajint*] Undocumented
1829 ** @param [r] TextCoef [float] Undocumented
1830 ** @param [r] Style2 [AjPStr const *] Undocumented
1831 ** @param [r] From [const float*] Undocumented
1832 ** @param [r] To [const float*] Undocumented
1833 ** @param [r] PosTicks [const AjPStr] Undocumented
1834 ** @return [float] Undocumented
1835 ******************************************************************************/
cirdna_TextGroupStr(AjPStr const * Name2,ajint NumLabels,const ajint * NumNames,float TextCoef,AjPStr const * Style2,const float * From,const float * To,const AjPStr PosTicks)1836 static float cirdna_TextGroupStr(AjPStr const *Name2, ajint NumLabels,
1837 const ajint *NumNames,
1838 float TextCoef, AjPStr const *Style2,
1839 const float* From, const float* To,
1840 const AjPStr PosTicks)
1841 {
1842 ajint i;
1843 ajint j;
1844 float charsize;
1845 float minsize = 100.0;
1846 float stringLength;
1847 float stringHeight;
1848 const AjPStr token;
1849
1850 for(i=0; i<NumLabels; i++)
1851 {
1852 for(j=0; j<NumNames[i]; j++)
1853 {
1854 if(!(ajStrMatchCaseC(Style2[i], "Tick") &&
1855 ajStrMatchCaseC(PosTicks, "Out")))
1856 {
1857 if(j==0)
1858 token = ajStrParseC(Name2[i], ";");
1859 else
1860 token = ajStrParseC(NULL, ";");
1861 stringLength = ajGraphicsCalcTextlengthS(token);
1862 stringHeight = ajGraphicsCalcTextheight();
1863 if(ajStrMatchCaseC(Style2[i], "Block") &&
1864 ((From[i]-To[i])<stringLength))
1865 charsize = ajGraphicsCalcCharsize(0, 0,
1866 (From[i]-To[i])/TextCoef,
1867 (From[i]-To[i])/TextCoef,
1868 ajStrGetPtr(token),
1869 stringHeight/TextCoef);
1870 else
1871 charsize = ajGraphicsCalcCharsize(0, 0,
1872 stringLength/TextCoef,
1873 stringLength/TextCoef,
1874 ajStrGetPtr(token),
1875 stringHeight/TextCoef);
1876 if(charsize < minsize)
1877 minsize = charsize;
1878 }
1879 }
1880 }
1881
1882 return minsize;
1883 }
1884
1885
1886
1887
1888 /* @funcstatic cirdna_HeightGroup *********************************************
1889 **
1890 ** compute the height of a group depending on what's in it
1891 **
1892 ** @param [r] postext [float] Undocumented
1893 ** @param [r] TickHeight [float] Undocumented
1894 ** @param [r] BlockHeight [float] Undocumented
1895 ** @param [r] RangeHeight [float] Undocumented
1896 ** @param [r] Style2 [AjPStr const *] Undocumented
1897 ** @param [r] NumLabels [ajint] Undocumented
1898 ** @param [r] PosTicks [const AjPStr] Undocumented
1899 ** @param [r] PosBlocks [const AjPStr] Undocumented
1900 ** @param [r] Adjust [ajint] Undocumented
1901 ** @return [float] Undocumented
1902 ******************************************************************************/
1903
cirdna_HeightGroup(float postext,float TickHeight,float BlockHeight,float RangeHeight,AjPStr const * Style2,ajint NumLabels,const AjPStr PosTicks,const AjPStr PosBlocks,ajint Adjust)1904 static float cirdna_HeightGroup(float postext,
1905 float TickHeight, float BlockHeight,
1906 float RangeHeight,
1907 AjPStr const *Style2, ajint NumLabels,
1908 const AjPStr PosTicks,
1909 const AjPStr PosBlocks, ajint Adjust)
1910 {
1911 ajint i;
1912 float GroupHeight;
1913 float uheight;
1914 float umaxheight = 0.0;
1915 float lheight;
1916 float lmaxheight = 0.0;
1917
1918
1919 for(i=0; i<NumLabels; i++)
1920 {
1921 if(ajStrMatchCaseC(Style2[i], "Tick") &&
1922 ajStrMatchCaseC(PosTicks, "In"))
1923 {
1924 uheight = TickHeight;
1925 lheight = 0.0;
1926 uheight+=cirdna_HorTextPileHeight(postext, 1);
1927
1928 if(uheight > umaxheight)
1929 umaxheight = uheight;
1930
1931 if(lheight > lmaxheight)
1932 lmaxheight = lheight;
1933 }
1934
1935 if(ajStrMatchCaseC(Style2[i], "Block"))
1936 {
1937 uheight = (float)1.0*BlockHeight/(float)2;
1938 lheight = (float)1.0*BlockHeight/(float)2;
1939
1940 if(ajStrMatchCaseC(PosBlocks, "Out"))
1941 uheight+=cirdna_HorTextPileHeight(postext, 1);
1942
1943 if(uheight > umaxheight)
1944 umaxheight = uheight;
1945
1946 if( lheight > lmaxheight )
1947 lmaxheight = lheight;
1948 }
1949
1950 if(ajStrMatchCaseC(Style2[i], "Range"))
1951 {
1952 uheight = (float)1.0*RangeHeight/2;
1953 lheight = (float)1.0*RangeHeight/2;
1954 uheight+=cirdna_HorTextPileHeight(postext, 1);
1955
1956 if(uheight > umaxheight)
1957 umaxheight = uheight;
1958
1959 if(lheight > lmaxheight)
1960 lmaxheight = lheight;
1961 }
1962 }
1963
1964 GroupHeight = umaxheight+lmaxheight+(Adjust*postext);
1965
1966 return GroupHeight;
1967 }
1968
1969
1970
1971
1972 /* @funcstatic cirdna_OverlapTextGroup ****************************************
1973 **
1974 ** find whether horizontal text strings overlap within a group
1975 **
1976 ** @param [r] Name2 [AjPStr const *] Undocumented
1977 ** @param [r] Style2 [AjPStr const *] Undocumented
1978 ** @param [r] NumLabels [ajint] Undocumented
1979 ** @param [r] From [const float*] Undocumented
1980 ** @param [r] To [const float*] Undocumented
1981 ** @param [r] Start [float] Undocumented
1982 ** @param [r] End [float] Undocumented
1983 ** @param [r] PosTicks [const AjPStr] Undocumented
1984 ** @param [w] Adjust [ajint*] Array elements written
1985 ** @return [ajint] Undocumented
1986 ******************************************************************************/
1987
cirdna_OverlapTextGroup(AjPStr const * Name2,AjPStr const * Style2,ajint NumLabels,const float * From,const float * To,float Start,float End,const AjPStr PosTicks,ajint * Adjust)1988 static ajint cirdna_OverlapTextGroup(AjPStr const *Name2, AjPStr const *Style2,
1989 ajint NumLabels,
1990 const float* From, const float* To,
1991 float Start, float End,
1992 const AjPStr PosTicks, ajint *Adjust)
1993 {
1994 ajint i;
1995 ajint j;
1996 ajint AdjustMax;
1997 const AjPStr token;
1998 static ajint maxnumlabels=0;
1999 float llim;
2000 float ulim;
2001 float stringLength;
2002
2003 if (NumLabels > maxnumlabels)
2004 {
2005 maxnumlabels = NumLabels;
2006 AJCRESIZE(cirdnaFromText, maxnumlabels);
2007 AJCRESIZE(cirdnaToText, maxnumlabels);
2008 }
2009 /* compute the length of the horizontal strings */
2010 for(i=0; i<NumLabels; i++)
2011 {
2012 if(ajStrMatchCaseC(Style2[i], "Tick") &&
2013 ajStrMatchCaseC(PosTicks, "In"))
2014 {
2015 token = ajStrParseC(Name2[i], ";");
2016 stringLength = ajGraphicsCalcTextlengthS(token);
2017 ulim = From[i]+stringLength/2;
2018 if(ulim>(End-Start-1))
2019 ulim = End-Start-1-ulim;
2020 llim = From[i]-stringLength/2;
2021 if((ulim<0.0) || (llim<0.0))
2022 {
2023 cirdnaFromText[i] = llim;
2024 cirdnaToText[i] = ulim;
2025 }
2026 else
2027 {
2028 cirdnaFromText[i] = ulim;
2029 cirdnaToText[i] = llim;
2030 }
2031 }
2032 else if(ajStrMatchCaseC(Style2[i], "Block"))
2033 {
2034 token = ajStrParseC(Name2[i], ";");
2035 stringLength = ajGraphicsCalcTextlengthS(token);
2036 ulim = (To[i]+From[i])/2+stringLength/2;
2037 if(ulim>(End-Start-1))
2038 ulim = End-Start-1-ulim;
2039 llim = (To[i]+From[i])/2-stringLength/2;
2040 if((ulim<0.0) || (llim<0.0))
2041 {
2042 cirdnaFromText[i] = llim;
2043 cirdnaToText[i] = ulim;
2044 }
2045 else
2046 {
2047 cirdnaFromText[i] = ulim;
2048 cirdnaToText[i] = llim;
2049 }
2050 }
2051 else if(ajStrMatchCaseC(Style2[i], "Range"))
2052 {
2053 token = ajStrParseC(Name2[i], ";");
2054 stringLength = ajGraphicsCalcTextlengthS(token);
2055 ulim = (To[i]+From[i])/2+stringLength/2;
2056 if(ulim>(End-Start-1))
2057 ulim = End-Start-1-ulim;
2058 llim = (To[i]+From[i])/2-stringLength/2;
2059 if((ulim<0.0) || (llim<0.0))
2060 {
2061 cirdnaFromText[i] = llim;
2062 cirdnaToText[i] = ulim;
2063 }
2064 else
2065 {
2066 cirdnaFromText[i] = ulim;
2067 cirdnaToText[i] = llim;
2068 }
2069 }
2070 else
2071 cirdnaFromText[i] = cirdnaToText[i] = 0.0;
2072 }
2073
2074 /*
2075 ** if some strings overlap, the position of the overlapping strings
2076 ** is moved upwards by Adjust
2077 */
2078 for(i=0; i<NumLabels; i++)
2079 Adjust[i] = 0;
2080
2081 for(i=0; i<NumLabels; i++)
2082 {
2083 for(j=0; j<NumLabels; j++)
2084 {
2085 if((i!=j) && (Adjust[i]==Adjust[j]))
2086 {
2087 if(j>i)
2088 {
2089 if(cirdnaFromText[i]<0.0)
2090 {
2091 ulim = End-Start-1+cirdnaFromText[i];
2092 if((cirdnaToText[j]<=ulim) &&
2093 (cirdnaFromText[j]>=ulim))
2094 Adjust[j] = Adjust[i]+1;
2095 }
2096 if((cirdnaToText[j]<=cirdnaFromText[i]) &&
2097 (cirdnaFromText[j]>=cirdnaFromText[i]))
2098 Adjust[j] = Adjust[i]+1;
2099 }
2100
2101 if(i>j)
2102 {
2103 if(cirdnaFromText[j]<0.0)
2104 {
2105 ulim = End-Start-1+cirdnaFromText[j];
2106 if((cirdnaToText[i]<=ulim) &&
2107 (cirdnaFromText[i]>=ulim))
2108 Adjust[i] = Adjust[j]+1;
2109 }
2110
2111 if((cirdnaToText[i]<=cirdnaFromText[j]) &&
2112 (cirdnaFromText[i]>=cirdnaFromText[j]))
2113 Adjust[i] = Adjust[j]+1;
2114 }
2115 }
2116 }
2117 }
2118
2119 AdjustMax = 0;
2120 for(i=0; i<NumLabels; i++)
2121 if(Adjust[i]>AdjustMax)
2122 AdjustMax = Adjust[i];
2123
2124 return AdjustMax;
2125 }
2126
2127
2128
2129
2130 /* @funcstatic cirdna_OverlapTickRuler ****************************************
2131 **
2132 ** find whether group ticks and ruler's ticks overlap
2133 **
2134 ** @param [r] NumGroups [ajint] Undocumented
2135 ** @param [r] NumLabels [const ajint*] Undocumented
2136 ** @param [r] From [float* const *] Undocumented
2137 ** @param [r] PosTicks [const AjPStr] Undocumented
2138 ** @param [r] RulerTick [ajint] Undocumented
2139 ** @return [AjBool] Undocumented
2140 ******************************************************************************/
2141
cirdna_OverlapTickRuler(ajint NumGroups,const ajint * NumLabels,float * const * From,const AjPStr PosTicks,ajint RulerTick)2142 static AjBool cirdna_OverlapTickRuler(ajint NumGroups, const ajint *NumLabels,
2143 float* const * From,
2144 const AjPStr PosTicks,
2145 ajint RulerTick)
2146 {
2147 ajint i;
2148 ajint j;
2149 ajint overlap = 0;
2150
2151 for(i=0; i<NumGroups; i++)
2152 for(j=0; j<NumLabels[i]; j++)
2153 {
2154 if(ajStrMatchCaseC(Style[i][j], "Tick") &&
2155 ajStrMatchCaseC(PosTicks, "Out") &&
2156 From[i][j]==RulerTick)
2157 {
2158 overlap = 1;
2159 break;
2160 }
2161 }
2162
2163 if(overlap==0)
2164 return ajFalse;
2165
2166 return ajTrue;
2167 }
2168
2169
2170
2171
2172 /* @funcstatic cirdna_DrawGroup ***********************************************
2173 **
2174 ** draw a group
2175 **
2176 ** @param [r] xDraw [float] Undocumented
2177 ** @param [r] yDraw [float] Undocumented
2178 ** @param [r] posblock [float] Undocumented
2179 ** @param [r] posrange [float] Undocumented
2180 ** @param [r] postext [float] Undocumented
2181 ** @param [r] TickHeight [float] Undocumented
2182 ** @param [r] BlockHeight [float] Undocumented
2183 ** @param [r] RangeHeight [float] Undocumented
2184 ** @param [r] RealLength [float] Undocumented
2185 ** @param [r] Radius [float] Undocumented
2186 ** @param [r] RadiusMax [float] Undocumented
2187 ** @param [r] From [const float*] Undocumented
2188 ** @param [r] To [const float*] Undocumented
2189 ** @param [r] Name2 [AjPStr const *] Undocumented
2190 ** @param [r] FromSymbol [const char*] Undocumented
2191 ** @param [r] ToSymbol [const char*] Undocumented
2192 ** @param [r] Style2 [AjPStr const *] Undocumented
2193 ** @param [r] InterSymbol [AjBool] Undocumented
2194 ** @param [r] InterTicks [AjBool] Undocumented
2195 ** @param [r] NumLabels [ajint] Undocumented
2196 ** @param [r] OriginAngle [float] Undocumented
2197 ** @param [r] NumNames [const ajint*] Undocumented
2198 ** @param [r] PosTicks [const AjPStr] Undocumented
2199 ** @param [r] PosBlocks [const AjPStr] Undocumented
2200 ** @param [r] Adjust [const ajint*] Undocumented
2201 ** @param [r] InterColour [ajint] Undocumented
2202 ** @param [r] Colour [const ajint*] Undocumented
2203 ** @param [r] BlockType [const AjPStr] Undocumented
2204 ** @return [void]
2205 ******************************************************************************/
2206
cirdna_DrawGroup(float xDraw,float yDraw,float posblock,float posrange,float postext,float TickHeight,float BlockHeight,float RangeHeight,float RealLength,float Radius,float RadiusMax,const float * From,const float * To,AjPStr const * Name2,const char * FromSymbol,const char * ToSymbol,AjPStr const * Style2,AjBool InterSymbol,AjBool InterTicks,ajint NumLabels,float OriginAngle,const ajint * NumNames,const AjPStr PosTicks,const AjPStr PosBlocks,const ajint * Adjust,ajint InterColour,const ajint * Colour,const AjPStr BlockType)2207 static void cirdna_DrawGroup(float xDraw, float yDraw, float posblock,
2208 float posrange, float postext, float TickHeight,
2209 float BlockHeight, float RangeHeight,
2210 float RealLength, float Radius, float RadiusMax,
2211 const float* From, const float* To,
2212 AjPStr const *Name2,
2213 const char *FromSymbol, const char *ToSymbol,
2214 AjPStr const *Style2,
2215 AjBool InterSymbol, AjBool InterTicks,
2216 ajint NumLabels,
2217 float OriginAngle, const ajint *NumNames,
2218 const AjPStr PosTicks, const AjPStr PosBlocks,
2219 const ajint *Adjust,
2220 ajint InterColour, const ajint *Colour,
2221 const AjPStr BlockType)
2222 {
2223 ajint i;
2224 ajint j;
2225 ajint NumBlocks;
2226
2227 if (NumLabels > cirdnaMaxinter)
2228 {
2229 cirdnaMaxinter = NumLabels;
2230 AJCRESIZE(cirdnaInter, cirdnaMaxinter);
2231 }
2232
2233 /* draw all labels */
2234 for(j=0, i=0; i<NumLabels; i++)
2235 {
2236 if(ajStrMatchCaseC(Style2[i], "Tick"))
2237 {
2238 if(ajStrMatchCaseC(PosTicks, "In"))
2239 {
2240 cirdna_DrawTicks(xDraw, yDraw, RealLength, Radius, TickHeight,
2241 From[i], Name2[i], OriginAngle,
2242 postext, PosTicks, NumNames[i],
2243 Adjust[i], Colour[i]);
2244 if(InterTicks)
2245 ajGraphicsDrawposCircle(xDraw, yDraw, Radius);
2246 }
2247 else
2248 cirdna_DrawTicks(xDraw, yDraw, RealLength, RadiusMax,
2249 TickHeight, From[i], Name2[i], OriginAngle,
2250 postext, PosTicks,
2251 NumNames[i], Adjust[i], Colour[i]);
2252 }
2253
2254 if( ajStrMatchCaseC(Style2[i], "Block") )
2255 {
2256 cirdna_DrawBlocks(xDraw, yDraw, RealLength, Radius-posblock,
2257 (ajint)BlockHeight, From[i], To[i],
2258 Name2[i], postext,
2259 OriginAngle, PosBlocks, NumNames[i], Adjust[i],
2260 Colour[i], BlockType);
2261 cirdnaInter[j++] = i;
2262 }
2263
2264 if(ajStrMatchCaseC(Style2[i], "Range"))
2265 cirdna_DrawRanges(xDraw, yDraw, RealLength, Radius-posrange,
2266 RangeHeight, From[i], To[i], FromSymbol[i],
2267 ToSymbol[i], Name2[i], OriginAngle, NumNames[i],
2268 postext, Adjust[i], Colour[i]);
2269 }
2270 NumBlocks = j;
2271
2272 /* draw all interblocks */
2273 for(i=0; i<NumBlocks-1; i++)
2274 cirdna_InterBlocks(xDraw, yDraw, RealLength, Radius-posblock,
2275 BlockHeight,
2276 From[cirdnaInter[i]], To[cirdnaInter[i+1]],
2277 OriginAngle, InterSymbol, InterColour);
2278
2279 return;
2280 }
2281