pos4.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. /*
  2. * Copyright 2021
  3. * (C) Universitaet Passau 1986-1991
  4. *
  5. * This program 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 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * 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 program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * These are the four essential freedoms with GNU GPL software:
  19. * 1: freedom to run the program, for any purpose
  20. * 2: freedom to study how the program works, and change it to make it do what you wish
  21. * 3: freedom to redistribute copies to help your Free Software friends
  22. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  23. * , ,
  24. * / \
  25. * ((__-^^-,-^^-__))
  26. * `-_---' `---_-'
  27. * `--|o` 'o|--'
  28. * \ ` /
  29. * ): :(
  30. * :o_o:
  31. * "-"
  32. *
  33. * SPDX-License-Identifier: GPL-3.0+
  34. * License-Filename: LICENSE
  35. */
  36. #include "config.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <math.h>
  40. #include "splay-tree.h"
  41. #include "main.h"
  42. #include "hier.h"
  43. #include "pos.h"
  44. #include "pos4.h"
  45. #include "dpmem.h"
  46. /* min. distance between 2 nodes */
  47. static int xmindist = 1;
  48. static int ymindist = 1;
  49. /* level step size, 1 or 2 */
  50. static int ssize = 1;
  51. struct node_data {
  52. struct gml_node *node;
  53. int priority;
  54. int done;
  55. };
  56. /* */
  57. static struct node_data *nl = NULL;
  58. /* */
  59. static struct node_data **dl = NULL;
  60. /* index in in dl */
  61. static int *cix = NULL;
  62. /* y size of levels */
  63. static int *szy = NULL;
  64. /* how many connection edges from previous level */
  65. static int upper_connectivity(struct gml_node *node)
  66. {
  67. return (node->indegree);
  68. }
  69. /* how many connection edges to next level */
  70. static int lower_connectivity(struct gml_node *node)
  71. {
  72. return (node->outdegree);
  73. }
  74. /* avg x pos of incoming edges */
  75. static int upper_barycenter(struct gml_node *node)
  76. {
  77. struct gml_elist *el = NULL;
  78. int result = 0;
  79. double r = 0.0;
  80. int abx = 0;
  81. /* incoming edges x sum for_targetlist(node,edge) */
  82. el = node->incoming_e;
  83. while (el) {
  84. if (ssize == 1) {
  85. /* todo testing +bbx/2 */
  86. abx = el->edge->from_node->absx + (el->edge->from_node->bbx / 2);
  87. } else {
  88. abx = el->edge->from_node->incoming_e->edge->from_node->absx;
  89. }
  90. result = result + abx;
  91. el = el->next;
  92. }
  93. if (result == 0) {
  94. r = (0.0);
  95. } else {
  96. r = (result / upper_connectivity(node));
  97. }
  98. if (1) {
  99. r = round(r);
  100. }
  101. return ((int)r);
  102. }
  103. /* avg x pos of outgoing edges */
  104. static int lower_barycenter(struct gml_node *node)
  105. {
  106. struct gml_elist *el = NULL;
  107. int result = 0;
  108. double r = 0.0;
  109. int abx = 0;
  110. /* get avg. x pos of outgoing edges for_sourcelist(node,edge) */
  111. el = node->outgoing_e;
  112. while (el) {
  113. if (ssize == 1) {
  114. /* todo testing +bbx/2 */
  115. abx = el->edge->to_node->absx + (el->edge->to_node->bbx / 2);
  116. } else {
  117. abx = el->edge->to_node->outgoing_e->edge->to_node->absx;
  118. }
  119. result = result + abx;
  120. el = el->next;
  121. }
  122. if (result == 0) {
  123. r = (0.0);
  124. } else {
  125. r = (result / lower_connectivity(node));
  126. }
  127. if (1) {
  128. r = round(r);
  129. }
  130. return ((int)r);
  131. }
  132. static void sort(int n)
  133. {
  134. int i = 0;
  135. int j = 0;
  136. struct node_data h;
  137. for (j = n - 1; j > 0; j--) {
  138. for (i = 0; i < j; i++) {
  139. /* issue here */
  140. if (nl[i].node && nl[i + 1].node) {
  141. if (nl[i].node->relx > nl[i + 1].node->relx) {
  142. /* swap */
  143. h = nl[i];
  144. nl[i] = nl[i + 1];
  145. nl[i + 1] = h;
  146. }
  147. } else {
  148. printf("%s(): nil nodes nl[i].node=%p nl[i + 1].node=%p\n", __func__, (void *)nl[i].node, (void *)nl[i + 1].node);
  149. }
  150. }
  151. }
  152. return;
  153. }
  154. /* prepare level */
  155. static void make_node_list_up(struct gml_graph *g, int l)
  156. {
  157. int i = 0;
  158. nl = dl[l];
  159. if (nl == NULL) {
  160. printf("%s(): nil nl at level %d\n", __func__, l);
  161. return;
  162. }
  163. for (i = 0; i < g->nnodes_of_level[l]; i++) {
  164. nl[i].done = 0;
  165. if (nl[i].node->dummy) {
  166. nl[i].priority = 1000 * nl[i].node->relx; // (100000 + nl[i].node->relx);
  167. // nl[i].priority = (1000 * (g->nnodes_of_level[l+2] + 1));
  168. } else {
  169. nl[i].priority = lower_connectivity(nl[i].node);
  170. }
  171. }
  172. return;
  173. }
  174. /* prepare level */
  175. static void make_node_list_down(struct gml_graph *g, int l)
  176. {
  177. int i = 0;
  178. nl = dl[l];
  179. if (nl == NULL) {
  180. printf("%s(): nil nl at level %d\n", __func__, l);
  181. fflush(stdout);
  182. return;
  183. }
  184. for (i = 0; i < g->nnodes_of_level[l]; i++) {
  185. nl[i].done = 0;
  186. if (nl[i].node->dummy) {
  187. nl[i].priority = 1000 * nl[i].node->relx; //(100000 + nl[i].node->relx);
  188. } else {
  189. nl[i].priority = upper_connectivity(nl[i].node);
  190. }
  191. }
  192. return;
  193. }
  194. /* get number of node with highest prio which is not done yet */
  195. static int find_next(int n)
  196. {
  197. int nindex = 0;
  198. int i = 0;
  199. int highest_priority = 0;
  200. for (i = 0; i < n; i++) {
  201. if (nl) {
  202. if (nl[i].priority >= highest_priority) {
  203. if (nl[i].done == 0) {
  204. nindex = i;
  205. highest_priority = nl[i].priority;
  206. }
  207. }
  208. }
  209. }
  210. return (nindex);
  211. }
  212. static void do_down(struct gml_graph *g, int l)
  213. {
  214. int i = 0;
  215. int index = 0;
  216. int j = 0;
  217. int optimal_position = 0;
  218. int distance = 0;
  219. int possible_distance = 0;
  220. if (nl == NULL) { /* shouldnothappen */
  221. return;
  222. }
  223. for (i = 0; i < g->nnodes_of_level[l]; i++) {
  224. index = find_next(g->nnodes_of_level[l]);
  225. optimal_position = upper_barycenter(nl[index].node);
  226. if (optimal_position == 0) {
  227. optimal_position = nl[index].node->absx;
  228. }
  229. if (optimal_position < nl[index].node->absx) {
  230. distance = nl[index].node->absx - optimal_position;
  231. possible_distance = 0;
  232. j = index;
  233. do {
  234. if (j > 0) {
  235. possible_distance += nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist;
  236. } else {
  237. /* j==0, no nodes at left */
  238. possible_distance += (nl[j].node->absx + nl[j].node->bbx) /* XXX +bbx? */ -xmindist;
  239. }
  240. j--;
  241. }
  242. while ((j >= 0) && (nl[j].done == 0));
  243. if (possible_distance < distance) {
  244. distance = possible_distance;
  245. }
  246. j = index;
  247. while (distance > 0) {
  248. int d = 0;
  249. int k = 0;
  250. if (j == 0) {
  251. d = distance;
  252. } else {
  253. if (nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist < distance) {
  254. d = nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist;
  255. } else {
  256. d = distance;
  257. }
  258. }
  259. for (k = j; k <= index; k++) {
  260. nl[k].node->absx -= d;
  261. }
  262. j--;
  263. distance -= d;
  264. }
  265. } else {
  266. distance = optimal_position - nl[index].node->absx;
  267. possible_distance = 0;
  268. j = index;
  269. do {
  270. if (j < g->nnodes_of_level[l] - 1) {
  271. possible_distance += nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist;
  272. } else {
  273. /* j == g->nnodes_of_level[l]-1, no nodes rechts */
  274. possible_distance += distance;
  275. }
  276. j++;
  277. }
  278. while ((j < g->nnodes_of_level[l]) && (nl[j].done == 0));
  279. if (possible_distance < distance) {
  280. distance = possible_distance;
  281. }
  282. j = index;
  283. while (distance > 0) {
  284. int d = 0;
  285. int k = 0;
  286. if (j == g->nnodes_of_level[l] - 1) {
  287. d = distance;
  288. } else {
  289. if (nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist < distance) {
  290. d = nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist;
  291. } else {
  292. d = distance;
  293. }
  294. }
  295. for (k = index; k <= j; k++) {
  296. nl[k].node->absx += d;
  297. }
  298. j++;
  299. distance -= d;
  300. }
  301. }
  302. nl[index].done = 1; /* TRUE */
  303. }
  304. return;
  305. }
  306. static void do_up(struct gml_graph *g, int l)
  307. {
  308. int i = 0;
  309. int index = 0;
  310. int j = 0;
  311. int optimal_position = 0;
  312. int distance = 0;
  313. int possible_distance = 0;
  314. for (i = 0; i < g->nnodes_of_level[l]; i++) {
  315. index = find_next(g->nnodes_of_level[l]);
  316. optimal_position = lower_barycenter(nl[index].node);
  317. if (optimal_position == 0) {
  318. optimal_position = nl[index].node->absx;
  319. }
  320. if (optimal_position < nl[index].node->absx) {
  321. distance = nl[index].node->absx - optimal_position;
  322. possible_distance = 0;
  323. j = index;
  324. do {
  325. if (j > 0) {
  326. possible_distance += nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist;
  327. } else {
  328. /* j == 0, no nodes links */
  329. possible_distance += (nl[0].node->absx + nl[0].node->bbx) /* XXX +bbx? */ -xmindist;
  330. }
  331. j--;
  332. }
  333. while ((j >= 0) && (nl[j].done == 0));
  334. if (possible_distance < distance) {
  335. distance = possible_distance;
  336. }
  337. j = index;
  338. while (distance > 0) {
  339. int d = 0;
  340. int k = 0;
  341. if (j == 0) {
  342. d = distance;
  343. } else {
  344. if (nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist < distance) {
  345. d = nl[j].node->absx - (nl[j - 1].node->absx + nl[j - 1].node->bbx) - xmindist;
  346. } else {
  347. d = distance;
  348. }
  349. }
  350. for (k = j; k <= index; k++) {
  351. nl[k].node->absx -= d;
  352. }
  353. j--;
  354. distance -= d;
  355. }
  356. } else {
  357. /* optimal_position >= nl[index].node->absx */
  358. distance = optimal_position - nl[index].node->absx;
  359. possible_distance = 0;
  360. j = index;
  361. do {
  362. if (j < g->nnodes_of_level[l] - 1) {
  363. possible_distance += nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist;
  364. } else {
  365. /* j == g->nnodes_of_level[l]-1, no nodes rechts */
  366. possible_distance += distance;
  367. }
  368. j++;
  369. }
  370. while ((j < g->nnodes_of_level[l]) && (nl[j].done == 0));
  371. if (possible_distance < distance) {
  372. distance = possible_distance;
  373. }
  374. j = index;
  375. while (distance > 0) {
  376. int d = 0;
  377. int k = 0;
  378. if (j == g->nnodes_of_level[l] - 1) {
  379. d = distance;
  380. } else {
  381. if (nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist < distance) {
  382. d = nl[j + 1].node->absx - (nl[j].node->absx + nl[j].node->bbx) - xmindist;
  383. } else {
  384. d = distance;
  385. }
  386. }
  387. for (k = index; k <= j; k++) {
  388. nl[k].node->absx += d;
  389. }
  390. j++;
  391. distance -= d;
  392. }
  393. }
  394. nl[index].done = 1; /* TRUE */
  395. }
  396. return;
  397. }
  398. /* build data */
  399. static void pos3init(struct gml_graph *g)
  400. {
  401. struct node_data *pnl = NULL;
  402. struct gml_nlist *gnl = NULL;
  403. struct gml_node *n = NULL;
  404. int i = 0;
  405. int j = 0;
  406. int my = 0;
  407. int yoff = 0;
  408. dl = dp_calloc(1, ((g->maxlevel + 1) * sizeof(struct node_data *)));
  409. for (i = 0; i <= g->maxlevel; i++) {
  410. dl[i] = dp_calloc(1, ((g->nnodes_of_level[i] + 1) * sizeof(struct node_data)));
  411. }
  412. cix = dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  413. /* for_all_nodes(g,n) */
  414. gnl = g->nodelist;
  415. while (gnl) {
  416. n = gnl->node;
  417. pnl = dl[n->rely];
  418. pnl[cix[n->rely]].node = n;
  419. pnl[cix[n->rely]].done = 0;
  420. pnl[cix[n->rely]].priority = 0;
  421. cix[n->rely]++;
  422. gnl = gnl->next;
  423. }
  424. for (i = 0; i <= g->maxlevel; i++) {
  425. nl = dl[i];
  426. if (g->nnodes_of_level[i]) {
  427. sort(g->nnodes_of_level[i]);
  428. }
  429. }
  430. /* calc max y-size at every level */
  431. szy = dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  432. /* y offset */
  433. yoff = 0;
  434. for (i = 0; i <= g->maxlevel; i++) {
  435. nl = dl[i];
  436. my = 0;
  437. /* determine needed y size of this level */
  438. for (j = 0; j < g->nnodes_of_level[i]; j++) {
  439. if (nl[j].node->bby > my) {
  440. /* node with largest y size */
  441. my = nl[j].node->bby;
  442. }
  443. }
  444. /* set this max. y as y size of this level */
  445. szy[i] = my;
  446. /* place the nodes */
  447. for (j = 0; j < g->nnodes_of_level[i]; j++) {
  448. /* node places centered halfway of level */
  449. nl[j].node->absy = yoff + ((szy[i] / 2) - (nl[j].node->bby / 2));
  450. nl[j].node->ly0 = yoff;
  451. nl[j].node->ly1 = (yoff + szy[i] /* XXX + ymindist */ );
  452. if (nl[j].node->dummy) {
  453. nl[j].node->bby = szy[i] + ymindist;
  454. }
  455. }
  456. yoff = yoff + my + ymindist;
  457. }
  458. return;
  459. }
  460. /* clear data */
  461. static void pos3clear(struct gml_graph *g)
  462. {
  463. struct node_data *pnl = NULL;
  464. int i = 0;
  465. if (dl) {
  466. for (i = 0; i <= g->maxlevel; i++) {
  467. pnl = dl[i];
  468. if (pnl) {
  469. dl[i] = dp_free(pnl);
  470. if (dl[i]) {
  471. }
  472. }
  473. }
  474. dl = dp_free(dl);
  475. if (dl) {
  476. }
  477. }
  478. if (cix) {
  479. cix = dp_free(cix);
  480. if (cix) {
  481. }
  482. }
  483. if (szy) {
  484. szy = dp_free(szy);
  485. if (szy) {
  486. }
  487. }
  488. dl = NULL;
  489. nl = NULL;
  490. return;
  491. }
  492. /* left most layout */
  493. static void pos3leftmost(struct gml_graph *g)
  494. {
  495. int i = 0;
  496. int j = 0;
  497. int mx = 0;
  498. /* left most layout setting all node x pos. to minimum needed value */
  499. for (i = 0; i < g->maxlevel; i++) {
  500. nl = dl[i];
  501. if (nl) {
  502. mx = 0;
  503. for (j = 0; j < g->nnodes_of_level[i]; j++) {
  504. if (nl[j].node) {
  505. nl[j].node->absx = mx;
  506. mx = mx + xmindist + nl[j].node->bbx;
  507. }
  508. }
  509. }
  510. }
  511. return;
  512. }
  513. /* fix dummy nodes */
  514. static void pos3fixdummy(struct gml_graph *g, int level)
  515. {
  516. int j = 0;
  517. int x0 = 0;
  518. int x1 = 0;
  519. nl = dl[level];
  520. if (nl == NULL) {
  521. return;
  522. }
  523. for (j = 0; j < g->nnodes_of_level[level]; j++) {
  524. /* do not move edge labels, only dummy nodes */
  525. if (nl[j].node->elabel == 0) {
  526. /* do not move if hor. edges */
  527. if (nl[j].node->incoming_e && nl[j].node->outgoing_e) {
  528. if (nl[j].node->incoming_e->edge->hedge == 0 && nl[j].node->outgoing_e->edge->hedge == 0) {
  529. /* this is a vertical edge */
  530. x0 = nl[j].node->incoming_e->edge->from_node->absx + (nl[j].node->incoming_e->edge->from_node->bbx / 2);
  531. x1 = nl[j].node->outgoing_e->edge->to_node->absx + (nl[j].node->outgoing_e->edge->to_node->bbx / 2);
  532. nl[j].node->absx = ((x0 + x1) / 2);
  533. }
  534. }
  535. }
  536. }
  537. return;
  538. }
  539. /* XXX todo this does not work as expected */
  540. /* determine relative node pos. from the barycenter rel. node pos. */
  541. static void improve_positions_3(struct gml_graph *g)
  542. {
  543. struct gml_nlist *gnl = NULL;
  544. int i = 0;
  545. int count = 0;
  546. int ii = 0;
  547. int sl = 0;
  548. int mx = 0;
  549. int mylevel = 0;
  550. /* step size */
  551. ssize = 1;
  552. /* min. node dist, minimum 1 */
  553. xmindist = xspacing;
  554. ymindist = yspacing;
  555. if (g->nsinglenodes) {
  556. /* single nodes in level 0 and skip this level */
  557. sl = 1;
  558. } else {
  559. /* start level is 0 */
  560. sl = 0;
  561. }
  562. /* copy the rel(x,y) pos into abs(x,y) and modify the absx pos here */
  563. gnl = g->nodelist;
  564. while (gnl) {
  565. gnl->node->absx = gnl->node->relx;
  566. gnl->node->absy = gnl->node->rely;
  567. gnl->node->finx = 0;
  568. gnl->node->finy = 0;
  569. gnl->node->ly0 = 0;
  570. gnl->node->ly1 = 0;
  571. if (gnl->node->dummy) {
  572. gnl->node->bbx = 0;
  573. gnl->node->bby = 0;
  574. }
  575. gnl = gnl->next;
  576. }
  577. /* build data */
  578. pos3init(g);
  579. /* left most layout */
  580. pos3leftmost(g);
  581. /* number of up/down sweeps */
  582. count = 2;
  583. for (ii = 0; ii < count; ii++) {
  584. /* from to of drawing to bottom */
  585. for (i = sl; i < g->maxlevel; i = i + ssize) {
  586. mylevel = i;
  587. if (g->nnodes_of_level[i]) {
  588. make_node_list_down(g, i);
  589. do_down(g, i);
  590. }
  591. }
  592. /* from bottom of drawing to top */
  593. for (i = mylevel; i > sl; i = i - ssize) {
  594. if (g->nnodes_of_level[i]) {
  595. make_node_list_up(g, i);
  596. do_up(g, i);
  597. }
  598. }
  599. }
  600. if ((sl + 2) < g->maxlevel) {
  601. for (i = sl; i < g->maxlevel; i = i + ssize) {
  602. if (g->nnodes_of_level[i]) {
  603. make_node_list_up(g, i);
  604. do_up(g, i);
  605. }
  606. }
  607. }
  608. /* left-align the image */
  609. /* find min. x pos in-use */
  610. mx = 1024 * 1024; /* just some high value */
  611. if (g->nsinglenodes) {
  612. /* single nodes in level 0 and skip this level */
  613. gnl = g->nodelist;
  614. while (gnl) {
  615. /* only level 1...n */
  616. if (gnl->node->rely) {
  617. if (gnl->node->absx < mx) {
  618. mx = gnl->node->absx;
  619. }
  620. }
  621. gnl = gnl->next;
  622. }
  623. /* move whole drawing to the left */
  624. gnl = g->nodelist;
  625. while (gnl) {
  626. /* only level 1...n */
  627. if (gnl->node->rely) {
  628. gnl->node->absx = (gnl->node->absx - mx);
  629. }
  630. gnl = gnl->next;
  631. }
  632. } else {
  633. /* no single nodes and level 0 is in use for the drawing */
  634. gnl = g->nodelist;
  635. while (gnl) {
  636. if (gnl->node->absx < mx) {
  637. mx = gnl->node->absx;
  638. }
  639. gnl = gnl->next;
  640. }
  641. /* move whole drawing to the left */
  642. gnl = g->nodelist;
  643. while (gnl) {
  644. gnl->node->absx = (gnl->node->absx - mx);
  645. gnl = gnl->next;
  646. }
  647. }
  648. /* tune in-between levels with dummy nodes */
  649. if (ssize == 2 || 0) {
  650. ssize = 2;
  651. for (i = sl; i < g->maxlevel; i = i + ssize) {
  652. pos3fixdummy(g, (i + 1));
  653. }
  654. }
  655. /* clear all data */
  656. pos3clear(g);
  657. return;
  658. }
  659. /* switched between different modes */
  660. void improve_positions4(struct gml_graph *g)
  661. {
  662. printf("%s(): positioning mode is %d\n", __func__, postype);
  663. fflush(stdout);
  664. /* this can happen */
  665. if (g->nnodes_of_level == NULL) {
  666. return;
  667. }
  668. improve_positions_3(g);
  669. return;
  670. }
  671. /* end */