pos2.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  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 "pos2.h"
  45. #include "dot.tab.h"
  46. #include "dpmem.h"
  47. /* min. distance between 2 nodes */
  48. static int mindist = 1;
  49. /* current startnode nr field */
  50. static int csn = 0;
  51. /* node list of part of graph */
  52. static struct gml_nlist *cnodelist = NULL;
  53. static struct gml_nlist *cnodelisttail = NULL;
  54. /* number of nodes at level */
  55. static int *cnnodes_of_level = NULL;
  56. /* max. x,y in part of graph */
  57. static int cmaxx = 0;
  58. static int cmaxy = 0;
  59. /* widest x level */
  60. static int cwidestnnodes = 0;
  61. /* x width at position */
  62. static int *cwpos = NULL;
  63. /* lists per pos. */
  64. static struct gml_nlist **cposnodes = NULL;
  65. /* hor pos */
  66. static int *chpos = NULL;
  67. /* hor pos */
  68. static struct gml_nlist **clevelnodes = NULL;
  69. /* */
  70. struct node_data {
  71. struct gml_node *node;
  72. int priority;
  73. int done;
  74. };
  75. /* nodes in one level */
  76. static struct node_data *nl = NULL;
  77. static int is_dummy(struct gml_node *node)
  78. {
  79. if (node->dummy) {
  80. return (1);
  81. } else {
  82. return (0);
  83. }
  84. }
  85. static int is_elabel(struct gml_node *node)
  86. {
  87. if (node->elabel) {
  88. return (1);
  89. } else {
  90. return (0);
  91. }
  92. }
  93. /* how many connection edges from previous level */
  94. static int upper_connectivity(struct gml_node *node)
  95. {
  96. struct gml_elist *el = NULL;
  97. int result;
  98. result = 0;
  99. if (node == NULL) {
  100. /* shouldnothappen */
  101. return (0);
  102. }
  103. /* incoming edges for_targetlist(node,edge) */
  104. el = node->incoming_e;
  105. while (el) {
  106. /* skip hor. edges */
  107. if (el->edge->hedge == 0) {
  108. /* only in this part of graph */
  109. if (el->edge->from_node->startnode == csn) {
  110. result++;
  111. }
  112. }
  113. el = el->next;
  114. }
  115. return (result);
  116. }
  117. /* how many connection edges to next level */
  118. static int lower_connectivity(struct gml_node *node)
  119. {
  120. struct gml_elist *el = NULL;
  121. int result = 0;
  122. result = 0;
  123. if (node == NULL) {
  124. /* shouldnothappen */
  125. return (0);
  126. }
  127. /* outgoing edges for_sourcelist(node,edge) */
  128. el = node->outgoing_e;
  129. while (el) {
  130. /* skip hor. edges */
  131. if (el->edge->hedge == 0) {
  132. /* only in this part of graph */
  133. if (el->edge->to_node->startnode == csn) {
  134. result++;
  135. }
  136. }
  137. el = el->next;
  138. }
  139. return (result);
  140. }
  141. /* avg x pos of incoming edges */
  142. static int upper_barycenter(struct gml_node *node)
  143. {
  144. struct gml_elist *el = NULL;
  145. int result = 0;
  146. double r = 0.0;
  147. if (node == NULL) {
  148. /* shouldnothappen */
  149. return (0);
  150. }
  151. /* incoming edges x sum for_targetlist(node,edge) */
  152. el = node->incoming_e;
  153. while (el) {
  154. /* skip hor. edges */
  155. if (el->edge->hedge == 0) {
  156. /* only in this part of graph */
  157. if (el->edge->from_node->startnode == csn) {
  158. result += (el->edge->from_node->absx);
  159. }
  160. }
  161. el = el->next;
  162. }
  163. if (result == 0) {
  164. r = (0.0);
  165. } else {
  166. if (upper_connectivity(node) == 0) {
  167. r = 0.0;
  168. } else {
  169. r = (result / upper_connectivity(node));
  170. }
  171. }
  172. r = round(r);
  173. return ((int)r);
  174. }
  175. /* avg x pos of outgoing edges */
  176. static int lower_barycenter(struct gml_node *node)
  177. {
  178. struct gml_elist *el = NULL;
  179. int result = 0;
  180. double r = 0.0;
  181. if (node == NULL) {
  182. /* shouldnothappen */
  183. return (0);
  184. }
  185. /* get avg. x pos of outgoing edges for_sourcelist(node,edge) */
  186. el = node->outgoing_e;
  187. while (el) {
  188. /* skip hor. edges */
  189. if (el->edge->hedge == 0) {
  190. /* only in this part of graph */
  191. if (el->edge->to_node->startnode == csn) {
  192. result += (el->edge->to_node->absx);
  193. }
  194. }
  195. el = el->next;
  196. }
  197. if (result == 0) {
  198. r = (0.0);
  199. } else {
  200. if (lower_connectivity(node) == 0) {
  201. r = 0.0;
  202. } else {
  203. r = (result / lower_connectivity(node));
  204. }
  205. }
  206. r = round(r);
  207. return ((int)r);
  208. }
  209. static void sort(int n)
  210. {
  211. int i = 0;
  212. int j = 0;
  213. struct node_data h;
  214. for (j = n - 1; j > 0; j--) {
  215. for (i = 0; i < j; i++) {
  216. /* issue here */
  217. if (nl[i].node && nl[i + 1].node) {
  218. if (nl[i].node->relx > nl[i + 1].node->relx) {
  219. /* swap */
  220. h = nl[i];
  221. nl[i] = nl[i + 1];
  222. nl[i + 1] = h;
  223. }
  224. }
  225. }
  226. }
  227. return;
  228. }
  229. /* */
  230. static void make_node_list_up(int l)
  231. {
  232. struct gml_nlist *gnl = NULL;
  233. struct gml_node *n = NULL;
  234. int i = 0;
  235. /* for_all_nodes(g,n) */
  236. gnl = cnodelist;
  237. i = 0;
  238. while (gnl) {
  239. n = gnl->node;
  240. if (n->absy == l) {
  241. nl[i].node = n;
  242. nl[i].done = 0; /* FALSE */
  243. /* give edge label nodes hight prio too */
  244. if ((is_dummy(n) == 1) || (is_elabel(n) == 1)) { /* */
  245. /* higer value then the highest node in this level */
  246. /*old nl[i].priority = (cnnodes_of_level[l + 1] + 1000 */
  247. nl[i].priority = (100000 - n->relx);
  248. } else {
  249. nl[i].priority = lower_connectivity(n);
  250. }
  251. i++;
  252. }
  253. gnl = gnl->next;
  254. }
  255. sort(cnnodes_of_level[l]);
  256. return;
  257. }
  258. /* */
  259. static void make_node_list_down(int l)
  260. {
  261. struct gml_nlist *gnl = NULL;
  262. struct gml_node *n = NULL;
  263. int i = 0;
  264. /* for_all_nodes(g,n) */
  265. gnl = cnodelist;
  266. while (gnl) {
  267. n = gnl->node;
  268. if (n->absy == l) {
  269. nl[i].node = n;
  270. nl[i].done = 0; /* FALSE */
  271. /* give edge labels lso high prio */
  272. if ((is_dummy(n) == 1) || (is_elabel(n) == 1)) { /* */
  273. /* give dummy node uniq high number */
  274. /*old nl[i].priority = (cnnodes_of_level[l - 1] + 1000 */
  275. nl[i].priority = (100000 - n->relx);
  276. } else {
  277. nl[i].priority = upper_connectivity(n);
  278. }
  279. i++;
  280. }
  281. gnl = gnl->next;
  282. }
  283. sort(cnnodes_of_level[l]);
  284. return;
  285. }
  286. /* get number of node with highest prio which is not done yet */
  287. static int find_next(int n)
  288. {
  289. int index = 0;
  290. int i = 0;
  291. int highest_priority = 0;
  292. for (i = 0; i < n; i++) {
  293. if ((nl[i].priority >= highest_priority)
  294. && (nl[i].done == 0 /* FALSE */ )) {
  295. index = i;
  296. highest_priority = nl[i].priority;
  297. }
  298. }
  299. return (index);
  300. }
  301. static void do_down(int l)
  302. {
  303. int i = 0;
  304. int index = 0;
  305. int j = 0;
  306. int optimal_position = 0;
  307. int distance = 0;
  308. int possible_distance = 0;
  309. for (i = 0; i < cnnodes_of_level[l]; i++) {
  310. index = find_next(cnnodes_of_level[l]);
  311. optimal_position = upper_barycenter(nl[index].node);
  312. if (optimal_position == 0) {
  313. optimal_position = nl[index].node->absx;
  314. }
  315. if (optimal_position < nl[index].node->absx) {
  316. distance = nl[index].node->absx - optimal_position;
  317. possible_distance = 0;
  318. j = index;
  319. do {
  320. if (j > 0) {
  321. possible_distance += nl[j].node->absx - nl[j - 1].node->absx - mindist;
  322. } else {
  323. /* j==0, no nodes at left */
  324. possible_distance += nl[j].node->absx - mindist;
  325. }
  326. j--;
  327. }
  328. while ((j >= 0) && !(nl[j].done));
  329. if (possible_distance < distance) {
  330. distance = possible_distance;
  331. }
  332. j = index;
  333. while (distance > 0) {
  334. int d = 0;
  335. int k = 0;
  336. if (j == 0) {
  337. d = distance;
  338. } else {
  339. if (nl[j].node->absx - nl[j - 1].node->absx - mindist < distance) {
  340. d = nl[j].node->absx - nl[j - 1].node->absx - mindist;
  341. } else {
  342. d = distance;
  343. }
  344. }
  345. for (k = j; k <= index; k++) {
  346. nl[k].node->absx -= d;
  347. }
  348. j--;
  349. distance -= d;
  350. }
  351. } else {
  352. distance = optimal_position - nl[index].node->absx;
  353. possible_distance = 0;
  354. j = index;
  355. do {
  356. if (j < cnnodes_of_level[l] - 1) {
  357. possible_distance += nl[j + 1].node->absx - nl[j].node->absx - mindist;
  358. } else {
  359. /* j == cnnodes_of_level[l]-1, no nodes rechts */
  360. possible_distance += distance;
  361. }
  362. j++;
  363. }
  364. while ((j < cnnodes_of_level[l]) && !(nl[j].done));
  365. if (possible_distance < distance) {
  366. distance = possible_distance;
  367. }
  368. j = index;
  369. while (distance > 0) {
  370. int d = 0;
  371. int k = 0;
  372. if (j == cnnodes_of_level[l] - 1) {
  373. d = distance;
  374. } else {
  375. if (nl[j + 1].node->absx - nl[j].node->absx - mindist < distance) {
  376. d = nl[j + 1].node->absx - nl[j].node->absx - mindist;
  377. } else {
  378. d = distance;
  379. }
  380. }
  381. for (k = index; k <= j; k++) {
  382. nl[k].node->absx += d;
  383. }
  384. j++;
  385. distance -= d;
  386. }
  387. }
  388. nl[index].done = 1; /* TRUE */
  389. }
  390. return;
  391. }
  392. static void do_up(int l)
  393. {
  394. int i = 0;
  395. int index = 0;
  396. int j = 0;
  397. int optimal_position = 0;
  398. int distance = 0;
  399. int possible_distance = 0;
  400. for (i = 0; i < cnnodes_of_level[l]; i++) {
  401. index = find_next(cnnodes_of_level[l]);
  402. optimal_position = lower_barycenter(nl[index].node);
  403. if (optimal_position == 0) {
  404. optimal_position = nl[index].node->absx;
  405. }
  406. if (optimal_position < nl[index].node->absx) {
  407. distance = nl[index].node->absx - optimal_position;
  408. possible_distance = 0;
  409. j = index;
  410. do {
  411. if (j > 0) {
  412. possible_distance += nl[j].node->absx - nl[j - 1].node->absx - mindist;
  413. } else {
  414. /* j == 0, no nodes links */
  415. possible_distance += nl[0].node->absx - mindist;
  416. }
  417. j--;
  418. }
  419. while ((j >= 0) && !(nl[j].done));
  420. if (possible_distance < distance) {
  421. distance = possible_distance;
  422. }
  423. j = index;
  424. while (distance > 0) {
  425. int d = 0;
  426. int k = 0;
  427. if (j == 0) {
  428. d = distance;
  429. } else {
  430. if (nl[j].node->absx - nl[j - 1].node->absx - mindist < distance) {
  431. d = nl[j].node->absx - nl[j - 1].node->absx - mindist;
  432. } else {
  433. d = distance;
  434. }
  435. }
  436. for (k = j; k <= index; k++) {
  437. nl[k].node->absx -= d;
  438. }
  439. j--;
  440. distance -= d;
  441. }
  442. } else {
  443. /* optimal_position >= nl[index].node->absx */
  444. distance = optimal_position - nl[index].node->absx;
  445. possible_distance = 0;
  446. j = index;
  447. do {
  448. if (j < cnnodes_of_level[l] - 1) {
  449. possible_distance += nl[j + 1].node->absx - nl[j].node->absx - mindist;
  450. } else {
  451. /* j == cnnodes_of_level[l]-1, no nodes rechts */
  452. possible_distance += distance;
  453. }
  454. j++;
  455. }
  456. while ((j < cnnodes_of_level[l]) && !(nl[j].done));
  457. if (possible_distance < distance) {
  458. distance = possible_distance;
  459. }
  460. j = index;
  461. while (distance > 0) {
  462. int d = 0;
  463. int k = 0;
  464. if (j == cnnodes_of_level[l] - 1) {
  465. d = distance;
  466. } else {
  467. if (nl[j + 1].node->absx - nl[j].node->absx - mindist < distance) {
  468. d = nl[j + 1].node->absx - nl[j].node->absx - mindist;
  469. } else {
  470. d = distance;
  471. }
  472. }
  473. for (k = index; k <= j; k++) {
  474. nl[k].node->absx += d;
  475. }
  476. j++;
  477. distance -= d;
  478. }
  479. }
  480. nl[index].done = 1; /* TRUE */
  481. }
  482. return;
  483. }
  484. /* determine relative node pos. from the barycenter rel. node pos. */
  485. static void improve_positions2local(struct gml_graph *g)
  486. {
  487. int i = 0;
  488. int count = 0;
  489. int ii = 0;
  490. int sl = 0;
  491. /* start level is 0 */
  492. sl = 0;
  493. /* min. node dist */
  494. mindist = 1;
  495. /* number of up/down sweeps */
  496. count = 1;
  497. for (ii = 0; ii < count; ii++) {
  498. /* DOWN */
  499. for (i = sl; i < g->maxlevel; i++) {
  500. if (cnnodes_of_level[i]) {
  501. nl = (struct node_data *)dp_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  502. make_node_list_down(i);
  503. do_down(i);
  504. nl = dp_free(nl);
  505. if (nl) {
  506. }
  507. }
  508. }
  509. /* UP */
  510. for (i = (g->maxlevel - 1); i >= sl; i--) {
  511. if (cnnodes_of_level[i]) {
  512. nl = (struct node_data *)dp_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  513. make_node_list_up(i);
  514. do_up(i);
  515. nl = dp_free(nl);
  516. if (nl) {
  517. }
  518. }
  519. }
  520. }
  521. /* top+bottom update */
  522. if ((sl + 2) < g->maxlevel) {
  523. for (i = sl + 2; i >= sl; i--) {
  524. if (cnnodes_of_level[i]) {
  525. nl = (struct node_data *)dp_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  526. make_node_list_up(i);
  527. do_up(i);
  528. nl = dp_free(nl);
  529. if (nl) {
  530. }
  531. }
  532. }
  533. }
  534. for (i = (g->maxlevel - 2); i <= g->maxlevel; i++) {
  535. if (i >= 0) {
  536. if (cnnodes_of_level[i]) {
  537. nl = (struct node_data *)dp_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  538. make_node_list_down(i);
  539. do_down(i);
  540. nl = dp_free(nl);
  541. if (nl) {
  542. }
  543. }
  544. }
  545. }
  546. return;
  547. }
  548. /* create nodes-at-level-count */
  549. static void make_cnnodes_at_level(struct gml_graph *g)
  550. {
  551. struct gml_nlist *gnl = NULL;
  552. cnnodes_of_level = (int *)dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  553. gnl = cnodelist;
  554. while (gnl) {
  555. cnnodes_of_level[gnl->node->rely] = cnnodes_of_level[gnl->node->rely] + 1;
  556. gnl = gnl->next;
  557. }
  558. return;
  559. }
  560. /* clear nodes-at-level-count */
  561. static void clear_cnnodes_at_level(void)
  562. {
  563. /* number of nodes at level */
  564. if (cnnodes_of_level) {
  565. cnnodes_of_level = dp_free(cnnodes_of_level);
  566. if (cnnodes_of_level) {
  567. }
  568. }
  569. return;
  570. }
  571. /* copy part of graph */
  572. static void make_cnodelist(struct gml_graph *g)
  573. {
  574. struct gml_nlist *gnl = NULL;
  575. struct gml_nlist *newnl = NULL;
  576. gnl = g->nodelist;
  577. while (gnl) {
  578. /* check if node belongs to part of graph */
  579. if (gnl->node->startnode == csn) {
  580. /* copy node in new list */
  581. newnl = (struct gml_nlist *)dp_calloc(1, sizeof(struct gml_nlist));
  582. newnl->node = gnl->node;
  583. if (cnodelist == NULL) {
  584. cnodelist = newnl;
  585. cnodelisttail = newnl;
  586. } else {
  587. cnodelisttail->next = newnl;
  588. cnodelisttail = newnl;
  589. }
  590. }
  591. gnl = gnl->next;
  592. }
  593. if (yydebug || 0) {
  594. printf("%s(): nodes in graph part with startnode %d are:\n", __func__, csn);
  595. gnl = cnodelist;
  596. while (gnl) {
  597. printf("%s(): node %d level=%d startnode %d\n", __func__, gnl->node->nr, gnl->node->rely, csn);
  598. gnl = gnl->next;
  599. }
  600. }
  601. return;
  602. }
  603. /* done with this part of graph */
  604. static void clear_cnodelist(void)
  605. {
  606. struct gml_nlist *gnl = NULL;
  607. struct gml_nlist *gnlnext = NULL;
  608. gnl = cnodelist;
  609. while (gnl) {
  610. gnlnext = gnl->next;
  611. gnl = dp_free(gnl);
  612. if (gnl) {
  613. }
  614. gnl = gnlnext;
  615. }
  616. /* node list of part of graph */
  617. cnodelist = NULL;
  618. cnodelisttail = NULL;
  619. return;
  620. }
  621. /* move image of this part of graph */
  622. static void move0(void)
  623. {
  624. struct gml_nlist *gnl = NULL;
  625. int mx = 0;
  626. /* find min. x pos in-use */
  627. mx = 1000 * 1000; /* just some high value */
  628. gnl = cnodelist;
  629. while (gnl) {
  630. if (gnl->node->absx < mx) {
  631. mx = gnl->node->absx;
  632. }
  633. gnl = gnl->next;
  634. }
  635. /* move whole drawing to the left */
  636. gnl = cnodelist;
  637. while (gnl) {
  638. gnl->node->absx = (gnl->node->absx - mx);
  639. gnl = gnl->next;
  640. }
  641. return;
  642. }
  643. /* */
  644. static void make_cposnodes(void)
  645. {
  646. struct gml_nlist *lnl = NULL;
  647. struct gml_nlist *newl = NULL;
  648. int i = 0;
  649. int lmaxw = 0;
  650. int maxrx = 0;
  651. /* widest x level */
  652. cwidestnnodes = 0;
  653. /* x width at position */
  654. cwpos = NULL;
  655. /* lists per pos. */
  656. cposnodes = NULL;
  657. /* extra check max rel. x pos. */
  658. lnl = cnodelist;
  659. while (lnl) {
  660. if (lnl->node->absx > maxrx) {
  661. maxrx = lnl->node->absx;
  662. }
  663. lnl = lnl->next;
  664. }
  665. /* pos2.c has moved node in x dir. */
  666. cwidestnnodes = maxrx;
  667. /* x width at position */
  668. cwpos = (int *)dp_calloc(1, (cwidestnnodes + 1) * sizeof(int));
  669. /* lists with nodes up to down at position */
  670. cposnodes = (struct gml_nlist **)dp_calloc(1, (cwidestnnodes + 1) * sizeof(struct gml_nlist *));
  671. /* create for every postion the list of nodes at that position */
  672. lnl = cnodelist;
  673. while (lnl) {
  674. i = lnl->node->absx;
  675. if (yydebug || 0) {
  676. printf("%s(): node \"%s\" at absx %d\n", __func__, lnl->node->nlabel, lnl->node->absx);
  677. }
  678. newl = (struct gml_nlist *)dp_calloc(1, sizeof(struct gml_nlist));
  679. newl->node = lnl->node;
  680. if (cposnodes[i] == NULL) {
  681. cposnodes[i] = newl;
  682. newl->next = NULL;
  683. } else {
  684. newl->next = cposnodes[i];
  685. cposnodes[i] = newl;
  686. }
  687. lnl = lnl->next;
  688. }
  689. /* determine the max width of a element at vertical pos. */
  690. for (i = 0; i < (cwidestnnodes + 1); i++) {
  691. lmaxw = 0;
  692. /* lists per pos. */
  693. lnl = cposnodes[i];
  694. while (lnl) {
  695. if (lnl->node->bbx > lmaxw) {
  696. lmaxw = lnl->node->bbx;
  697. }
  698. lnl = lnl->next;
  699. }
  700. cwpos[i] = lmaxw;
  701. }
  702. return;
  703. }
  704. /* */
  705. static void clear_cposnodes(void)
  706. {
  707. int i = 0;
  708. struct gml_nlist *lnl = NULL;
  709. struct gml_nlist *nlnext = NULL;
  710. /* width of positions */
  711. if (cwpos) {
  712. cwpos = dp_free(cwpos);
  713. if (cwpos) {
  714. }
  715. }
  716. for (i = 0; i < (cwidestnnodes + 1); i++) {
  717. /* lists per pos. */
  718. lnl = cposnodes[i];
  719. while (lnl) {
  720. nlnext = lnl->next;
  721. lnl = dp_free(lnl);
  722. if (lnl) {
  723. }
  724. lnl = nlnext;
  725. }
  726. cposnodes[i] = NULL;
  727. }
  728. cposnodes = dp_free(cposnodes);
  729. if (cposnodes) {
  730. }
  731. return;
  732. }
  733. /* y positioning */
  734. static void make_clevelnodes(struct gml_graph *g)
  735. {
  736. struct gml_nlist *lnl = NULL;
  737. struct gml_nlist *newl = NULL;
  738. int i = 0;
  739. int lmaxh = 0;
  740. chpos = (int *)dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  741. clevelnodes = (struct gml_nlist **)dp_calloc(1, ((g->maxlevel + 1) * sizeof(struct gml_nlist *)));
  742. lnl = cnodelist;
  743. while (lnl) {
  744. i = lnl->node->absy;
  745. if (yydebug || 0) {
  746. printf("%s(): at \"%s\" absx %d absy %d\n", __func__, lnl->node->nlabel, lnl->node->absx, lnl->node->absy);
  747. }
  748. newl = dp_calloc(1, sizeof(struct gml_nlist));
  749. newl->node = lnl->node;
  750. if (clevelnodes[i] == NULL) {
  751. clevelnodes[i] = newl;
  752. newl->next = NULL;
  753. } else {
  754. newl->next = clevelnodes[i];
  755. clevelnodes[i] = newl;
  756. }
  757. lnl = lnl->next;
  758. }
  759. /* determine the max width of a element at vertical pos. */
  760. for (i = 0; i < (g->maxlevel + 1); i++) {
  761. lmaxh = 0;
  762. /* lists per pos. */
  763. lnl = clevelnodes[i];
  764. while (lnl) {
  765. if (yydebug || 0) {
  766. printf("%s(): scan \"%s\"\n", __func__, lnl->node->nlabel);
  767. }
  768. if (lnl->node->bby > lmaxh) {
  769. lmaxh = lnl->node->bby;
  770. }
  771. lnl = lnl->next;
  772. }
  773. chpos[i] = lmaxh;
  774. }
  775. return;
  776. }
  777. static void clear_clevelnodes(struct gml_graph *g)
  778. {
  779. int i = 0;
  780. struct gml_nlist *lnl = NULL;
  781. struct gml_nlist *lnl2 = NULL;
  782. struct gml_nlist *nlnext = NULL;
  783. /* width of positions */
  784. if (chpos) {
  785. chpos = dp_free(chpos);
  786. if (chpos) {
  787. }
  788. }
  789. if (clevelnodes) {
  790. for (i = 0; i < (g->maxlevel + 1); i++) {
  791. /* lists per pos. */
  792. lnl = clevelnodes[i];
  793. while (lnl) {
  794. nlnext = lnl->next;
  795. lnl2 = dp_free(lnl);
  796. if (lnl2) {
  797. }
  798. lnl = nlnext;
  799. }
  800. clevelnodes[i] = NULL; /* */
  801. }
  802. clevelnodes = dp_free(clevelnodes);
  803. if (clevelnodes) {
  804. }
  805. }
  806. return;
  807. }
  808. /* determine final (x,y) pos */
  809. static void cfinalxy(struct gml_graph *g)
  810. {
  811. struct gml_nlist *lnl = NULL;
  812. int hw = 0;
  813. int xoff = 0;
  814. int yoff = 0;
  815. int i = 0;
  816. int ecount = 0;
  817. /* x positioning */
  818. make_cposnodes();
  819. cmaxx = 0;
  820. xoff = 0;
  821. /* scan hor. to adjust the x positions. */
  822. for (i = 0; i < (cwidestnnodes + 1); i++) {
  823. /* x spacing between the hor. levels */
  824. xoff = xoff + xspacing;
  825. /* determine half-way of the xpos. */
  826. if (cwpos[i] == 0) {
  827. /* if only dummy nodes */
  828. hw = xspacing / 2;
  829. } else {
  830. hw = (cwpos[i] / 2);
  831. }
  832. /* update with current x */
  833. hw = hw + xoff;
  834. lnl = cposnodes[i];
  835. /* scan the nodes at this x pos. */
  836. while (lnl) {
  837. /* center the node around the half-way */
  838. lnl->node->finx = (hw - (lnl->node->bbx / 2));
  839. if ((lnl->node->finx + lnl->node->bbx) > cmaxx) {
  840. cmaxx = (lnl->node->finx + lnl->node->bbx);
  841. }
  842. lnl = lnl->next;
  843. }
  844. /* set x0,x1 pos in the nodes */
  845. lnl = cposnodes[i];
  846. /* scan the nodes at this x pos. */
  847. while (lnl) {
  848. /* */
  849. lnl->node->lx0 = xoff;
  850. lnl->node->lx1 = xoff + cwpos[i];
  851. lnl = lnl->next;
  852. }
  853. /* x spacing between the hor. levels */
  854. xoff = xoff + xspacing;
  855. /* x to next pos. */
  856. xoff = xoff + cwpos[i];
  857. }
  858. /* */
  859. clear_cposnodes();
  860. /* y positioning */
  861. make_clevelnodes(g);
  862. cmaxy = 0;
  863. yoff = 0;
  864. /* number of edges between level n and n+1 */
  865. if (g->nume) {
  866. g->nume = (int *)dp_free((int *)g->nume);
  867. }
  868. g->nume = (int *)dp_calloc(1, (g->maxlevel + 1) * sizeof(int));
  869. /* scan vert. to adjust the y positions. */
  870. for (i = 0; i < (g->maxlevel + 1); i++) {
  871. /* determine half-way of the ypos. */
  872. if (chpos[i] == 0) {
  873. /* if only dummy nodes */
  874. hw = (yspacing / 2);
  875. } else {
  876. hw = (chpos[i] / 2);
  877. }
  878. /* update half-way with current y */
  879. hw = hw + yoff;
  880. if (yydebug || 0) {
  881. printf("%s(): at level %d y size is %d from %d to %d and half-way is %d\n", __func__, i, chpos[i], yoff,
  882. yoff + chpos[i], hw);
  883. }
  884. /* nodes at this relative y level */
  885. lnl = clevelnodes[i];
  886. ecount = 0;
  887. /* scan the nodes at this y pos. */
  888. while (lnl) {
  889. if (lnl->node->rely != i) {
  890. printf("%s(): wrong level for node \"%s\" at level %d versus rely=%d\n", __func__, lnl->node->name,
  891. i, lnl->node->rely);
  892. }
  893. /* set start, end of y level */
  894. lnl->node->ly0 = yoff;
  895. lnl->node->ly1 = (yoff + chpos[i]);
  896. /* center the node around the half-way */
  897. lnl->node->finy = (hw - (lnl->node->bby / 2));
  898. if (yydebug || 0) {
  899. printf("%s(): node \"%s\" at y-pos=%d level %d\n", __func__, lnl->node->name, lnl->node->finy, lnl->node->rely);
  900. }
  901. /* update drawing max y pos used */
  902. if ((lnl->node->finy + lnl->node->bby) > cmaxy) {
  903. cmaxy = (lnl->node->finy + lnl->node->bby);
  904. }
  905. /* give dummy nodes a vertical size of the level */
  906. if (lnl->node->dummy) {
  907. lnl->node->bby = chpos[i];
  908. /* if only dummy nodes at level, use spacing */
  909. if (chpos[i] == 0) {
  910. lnl->node->bby = yspacing;
  911. }
  912. }
  913. /* number of edges between level n and n+1 */
  914. ecount = ecount + lnl->node->outdegree;
  915. lnl = lnl->next;
  916. }
  917. g->nume[i] = ecount;
  918. /* y spacing between the vert. levels */
  919. yoff = yoff + yspacing;
  920. /* yspacing depends on number of edges at this level
  921. * turned off, does increase y too much
  922. * yoff = yoff + (ecount * 2);
  923. */
  924. /* yspacing depends on number of crossing edges at this level
  925. * temp test
  926. */
  927. yoff = yoff + (1 * (g->numce[i] / 16));
  928. /* y to next pos. */
  929. yoff = yoff + chpos[i];
  930. }
  931. clear_clevelnodes(g);
  932. /* clear number of edges between level n and n+1 */
  933. clear_nume_r(g);
  934. return;
  935. }
  936. /* move whole part to new x offset position */
  937. static void movefinal(int xoffset)
  938. {
  939. struct gml_nlist *gnl = NULL;
  940. gnl = cnodelist;
  941. while (gnl) {
  942. gnl->node->finx = gnl->node->finx + xoffset;
  943. gnl->node->lx0 = gnl->node->lx0 + xoffset;
  944. gnl->node->lx1 = gnl->node->lx1 + xoffset;
  945. /* x,y size of raster */
  946. gnl->node->lxsize = (gnl->node->lx1 - gnl->node->lx0);
  947. gnl->node->lysize = (gnl->node->ly1 - gnl->node->ly0);
  948. /* extra check */
  949. if (gnl->node->lxsize < 0) {
  950. printf("%s(): lxsize=%d fixme\n", __func__, gnl->node->lxsize);
  951. }
  952. if (gnl->node->lysize < 0) {
  953. printf("%s(): lysize=%d fixme\n", __func__, gnl->node->lysize);
  954. }
  955. gnl = gnl->next;
  956. }
  957. return;
  958. }
  959. /* dummy nodes can be centered, or left/right most placed */
  960. static void tunedummy(struct gml_graph *g)
  961. {
  962. struct gml_nlist *gnl = NULL;
  963. int x1 = 0;
  964. int x2 = 0;
  965. int x3 = 0;
  966. gnl = g->nodelist;
  967. while (gnl) {
  968. if (gnl->node->dummy) {
  969. x1 = gnl->node->finx;
  970. if (gnl->node->incoming_e && gnl->node->outgoing_e) {
  971. x2 = gnl->node->incoming_e->edge->from_node->finx + gnl->node->incoming_e->edge->from_node->bbx / 2;
  972. x3 = gnl->node->outgoing_e->edge->to_node->finx + gnl->node->outgoing_e->edge->to_node->bbx / 2;
  973. if ((x1 == x2) && (x1 == x3)) {
  974. /* no move */
  975. } else {
  976. if ((x2 < x1) && (x3 < x1)) {
  977. /* to left */
  978. gnl->node->finx = gnl->node->lx0;
  979. }
  980. if ((x2 > x1) && (x3 > x1)) {
  981. /* to right */
  982. gnl->node->finx = gnl->node->lx1;
  983. }
  984. }
  985. } else {
  986. /* shouldnothappen */
  987. printf("%s(): dummy node with in_e %p and out_e %p\n", __func__, (void *)gnl->node->incoming_e,
  988. (void *)gnl->node->outgoing_e);
  989. }
  990. }
  991. gnl = gnl->next;
  992. }
  993. return;
  994. }
  995. /* move some nodes up/down */
  996. static void tunenodes(struct gml_graph *g)
  997. {
  998. struct gml_nlist *gnl = NULL;
  999. gnl = g->nodelist;
  1000. while (gnl) {
  1001. /* only at real nodes */
  1002. if (gnl->node->dummy == 0) {
  1003. if (gnl->node->hashedge) {
  1004. /* do not move node with hor. edge */
  1005. } else {
  1006. if (gnl->node->indegree > 0 && gnl->node->outdegree == 0) {
  1007. /* move up */
  1008. gnl->node->finy = gnl->node->ly0;
  1009. }
  1010. if (gnl->node->indegree == 0 && gnl->node->outdegree > 0) {
  1011. /* move down */
  1012. gnl->node->finy = (gnl->node->ly1 - gnl->node->bby);
  1013. }
  1014. if (gnl->node->indegree > 0 && gnl->node->outdegree > 0) {
  1015. if (gnl->node->indegree == gnl->node->outdegree) {
  1016. /* no movement
  1017. *
  1018. */
  1019. } else {
  1020. if (gnl->node->indegree > gnl->node->outdegree) {
  1021. /* move up */
  1022. gnl->node->finy = gnl->node->ly0;
  1023. }
  1024. if (gnl->node->outdegree > gnl->node->indegree) {
  1025. /* move down */
  1026. gnl->node->finy = (gnl->node->ly1 - gnl->node->bby);
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. gnl = gnl->next;
  1033. }
  1034. return;
  1035. }
  1036. /* position in parts of graph at each step */
  1037. void improve_positions2(struct gml_graph *g)
  1038. {
  1039. struct gml_nlist *gnl = NULL;
  1040. int i = 0;
  1041. int xoffset = 0;
  1042. /* copy the rel(x,y) pos into abs(x,y) and modify the absx pos here */
  1043. gnl = g->nodelist;
  1044. while (gnl) {
  1045. gnl->node->absx = gnl->node->relx;
  1046. gnl->node->absy = gnl->node->rely;
  1047. gnl->node->finx = 0;
  1048. gnl->node->finy = 0;
  1049. gnl->node->lx0 = -1; /* undefined */
  1050. gnl->node->ly0 = -1;
  1051. gnl->node->lx1 = -1;
  1052. gnl->node->ly1 = -1;
  1053. if (gnl->node->startnode < 0) {
  1054. printf("%s(): node %d %s has no startnode\n", __func__, gnl->node->nr, gnl->node->name);
  1055. }
  1056. if (yydebug || 0) {
  1057. printf("%s(): node \"%s\" is at level %d position %d startnode %d\n", __func__, gnl->node->nlabel,
  1058. gnl->node->rely, gnl->node->relx, gnl->node->startnode);
  1059. }
  1060. gnl = gnl->next;
  1061. }
  1062. /* offset in drawing of part of graph */
  1063. xoffset = 0;
  1064. printf("%s(): %d startnodes\n", __func__, g->nstartnodes);
  1065. for (i = 0; i < g->nstartnodes; i++) {
  1066. /* set current startnode */
  1067. csn = g->startnodes[i];
  1068. if (yydebug || 0) {
  1069. printf("%s(): step %d for startnode=%d\n", __func__, i, csn);
  1070. }
  1071. /* print progress info */
  1072. if ((i == 0) || (i == g->nstartnodes / 2) || (i == g->nstartnodes - 1)) {
  1073. printf("%s(): positioning step %d of %d start nr=%d\n", __func__, i + 1, g->nstartnodes, csn);
  1074. fflush(stdout);
  1075. }
  1076. /* max. x in part of graph */
  1077. cmaxx = 0;
  1078. /* copy part of graph */
  1079. make_cnodelist(g);
  1080. /* create nodes-at-level-count */
  1081. make_cnnodes_at_level(g);
  1082. /* run up/down placement */
  1083. improve_positions2local(g);
  1084. /* move image of this part of graph */
  1085. move0();
  1086. /* set final x,y */
  1087. cfinalxy(g);
  1088. /* tune dummy nodes */
  1089. tunedummy(g);
  1090. /* tune nodes */
  1091. tunenodes(g);
  1092. /* move */
  1093. movefinal(xoffset);
  1094. /* update for next */
  1095. xoffset = xoffset + cmaxx + xspacing;
  1096. /* clear nodes-at-level-count */
  1097. clear_cnnodes_at_level();
  1098. /* done with this part of graph */
  1099. clear_cnodelist();
  1100. }
  1101. /* position level 0, single nodes if any */
  1102. if (g->nsinglenodes) {
  1103. /* done in finalxy() in main.c */
  1104. }
  1105. /* run extra check */
  1106. gnl = g->nodelist;
  1107. while (gnl) {
  1108. /* check undefined */
  1109. if ((gnl->node->lx0 == -1) || (gnl->node->ly0 == -1) || (gnl->node->lx1 == -1) || (gnl->node->ly1 == -1)
  1110. ) {
  1111. printf("%s(): node level undefined\n", __func__);
  1112. }
  1113. gnl = gnl->next;
  1114. }
  1115. return;
  1116. }
  1117. /* end */