sfg.c 126 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659
  1. /*
  2. * Copyright t lefering
  3. * parts are (C) Universitaet Passau 1986-1991
  4. * parts are Copyright (C) 1998-2021 Free Software Foundation, Inc.
  5. * parts are Copyright (C) Felix von Leitner from dietlibc
  6. *
  7. * https://notabug.org/mooigraph/sfgraph
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * These are the four essential freedoms with GNU GPL software:
  23. * 1: freedom to run the program, for any purpose
  24. * 2: freedom to study how the program works, and change it to make it do what you wish
  25. * 3: freedom to redistribute copies to help your Free Software friends
  26. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  27. * , ,
  28. * / \
  29. * ((__-^^-,-^^-__))
  30. * `-_---' `---_-'
  31. * `--|o` 'o|--'
  32. * \ ` /
  33. * ): :(
  34. * :o_o:
  35. * "-"
  36. *
  37. * SPDX-License-Identifier: GPL-3.0+
  38. * License-Filename: LICENSE
  39. */
  40. /* Single File Graph layout for directed graphs.
  41. * the api to use this file is in sfg.h
  42. * the demo program how to use is sfgdemo.c
  43. */
  44. #undef __BEGIN_DECLS
  45. #undef __END_DECLS
  46. #ifdef __cplusplus
  47. # define __BEGIN_DECLS extern "C" {
  48. # define __END_DECLS }
  49. #else
  50. # define __BEGIN_DECLS /* empty */
  51. # define __END_DECLS /* empty */
  52. #endif
  53. __BEGIN_DECLS
  54. #include <stdio.h>
  55. #include <stdlib.h> /* for calloc() free() */
  56. /* from <limits.h> for CHAR_BIT is 8 definition */
  57. #ifndef CHAR_BIT
  58. #define CHAR_BIT 8
  59. #endif
  60. /* min (x,y) spacing between nodes */
  61. #define NXSPACING 5
  62. #define NYSPACING 15
  63. #include "sfg.h"
  64. struct gml_graph;
  65. struct gml_node;
  66. struct gml_edge;
  67. struct gml_nlist;
  68. struct gml_elist;
  69. /* here calloc/free can be changed and malloc, realloc is not used */
  70. static inline void *sfg_calloc (size_t nmemb, size_t size)
  71. {
  72. void *ret = NULL;
  73. if ((nmemb * size) == 0) {
  74. /* should not happen */
  75. }
  76. ret = xcalloc (nmemb, size);
  77. if (ret == (void *)0) {
  78. /* should not happen */
  79. exit (1);
  80. }
  81. return (ret);
  82. }
  83. static inline void *sfg_free (void *ptr)
  84. {
  85. if (ptr) {
  86. free (ptr);
  87. }
  88. return ((void *)0);
  89. }
  90. /* how many bytes can a splay key to index on have max.
  91. * this data type must be large enough for a pointer.
  92. * The size of `void *', as computed by sizeof.
  93. * #define SIZEOF_VOID_P 8
  94. * in configure.ac is:
  95. * AC_CHECK_SIZEOF([void *])
  96. * The size of `uintptr_t', as computed by sizeof.
  97. * #define SIZEOF_UINTPTR_T 8
  98. *
  99. * #include <stdint.h> // for uintptr_t definition
  100. * typedef unsigned long long int splay_tree_key;
  101. * typedef uintptr_t splay_tree_key;
  102. * in this situation it can be:
  103. */
  104. typedef uintptr_t sfg_splay_tree_key;
  105. /* how many bytes can a splay value have max
  106. * typedef unsigned long long int splay_tree_value;
  107. * typedef uintptr_t splay_tree_value;
  108. * int this situation it can be:
  109. */
  110. typedef struct gml_node *sfg_splay_tree_value;
  111. /* Forward declaration for a tree. */
  112. typedef struct sfg_splay_tree_t *sfg_splay_tree;
  113. /* The nodes in the splay tree. */
  114. struct sfg_splay_tree_node_n {
  115. /* The key. */
  116. sfg_splay_tree_key key;
  117. /* The value. */
  118. sfg_splay_tree_value value;
  119. /* The left and right children, respectively. */
  120. struct sfg_splay_tree_node_n *left;
  121. struct sfg_splay_tree_node_n *right;
  122. };
  123. /* Forward declaration for a node in the tree. */
  124. typedef struct sfg_splay_tree_node_n *sfg_splay_tree_node;
  125. /* The type of a function which compares two splay-tree keys. The
  126. function should return values as for qsort. */
  127. typedef int (*sfg_splay_tree_compare_fn)(sfg_splay_tree_key, sfg_splay_tree_key);
  128. /* The type of a function used to deallocate any resources associated
  129. with the key. */
  130. typedef void (*sfg_splay_tree_delete_key_fn)(sfg_splay_tree_key);
  131. /* The type of a function used to deallocate any resources associated
  132. with the value. */
  133. typedef void (*sfg_splay_tree_delete_value_fn)(sfg_splay_tree_value);
  134. /* The type of a function used to iterate over the tree. */
  135. typedef int (*sfg_splay_tree_foreach_fn)(sfg_splay_tree_node, void *);
  136. /* The splay tree itself. */
  137. struct sfg_splay_tree_t {
  138. /* The root of the tree. */
  139. struct sfg_splay_tree_node_n *root;
  140. /* The comparision function. */
  141. sfg_splay_tree_compare_fn comp;
  142. /* The deallocate-key function. NULL if no cleanup is necessary. */
  143. sfg_splay_tree_delete_key_fn delete_key;
  144. /* The deallocate-value function. NULL if no cleanup is necessary. */
  145. sfg_splay_tree_delete_value_fn delete_value;
  146. };
  147. struct gml_graph {
  148. int layouted; /* set if layout is done */
  149. int nodenum; /* highest node number in use */
  150. int nnodes; /* number of nodes in the graph */
  151. int edgenum; /* highest edge number in use */
  152. int nedges; /* number of edges in the graph */
  153. int maxlevel; /* maximum relative level */
  154. int nedgelabels; /* number of edgelabels */
  155. int do_edgelabels; /* if set add edgelabels in the graph */
  156. int nsinglenodes; /* number of single nodes */
  157. int nhedges; /* number of hor edges */
  158. int startnodeslevel; /* level where graph drawing starts */
  159. int nstartnodes; /* number of start node numbers */
  160. int *startnodes; /* array with start node numbers */
  161. int xspacing; /* min x spacing between nodes */
  162. int yspacing; /* min y spacing between nodes */
  163. struct gml_nlist *nodelist; /* list of nodes */
  164. struct gml_nlist *nodelistend;
  165. struct gml_nlist *singlenodelist; /* list of single nodes */
  166. struct gml_nlist *singlenodelistend;
  167. struct gml_elist *edgelist; /* list of edges */
  168. struct gml_elist *edgelistend;
  169. int *nnodes_of_level; /* number of nodes for each level */
  170. int widestnnodes; /* widest number of nodes on one level */
  171. int widestlevel; /* widest level */
  172. int sugi_icrossings; /* initial crossings */
  173. int sugi_fcrossings; /* final crossings */
  174. int sugi_changes; /* sugiyama changes made */
  175. int *numce; /* number of crossings at every level */
  176. int *nume; /* number of edges */
  177. int maxx; /* max x pos of drawing */
  178. int maxy; /* max y pos of drawing */
  179. int nodemin; /* min. node number in use */
  180. int nodemax; /* max. node number in use */
  181. int edgemin; /* min. edge number in use */
  182. int edgemax; /* max. edge number in use */
  183. };
  184. struct gml_node {
  185. int nr; /* uniq node number */
  186. int tx; /* text xsize */
  187. int ty; /* text ysize */
  188. int bbx; /* text xsize */
  189. int bby; /* text ysize */
  190. int dummy; /* set to 1 if dummy node */
  191. int elabel; /* set if node is a edge label */
  192. int enumber; /* orig. edge number of the edge label */
  193. int nselfedges; /* number of self edges at this node */
  194. int done; /* dfs black/white */
  195. int grey; /* dfs grey */
  196. int indegree; /* incoming edges to node */
  197. int outdegree; /* outgoing edges from node */
  198. int hashedge; /* set if node has hor. edge */
  199. void *data; /* user data */
  200. int relx; /* relative xpos */
  201. int rely; /* relative ypos */
  202. int absx; /* absolute xpos */
  203. int absy; /* absolute ypos */
  204. int lx0; /* absolute xpos */
  205. int ly0; /* absolute xpos */
  206. int lx1; /* absolute ypos */
  207. int ly1; /* absolute ypos */
  208. int finx; /* absolute xpos */
  209. int finy; /* absolute ypos */
  210. struct gml_elist *outgoing_e; /* source list, outgoing edges */
  211. struct gml_elist *outgoing_etail; /* source list, outgoing edges */
  212. struct gml_elist *incoming_e; /* target list, incoming edges */
  213. struct gml_elist *incoming_etail; /* target list, incoming edges */
  214. int startnode; /* node belongs to part of graph with this startnode */
  215. struct gml_node *el_fnode; /* in edge-label the from-node */
  216. struct gml_node *el_tnode; /* in edge-label the to-node */
  217. };
  218. struct gml_edge {
  219. int nr; /* uniq edge number */
  220. struct gml_node *from_node; /* from node */
  221. struct gml_node *to_node; /* to node */
  222. int tx; /* text xsize */
  223. int ty; /* text ysize */
  224. int elabel; /* set if there is a edge label */
  225. int reversed; /* set if edge is reversed */
  226. int hedge; /* set if hor. edge */
  227. };
  228. struct gml_nlist {
  229. struct gml_node *node;
  230. struct gml_nlist *next;
  231. };
  232. struct gml_elist {
  233. struct gml_edge *edge;
  234. struct gml_elist *next;
  235. };
  236. /* local vars */
  237. static struct gml_graph *maingraph = NULL;
  238. /* by uniq number of node */
  239. static sfg_splay_tree uniqnode_splaytree = NULL;
  240. /* forward declarations zz */
  241. static struct sfg_splay_tree_node_n *splay(sfg_splay_tree sp, sfg_splay_tree_key key);
  242. static sfg_splay_tree_node sfg_splay_tree_lookup(sfg_splay_tree sp, sfg_splay_tree_key key);
  243. static sfg_splay_tree sfg_splay_tree_delete(sfg_splay_tree sp);
  244. static sfg_splay_tree sfg_splay_tree_new(sfg_splay_tree_compare_fn compare_fn, sfg_splay_tree_delete_key_fn delete_key_fn,
  245. sfg_splay_tree_delete_value_fn delete_value_fn);
  246. static int sfg_splay_tree_compare_ints(sfg_splay_tree_key k1, sfg_splay_tree_key k2);
  247. static struct gml_node *uniqnode(struct gml_graph *g, int nr);
  248. static void uniqnode_add(struct gml_graph *g, struct gml_node *node);
  249. static void clear_nodelist(struct gml_graph *g);
  250. static void clear_edgelist(struct gml_graph *g);
  251. static void prep(struct gml_graph *g);
  252. static void reorg(struct gml_graph *g);
  253. static void uncycle(struct gml_graph *g);
  254. static void make_stlist(struct gml_graph *g);
  255. static void clear_stlist(struct gml_node *node);
  256. static void clear_stlist_all(struct gml_graph *g);
  257. static void ylevels(struct gml_graph *g);
  258. static void set_level2(struct gml_graph *g, struct gml_node *n, int i, int startnode);
  259. static void shorteredges(struct gml_graph *g);
  260. static void edgesdownwards(struct gml_graph *g);
  261. static void edgelen(struct gml_graph *g);
  262. static void doublespacey(struct gml_graph *g);
  263. static void edgelabels(struct gml_graph *g);
  264. static void splitedges(struct gml_graph *g);
  265. static void nodecounts(struct gml_graph *g);
  266. static void barycenter(struct gml_graph *g, int it1v, int it2v);
  267. static void improve_positions(struct gml_graph *g);
  268. static void finalxy(struct gml_graph *g);
  269. static struct gml_edge *findedge(int num);
  270. static void setminmax(struct gml_graph *g);
  271. /* returns a version number as version 1.0 returns int 10 */
  272. int sfg_version(void)
  273. {
  274. return (30);
  275. }
  276. /* init
  277. * returns 0 if oke
  278. * returns -1 if already inited
  279. * returns -2 if other error
  280. */
  281. int sfg_init(void)
  282. {
  283. if (maingraph) {
  284. return (-1);
  285. }
  286. maingraph = (struct gml_graph *) sfg_calloc(1, sizeof(struct gml_graph));
  287. if (maingraph == NULL) {
  288. return (-2);
  289. }
  290. uniqnode_splaytree = sfg_splay_tree_new(sfg_splay_tree_compare_ints, NULL, NULL);
  291. if (uniqnode_splaytree == NULL) {
  292. return (-2);
  293. }
  294. /* min (x,y) spacing between nodes */
  295. maingraph->xspacing = NXSPACING;
  296. maingraph->yspacing = NYSPACING;
  297. maingraph->do_edgelabels = 1;
  298. return (0);
  299. }
  300. /* de-init
  301. * returns 0 if oke
  302. * returns -1 if not inited
  303. */
  304. int sfg_deinit(void)
  305. {
  306. if (maingraph == NULL) {
  307. return (-1);
  308. }
  309. if (maingraph->numce) {
  310. maingraph->numce = (int *) sfg_free (maingraph->numce);
  311. }
  312. if (maingraph->nnodes_of_level) {
  313. maingraph->nnodes_of_level = (int *) sfg_free (maingraph->nnodes_of_level);
  314. }
  315. if (maingraph->startnodes) {
  316. maingraph->startnodes = (int *) sfg_free(maingraph->startnodes);
  317. }
  318. clear_stlist_all(maingraph);
  319. clear_edgelist(maingraph);
  320. clear_nodelist(maingraph);
  321. uniqnode_splaytree = sfg_splay_tree_delete(uniqnode_splaytree);
  322. maingraph = (struct gml_graph *) sfg_free (maingraph);
  323. return (0);
  324. }
  325. /* add a node with uniq number starting at 1
  326. * with (tx,ty) as rectangle size for label text or (0,0)
  327. * before adding edges all node numbers must be defined
  328. * returns 0 if oke
  329. * returns -1 if not inited
  330. * returns -2 if number is lower then 1
  331. * returns -3 if tx number is lower then 0
  332. * returns -4 if ty number is lower then 0
  333. * returns -5 if layout already done
  334. * returns -6 if node already defined
  335. * returns -7 if other error
  336. */
  337. int sfg_addnode(int number, int tx, int ty)
  338. {
  339. struct gml_node *nn = NULL;
  340. struct gml_nlist *nl = NULL;
  341. if (maingraph == NULL) {
  342. return (-1);
  343. }
  344. if (number < 1) {
  345. return (-2);
  346. }
  347. if (tx < 0) {
  348. return (-3);
  349. }
  350. if (ty < 0) {
  351. return (-4);
  352. }
  353. if (maingraph->layouted) {
  354. return (-5);
  355. }
  356. /* check if node does exist already */
  357. if (uniqnode(maingraph, number)) {
  358. return (-6);
  359. }
  360. /* create the new node */
  361. nn = (struct gml_node *) sfg_calloc(1, sizeof(struct gml_node));
  362. if (nn == NULL) {
  363. return (-7);
  364. }
  365. nl = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  366. if (nl == NULL) {
  367. nn = (struct gml_node *) sfg_free (nn);
  368. return (-7);
  369. }
  370. nn->nr = number;
  371. nn->tx = tx;
  372. nn->ty = ty;
  373. /* data field is inited NULL and is set via other routine */
  374. nl->node = nn;
  375. if (maingraph->nodelist == NULL) {
  376. maingraph->nodelist = nl;
  377. maingraph->nodelistend = nl;
  378. } else {
  379. maingraph->nodelistend->next = nl;
  380. maingraph->nodelistend = nl;
  381. }
  382. if (number > maingraph->nodenum) {
  383. /* highest node number in use */
  384. maingraph->nodenum = number;
  385. }
  386. uniqnode_add(maingraph, nn);
  387. /* number of nodes in the graph */
  388. maingraph->nnodes++;
  389. return (0);
  390. }
  391. /* add a edge with uniq number starting at 1
  392. * the from-node number is in from, the to-node number is in to
  393. * self-edges are allowed but not with a label
  394. * with (tx,ty) as rectangle size for label text or (0,0)
  395. * returns 0 if oke
  396. * returns -1 if not inited
  397. * returns -2 if number is lower then 1
  398. * returns -3 if tx number is lower then 0
  399. * returns -4 if ty number is lower then 0
  400. * returns -5 if from-node number is not defined
  401. * returns -6 if to-node number is not defined
  402. * returns -7 if self-edge with a label
  403. * returns -8 if layout already done
  404. * returns -9 if other error
  405. */
  406. int sfg_addedge(int number, int from, int to, int tx, int ty)
  407. {
  408. struct gml_node *fn = NULL;
  409. struct gml_node *tn = NULL;
  410. struct gml_edge *e = NULL;
  411. struct gml_elist *el = NULL;
  412. if (maingraph == NULL) {
  413. return (-1);
  414. }
  415. if (number < 1) {
  416. return (-2);
  417. }
  418. if (tx < 0) {
  419. return (-3);
  420. }
  421. if (ty < 0) {
  422. return (-4);
  423. }
  424. if (from < 1) {
  425. return (-5);
  426. }
  427. if (to < 1) {
  428. return (-6);
  429. }
  430. if (from == to) {
  431. if (tx || ty) { /* do not allow self-edge with a label */
  432. return (-7);
  433. }
  434. }
  435. if (maingraph->layouted) {
  436. return (-8);
  437. }
  438. fn = uniqnode(maingraph, from);
  439. if (fn == NULL) {
  440. return (-5);
  441. }
  442. tn = uniqnode(maingraph, to);
  443. if (tn == NULL) {
  444. return (-6);
  445. }
  446. if (number > maingraph->edgenum) {
  447. maingraph->edgenum = number;
  448. }
  449. maingraph->nedges++;
  450. if (fn == tn) {
  451. /* at self-edge increase counter at node */
  452. fn->nselfedges++;
  453. } else {
  454. /* fresh new edge */
  455. e = (struct gml_edge *) sfg_calloc(1, sizeof(struct gml_edge));
  456. if (e == NULL) {
  457. return (-9);
  458. }
  459. el = (struct gml_elist *) sfg_calloc(1, sizeof(struct gml_elist));
  460. if (el == NULL) {
  461. e = (struct gml_edge *) sfg_free(e);
  462. return (-9);
  463. }
  464. e->nr = number;
  465. e->from_node = fn;
  466. e->to_node = tn;
  467. e->tx = tx;
  468. e->ty = ty;
  469. if (tx || ty) {
  470. /* mark there is a edgelabel */
  471. e->elabel = 1;
  472. /* number of edge labels in the graph */
  473. maingraph->nedgelabels++;
  474. }
  475. el->edge = e;
  476. if (maingraph->edgelist == NULL) {
  477. maingraph->edgelist = el;
  478. maingraph->edgelistend = el;
  479. } else {
  480. maingraph->edgelistend->next = el;
  481. maingraph->edgelistend = el;
  482. }
  483. }
  484. return (0);
  485. }
  486. /* run sugiyama barycenter layout
  487. * returns 0 if oke
  488. * returns -1 if not inited
  489. * returns -2 if layout already done
  490. * returns -3 if no nodes in the graph
  491. */
  492. int sfg_layout(void)
  493. {
  494. if (maingraph == NULL) {
  495. return (-1);
  496. }
  497. if (maingraph->layouted) {
  498. return (-2);
  499. }
  500. if (maingraph->nodelist == NULL) {
  501. return (-3);
  502. }
  503. /* prepare */
  504. prep(maingraph);
  505. /* re-organize nodelist */
  506. reorg(maingraph);
  507. /* change cycles in the graph */
  508. uncycle(maingraph);
  509. /* re-organize nodelist */
  510. reorg(maingraph);
  511. /* set y level of all nodes */
  512. ylevels(maingraph);
  513. /* find shorter edges */
  514. shorteredges(maingraph);
  515. /* change edge directions downwards */
  516. edgesdownwards(maingraph);
  517. /* check length of edges */
  518. edgelen(maingraph);
  519. /* doublespace the vertical levels */
  520. doublespacey(maingraph);
  521. /* split edges with label into node->label->node */
  522. edgelabels(maingraph);
  523. /* split longer edges */
  524. splitedges(maingraph);
  525. /* create level node count data */
  526. nodecounts(maingraph);
  527. /* run barycenter using defaults (0,0) or a value */
  528. barycenter(maingraph, 100, 100);
  529. /* re-calc positions */
  530. improve_positions(maingraph);
  531. /* final (x,y) positioning of nodes/edges */
  532. finalxy(maingraph);
  533. /* update node min/max and edge min/max */
  534. setminmax(maingraph);
  535. /* set layout is calculated */
  536. maingraph->layouted = 1;
  537. return (0);
  538. }
  539. /* return edge crossings in the graph
  540. * returns crossings >= 0 if oke
  541. * returns -1 if not inited
  542. * returns -2 if layout not done
  543. */
  544. int sfg_crossings(void)
  545. {
  546. if (maingraph == NULL) {
  547. return (-1);
  548. }
  549. if (maingraph->layouted == 0) {
  550. return (-22);
  551. }
  552. return (maingraph->sugi_fcrossings);
  553. }
  554. /* return initial edge crossings in the graph
  555. * returns crossings >= 0 if oke
  556. * returns -1 if not inited
  557. * returns -2 if layout not done
  558. */
  559. int sfg_initialcrossings(void)
  560. {
  561. if (maingraph == NULL) {
  562. return (-1);
  563. }
  564. if (maingraph->layouted == 0) {
  565. return (-2);
  566. }
  567. return (maingraph->sugi_icrossings);
  568. }
  569. /* set 1 to add edgelabels, or 0 to remove edgelabels
  570. * returns 0 if oke
  571. * returns -1 if not inited
  572. * returns -2 if already layouted
  573. */
  574. int sfg_edgelabels(int status)
  575. {
  576. if (maingraph == NULL) {
  577. return (-1);
  578. }
  579. if (maingraph->layouted) {
  580. return (-2);
  581. }
  582. if (status) {
  583. maingraph->do_edgelabels = 1;
  584. } else {
  585. maingraph->do_edgelabels = 1;
  586. }
  587. return (0);
  588. }
  589. /* return x pos of node with uniq number
  590. * returns >= 0 if oke
  591. * returns -1 if not inited
  592. * returns -2 if layout not done
  593. * returns -3 if number < 1
  594. * returns -4 if node not found
  595. */
  596. int sfg_nodexpos(int num)
  597. {
  598. struct gml_node *n = NULL;
  599. if (maingraph == NULL) {
  600. return (-1);
  601. }
  602. if (maingraph->layouted == 0) {
  603. return (-2);
  604. }
  605. if (num < 1) {
  606. return (-3);
  607. }
  608. n = uniqnode(maingraph, num);
  609. if (n == NULL) {
  610. return (-4);
  611. }
  612. return (n->finx);
  613. }
  614. /* return y pos of node with uniq number
  615. * returns >= 0 if oke
  616. * returns -1 if not inited
  617. * returns -2 if layout not done
  618. * returns -3 if number < 1
  619. * returns -4 if node not found
  620. */
  621. int sfg_nodeypos(int num)
  622. {
  623. struct gml_node *n = NULL;
  624. if (maingraph == NULL) {
  625. return (-1);
  626. }
  627. if (maingraph->layouted == 0) {
  628. return (-2);
  629. }
  630. if (num < 1) {
  631. return (-3);
  632. }
  633. n = uniqnode(maingraph, num);
  634. if (n == NULL) {
  635. return (-4);
  636. }
  637. return (n->finy);
  638. }
  639. /* return relative x pos of node with uniq number
  640. * returns >= 0 if oke
  641. * returns -1 if not inited
  642. * returns -2 if layout not done
  643. * returns -3 if number < 1
  644. * returns -4 if node not found
  645. */
  646. int sfg_noderelxpos(int num)
  647. {
  648. struct gml_node *n = NULL;
  649. if (maingraph == NULL) {
  650. return (-1);
  651. }
  652. if (maingraph->layouted == 0) {
  653. return (-2);
  654. }
  655. if (num < 1) {
  656. return (-3);
  657. }
  658. n = uniqnode(maingraph, num);
  659. if (n == NULL) {
  660. return (-4);
  661. }
  662. return (n->relx);
  663. }
  664. /* return relative y pos of node with uniq number
  665. * returns >= 0 if oke
  666. * returns -1 if not inited
  667. * returns -2 if layout not done
  668. * returns -3 if number < 1
  669. * returns -4 if node not found
  670. */
  671. int sfg_noderelypos(int num)
  672. {
  673. struct gml_node *n = NULL;
  674. if (maingraph == NULL) {
  675. return (-1);
  676. }
  677. if (maingraph->layouted == 0) {
  678. return (-2);
  679. }
  680. if (num < 1) {
  681. return (-3);
  682. }
  683. n = uniqnode(maingraph, num);
  684. if (n == NULL) {
  685. return (-4);
  686. }
  687. return (n->rely);
  688. }
  689. /* return level y start pos of node with uniq number
  690. * returns >= 0 if oke
  691. * returns -1 if not inited
  692. * returns -2 if layout not done
  693. * returns -3 if number < 1
  694. * returns -4 if node not found
  695. */
  696. int sfg_nodely0(int num)
  697. {
  698. struct gml_node *n = NULL;
  699. if (maingraph == NULL) {
  700. return (-1);
  701. }
  702. if (maingraph->layouted == 0) {
  703. return (-2);
  704. }
  705. if (num < 1) {
  706. return (-3);
  707. }
  708. n = uniqnode(maingraph, num);
  709. if (n == NULL) {
  710. return (-4);
  711. }
  712. return (n->ly0);
  713. }
  714. /* return level y end pos of node with uniq number
  715. * returns >= 0 if oke
  716. * returns -1 if not inited
  717. * returns -2 if layout not done
  718. * returns -3 if number < 1
  719. * returns -4 if node not found
  720. */
  721. int sfg_nodely1(int num)
  722. {
  723. struct gml_node *n = NULL;
  724. if (maingraph == NULL) {
  725. return (-1);
  726. }
  727. if (maingraph->layouted == 0) {
  728. return (-2);
  729. }
  730. if (num < 1) {
  731. return (-3);
  732. }
  733. n = uniqnode(maingraph, num);
  734. if (n == NULL) {
  735. return (-4);
  736. }
  737. return (n->ly1);
  738. }
  739. /* return x size of node with uniq number
  740. * returns >= 0 if oke
  741. * returns -1 if not inited
  742. * returns -2 if layout not done
  743. * returns -3 if number < 1
  744. * returns -4 if node not found
  745. */
  746. int sfg_nodexsize(int num)
  747. {
  748. struct gml_node *n = NULL;
  749. if (maingraph == NULL) {
  750. return (-1);
  751. }
  752. if (maingraph->layouted == 0) {
  753. return (-2);
  754. }
  755. if (num < 1) {
  756. return (-3);
  757. }
  758. n = uniqnode(maingraph, num);
  759. if (n == NULL) {
  760. return (-4);
  761. }
  762. return (n->tx);
  763. }
  764. /* return y size of node with uniq number
  765. * returns >= 0 if oke
  766. * returns -1 if not inited
  767. * returns -2 if layout not done
  768. * returns -3 if number < 1
  769. * returns -4 if node not found
  770. */
  771. int sfg_nodeysize(int num)
  772. {
  773. struct gml_node *n = NULL;
  774. if (maingraph == NULL) {
  775. return (-1);
  776. }
  777. if (maingraph->layouted == 0) {
  778. return (-2);
  779. }
  780. if (num < 1) {
  781. return (-3);
  782. }
  783. n = uniqnode(maingraph, num);
  784. if (n == NULL) {
  785. return (-4);
  786. }
  787. return (n->ty);
  788. }
  789. /* set min. x spacing between nodes
  790. * returns 0 if oke
  791. * returns -1 if not inited
  792. * returns -2 if number is lower then 0
  793. * returns -3 if layout already done
  794. */
  795. int sfg_xspacing(int num)
  796. {
  797. if (maingraph == NULL) {
  798. return (-1);
  799. }
  800. if (num < 1) {
  801. return (-2);
  802. }
  803. if (maingraph->layouted) {
  804. return (-3);
  805. }
  806. maingraph->xspacing = num;
  807. return (0);
  808. }
  809. /* set min. y spacing between nodes
  810. * returns 0 if oke
  811. * returns -1 if not inited
  812. * returns -2 if number is lower then 0
  813. * returns -3 if layout already done
  814. */
  815. int sfg_yspacing(int num)
  816. {
  817. if (maingraph == NULL) {
  818. return (-1);
  819. }
  820. if (num < 1) {
  821. return (-2);
  822. }
  823. if (maingraph->layouted) {
  824. return (-3);
  825. }
  826. maingraph->yspacing = num;
  827. return (0);
  828. }
  829. /* get max x pos in drawing
  830. * returns value if oke
  831. * returns -1 if not inited
  832. * returns -2 if layout not done
  833. */
  834. int sfg_maxx(void)
  835. {
  836. if (maingraph == NULL) {
  837. return (-1);
  838. }
  839. if (maingraph->layouted == 0) {
  840. return (-2);
  841. }
  842. return (maingraph->maxx);
  843. }
  844. /* get max y pos in drawing
  845. * returns value if oke
  846. * returns -1 if not inited
  847. * returns -2 if layout not done
  848. */
  849. int sfg_maxy(void)
  850. {
  851. if (maingraph == NULL) {
  852. return (-1);
  853. }
  854. if (maingraph->layouted == 0) {
  855. return (-2);
  856. }
  857. return (maingraph->maxy);
  858. }
  859. /* get min node number in use after layout
  860. * returns value if oke
  861. * returns -1 if not inited
  862. * returns -2 if layout not done
  863. * returns -3 if there are no nodes
  864. */
  865. int sfg_nodemin(void)
  866. {
  867. if (maingraph == NULL) {
  868. return (-1);
  869. }
  870. if (maingraph->layouted == 0) {
  871. return (-2);
  872. }
  873. if (maingraph->nodelist == NULL) {
  874. return (-3);
  875. }
  876. return (maingraph->nodemin);
  877. }
  878. /* get maxc node number in use after layout
  879. * returns value if oke
  880. * returns -1 if not inited
  881. * returns -2 if layout not done
  882. * returns -3 if there are no nodes
  883. */
  884. int sfg_nodemax(void)
  885. {
  886. if (maingraph == NULL) {
  887. return (-1);
  888. }
  889. if (maingraph->layouted == 0) {
  890. return (-2);
  891. }
  892. if (maingraph->nodelist == NULL) {
  893. return (-3);
  894. }
  895. return (maingraph->nodemax);
  896. }
  897. /* get min edge number in use after layout
  898. * returns value if oke
  899. * returns -1 if not inited
  900. * returns -2 if layout not done
  901. * returns -3 if there are no edges
  902. */
  903. int sfg_edgemin(void)
  904. {
  905. if (maingraph == NULL) {
  906. return (-1);
  907. }
  908. if (maingraph->layouted == 0) {
  909. return (-2);
  910. }
  911. if (maingraph->edgelist == NULL) {
  912. return (-3);
  913. }
  914. return (maingraph->edgemin);
  915. }
  916. /* get max edge number in use after layout
  917. * returns value if oke
  918. * returns -1 if not inited
  919. * returns -2 if layout not done
  920. * returns -3 if there are no edges
  921. */
  922. int sfg_edgemax(void)
  923. {
  924. if (maingraph == NULL) {
  925. return (-1);
  926. }
  927. if (maingraph->layouted == 0) {
  928. return (-2);
  929. }
  930. if (maingraph->edgelist == NULL) {
  931. return (-3);
  932. }
  933. return (maingraph->edgemax);
  934. }
  935. /* get number of levels
  936. * returns value if oke
  937. * returns -1 if not inited
  938. * returns -2 if layout not done
  939. */
  940. int sfg_nlevels(void)
  941. {
  942. if (maingraph == NULL) {
  943. return (-1);
  944. }
  945. if (maingraph->layouted == 0) {
  946. return (-2);
  947. }
  948. return (maingraph->maxlevel + 1);
  949. }
  950. /* get number of nodes
  951. * returns value if oke
  952. * returns -1 if not inited
  953. * returns -2 if layout not done
  954. */
  955. int sfg_nnodes(void)
  956. {
  957. if (maingraph == NULL) {
  958. return (-1);
  959. }
  960. if (maingraph->layouted == 0) {
  961. return (-2);
  962. }
  963. return (maingraph->nnodes);
  964. }
  965. /* get number of edges
  966. * returns value if oke
  967. * returns -1 if not inited
  968. * returns -2 if layout not done
  969. */
  970. int sfg_nedges(void)
  971. {
  972. if (maingraph == NULL) {
  973. return (-1);
  974. }
  975. if (maingraph->layouted == 0) {
  976. return (-2);
  977. }
  978. return (maingraph->nedges);
  979. }
  980. /* return type of node with uniq number
  981. * returns type of node, 1=regular, 2=dummy, 3=edgelabel node
  982. * returns -1 not inited
  983. * returns -2 if layout not done
  984. * returns -3 if nodenumber is < 1
  985. * returns -4 if node not found
  986. */
  987. int sfg_nodetype(int num)
  988. {
  989. struct gml_node *n = NULL;
  990. int type = 0;
  991. if (maingraph == NULL) {
  992. return (-1);
  993. }
  994. if (maingraph->layouted == 0) {
  995. return (-2);
  996. }
  997. if (num < 1) {
  998. return (-3);
  999. }
  1000. n = uniqnode(maingraph, num);
  1001. if (n == NULL) {
  1002. return (-4);
  1003. }
  1004. if (n->dummy) {
  1005. type = 2;
  1006. } else if (n->elabel) {
  1007. type = 3;
  1008. } else {
  1009. type = 1;
  1010. }
  1011. return (type);
  1012. }
  1013. /* return number of selfedges at node
  1014. * returns number of selfedges if oke
  1015. * returns -1 not inited
  1016. * returns -2 if layout not done
  1017. * returns -3 if nodenumber is < 1
  1018. * returns -4 if node not found
  1019. */
  1020. int sfg_nodeselfedges(int num)
  1021. {
  1022. struct gml_node *n = NULL;
  1023. if (maingraph == NULL) {
  1024. return (-1);
  1025. }
  1026. if (maingraph->layouted == 0) {
  1027. return (-2);
  1028. }
  1029. if (num < 1) {
  1030. return (-3);
  1031. }
  1032. n = uniqnode(maingraph, num);
  1033. if (n == NULL) {
  1034. return (-4);
  1035. }
  1036. return (n->nselfedges);
  1037. }
  1038. /* return number of incoming edges to node
  1039. * returns indegree number if oke
  1040. * returns -1 not inited
  1041. * returns -2 if layout not done
  1042. * returns -3 if nodenumber is < 1
  1043. * returns -4 if node not found
  1044. */
  1045. int sfg_nodeindegree(int num)
  1046. {
  1047. struct gml_node *n = NULL;
  1048. if (maingraph == NULL) {
  1049. return (-1);
  1050. }
  1051. if (maingraph->layouted == 0) {
  1052. return (-2);
  1053. }
  1054. if (num < 1) {
  1055. return (-3);
  1056. }
  1057. n = uniqnode(maingraph, num);
  1058. if (n == NULL) {
  1059. return (-4);
  1060. }
  1061. return (n->indegree);
  1062. }
  1063. /* return number of outgoing edges from node
  1064. * returns outdegree number if oke
  1065. * returns -1 not inited
  1066. * returns -2 if layout not done
  1067. * returns -3 if nodenumber is < 1
  1068. * returns -4 if node not found
  1069. */
  1070. int sfg_nodeoutdegree(int num)
  1071. {
  1072. struct gml_node *n = NULL;
  1073. if (maingraph == NULL) {
  1074. return (-1);
  1075. }
  1076. if (maingraph->layouted == 0) {
  1077. return (-2);
  1078. }
  1079. if (num < 1) {
  1080. return (-3);
  1081. }
  1082. n = uniqnode(maingraph, num);
  1083. if (n == NULL) {
  1084. return (-4);
  1085. }
  1086. return (n->outdegree);
  1087. }
  1088. /* return edge number of node if edgelabel node
  1089. * returns number of original edge with edgelabel if oke
  1090. * returns -1 not inited
  1091. * returns -2 if layout not done
  1092. * returns -3 if nodenumber is < 1
  1093. * returns -4 if node not found
  1094. * returns -5 if node is not edgelabel
  1095. */
  1096. int sfg_nodeenum(int num)
  1097. {
  1098. struct gml_node *n = NULL;
  1099. if (maingraph == NULL) {
  1100. return (-1);
  1101. }
  1102. if (maingraph->layouted == 0) {
  1103. return (-2);
  1104. }
  1105. if (num < 1) {
  1106. return (-3);
  1107. }
  1108. n = uniqnode(maingraph, num);
  1109. if (n == NULL) {
  1110. return (-4);
  1111. }
  1112. if (n->elabel == 0) {
  1113. return (-5);
  1114. }
  1115. return (n->enumber);
  1116. }
  1117. /* get optional data pointer of node
  1118. * returns data pointer if oke
  1119. * returns NULL if not inited
  1120. * returns NULL if layout not done
  1121. * returns NULL if nodenumber is < 1
  1122. * returns NULL if node not found
  1123. */
  1124. void *sfg_nodedata(int num)
  1125. {
  1126. struct gml_node *n = NULL;
  1127. if (maingraph == NULL) {
  1128. return (NULL);
  1129. }
  1130. if (maingraph->layouted == 0) {
  1131. return (NULL);
  1132. }
  1133. if (num < 1) {
  1134. return (NULL);
  1135. }
  1136. n = uniqnode(maingraph, num);
  1137. if (n == NULL) {
  1138. return (NULL);
  1139. }
  1140. return (n->data);
  1141. }
  1142. /* set optional data pointer of node
  1143. * returns 0 if oke
  1144. * returns -1 if not inited
  1145. * returns -2 if layout not done
  1146. * returns -3 if nodenumber is < 1
  1147. * returns -4 if node not found
  1148. */
  1149. int sfg_setnodedata(int num, void *data)
  1150. {
  1151. struct gml_node *n = NULL;
  1152. if (maingraph == NULL) {
  1153. return (-1);
  1154. }
  1155. if (maingraph->layouted == 0) {
  1156. return (-2);
  1157. }
  1158. if (num < 1) {
  1159. return (-3);
  1160. }
  1161. n = uniqnode(maingraph, num);
  1162. if (n == NULL) {
  1163. return (-4);
  1164. }
  1165. n->data = data;
  1166. return (0);
  1167. }
  1168. /* get node data and the calculated positions
  1169. * the user must supply a pointer to the callback routine
  1170. * this runs a supplied callback routine for every node
  1171. * the callback routine gets the node number as supplied,
  1172. * the level as supplied and the calculated pos position.
  1173. * the data is the supplied data and can be used similar.
  1174. * when the callback function needs to stop the iteration
  1175. * over the node list then it must return a non-zero status
  1176. * and that status is returned by sfg_node_foreach()
  1177. * the parameters in the callback function are
  1178. * int num, uniq node number
  1179. * int level, relative vertical level
  1180. * int pos, relative horizontal level
  1181. * void *data, optional user data
  1182. * int xpos, x-coord of upperleft node label area or 0 at no label
  1183. * int ypos, y-coord of upperleft node label area or 0 at no label
  1184. * int tx, x size of text area
  1185. * int ty, y size of text area
  1186. * int nselfedges, number of self-edges at this node
  1187. * int type, type of node, 1=regular, 2=dummy, 3=edgelabel node
  1188. * int indegree, number of incoming edges to the node
  1189. * int outdegree, number of outgoing edges from the node
  1190. * int ly0, start y of level of node
  1191. * int ly1, end y of level of node
  1192. * returns 0 from this routine if everything is oke or no data.
  1193. * returns -1 if not inited
  1194. * returns -2 if no layout is done
  1195. * returns -3 if no callback routine
  1196. */
  1197. int sfg_node_foreach(int (*getnodedata)
  1198. (int num, int level, int pos, int xpos, int ypos, int tx, int ty, int nselfedges, int type,
  1199. int indegree, int outdegree, int ly0, int ly1))
  1200. {
  1201. struct gml_nlist *nl = NULL;
  1202. struct gml_node *n = NULL;
  1203. int status = 0;
  1204. int type = 0;
  1205. if (maingraph == NULL) {
  1206. return (-1);
  1207. }
  1208. if (maingraph->layouted == 0) {
  1209. return (-2);
  1210. }
  1211. if (getnodedata == NULL) {
  1212. return (-3);
  1213. }
  1214. nl = maingraph->nodelist;
  1215. while (nl) {
  1216. n = nl->node;
  1217. /* todo set type of node here */
  1218. type = 0;
  1219. status =
  1220. (*getnodedata) (n->nr, n->rely, n->relx, n->finx, n->finy, n->tx, n->ty, n->nselfedges, type,
  1221. n->indegree, n->outdegree, n->ly0, n->ly1);
  1222. if (status != 0) {
  1223. break;
  1224. }
  1225. nl = nl->next;
  1226. }
  1227. return (0);
  1228. }
  1229. /* get from-node of edge
  1230. * returns from-node number if oke
  1231. * returns -1 not inited
  1232. * returns -2 if layout not done
  1233. * returns -3 if edgenumber is < 1
  1234. * returns -4 if edge not found
  1235. */
  1236. int sfg_edgefrom(int num)
  1237. {
  1238. struct gml_edge *e = NULL;
  1239. if (maingraph == NULL) {
  1240. return (-1);
  1241. }
  1242. if (maingraph->layouted == 0) {
  1243. return (-2);
  1244. }
  1245. if (num < 1) {
  1246. return (-3);
  1247. }
  1248. e = findedge(num);
  1249. if (e == NULL) {
  1250. return (-4);
  1251. }
  1252. return (e->from_node->nr);
  1253. }
  1254. /* get to-node of edge
  1255. * returns to-node number if oke
  1256. * returns -1 not inited
  1257. * returns -2 if layout not done
  1258. * returns -3 if edgenumber is < 1
  1259. * returns -4 if edge not found
  1260. */
  1261. int sfg_edgeto(int num)
  1262. {
  1263. struct gml_edge *e = NULL;
  1264. if (maingraph == NULL) {
  1265. return (-1);
  1266. }
  1267. if (maingraph->layouted == 0) {
  1268. return (-2);
  1269. }
  1270. if (num < 1) {
  1271. return (-3);
  1272. }
  1273. e = findedge(num);
  1274. if (e == NULL) {
  1275. return (-4);
  1276. }
  1277. return (e->to_node->nr);
  1278. }
  1279. /* get edge type
  1280. * returns type if oke, 1=regular, 2=selfedge, 3=hor. edge
  1281. * returns -1 not inited
  1282. * returns -2 if layout not done
  1283. * returns -3 if edgenumber is < 1
  1284. * returns -4 if edge not found
  1285. */
  1286. int sfg_edgetype(int num)
  1287. {
  1288. struct gml_edge *e = NULL;
  1289. int type = 0;
  1290. if (maingraph == NULL) {
  1291. return (-1);
  1292. }
  1293. if (maingraph->layouted == 0) {
  1294. return (-2);
  1295. }
  1296. if (num < 1) {
  1297. return (-3);
  1298. }
  1299. e = findedge(num);
  1300. if (e == NULL) {
  1301. return (-4);
  1302. }
  1303. if (e->from_node->nr == e->to_node->nr) {
  1304. type = 2;
  1305. } else if (e->hedge) {
  1306. type = 3;
  1307. } else {
  1308. type = 1;
  1309. }
  1310. return (type);
  1311. }
  1312. /* get edge reversed status
  1313. * returns 1 if reversed edge or 0 if not
  1314. * returns -1 not inited
  1315. * returns -2 if layout not done
  1316. * returns -3 if edgenumber is < 1
  1317. * returns -4 if edge not found
  1318. */
  1319. int sfg_edgerev(int num)
  1320. {
  1321. struct gml_edge *e = NULL;
  1322. if (maingraph == NULL) {
  1323. return (-1);
  1324. }
  1325. if (maingraph->layouted == 0) {
  1326. return (-2);
  1327. }
  1328. if (num < 1) {
  1329. return (-3);
  1330. }
  1331. e = findedge(num);
  1332. if (e == NULL) {
  1333. return (-4);
  1334. }
  1335. return (e->reversed);
  1336. }
  1337. /* get edge data and the calculated position
  1338. * the user must supply a pointer to the callback routine
  1339. * this runs a supplied callback routine for every edge
  1340. * when the callback function needs to stop the iteration
  1341. * over the edge list then it must return a non-zero status
  1342. * the parameters in the callback function are
  1343. * int num, uniq edge number
  1344. * int from, uniq from-node number
  1345. * int to, uniq to-node number
  1346. * void *data, optional user data
  1347. * int type, 1=regular, 2=selfedge, 3 hor. edge
  1348. * int rev, set if edge is reversed
  1349. * returns 0 if oke
  1350. * returns -1 if not inited
  1351. * returns -2 if no layout is done
  1352. * returns -3 if no callback routine
  1353. */
  1354. int sfg_edge_foreach(int (*getedgedata)(int num, int from, int to, int type, int rev))
  1355. {
  1356. struct gml_elist *el = NULL;
  1357. struct gml_edge *e = NULL;
  1358. int status = 0;
  1359. int type = 0;
  1360. if (maingraph == NULL) {
  1361. return (-1);
  1362. }
  1363. if (maingraph->layouted == 0) {
  1364. return (-2);
  1365. }
  1366. if (getedgedata == NULL) {
  1367. return (-3);
  1368. }
  1369. el = maingraph->edgelist;
  1370. while (el) {
  1371. e = el->edge;
  1372. /* set type */
  1373. if (e->from_node->nr == e->to_node->nr) {
  1374. type = 2;
  1375. } else if (e->hedge) {
  1376. type = 3;
  1377. } else {
  1378. type = 1;
  1379. }
  1380. status = (*getedgedata) (e->nr, e->from_node->nr, e->to_node->nr, type, e->reversed);
  1381. if (status != 0) {
  1382. break;
  1383. }
  1384. el = el->next;
  1385. }
  1386. return (0);
  1387. }
  1388. /* A splay-tree datatype.
  1389. Copyright (C) 1998-2021 Free Software Foundation, Inc.
  1390. Contributed by Mark Mitchell (mark@markmitchell.com).
  1391. This file is part of GNU CC.
  1392. GNU CC is free software; you can redistribute it and/or modify it
  1393. under the terms of the GNU General Public License as published by
  1394. the Free Software Foundation; either version 2, or (at your option)
  1395. any later version.
  1396. GNU CC is distributed in the hope that it will be useful, but
  1397. WITHOUT ANY WARRANTY; without even the implied warranty of
  1398. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  1399. General Public License for more details.
  1400. You should have received a copy of the GNU General Public License
  1401. along with GNU CC; see the file COPYING. If not, write to
  1402. the Free Software Foundation, 51 Franklin Street - Fifth Floor,
  1403. Boston, MA 02110-1301, USA. */
  1404. /* For an easily readable description of splay-trees, see:
  1405. Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
  1406. Algorithms. Harper-Collins, Inc. 1991. */
  1407. /* Deallocate NODE (a member of SP), and all its sub-trees. */
  1408. static void sfg_splay_tree_delete_helper(sfg_splay_tree sp, sfg_splay_tree_node node)
  1409. {
  1410. if (node == NULL) {
  1411. return;
  1412. }
  1413. /* recurse */
  1414. sfg_splay_tree_delete_helper(sp, node->left);
  1415. sfg_splay_tree_delete_helper(sp, node->right);
  1416. /* free() key if needed */
  1417. if (sp->delete_key) {
  1418. (*sp->delete_key) (node->key);
  1419. node->key = (sfg_splay_tree_key) 0;
  1420. }
  1421. /* free() value if needed */
  1422. if (sp->delete_value) {
  1423. (*sp->delete_value) (node->value);
  1424. node->value = (sfg_splay_tree_value) 0;
  1425. }
  1426. (void) sfg_free ((void *)node);
  1427. return;
  1428. }
  1429. /* delete whole sp tree */
  1430. static sfg_splay_tree sfg_splay_tree_delete(sfg_splay_tree sp)
  1431. {
  1432. if (sp) {
  1433. sfg_splay_tree_delete_helper(sp, sp->root);
  1434. (void) sfg_free ((void *)sp);
  1435. }
  1436. return ((sfg_splay_tree) 0);
  1437. }
  1438. /* Allocate a new splay tree, using COMPARE_FN to compare nodes,
  1439. DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate
  1440. values. */
  1441. static sfg_splay_tree
  1442. sfg_splay_tree_new(sfg_splay_tree_compare_fn compare_fn, sfg_splay_tree_delete_key_fn delete_key_fn, sfg_splay_tree_delete_value_fn delete_value_fn)
  1443. {
  1444. sfg_splay_tree sp = (sfg_splay_tree) 0;
  1445. /* there must be a compare function, the free() functions are optional */
  1446. if (compare_fn == (sfg_splay_tree_compare_fn) 0) {
  1447. return ((sfg_splay_tree) 0);
  1448. }
  1449. sp = (sfg_splay_tree) sfg_calloc(1, sizeof(struct sfg_splay_tree_t));
  1450. if (sp == (sfg_splay_tree) 0) {
  1451. return ((sfg_splay_tree) 0);
  1452. }
  1453. /* set root node to use and the functions */
  1454. sp->root = (sfg_splay_tree_node) 0;
  1455. sp->comp = compare_fn;
  1456. sp->delete_key = delete_key_fn;
  1457. sp->delete_value = delete_value_fn;
  1458. return ((sfg_splay_tree) sp);
  1459. }
  1460. /* Insert a new node (associating KEY with DATA) into SP. If a
  1461. previous node with the indicated KEY exists, its data is not replaced
  1462. with the new value. */
  1463. static void sfg_splay_tree_insert(sfg_splay_tree sp, sfg_splay_tree_key key, sfg_splay_tree_value value)
  1464. {
  1465. sfg_splay_tree_node spn = (sfg_splay_tree_node) 0;
  1466. int comparison = 0;
  1467. if (sp == (sfg_splay_tree) 0) {
  1468. /* no tree */
  1469. return;
  1470. }
  1471. spn = sfg_splay_tree_lookup(sp, key);
  1472. if (spn != (sfg_splay_tree_node) 0) {
  1473. /* did already exist */
  1474. return;
  1475. }
  1476. /* Create a new node, and insert it at the root. */
  1477. spn = (sfg_splay_tree_node) sfg_calloc(1, sizeof(struct sfg_splay_tree_node_n));
  1478. if (spn == (sfg_splay_tree_node) 0) {
  1479. /* shouldnothappen */
  1480. return;
  1481. }
  1482. /* set node data */
  1483. spn->key = key;
  1484. spn->value = value;
  1485. if (sp->root == (sfg_splay_tree_node) 0) {
  1486. /* first entry */
  1487. sp->root = spn;
  1488. return;
  1489. }
  1490. /* add in tree */
  1491. comparison = (*sp->comp) (sp->root->key, key);
  1492. if (comparison < 0) {
  1493. spn->left = sp->root;
  1494. spn->right = spn->left->right;
  1495. spn->left->right = (sfg_splay_tree_node) 0;
  1496. } else {
  1497. /* > or == */
  1498. spn->right = sp->root;
  1499. spn->left = spn->right->left;
  1500. spn->right->left = (sfg_splay_tree_node) 0;
  1501. }
  1502. sp->root = spn;
  1503. return;
  1504. }
  1505. /* Lookup KEY in SP, returning VALUE if present, and NULL
  1506. otherwise. */
  1507. static sfg_splay_tree_node sfg_splay_tree_lookup(sfg_splay_tree sp, sfg_splay_tree_key key)
  1508. {
  1509. sfg_splay_tree_node spn = (sfg_splay_tree_node) 0;
  1510. if (sp == (sfg_splay_tree) 0) {
  1511. /* no tree */
  1512. return ((sfg_splay_tree_node) 0);
  1513. }
  1514. if (sp->root == (sfg_splay_tree_node) 0) {
  1515. /* no data */
  1516. return ((sfg_splay_tree_node) 0);
  1517. }
  1518. if ((*sp->comp) (sp->root->key, key) == 0) {
  1519. /* found */
  1520. return ((sfg_splay_tree_node) sp->root);
  1521. }
  1522. spn = splay(sp, key);
  1523. if (spn) {
  1524. if ((*sp->comp) (sp->root->key, key) == 0) {
  1525. /* found */
  1526. return ((sfg_splay_tree_node) sp->root);
  1527. }
  1528. }
  1529. /* not found */
  1530. return ((sfg_splay_tree_node) 0);
  1531. }
  1532. /* Splay-tree comparison function, treating the keys as ints. */
  1533. static int sfg_splay_tree_compare_ints(sfg_splay_tree_key k1, sfg_splay_tree_key k2)
  1534. {
  1535. if ((int)k1 < (int)k2) {
  1536. return ((int)-1);
  1537. } else if ((int)k1 > (int)k2) {
  1538. return (1);
  1539. } else {
  1540. return (0);
  1541. }
  1542. }
  1543. /* */
  1544. static struct sfg_splay_tree_node_n *splay(sfg_splay_tree sp, sfg_splay_tree_key key)
  1545. {
  1546. struct sfg_splay_tree_node_n *t = (struct sfg_splay_tree_node_n *)0;
  1547. struct sfg_splay_tree_node_n *l = (struct sfg_splay_tree_node_n *)0;
  1548. struct sfg_splay_tree_node_n *r = (struct sfg_splay_tree_node_n *)0;
  1549. struct sfg_splay_tree_node_n *y = (struct sfg_splay_tree_node_n *)0;
  1550. int comparevalue = 0;
  1551. int comparevalue2 = 0;
  1552. struct sfg_splay_tree_node_n tmp = {
  1553. /* The key. */
  1554. (sfg_splay_tree_key) 0,
  1555. /* The value. */
  1556. (sfg_splay_tree_value) 0,
  1557. /* The left and right children, respectively. */
  1558. (struct sfg_splay_tree_node_n *)0, /* left */
  1559. (struct sfg_splay_tree_node_n *)0 /* right */
  1560. };
  1561. /* no tree */
  1562. if (sp == (sfg_splay_tree) 0) {
  1563. return ((struct sfg_splay_tree_node_n *)0);
  1564. }
  1565. /* no data in root. return 0 */
  1566. if (sp->root == (struct sfg_splay_tree_node_n *)0) {
  1567. return ((struct sfg_splay_tree_node_n *)0);
  1568. }
  1569. /* current root */
  1570. t = sp->root;
  1571. tmp.left = (struct sfg_splay_tree_node_n *)0;
  1572. tmp.right = (struct sfg_splay_tree_node_n *)0;
  1573. l = &tmp;
  1574. r = &tmp;
  1575. labelstart:
  1576. /* */
  1577. comparevalue = (*sp->comp) (key, t->key);
  1578. if (comparevalue < 0) {
  1579. if (t->left == (struct sfg_splay_tree_node_n *)0) {
  1580. goto labelend;
  1581. }
  1582. /* */
  1583. comparevalue2 = (*sp->comp) (key, t->left->key);
  1584. if (comparevalue2 < 0) {
  1585. y = t->left;
  1586. t->left = y->right;
  1587. y->right = t;
  1588. t = y;
  1589. if (t->left == (struct sfg_splay_tree_node_n *)0) {
  1590. goto labelend;
  1591. }
  1592. }
  1593. /* */
  1594. r->left = t;
  1595. r = t;
  1596. t = t->left;
  1597. } else if (comparevalue > 0) {
  1598. if (t->right == (struct sfg_splay_tree_node_n *)0) {
  1599. goto labelend;
  1600. }
  1601. /* */
  1602. comparevalue2 = (*sp->comp) (key, t->right->key);
  1603. if (comparevalue2 > 0) {
  1604. /* */
  1605. y = t->right;
  1606. t->right = y->left;
  1607. y->left = t;
  1608. t = y;
  1609. if (t->right == (struct sfg_splay_tree_node_n *)0) {
  1610. goto labelend;
  1611. }
  1612. }
  1613. /* */
  1614. l->right = t;
  1615. l = t;
  1616. t = t->right;
  1617. } else {
  1618. /* here if (comparevalue == 0) */
  1619. goto labelend;
  1620. }
  1621. goto labelstart;
  1622. labelend:
  1623. l->right = t->left;
  1624. r->left = t->right;
  1625. t->left = tmp.right;
  1626. t->right = tmp.left;
  1627. sp->root = t;
  1628. return ((struct sfg_splay_tree_node_n *)t);
  1629. }
  1630. /* get node with this number */
  1631. static struct gml_node *uniqnode(struct gml_graph *g, int nr)
  1632. {
  1633. sfg_splay_tree_node spn = NULL;
  1634. if (g) {
  1635. }
  1636. if (uniqnode_splaytree == NULL) {
  1637. return (NULL);
  1638. }
  1639. spn = sfg_splay_tree_lookup(uniqnode_splaytree, (sfg_splay_tree_key) nr);
  1640. if (spn) {
  1641. return ((struct gml_node *)spn->value);
  1642. } else {
  1643. return (NULL);
  1644. }
  1645. }
  1646. /* add node to db */
  1647. static void uniqnode_add(struct gml_graph *g, struct gml_node *node)
  1648. {
  1649. sfg_splay_tree_node spn = NULL;
  1650. if (g) {
  1651. }
  1652. if (node == NULL) {
  1653. /* shouldnothappen */
  1654. return;
  1655. }
  1656. if (uniqnode_splaytree == NULL) {
  1657. uniqnode_splaytree = sfg_splay_tree_new(sfg_splay_tree_compare_ints, NULL, NULL);
  1658. }
  1659. spn = sfg_splay_tree_lookup(uniqnode_splaytree, (sfg_splay_tree_key) node->nr);
  1660. if (spn) {
  1661. /* shouldnothappen */
  1662. return;
  1663. } else {
  1664. sfg_splay_tree_insert(uniqnode_splaytree, (sfg_splay_tree_key) node->nr, (sfg_splay_tree_value) node);
  1665. }
  1666. return;
  1667. }
  1668. /* clear nodelist with the nodes */
  1669. static void clear_nodelist(struct gml_graph *g)
  1670. {
  1671. struct gml_nlist *lnll = NULL;
  1672. struct gml_nlist *nlnext = NULL;
  1673. lnll = g->nodelist;
  1674. while (lnll) {
  1675. nlnext = lnll->next;
  1676. lnll->node = (struct gml_node *) sfg_free(lnll->node);
  1677. lnll = (struct gml_nlist *) sfg_free(lnll);
  1678. lnll = nlnext;
  1679. }
  1680. g->nodelist = NULL;
  1681. g->nodelistend = NULL;
  1682. g->nodenum = 0;
  1683. g->nnodes = 0;
  1684. return;
  1685. }
  1686. /* clear edgelist and edge itself */
  1687. static void clear_edgelist(struct gml_graph *g)
  1688. {
  1689. struct gml_elist *el = NULL;
  1690. struct gml_elist *elnext = NULL;
  1691. el = g->edgelist;
  1692. while (el) {
  1693. elnext = el->next;
  1694. el->edge = (struct gml_edge *) sfg_free(el->edge);
  1695. el = (struct gml_elist *) sfg_free(el);
  1696. el = elnext;
  1697. }
  1698. g->edgelist = NULL;
  1699. g->edgelistend = NULL;
  1700. g->nedges = 0;
  1701. g->edgenum = 0;
  1702. return;
  1703. }
  1704. /* optional prepare extra's here */
  1705. static void prep(struct gml_graph *g)
  1706. {
  1707. struct gml_elist *el = NULL;
  1708. el = g->edgelist;
  1709. while (el) {
  1710. /* update degree of nodes */
  1711. el->edge->from_node->outdegree++;
  1712. el->edge->to_node->indegree++;
  1713. el = el->next;
  1714. }
  1715. return;
  1716. }
  1717. /* re-organize nodelist */
  1718. static void reorg(struct gml_graph *g)
  1719. {
  1720. struct gml_nlist *nl = NULL;
  1721. struct gml_nlist *nlnext = NULL;
  1722. struct gml_nlist *nn1 = NULL;
  1723. struct gml_nlist *nn2 = NULL;
  1724. struct gml_nlist *nn3 = NULL;
  1725. struct gml_nlist *nn4 = NULL;
  1726. struct gml_nlist *nnl = NULL;
  1727. struct gml_nlist *nnlend = NULL;
  1728. nl = g->nodelist;
  1729. if (nl == NULL) {
  1730. return;
  1731. }
  1732. while (nl) {
  1733. /* first the single nodes */
  1734. if (nl->node->indegree == 0 && nl->node->outdegree == 0) {
  1735. nn1 = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  1736. if (nn1) {
  1737. nn1->node = nl->node;
  1738. if (nnl == NULL) {
  1739. nnl = nn1;
  1740. nnlend = nn1;
  1741. } else {
  1742. nnlend->next = nn1;
  1743. nnlend = nn1;
  1744. }
  1745. }
  1746. }
  1747. nl = nl->next;
  1748. }
  1749. nl = g->nodelist;
  1750. while (nl) {
  1751. /* second the starter nodes */
  1752. if (nl->node->indegree == 0 && nl->node->outdegree != 0) {
  1753. nn2 = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  1754. if (nn2) {
  1755. nn2->node = nl->node;
  1756. if (nnl == NULL) {
  1757. nnl = nn2;
  1758. nnlend = nn2;
  1759. } else {
  1760. nnlend->next = nn2;
  1761. nnlend = nn2;
  1762. }
  1763. }
  1764. }
  1765. nl = nl->next;
  1766. }
  1767. nl = g->nodelist;
  1768. while (nl) {
  1769. /* third the middle nodes */
  1770. if (nl->node->indegree != 0 && nl->node->outdegree != 0) {
  1771. nn3 = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  1772. if (nn3) {
  1773. nn3->node = nl->node;
  1774. if (nnl == NULL) {
  1775. nnl = nn3;
  1776. nnlend = nn3;
  1777. } else {
  1778. nnlend->next = nn3;
  1779. nnlend = nn3;
  1780. }
  1781. }
  1782. }
  1783. nl = nl->next;
  1784. }
  1785. nl = g->nodelist;
  1786. while (nl) {
  1787. /* fourth the tail nodes */
  1788. if (nl->node->indegree != 0 && nl->node->outdegree == 0) {
  1789. nn4 = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  1790. if (nn4) {
  1791. nn4->node = nl->node;
  1792. if (nnl == NULL) {
  1793. nnl = nn4;
  1794. nnlend = nn4;
  1795. } else {
  1796. nnlend->next = nn4;
  1797. nnlend = nn4;
  1798. }
  1799. }
  1800. }
  1801. nl = nl->next;
  1802. }
  1803. /* clear nodelist but keep the nodes */
  1804. nl = g->nodelist;
  1805. while (nl) {
  1806. nlnext = nl->next;
  1807. nl = (struct gml_nlist *) sfg_free(nl);
  1808. nl = nlnext;
  1809. }
  1810. /* set the refreshed nodelist */
  1811. g->nodelist = nnl;
  1812. g->nodelistend = nnlend;
  1813. return;
  1814. }
  1815. /* recursive dfs */
  1816. static int decycle3(struct gml_graph *g, struct gml_node *n, int level)
  1817. {
  1818. struct gml_node *tmpnode = NULL;
  1819. struct gml_node *source = NULL;
  1820. struct gml_node *target = NULL;
  1821. struct gml_elist *el = NULL;
  1822. struct gml_edge *edge = NULL;
  1823. int changed = 0;
  1824. if (n->done) {
  1825. if (level > n->rely) {
  1826. n->rely = level;
  1827. }
  1828. return (0);
  1829. }
  1830. n->rely = level;
  1831. n->done = 1;
  1832. /* mark this node is being processed */
  1833. n->grey = 1;
  1834. source = n;
  1835. /* follow outgoing edges */
  1836. el = source->outgoing_e;
  1837. while (el) {
  1838. edge = el->edge;
  1839. /* get the to-node */
  1840. target = edge->to_node;
  1841. if (target->grey) {
  1842. changed++;
  1843. tmpnode = edge->to_node;
  1844. edge->to_node = edge->from_node;
  1845. edge->from_node = tmpnode;
  1846. /* toggle the edge is reversed bit */
  1847. if (edge->reversed) {
  1848. edge->reversed = 0;
  1849. } else {
  1850. edge->reversed = 1;
  1851. }
  1852. } else {
  1853. if (target->done == 0) {
  1854. changed += decycle3(g, target, (level + 1));
  1855. }
  1856. }
  1857. el = el->next;
  1858. }
  1859. /* this node is ready being processed */
  1860. n->grey = 0;
  1861. return (changed);
  1862. }
  1863. /* remove cycles in the graph */
  1864. static void uncycle(struct gml_graph *g)
  1865. {
  1866. struct gml_nlist *lnll = NULL;
  1867. int changed = 0;
  1868. /* build the s/tlist of a node */
  1869. clear_stlist_all(g);
  1870. make_stlist(g);
  1871. /* revert cycles at the last edge in the chain */
  1872. g->maxlevel = 0;
  1873. lnll = g->nodelist;
  1874. while (lnll) {
  1875. lnll->node->rely = -1;
  1876. lnll->node->done = 0;
  1877. lnll->node->grey = 0;
  1878. lnll = lnll->next;
  1879. }
  1880. /* first the startnodes */
  1881. lnll = g->nodelist;
  1882. changed = 0;
  1883. while (lnll) {
  1884. /* select start nodes */
  1885. if (lnll->node->indegree == 0 && lnll->node->outdegree != 0) {
  1886. if (lnll->node->done == 0) {
  1887. /* use v3 */
  1888. changed += decycle3(g, lnll->node, 0);
  1889. }
  1890. }
  1891. lnll = lnll->next;
  1892. }
  1893. /* check nodes */
  1894. lnll = g->nodelist;
  1895. while (lnll) {
  1896. /* select other nodes */
  1897. if (lnll->node->rely == -1) {
  1898. /* use v3 */
  1899. changed += decycle3(g, lnll->node, 0);
  1900. }
  1901. lnll = lnll->next;
  1902. }
  1903. if (changed) {
  1904. /* build the s/tlist of a node */
  1905. clear_stlist_all(g);
  1906. make_stlist(g);
  1907. }
  1908. return;
  1909. }
  1910. /* rebuild nodes st lists */
  1911. static void make_stlist(struct gml_graph *g)
  1912. {
  1913. struct gml_elist *el = NULL;
  1914. struct gml_edge *edge = NULL;
  1915. struct gml_node *sn = NULL;
  1916. struct gml_node *tn = NULL;
  1917. struct gml_elist *ne = NULL;
  1918. struct gml_nlist *lnll = NULL;
  1919. /* refresh degree count of nodes */
  1920. lnll = g->nodelist;
  1921. while (lnll) {
  1922. /* make ure these are cleared */
  1923. lnll->node->outgoing_e = NULL; /* source list, outgoing edges */
  1924. lnll->node->outgoing_etail = NULL; /* source list, outgoing edges */
  1925. lnll->node->incoming_e = NULL; /* target list, incoming edges */
  1926. lnll->node->incoming_etail = NULL; /* target list, incoming edges */
  1927. lnll->node->indegree = 0;
  1928. lnll->node->outdegree = 0;
  1929. lnll = lnll->next;
  1930. }
  1931. el = g->edgelist;
  1932. while (el) {
  1933. edge = el->edge;
  1934. /* from/to nodes */
  1935. sn = edge->from_node;
  1936. tn = edge->to_node;
  1937. ne = (struct gml_elist *) sfg_calloc(1, sizeof(struct gml_elist));
  1938. if (ne == NULL) {
  1939. return;
  1940. }
  1941. ne->edge = edge;
  1942. /* list of outgoing edges */
  1943. if (sn->outgoing_e == NULL) {
  1944. sn->outgoing_e = ne;
  1945. sn->outgoing_etail = ne;
  1946. } else {
  1947. sn->outgoing_etail->next = ne;
  1948. sn->outgoing_etail = ne;
  1949. }
  1950. sn->outdegree++;
  1951. ne = (struct gml_elist *) sfg_calloc(1, sizeof(struct gml_elist));
  1952. if (ne == NULL) {
  1953. return;
  1954. }
  1955. ne->edge = edge;
  1956. /* list of incoming edges */
  1957. if (tn->incoming_e == NULL) {
  1958. tn->incoming_e = ne;
  1959. tn->incoming_etail = ne;
  1960. } else {
  1961. tn->incoming_etail->next = ne;
  1962. tn->incoming_etail = ne;
  1963. }
  1964. tn->indegree++;
  1965. el = el->next;
  1966. }
  1967. return;
  1968. }
  1969. /* clear the s/t list of a node */
  1970. static void clear_stlist(struct gml_node *node)
  1971. {
  1972. struct gml_elist *ell = NULL;
  1973. struct gml_elist *ellnext = NULL;
  1974. /* free outgoing edges */
  1975. ell = node->outgoing_e;
  1976. while (ell) {
  1977. ellnext = ell->next;
  1978. ell = (struct gml_elist *) sfg_free(ell);
  1979. ell = ellnext;
  1980. }
  1981. node->outgoing_e = NULL;
  1982. node->outgoing_etail = NULL;
  1983. node->outdegree = 0;
  1984. /* free incoming edges */
  1985. ell = node->incoming_e;
  1986. while (ell) {
  1987. ellnext = ell->next;
  1988. ell = (struct gml_elist *) sfg_free(ell);
  1989. ell = ellnext;
  1990. }
  1991. node->incoming_e = NULL;
  1992. node->incoming_etail = NULL;
  1993. node->indegree = 0;
  1994. return;
  1995. }
  1996. /* clear the s/t list of all nodes */
  1997. static void clear_stlist_all(struct gml_graph *g)
  1998. {
  1999. struct gml_nlist *lnll = NULL;
  2000. lnll = g->nodelist;
  2001. while (lnll) {
  2002. clear_stlist(lnll->node);
  2003. lnll = lnll->next;
  2004. }
  2005. return;
  2006. }
  2007. /* add node as single node */
  2008. static void add_singlenode(struct gml_graph *g, struct gml_node *node)
  2009. {
  2010. struct gml_nlist *lnll = NULL;
  2011. lnll = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  2012. if (lnll) {
  2013. lnll->node = node;
  2014. if (g->singlenodelist == NULL) {
  2015. g->singlenodelist = lnll;
  2016. g->singlenodelistend = lnll;
  2017. } else {
  2018. g->singlenodelistend->next = lnll;
  2019. g->singlenodelistend = lnll;
  2020. }
  2021. }
  2022. return;
  2023. }
  2024. /* set rel. y level of all nodes */
  2025. static void ylevels(struct gml_graph *g)
  2026. {
  2027. struct gml_nlist *lnll = NULL;
  2028. int i = 0;
  2029. int start2 = 0;
  2030. int special = 0;
  2031. int nnodes = 0;
  2032. if (g->nodelist == NULL) {
  2033. /* nothing to do */
  2034. return;
  2035. }
  2036. /* no single nodes in the graph */
  2037. g->nsinglenodes = 0;
  2038. /* set all y levels to undefined */
  2039. lnll = g->nodelist;
  2040. nnodes = 0;
  2041. while (lnll) {
  2042. nnodes++;
  2043. /* y = -1, means undefined */
  2044. lnll->node->rely = -1;
  2045. lnll->node->done = 0;
  2046. lnll->node->grey = 0;
  2047. lnll->node->startnode = -1;
  2048. /* check for single nodes and mark them */
  2049. if (lnll->node->outgoing_e == NULL && lnll->node->incoming_e == NULL) {
  2050. /* set single nodes at fixed level 0 */
  2051. lnll->node->rely = 0;
  2052. lnll->node->done = 1;
  2053. /* node belongs to part of graph with this startnode */
  2054. lnll->node->startnode = 0;
  2055. g->nsinglenodes = (g->nsinglenodes + 1);
  2056. add_singlenode(g, lnll->node);
  2057. }
  2058. lnll = lnll->next;
  2059. }
  2060. /* if there are single nodes on level 0, start the graph at level 1 */
  2061. if (g->nsinglenodes) {
  2062. start2 = 1;
  2063. } else {
  2064. start2 = 0;
  2065. }
  2066. /* number of start nodes in the graph */
  2067. g->nstartnodes = 0;
  2068. /* where the actual drawing starts at y-level */
  2069. g->startnodeslevel = start2;
  2070. special = 0;
  2071. /* dfs */
  2072. lnll = g->nodelist;
  2073. while (lnll) {
  2074. if (lnll->node->rely == -1) {
  2075. /* select start nodes */
  2076. if (lnll->node->indegree == 0 && lnll->node->outdegree != 0) {
  2077. g->nstartnodes++;
  2078. set_level2(g, lnll->node, start2, lnll->node->nr);
  2079. }
  2080. }
  2081. lnll = lnll->next;
  2082. }
  2083. /* check that all nodes have y position now */
  2084. lnll = g->nodelist;
  2085. while (lnll) {
  2086. if (lnll->node->rely == -1) {
  2087. set_level2(g, lnll->node, start2, lnll->node->nr);
  2088. }
  2089. lnll = lnll->next;
  2090. }
  2091. /* graph can have zero startnodes.
  2092. * set first node as startnode.
  2093. */
  2094. if (g->nstartnodes == 0) {
  2095. g->nstartnodes++;
  2096. if (g->nodelist) {
  2097. set_level2(g, g->nodelist->node, start2, g->nodelist->node->nr);
  2098. }
  2099. special = 1;
  2100. }
  2101. /* fill the table with startnodes */
  2102. g->startnodes = (int *) sfg_calloc(1, g->nstartnodes * sizeof(int));
  2103. if (g->startnodes == NULL) {
  2104. return;
  2105. }
  2106. /* special case if there were no startnodes */
  2107. if (special) {
  2108. /* set first node as startnode */
  2109. if (g->nodelist) {
  2110. g->startnodes[0] = g->nodelist->node->nr;
  2111. }
  2112. } else {
  2113. /* copy the startnodes numbers in the (int *)array */
  2114. i = 0;
  2115. lnll = g->nodelist;
  2116. while (lnll) {
  2117. /* no incoming edges and at least one outgoing edge */
  2118. if (lnll->node->indegree == 0 && lnll->node->outdegree != 0) {
  2119. /* set node number. this is not the id number in the input. */
  2120. g->startnodes[i] = lnll->node->nr;
  2121. i++;
  2122. }
  2123. lnll = lnll->next;
  2124. }
  2125. }
  2126. return;
  2127. }
  2128. /* set rel. y level of nodes */
  2129. static void set_level2(struct gml_graph *g, struct gml_node *n, int i, int startnode)
  2130. {
  2131. struct gml_node *target = NULL;
  2132. struct gml_edge *edge = NULL;
  2133. struct gml_elist *el = NULL;
  2134. if (n->done) {
  2135. if (i > n->rely && n->grey == 0) {
  2136. n->rely = i;
  2137. if (i > g->maxlevel) {
  2138. g->maxlevel = i;
  2139. }
  2140. }
  2141. if (n->grey) {
  2142. return;
  2143. }
  2144. if (n->done > 1) {
  2145. return;
  2146. }
  2147. }
  2148. n->grey++;
  2149. n->done++;
  2150. n->rely = i;
  2151. n->startnode = startnode;
  2152. if (i > g->maxlevel) {
  2153. g->maxlevel = i;
  2154. }
  2155. /* follow outgoing edges */
  2156. el = n->outgoing_e;
  2157. while (el) {
  2158. edge = el->edge;
  2159. target = edge->to_node;
  2160. set_level2(g, target, (i + 1), startnode);
  2161. el = el->next;
  2162. }
  2163. n->grey = 0;
  2164. return;
  2165. }
  2166. /* undo reversed edges and refresh node edgelists */
  2167. static void unrev(struct gml_graph *g)
  2168. {
  2169. struct gml_elist *el = NULL;
  2170. struct gml_node *tmpnode = NULL;
  2171. struct gml_node *sn = NULL;
  2172. struct gml_node *tn = NULL;
  2173. struct gml_edge *edge = NULL;
  2174. int changed = 0;
  2175. el = g->edgelist;
  2176. while (el) {
  2177. edge = el->edge;
  2178. if (el->edge->reversed) {
  2179. changed++;
  2180. sn = edge->from_node;
  2181. tn = edge->to_node;
  2182. /* swap */
  2183. tmpnode = tn;
  2184. el->edge->to_node = sn;
  2185. el->edge->from_node = tmpnode;
  2186. el->edge->reversed = 0;
  2187. }
  2188. el = el->next;
  2189. }
  2190. if (changed) {
  2191. /* rebuild the in/out edges lists at the nodes in the modified graph */
  2192. g->maxlevel = 0;
  2193. /* refresh st lists */
  2194. clear_stlist_all(g);
  2195. make_stlist(g);
  2196. }
  2197. return;
  2198. }
  2199. static int do_abs(int i)
  2200. {
  2201. if (i < 0) {
  2202. return (-i);
  2203. } else {
  2204. return (i);
  2205. }
  2206. }
  2207. /* try to find shorter edges */
  2208. static void shorteredges(struct gml_graph *g)
  2209. {
  2210. struct gml_nlist *lnll = NULL;
  2211. struct gml_elist *ine = NULL;
  2212. struct gml_elist *oute = NULL;
  2213. struct gml_edge *etop = NULL;
  2214. struct gml_edge *ebot = NULL;
  2215. struct gml_node *ntop = NULL;
  2216. struct gml_node *nbot = NULL;
  2217. /* undo reversed edges and refresh node edgelists */
  2218. unrev(g);
  2219. /* move in between nodes at halfway */
  2220. lnll = g->nodelist;
  2221. while (lnll) {
  2222. if ((lnll->node->indegree == 1) && (lnll->node->outdegree == 1)) {
  2223. oute = lnll->node->outgoing_e;
  2224. ine = lnll->node->incoming_e;
  2225. etop = ine->edge;
  2226. ebot = oute->edge;
  2227. ntop = etop->from_node;
  2228. nbot = ebot->to_node;
  2229. if ((do_abs(ntop->rely - lnll->node->rely) > 1)
  2230. || (do_abs(nbot->rely - lnll->node->rely) > 1)) {
  2231. /* put node at the middle, does not depend on edge direction up/down */
  2232. lnll->node->rely = ((ntop->rely + nbot->rely) / 2);
  2233. }
  2234. }
  2235. lnll = lnll->next;
  2236. }
  2237. return;
  2238. }
  2239. /* all edges downwards */
  2240. static void edgesdownwards(struct gml_graph *g)
  2241. {
  2242. struct gml_elist *el = NULL;
  2243. struct gml_node *tmpnode = NULL;
  2244. struct gml_node *sn = NULL;
  2245. struct gml_node *tn = NULL;
  2246. struct gml_edge *edge = NULL;
  2247. int changed1 = 0;
  2248. el = g->edgelist;
  2249. while (el) {
  2250. edge = el->edge;
  2251. sn = edge->from_node;
  2252. tn = edge->to_node;
  2253. if ((tn->rely - sn->rely) < 0) {
  2254. /* swap */
  2255. tmpnode = tn;
  2256. el->edge->to_node = el->edge->from_node;
  2257. el->edge->from_node = tmpnode;
  2258. /* toggle the edge is reversed bit */
  2259. if (el->edge->reversed) {
  2260. el->edge->reversed = 0;
  2261. } else {
  2262. el->edge->reversed = 1;
  2263. }
  2264. changed1++;
  2265. }
  2266. el = el->next;
  2267. }
  2268. if (changed1) {
  2269. /* rebuild the in/out edges lists at the nodes in the modified graph */
  2270. g->maxlevel = 0;
  2271. /* refresh st lists */
  2272. clear_stlist_all(g);
  2273. make_stlist(g);
  2274. }
  2275. return;
  2276. }
  2277. /* dfs check again and revers if needed */
  2278. static void edgelen(struct gml_graph *g)
  2279. {
  2280. struct gml_elist *el = NULL;
  2281. struct gml_edge *edge = NULL;
  2282. struct gml_node *sn = NULL;
  2283. struct gml_node *tn = NULL;
  2284. struct gml_node *tmpnode = NULL;
  2285. int changed = 0;
  2286. el = g->edgelist;
  2287. while (el) {
  2288. edge = el->edge;
  2289. sn = edge->from_node;
  2290. tn = edge->to_node;
  2291. if ((tn->rely - sn->rely) < 0) {
  2292. changed++;
  2293. tmpnode = tn;
  2294. el->edge->to_node = el->edge->from_node;
  2295. el->edge->from_node = tmpnode;
  2296. }
  2297. el = el->next;
  2298. }
  2299. if (changed) {
  2300. /* refresh st lists */
  2301. clear_stlist_all(g);
  2302. make_stlist(g);
  2303. }
  2304. return;
  2305. }
  2306. /* doublespace the vertical levels */
  2307. static void doublespacey(struct gml_graph *g)
  2308. {
  2309. struct gml_nlist *lnll = NULL;
  2310. /* same edges now will have different dummy nodes resulting in 2 lines */
  2311. g->maxlevel = 0;
  2312. /* at the odd levels the edge labels will be placed. */
  2313. lnll = g->nodelist;
  2314. while (lnll) {
  2315. lnll->node->rely = (2 * lnll->node->rely);
  2316. if (lnll->node->rely > g->maxlevel) {
  2317. g->maxlevel = lnll->node->rely;
  2318. }
  2319. lnll = lnll->next;
  2320. }
  2321. return;
  2322. }
  2323. /* dummy nodes are only in nodelist, not raw nodelist */
  2324. static void add_new_dummynode(struct gml_graph *g, int foundid)
  2325. {
  2326. struct gml_node *node = NULL;
  2327. struct gml_nlist *lnll = NULL;
  2328. if (uniqnode(maingraph, foundid)) {
  2329. return;
  2330. }
  2331. node = (struct gml_node *) sfg_calloc(1, sizeof(struct gml_node));
  2332. if (node == NULL) {
  2333. return;
  2334. }
  2335. node->nr = foundid;
  2336. uniqnode_add(maingraph, node);
  2337. lnll = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  2338. if (lnll == NULL) {
  2339. node = (struct gml_node *) sfg_free(node);
  2340. return;
  2341. }
  2342. lnll->node = node;
  2343. if (g->nodelist == NULL) {
  2344. g->nodelist = lnll;
  2345. g->nodelistend = lnll;
  2346. } else {
  2347. g->nodelistend->next = lnll;
  2348. g->nodelistend = lnll;
  2349. }
  2350. return;
  2351. }
  2352. /* edge to dummy node */
  2353. static void add_new_dummyedge(struct gml_graph *g, int foundsource, int foundtarget, int reversed)
  2354. {
  2355. struct gml_node *snode = NULL;
  2356. struct gml_node *tnode = NULL;
  2357. struct gml_edge *edge = NULL;
  2358. struct gml_elist *el = NULL;
  2359. snode = uniqnode(maingraph, foundsource);
  2360. if (snode == NULL) {
  2361. return;
  2362. }
  2363. tnode = uniqnode(maingraph, foundtarget);
  2364. if (tnode == NULL) {
  2365. return;
  2366. }
  2367. edge = (struct gml_edge *) sfg_calloc(1, sizeof(struct gml_edge));
  2368. if (edge == NULL) {
  2369. return;
  2370. }
  2371. g->edgenum++;
  2372. edge->nr = g->edgenum;
  2373. edge->from_node = snode; /* from-node */
  2374. edge->to_node = tnode; /* to-node */
  2375. edge->reversed = reversed; /* edge attr. edge-is-reversed */
  2376. el = (struct gml_elist *) sfg_calloc(1, sizeof(struct gml_elist));
  2377. if (el == NULL) {
  2378. edge = (struct gml_edge *) sfg_free(edge);
  2379. return;
  2380. }
  2381. el->edge = edge;
  2382. if (g->edgelist == NULL) {
  2383. g->edgelist = el;
  2384. g->edgelistend = el;
  2385. } else {
  2386. g->edgelistend->next = el;
  2387. g->edgelistend = el;
  2388. }
  2389. return;
  2390. }
  2391. /* delete edge when replaced with a chain of edges */
  2392. static void del_edge(struct gml_graph *g, struct gml_elist *edgeel)
  2393. {
  2394. struct gml_elist *elprev = NULL;
  2395. struct gml_elist *el = NULL;
  2396. struct gml_elist *elto = NULL;
  2397. if (g->edgelist == NULL) {
  2398. return;
  2399. }
  2400. if (edgeel == g->edgelist) {
  2401. g->edgelist = g->edgelist->next;
  2402. if (g->edgelistend == edgeel) {
  2403. g->edgelistend = NULL;
  2404. } else {
  2405. el = g->edgelist;
  2406. elprev = el;
  2407. while (el) {
  2408. elprev = el;
  2409. if (el->next == edgeel) {
  2410. break;
  2411. }
  2412. el = el->next;
  2413. }
  2414. g->edgelistend = elprev;
  2415. }
  2416. edgeel->edge = (struct gml_edge *) sfg_free(edgeel->edge);
  2417. edgeel = (struct gml_elist *) sfg_free(edgeel);
  2418. } else {
  2419. elto = edgeel->next;
  2420. el = g->edgelist;
  2421. elprev = el;
  2422. while (el) {
  2423. elprev = el;
  2424. if (el->next == edgeel) {
  2425. break;
  2426. }
  2427. el = el->next;
  2428. }
  2429. elprev->next = elto;
  2430. if (g->edgelistend == edgeel) {
  2431. g->edgelistend = elprev;
  2432. }
  2433. edgeel->edge = (struct gml_edge *) sfg_free(edgeel->edge);
  2434. edgeel = (struct gml_elist *) sfg_free(edgeel);
  2435. }
  2436. return;
  2437. }
  2438. /* splits edgelabel edges into node->label->node */
  2439. static void edgelabels(struct gml_graph *g)
  2440. {
  2441. struct gml_elist *el = NULL;
  2442. struct gml_elist *elnext = NULL;
  2443. struct gml_node *ln = NULL;
  2444. char rev = 0;
  2445. int ydiff = 0;
  2446. int enumber = 0;
  2447. if (g->nedgelabels == 0) {
  2448. /* no edge labels, nothing todo here */
  2449. return;
  2450. }
  2451. if (g->do_edgelabels == 0) {
  2452. /* skip edge label processing */
  2453. return;
  2454. }
  2455. /* scan edges all downwards */
  2456. el = g->edgelist;
  2457. while (el) {
  2458. /* make sure, from-node is lower y then to-node */
  2459. if (el->edge->from_node->rely > el->edge->to_node->rely) {
  2460. ln = el->edge->from_node;
  2461. el->edge->from_node = el->edge->to_node;
  2462. el->edge->to_node = ln;
  2463. /* toggle rev flag */
  2464. if (el->edge->reversed) {
  2465. el->edge->reversed = 0;
  2466. } else {
  2467. el->edge->reversed = 1;
  2468. }
  2469. }
  2470. el = el->next;
  2471. }
  2472. /* scan edges for edge labels */
  2473. el = g->edgelist;
  2474. while (el) {
  2475. elnext = el->next;
  2476. /* do if there is a edge label */
  2477. if (el->edge->elabel) {
  2478. /* number of edge with edgelabel */
  2479. enumber = el->edge->nr;
  2480. /* edge attr. is-reversed */
  2481. rev = el->edge->reversed;
  2482. maingraph->nodenum++;
  2483. /* create label node */
  2484. add_new_dummynode(g, maingraph->nodenum);
  2485. /* mark this is a label node and set label text */
  2486. ln = uniqnode(maingraph, maingraph->nodenum);
  2487. /* edge-label-node, original from/to node */
  2488. ln->el_fnode = el->edge->from_node;
  2489. ln->el_tnode = el->edge->to_node;
  2490. /* y level difference between original from/to-nodes */
  2491. ydiff = (ln->el_tnode->rely - ln->el_fnode->rely);
  2492. /* put edge label halfway */
  2493. ln->rely = ln->el_fnode->rely + (ydiff / 2);
  2494. ln->elabel = 1; /* mark this is a edgelabel */
  2495. ln->dummy = 0;
  2496. /* set in the edgelabel node the number of the orig. edge */
  2497. ln->enumber = enumber;
  2498. /* set the size of the edge label text in the new node */
  2499. ln->tx = el->edge->tx;
  2500. ln->ty = el->edge->ty;
  2501. /* node belongs to graph with this startnode */
  2502. ln->startnode = el->edge->from_node->startnode;
  2503. /* create new edges with label node in between */
  2504. add_new_dummyedge(g, el->edge->from_node->nr, maingraph->nodenum, rev);
  2505. add_new_dummyedge(g, maingraph->nodenum, el->edge->to_node->nr, rev);
  2506. /* free old edge */
  2507. del_edge(g, el);
  2508. }
  2509. el = elnext;
  2510. }
  2511. /* refresh st lists */
  2512. clear_stlist_all(g);
  2513. make_stlist(g);
  2514. return;
  2515. }
  2516. /* split longer edges */
  2517. static void splitedges(struct gml_graph *g)
  2518. {
  2519. struct gml_elist *el = NULL;
  2520. struct gml_elist *elnext = NULL;
  2521. struct gml_edge *edge = NULL;
  2522. struct gml_node *sn = NULL;
  2523. struct gml_node *tn = NULL;
  2524. struct gml_node *nlnode = NULL;
  2525. int edgelen = 0;
  2526. int prevnodeid = 0;
  2527. int newid = 0;
  2528. int i = 0;
  2529. int sny = 0;
  2530. char rev = 0;
  2531. el = g->edgelist;
  2532. while (el) {
  2533. elnext = el->next;
  2534. edge = el->edge;
  2535. sn = edge->from_node; /* from-node */
  2536. tn = edge->to_node; /* to-node */
  2537. rev = edge->reversed; /* edge attr. to copy when splitting edge */
  2538. edgelen = (tn->rely - sn->rely);
  2539. /* horizontal edge */
  2540. if (edgelen == 0) {
  2541. /* horizontal edge has original endpoints, used in drawing edges */
  2542. edge->hedge = 1;
  2543. g->nhedges++; /* number of horizontal edges */
  2544. /* mark that nodes have a hor. edge */
  2545. sn->hashedge = 1;
  2546. tn->hashedge = 1;
  2547. } else if (edgelen > 1) {
  2548. prevnodeid = sn->nr;
  2549. sny = sn->rely;
  2550. for (i = 1; i < edgelen; i++) {
  2551. /* dummy node numbers start at first free node nr number */
  2552. maingraph->nodenum++;
  2553. newid = maingraph->nodenum;
  2554. add_new_dummynode(maingraph, newid);
  2555. nlnode = uniqnode(maingraph, newid);
  2556. nlnode->dummy = 1; /* this is a dummy node */
  2557. nlnode->elabel = 0; /* not a edgelabel */
  2558. nlnode->rely = (sny + i);
  2559. nlnode->startnode = sn->startnode;
  2560. add_new_dummyedge(g, prevnodeid, newid, rev);
  2561. prevnodeid = newid;
  2562. }
  2563. add_new_dummyedge(g, prevnodeid, tn->nr, rev);
  2564. del_edge(g, el);
  2565. } else if (edgelen == 1) {
  2566. /* edge len is 1 oke. */
  2567. } else {
  2568. /* shouldnothappen */
  2569. }
  2570. el = elnext;
  2571. }
  2572. return;
  2573. }
  2574. /* create level node count data */
  2575. static void nodecounts(struct gml_graph *g)
  2576. {
  2577. struct gml_nlist *lnll = NULL;
  2578. /* refresh st lists */
  2579. clear_stlist_all(g);
  2580. make_stlist(g);
  2581. /* table with number of nodes per level */
  2582. g->nnodes_of_level = (int *) sfg_calloc((g->maxlevel + 1), sizeof(int));
  2583. if (g->nnodes_of_level == NULL) {
  2584. return;
  2585. }
  2586. /* determine widest level and how many nodes it has */
  2587. g->widestlevel = 0;
  2588. g->widestnnodes = 0;
  2589. lnll = g->nodelist;
  2590. while (lnll) {
  2591. /* rely used for sugi */
  2592. g->nnodes_of_level[lnll->node->rely] = g->nnodes_of_level[lnll->node->rely] + 1;
  2593. /* x used for sugi, offset 1...n */
  2594. lnll->node->relx = g->nnodes_of_level[lnll->node->rely];
  2595. if (g->nnodes_of_level[lnll->node->rely] >= g->widestnnodes) {
  2596. g->widestnnodes = g->nnodes_of_level[lnll->node->rely];
  2597. g->widestlevel = lnll->node->rely;
  2598. }
  2599. lnll = lnll->next;
  2600. }
  2601. return;
  2602. }
  2603. struct mmatrix {
  2604. int level; /* upper level */
  2605. int nrows; /* nr. of rows (in upper level) */
  2606. int ncols; /* nr. of cols (in level+1) */
  2607. int nbytes; /* bytes used for matrix */
  2608. int *mi0; /* row node id's level i */
  2609. int nmi0; /* how many byte's in mi0 */
  2610. int *m0i; /* col node id's level (i+1) */
  2611. int nm0i; /* how many bytes in m0i */
  2612. int bbytes; /* bytes for double barycenter values */
  2613. double *b; /* buffer barycenter values */
  2614. unsigned char *bits; /* matrix bits */
  2615. };
  2616. static void sfg_setbit(unsigned char *a, int k)
  2617. {
  2618. if (k == 0) {
  2619. } else {
  2620. a[k / CHAR_BIT] |= (1 << (k % CHAR_BIT));
  2621. }
  2622. return;
  2623. }
  2624. static inline void clearbit(unsigned char a[], int k)
  2625. {
  2626. if (k == 0) {
  2627. } else {
  2628. a[k / CHAR_BIT] &= ~(1 << (k % CHAR_BIT));
  2629. }
  2630. return;
  2631. }
  2632. static inline int testbit(struct mmatrix *m, unsigned char a[], int k)
  2633. {
  2634. int ret = 0;
  2635. unsigned int mask = 0;
  2636. unsigned int mask2 = 0;
  2637. unsigned int i = 0;
  2638. if (k == 0) {
  2639. }
  2640. /* todo here tofix */
  2641. if (k > ((m->ncols + 1) * (m->nrows + 1))) {
  2642. }
  2643. /* compiler issue: the use of << is undefined here */
  2644. /* issue CHAR_BIT is often 8 but does not have to be 8 */
  2645. mask = (k % CHAR_BIT);
  2646. /*old: mask2 = (1 << mask); */
  2647. mask2 = 1;
  2648. for (i = 0; i < mask; i++) {
  2649. mask2 = (mask2 * 2);
  2650. }
  2651. ret = ((a[k / CHAR_BIT]) & mask2);
  2652. /*old return ((a[k / CHAR_BIT] & (1 << (k % CHAR_BIT))) != 0); */
  2653. return (ret);
  2654. }
  2655. /* i cols, j rows */
  2656. static inline int mget(struct mmatrix *m, int i, int j)
  2657. {
  2658. return (testbit(m, m->bits, ((i * (m->ncols + 0)) + j)));
  2659. }
  2660. /* i is the from-node, j is the to-node, value is 1 for edge, otherwise 0 */
  2661. static inline void mget_set(struct mmatrix *m, int i, int j, int value)
  2662. {
  2663. if (value) {
  2664. sfg_setbit(m->bits, ((i * (m->ncols + 0)) + j));
  2665. } else {
  2666. clearbit(m->bits, ((i * (m->ncols + 0)) + j));
  2667. }
  2668. return;
  2669. }
  2670. static int number_of_crossings2(struct mmatrix *m, int r, int c)
  2671. {
  2672. int j = 0;
  2673. int k = 0;
  2674. int alpha = 0;
  2675. int beta = 1;
  2676. int result = 0;
  2677. for (j = 1; j <= r - 1; j++) {
  2678. for (k = j + 1; k <= r; k++) {
  2679. for (alpha = 1; alpha <= c - 1; alpha++) {
  2680. for (beta = alpha + 1; beta <= c; beta++) {
  2681. /* here 1*0=0, 0*1=0, 0*0=0 or 1*1=1 */
  2682. result = result + ((mget(m, j, beta) * mget(m, k, alpha)));
  2683. }
  2684. }
  2685. }
  2686. }
  2687. return (result);
  2688. }
  2689. static int number_of_crossings3(struct mmatrix *m, int r, int c)
  2690. {
  2691. int j = 0;
  2692. int k = 0;
  2693. int alpha = 0;
  2694. int beta = 1;
  2695. int result2 = 0;
  2696. if (0) {
  2697. result2 = number_of_crossings2(m, r, c);
  2698. }
  2699. for (j = 1; j <= (r - 1); j++) {
  2700. for (k = (j + 1); k <= r; k++) {
  2701. for (alpha = 1; alpha <= (c - 1); alpha++) {
  2702. /* */
  2703. if (mget(m, k, alpha)) {
  2704. for (beta = alpha + 1; beta <= c; beta++) {
  2705. /* */
  2706. if (mget(m, j, beta)) {
  2707. result2++;
  2708. }
  2709. }
  2710. }
  2711. /* */
  2712. }
  2713. }
  2714. }
  2715. return (result2);
  2716. }
  2717. /* number of crossings in whole graph */
  2718. static int number_of_crossings_a(struct gml_graph *g, struct mmatrix **mm)
  2719. {
  2720. int ktot = 0;
  2721. int k = 0;
  2722. int i = 0;
  2723. for (i = 0; i < g->maxlevel; i++) {
  2724. if (mm[i]) {
  2725. k = number_of_crossings3(mm[i], mm[i]->nrows, mm[i]->ncols);
  2726. /* save number of edge crossings at level */
  2727. g->numce[i] = k;
  2728. ktot = ktot + k;
  2729. }
  2730. }
  2731. return (ktot);
  2732. }
  2733. /* configure matrix data for level l in the graph */
  2734. static void make_matrix(struct gml_graph *g, int l, struct mmatrix *m)
  2735. {
  2736. struct gml_nlist *nl = NULL;
  2737. struct gml_elist *el = NULL;
  2738. int i = 0;
  2739. int j = 0;
  2740. int c = 0;
  2741. int r = 0;
  2742. /* add node numbers in the 0 position */
  2743. nl = g->nodelist;
  2744. while (nl) {
  2745. /* if (level(n) == l) */
  2746. if (nl->node->rely == l) {
  2747. /* rows */
  2748. i = nl->node->relx;
  2749. m->mi0[i] = nl->node->nr; /* uniq node number, not id */
  2750. } else if (nl->node->rely == (l + 1)) {
  2751. /* columns */
  2752. j = nl->node->relx;
  2753. m->m0i[j] = nl->node->nr; /* uniq node number, not id */
  2754. }
  2755. nl = nl->next;
  2756. }
  2757. /* matrix bits config, first init then set bits. */
  2758. r = m->nrows;
  2759. c = m->ncols;
  2760. for (i = 1; i <= r; i++) {
  2761. for (j = 1; j <= c; j++) {
  2762. mget_set(m, i, j, 0);
  2763. }
  2764. }
  2765. nl = g->nodelist;
  2766. while (nl) {
  2767. /* if (level(n) == l) */
  2768. if (nl->node->rely == l) {
  2769. /* outgoing edges : for_sourcelist (n, e) */
  2770. el = nl->node->outgoing_e;
  2771. while (el) {
  2772. /* skip the horizontal edges */
  2773. if (el->edge->hedge == 0) {
  2774. /* from-node rel. x pos */
  2775. i = nl->node->relx;
  2776. /* to-node rel. x pos */
  2777. j = el->edge->to_node->relx;
  2778. /* set this is edge */
  2779. mget_set(m, i, j, 1);
  2780. }
  2781. el = el->next;
  2782. }
  2783. }
  2784. nl = nl->next;
  2785. }
  2786. return;
  2787. }
  2788. /* find node with given id number */
  2789. static struct gml_node *su_find_node_with_number(struct gml_graph *g, int nr)
  2790. {
  2791. return (uniqnode(g, nr));
  2792. }
  2793. static void store_new_positions(struct gml_graph *g, struct mmatrix *m, int level)
  2794. {
  2795. struct gml_node *n = NULL;
  2796. int i = 0;
  2797. if (level) {
  2798. }
  2799. if (m == NULL) {
  2800. return;
  2801. }
  2802. for (i = 1; i <= m->nrows; i++) {
  2803. /* rows */
  2804. n = su_find_node_with_number(g, m->mi0[i]);
  2805. if (n) {
  2806. /* offset is 1, make it into 0..n */
  2807. n->relx = (i - 1);
  2808. } else {
  2809. }
  2810. }
  2811. for (i = 1; i <= m->ncols; i++) {
  2812. /* columns */
  2813. n = su_find_node_with_number(g, m->m0i[i]);
  2814. if (n) {
  2815. /* offset is 1, make it into 0..n */
  2816. n->relx = (i - 1);
  2817. } else {
  2818. }
  2819. }
  2820. return;
  2821. }
  2822. /* parts are Copyright (C) Felix von Leitner from dietlibc */
  2823. static void *do_memmove(void *dst, void *src, size_t count)
  2824. {
  2825. char *a = (char *)dst;
  2826. char *b = (char *)src;
  2827. if (src != dst) {
  2828. if (src > dst) {
  2829. while (count--)
  2830. *a++ = *b++;
  2831. } else {
  2832. a += count - 1;
  2833. b += count - 1;
  2834. while (count--)
  2835. *a-- = *b--;
  2836. }
  2837. }
  2838. return dst;
  2839. }
  2840. /* copy matrix m1 to m2 */
  2841. static void copy_m(struct mmatrix *m1, struct mmatrix *m2)
  2842. {
  2843. if (m1 && m2) {
  2844. m2->level = m1->level; /* upper level */
  2845. m2->nrows = m1->nrows; /* nr. of rows (in upper level) */
  2846. m2->ncols = m1->ncols; /* nr. of cols (in level+1) */
  2847. m2->nbytes = m1->nbytes; /* bytes used for matrix */
  2848. (void)do_memmove(m2->bits, m1->bits, m1->nbytes); /* matrix bits */
  2849. (void)do_memmove(m2->mi0, m1->mi0, m1->nmi0); /* row node id's level i */
  2850. m2->nmi0 = m1->nmi0; /* how many byte's in mi0 */
  2851. (void)do_memmove(m2->m0i, m1->m0i, m1->nm0i); /* col node id's level (i+1) */
  2852. m2->nm0i = m1->nm0i; /* how many bytes in m0i */
  2853. m2->bbytes = m1->bbytes; /* bytes for double barycenter values */
  2854. (void)do_memmove(m2->b, m1->b, m1->bbytes); /* barycenter values */
  2855. }
  2856. return;
  2857. }
  2858. /* are m1,m2 equal? */
  2859. static int equal_m(struct mmatrix *m1, struct mmatrix *m2, int r, int c)
  2860. {
  2861. int i = 0;
  2862. int j = 0;
  2863. for (i = 1; i <= r; i++) {
  2864. for (j = 1; j <= c; j++) {
  2865. if (mget(m1, i, j) != mget(m2, i, j)) {
  2866. return (0); /* FALSE */
  2867. }
  2868. }
  2869. }
  2870. return (1); /* TRUE */
  2871. }
  2872. /* is whole graph equal */
  2873. static int equal_a(struct gml_graph *g, struct mmatrix **mm1, struct mmatrix **mm2)
  2874. {
  2875. int l = 0;
  2876. if (mm1 == NULL || mm2 == NULL) {
  2877. return (0);
  2878. }
  2879. for (l = 0; l < g->maxlevel; l++) {
  2880. if (equal_m(mm1[l], mm2[l], mm1[l]->nrows /* old g->nnodes_of_level[l] */ ,
  2881. mm1[l]->ncols /* old g->nnodes_of_level[l + 1] */ ) ==
  2882. 0 /* FALSE */ ) {
  2883. return (0); /* FALSE */
  2884. }
  2885. }
  2886. return (1); /* TRUE */
  2887. }
  2888. /* copy whole graph */
  2889. static inline void copy_a(struct gml_graph *g, struct mmatrix **mm1, struct mmatrix **mm2)
  2890. {
  2891. int i = 0;
  2892. for (i = 0; i < g->maxlevel; i++) {
  2893. copy_m(mm1[i], mm2[i]);
  2894. }
  2895. return;
  2896. }
  2897. static void exch_rows(struct mmatrix *m, int r1, int r2)
  2898. {
  2899. int j = 0;
  2900. int id1 = 0;
  2901. int id2 = 0;
  2902. int bit1 = 0;
  2903. int bit2 = 0;
  2904. /*
  2905. * h = m[r1][j];
  2906. * m[r1][j] = m[r2][j];
  2907. * m[r2][j] = h;
  2908. */
  2909. /* swap node id numbers */
  2910. id1 = m->mi0[r1];
  2911. id2 = m->mi0[r2];
  2912. m->mi0[r1] = id2;
  2913. m->mi0[r2] = id1;
  2914. /* swap matrix bits */
  2915. for (j = 1; j <= m->ncols; j++) {
  2916. bit1 = mget(m, r1, j);
  2917. bit2 = mget(m, r2, j);
  2918. mget_set(m, r1, j, bit2);
  2919. mget_set(m, r2, j, bit1);
  2920. }
  2921. return;
  2922. }
  2923. static void exch_columns(struct mmatrix *m, int c1, int c2)
  2924. {
  2925. int i = 0;
  2926. int id1 = 0;
  2927. int id2 = 0;
  2928. int bit1 = 0;
  2929. int bit2 = 0;
  2930. /*
  2931. * h = m[i][c1];
  2932. * m[i][c1] = m[i][c2];
  2933. * m[i][c2] = h;
  2934. */
  2935. /* swap node id numbers */
  2936. id1 = m->m0i[c1];
  2937. id2 = m->m0i[c2];
  2938. m->m0i[c1] = id2;
  2939. m->m0i[c2] = id1;
  2940. /* swap matrix bits */
  2941. for (i = 1; i <= m->nrows; i++) {
  2942. bit1 = mget(m, i, c1);
  2943. bit2 = mget(m, i, c2);
  2944. mget_set(m, i, c1, bit2);
  2945. mget_set(m, i, c2, bit1);
  2946. }
  2947. return;
  2948. }
  2949. static int reverse_r(struct mmatrix *m, int r1, int r2)
  2950. {
  2951. int i = 0;
  2952. int j = 0;
  2953. int ch = 0;
  2954. for (i = r1, j = r2; i < j; i++, j--) {
  2955. ch++;
  2956. exch_rows(m, i, j);
  2957. }
  2958. return (ch);
  2959. }
  2960. static int reverse_c(struct mmatrix *m, int c1, int c2)
  2961. {
  2962. int i = 0;
  2963. int j = 0;
  2964. int ch = 0;
  2965. for (i = c1, j = c2; i < j; i++, j--) {
  2966. ch++;
  2967. exch_columns(m, i, j);
  2968. }
  2969. return (ch);
  2970. }
  2971. static double row_barycenter(struct mmatrix *m, int i, int maxval)
  2972. {
  2973. int j = 0;
  2974. int r1 = 0; /* sum */
  2975. int r2 = 0; /* div */
  2976. for (j = 1; j <= maxval; j++) {
  2977. if (mget(m, i, j)) {
  2978. r1 = r1 + j;
  2979. r2++;
  2980. }
  2981. }
  2982. if (r2 == 0) {
  2983. return (0.0);
  2984. } else {
  2985. return ((double)r1 / (double)r2);
  2986. }
  2987. }
  2988. static double column_barycenter(struct mmatrix *m, int j, int maxval)
  2989. {
  2990. int i = 0;
  2991. int r1 = 0; /* sum */
  2992. int r2 = 0; /* div */
  2993. for (i = 1; i <= maxval; i++) {
  2994. if (mget(m, i, j)) {
  2995. r1 = r1 + i;
  2996. r2++;
  2997. }
  2998. }
  2999. if (r2 == 0) {
  3000. return (0.0);
  3001. } else {
  3002. return ((double)r1 / (double)r2);
  3003. }
  3004. }
  3005. /* reverse rows */
  3006. static int r_r(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  3007. {
  3008. int i = 0;
  3009. int j = 0;
  3010. int ch = 0;
  3011. for (i = 1; i <= max_r; i++) {
  3012. m1->b[i] = row_barycenter(m1, i, max_c);
  3013. }
  3014. for (i = 1; i < max_r; i++) {
  3015. j = i;
  3016. while ((j < max_r) && (m1->b[j + 1] == m1->b[j])) {
  3017. j++;
  3018. }
  3019. if (j > i) {
  3020. ch += reverse_r(m1, i, j);
  3021. if (m2 != NULL) {
  3022. ch += reverse_c(m2, i, j);
  3023. }
  3024. i = j;
  3025. }
  3026. }
  3027. return (ch);
  3028. }
  3029. /* reverse columns */
  3030. static int r_c(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  3031. {
  3032. int i = 0;
  3033. int j = 0;
  3034. int ch = 0;
  3035. for (i = 1; i <= max_c; i++) {
  3036. m1->b[i] = column_barycenter(m1, i, max_r);
  3037. }
  3038. for (i = 1; i < max_c; i++) {
  3039. j = i;
  3040. while ((j < max_c) && (m1->b[j + 1] == m1->b[j])) {
  3041. j++;
  3042. }
  3043. if (j > i) {
  3044. ch += reverse_c(m1, i, j);
  3045. if (m2 != NULL) {
  3046. ch += reverse_r(m2, i, j);
  3047. }
  3048. i = j;
  3049. }
  3050. }
  3051. return (ch);
  3052. }
  3053. /* barycenter rows */
  3054. static int b_r(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  3055. {
  3056. double tmpb = 0.0;
  3057. int i = 0;
  3058. int j = 0;
  3059. int k = 0;
  3060. int ch = 0;
  3061. for (i = 1; i <= max_r; i++) {
  3062. m1->b[i] = row_barycenter(m1, i, max_c);
  3063. }
  3064. for (j = max_r; j > 1; j--) {
  3065. if (m1->b[j] != 0.0) {
  3066. for (i = 1; i < j; i++) {
  3067. if (m1->b[i] != 0.0) {
  3068. k = i + 1;
  3069. while (m1->b[k] == 0.0) {
  3070. k++;
  3071. }
  3072. if (m1->b[i] > m1->b[k]) {
  3073. ch++;
  3074. /* exch_double */
  3075. tmpb = m1->b[k];
  3076. m1->b[k] = m1->b[i];
  3077. m1->b[i] = tmpb;
  3078. exch_rows(m1, i, k);
  3079. if (m2 != NULL) {
  3080. ch++;
  3081. /* exchange cols from i to k */
  3082. exch_columns(m2, i, k);
  3083. }
  3084. }
  3085. }
  3086. }
  3087. }
  3088. }
  3089. return (ch);
  3090. }
  3091. /* barycenter cols */
  3092. static int b_c(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  3093. {
  3094. double tmpb = 0.0;
  3095. int i = 0;
  3096. int j = 0;
  3097. int k = 0;
  3098. int ch = 0;
  3099. for (i = 1; i <= max_c; i++) {
  3100. m1->b[i] = column_barycenter(m1, i, max_r);
  3101. }
  3102. for (j = max_c; j > 1; j--) {
  3103. if (m1->b[j] != 0.0) {
  3104. for (i = 1; i < j; i++) {
  3105. if (m1->b[i] != 0.0) {
  3106. k = i + 1;
  3107. while (m1->b[k] == 0.0) {
  3108. k++;
  3109. }
  3110. if (m1->b[i] > m1->b[k]) {
  3111. ch++;
  3112. /* exch_double */
  3113. tmpb = m1->b[k];
  3114. m1->b[k] = m1->b[i];
  3115. m1->b[i] = tmpb;
  3116. /* exchange cols from i to k */
  3117. exch_columns(m1, i, k);
  3118. if (m2 != NULL) {
  3119. ch++;
  3120. exch_rows(m2, i, k);
  3121. }
  3122. }
  3123. }
  3124. }
  3125. }
  3126. }
  3127. return (ch);
  3128. }
  3129. /* test if array is sorted, 1 if sorted from hight-to-low */
  3130. static int sorted(double *vector, int maxval)
  3131. {
  3132. int i = 0;
  3133. for (i = 1; i < maxval; i++) {
  3134. /* but ignore 0.0 values */
  3135. if ((vector[i] > vector[i + 1]) && (vector[i + 1] != 0.0)) {
  3136. return (0); /* FALSE */
  3137. }
  3138. }
  3139. return (1); /* TRUE */
  3140. }
  3141. static inline int phase1_down(struct gml_graph *g, struct mmatrix **mm)
  3142. {
  3143. int i = 0;
  3144. int ch = 0;
  3145. /* from level0 down to level max */
  3146. for (i = 0; i < g->maxlevel - 1; i++) {
  3147. ch += b_c(mm[i], mm[i + 1], mm[i]->nrows, mm[i]->ncols);
  3148. }
  3149. ch += b_c(mm[g->maxlevel - 1], NULL, mm[g->maxlevel - 1]->nrows, mm[g->maxlevel - 1]->ncols);
  3150. return (ch);
  3151. }
  3152. static inline int phase1_up(struct gml_graph *g, struct mmatrix **mm)
  3153. {
  3154. int i = 0;
  3155. int ch = 0;
  3156. if (mm == NULL) {
  3157. return (0);
  3158. }
  3159. /* from level max up to level0 */
  3160. for (i = (g->maxlevel - 1); i > 0; i--) {
  3161. ch += b_r(mm[i], mm[i - 1], mm[i]->nrows /* old g->nnodes_of_level[i] */ ,
  3162. mm[i]->ncols /* old g->nnodes_of_level[i + 1] */ );
  3163. }
  3164. ch += b_r(mm[0], NULL, mm[0]->nrows /* g->nnodes_of_level[0] */ ,
  3165. mm[0]->ncols /* g->nnodes_of_level[1] */ );
  3166. return (ch);
  3167. }
  3168. /* */
  3169. static inline int phase2_down(struct gml_graph *g, struct mmatrix **mm)
  3170. {
  3171. int l = 0; /* Level */
  3172. int i = 0;
  3173. int ch = 0;
  3174. for (l = 0; l < (g->maxlevel - 1); l++) {
  3175. for (i = 1; i <= mm[l]->ncols /* g->nnodes_of_level[l + 1] */ ; i++) {
  3176. mm[l]->b[i] = column_barycenter(mm[l], i, mm[l]->nrows /* g->nnodes_of_level[l] */ );
  3177. }
  3178. if (sorted(mm[l]->b, mm[l]->ncols /* g->nnodes_of_level[l + 1] */ ) ==
  3179. 1 /* TRUE */ ) {
  3180. /* reverse columns */
  3181. ch += r_c(mm[l], mm[l + 1], mm[l]->nrows /* g->nnodes_of_level[l] */ ,
  3182. mm[l]->ncols /* g->nnodes_of_level[l + 1] */ );
  3183. } else {
  3184. return (ch);
  3185. }
  3186. }
  3187. for (i = 1; i <= g->nnodes_of_level[g->maxlevel]; i++) {
  3188. mm[g->maxlevel - 1]->b[i] = column_barycenter(mm[g->maxlevel - 1], i, mm[g->maxlevel - 1]->nrows
  3189. /* g->nnodes_of_level[g->maxlevel - 1] */ );
  3190. }
  3191. if (sorted(mm[g->maxlevel - 1]->b, mm[g->maxlevel - 1]->ncols /* g->nnodes_of_level[g->maxlevel] */ ) ==
  3192. 1 /* TRUE */ ) {
  3193. /* reverse columns */
  3194. ch += r_c(mm[g->maxlevel - 1], NULL, mm[g->maxlevel - 1]->nrows /* g->nnodes_of_level[g->maxlevel - 1] */ ,
  3195. mm[g->maxlevel - 1]->ncols /* g->nnodes_of_level[g->maxlevel] */ );
  3196. }
  3197. return (ch);
  3198. }
  3199. /* */
  3200. static inline int phase2_up(struct gml_graph *g, struct mmatrix **mm)
  3201. {
  3202. int l = 0; /* Level */
  3203. int i = 0;
  3204. int ch = 0;
  3205. if (g) {
  3206. }
  3207. for (l = (g->maxlevel - 1); l > 0; l--) {
  3208. for (i = 1; i <= /* g->nnodes_of_level[l] */ mm[l]->nrows; i++) {
  3209. mm[l]->b[i] = row_barycenter(mm[l], i, /* g->nnodes_of_level[l + 1] */
  3210. mm[l]->ncols);
  3211. }
  3212. if (sorted(mm[l]->b, /* g->nnodes_of_level[l] */ mm[l]->nrows) ==
  3213. 1 /* TRUE */ ) {
  3214. /* reverse rows */
  3215. ch += r_r(mm[l], mm[l - 1], mm[l]->nrows /* g->nnodes_of_level[l] */ ,
  3216. mm[l]->ncols /* g->nnodes_of_level[l + 1] */ );
  3217. } else {
  3218. return (ch);
  3219. }
  3220. }
  3221. for (i = 1; i <= mm[0]->nrows /* g->nnodes_of_level[0] */ ; i++) {
  3222. mm[0]->b[i] = row_barycenter(mm[0], i, mm[0]->ncols /* g->nodes_of_level[1] */ );
  3223. }
  3224. /* if level0 is sorted, r_r */
  3225. if (sorted(mm[0]->b, mm[0]->nrows /* g->nnodes_of_level[0] */ ) ==
  3226. 1 /* TRUE */ ) {
  3227. /* reverse rows */
  3228. ch += r_r(mm[0], NULL, mm[0]->nrows /* g->nnodes_of_level[0] */ ,
  3229. mm[0]->ncols /* g->nnodes_of_level[1] */ );
  3230. }
  3231. return (ch);
  3232. }
  3233. /* here if maxlevel >1 */
  3234. static void bc_n(struct gml_graph *g, int it1value, int it2value)
  3235. {
  3236. struct mmatrix **a = NULL;
  3237. struct mmatrix **a1 = NULL;
  3238. struct mmatrix **a2 = NULL;
  3239. struct mmatrix **as = NULL;
  3240. int i = 0;
  3241. int ks = 0;
  3242. int k = 0;
  3243. int n1 = 0;
  3244. int n2 = 0;
  3245. int cht = 0;
  3246. int ch1 = 0;
  3247. int ch2 = 0;
  3248. int r1 = 0;
  3249. int r2 = 0;
  3250. int r3 = 0;
  3251. int rr1 = 0;
  3252. int rr2 = 0;
  3253. int rr3 = 0;
  3254. int it1 = 20; /* iterations phase1 */
  3255. int it2 = 40; /* iterations pahse2 */
  3256. if (it1value == 0) {
  3257. it1 = 20;
  3258. } else {
  3259. it1 = it1value;
  3260. }
  3261. if (it2value == 0) {
  3262. it2 = 40;
  3263. } else {
  3264. it2 = it2value;
  3265. }
  3266. /* the whole graph structures */
  3267. a = (struct mmatrix **) sfg_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  3268. a1 = (struct mmatrix **) sfg_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  3269. a2 = (struct mmatrix **) sfg_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  3270. as = (struct mmatrix **) sfg_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  3271. /* get matrix struct */
  3272. for (i = 0; i < g->maxlevel; i++) {
  3273. a[i] = (struct mmatrix *) sfg_calloc(1, sizeof(struct mmatrix));
  3274. a1[i] = (struct mmatrix *) sfg_calloc(1, sizeof(struct mmatrix));
  3275. a2[i] = (struct mmatrix *) sfg_calloc(1, sizeof(struct mmatrix));
  3276. as[i] = (struct mmatrix *) sfg_calloc(1, sizeof(struct mmatrix));
  3277. }
  3278. /* get data inside struct */
  3279. for (i = 0; i < g->maxlevel; i++) {
  3280. /* upper level */
  3281. a[i]->level = i;
  3282. a1[i]->level = i;
  3283. a2[i]->level = i;
  3284. as[i]->level = i;
  3285. /* number of rows */
  3286. a[i]->nrows = g->nnodes_of_level[i];
  3287. a1[i]->nrows = g->nnodes_of_level[i];
  3288. a2[i]->nrows = g->nnodes_of_level[i];
  3289. as[i]->nrows = g->nnodes_of_level[i];
  3290. /* number of columns */
  3291. a[i]->ncols = g->nnodes_of_level[i + 1];
  3292. a1[i]->ncols = g->nnodes_of_level[i + 1];
  3293. a2[i]->ncols = g->nnodes_of_level[i + 1];
  3294. as[i]->ncols = g->nnodes_of_level[i + 1];
  3295. /* buffer for barycenter values */
  3296. if (a[i]->nrows > a[i]->ncols) {
  3297. a[i]->bbytes = ((a[i]->nrows + 1) * sizeof(double));
  3298. a1[i]->bbytes = ((a1[i]->nrows + 1) * sizeof(double));
  3299. a2[i]->bbytes = ((a2[i]->nrows + 1) * sizeof(double));
  3300. as[i]->bbytes = ((as[i]->nrows + 1) * sizeof(double));
  3301. } else {
  3302. a[i]->bbytes = ((a[i]->ncols + 1) * sizeof(double));
  3303. a1[i]->bbytes = ((a1[i]->ncols + 1) * sizeof(double));
  3304. a2[i]->bbytes = ((a2[i]->ncols + 1) * sizeof(double));
  3305. as[i]->bbytes = ((as[i]->ncols + 1) * sizeof(double));
  3306. }
  3307. a[i]->b = (double *) sfg_calloc(1, a[i]->bbytes);
  3308. a1[i]->b = (double *) sfg_calloc(1, a1[i]->bbytes);
  3309. a2[i]->b = (double *) sfg_calloc(1, a2[i]->bbytes);
  3310. as[i]->b = (double *) sfg_calloc(1, as[i]->bbytes);
  3311. /* number of bytes used */
  3312. a[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  3313. a1[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  3314. a2[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  3315. as[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  3316. /* row node id's (int's) */
  3317. a[i]->mi0 = (int *) sfg_calloc(1, a[i]->nmi0);
  3318. a1[i]->mi0 = (int *) sfg_calloc(1, a1[i]->nmi0);
  3319. a2[i]->mi0 = (int *) sfg_calloc(1, a2[i]->nmi0);
  3320. as[i]->mi0 = (int *) sfg_calloc(1, as[i]->nmi0);
  3321. /* number of bytes used */
  3322. a[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  3323. a1[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  3324. a2[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  3325. as[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  3326. /* col node id's (int's) */
  3327. a[i]->m0i = (int *) sfg_calloc(1, a[i]->nm0i);
  3328. a1[i]->m0i = (int *) sfg_calloc(1, a1[i]->nm0i);
  3329. a2[i]->m0i = (int *) sfg_calloc(1, a2[i]->nm0i);
  3330. as[i]->m0i = (int *) sfg_calloc(1, as[i]->nm0i);
  3331. /* bits array for the matrix */
  3332. a[i]->nbytes = 1 + ((((a[i]->nrows + 1) * (a[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  3333. a1[i]->nbytes = 1 + ((((a1[i]->nrows + 1) * (a1[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  3334. a2[i]->nbytes = 1 + ((((a2[i]->nrows + 1) * (a2[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  3335. as[i]->nbytes = 1 + ((((as[i]->nrows + 1) * (as[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  3336. a[i]->bits = (unsigned char *) sfg_calloc(1, a[i]->nbytes);
  3337. a1[i]->bits = (unsigned char *) sfg_calloc(1, a1[i]->nbytes);
  3338. a2[i]->bits = (unsigned char *) sfg_calloc(1, a2[i]->nbytes);
  3339. as[i]->bits = (unsigned char *) sfg_calloc(1, as[i]->nbytes);
  3340. }
  3341. /* fill the matrix with data for all levels */
  3342. for (i = 0; i < g->maxlevel; i++) {
  3343. make_matrix(g, i, a[i]);
  3344. }
  3345. copy_a(g, a, as);
  3346. ks = number_of_crossings_a(g, as);
  3347. g->sugi_icrossings = ks; /* sugiyama initial crossings */
  3348. if (ks > 0) {
  3349. /* Phase1 */
  3350. ch1 = 0;
  3351. /* first does alwasy improve */
  3352. ch1 += phase1_down(g, a);
  3353. copy_a(g, a, as);
  3354. ch1 += phase1_up(g, a);
  3355. copy_a(g, a, as);
  3356. /* loop phase1 */
  3357. n1 = 0;
  3358. do {
  3359. copy_a(g, a, a1);
  3360. ch1 += phase1_down(g, a);
  3361. k = number_of_crossings_a(g, a);
  3362. if (k < ks) {
  3363. /* reduced crossings, save the new state */
  3364. ks = k;
  3365. copy_a(g, a, as);
  3366. }
  3367. ch1 += phase1_up(g, a);
  3368. k = number_of_crossings_a(g, a);
  3369. if (k < ks) {
  3370. ks = k;
  3371. copy_a(g, a, as);
  3372. }
  3373. cht += ch1;
  3374. if (ks == 0) {
  3375. break;
  3376. }
  3377. /* check if number of crossings changed */
  3378. r1 = r2;
  3379. r2 = r3;
  3380. r3 = ks;
  3381. if (r1 == r2) {
  3382. if (r2 == r3) {
  3383. break;
  3384. }
  3385. }
  3386. }
  3387. while (++n1 < it1 && (equal_a(g, a, a1) == 0 /* FALSE */ ));
  3388. /* if matrices differ, save state */
  3389. if (equal_a(g, a, as) == 0 /* FALSE */ ) {
  3390. copy_a(g, as, a);
  3391. }
  3392. if (ks > 0) {
  3393. /* Phase2 */
  3394. n2 = 0;
  3395. cht += ch1;
  3396. do {
  3397. ch2 = 0;
  3398. copy_a(g, a, a2);
  3399. ch2 += phase2_down(g, a);
  3400. n1 = 0;
  3401. do {
  3402. ch1 = 0;
  3403. copy_a(g, a, a1);
  3404. ch1 += phase1_down(g, a);
  3405. k = number_of_crossings_a(g, a);
  3406. if (k < ks) {
  3407. ks = k;
  3408. copy_a(g, a, as);
  3409. }
  3410. ch1 += phase1_up(g, a);
  3411. k = number_of_crossings_a(g, a);
  3412. if (k < ks) {
  3413. ks = k;
  3414. copy_a(g, a, as);
  3415. }
  3416. if (ks == 0) {
  3417. break;
  3418. }
  3419. /* check if number of crossings changed */
  3420. rr1 = rr2;
  3421. rr2 = rr3;
  3422. rr3 = ks;
  3423. if (rr1 == rr2) {
  3424. if (rr2 == rr3) {
  3425. break;
  3426. }
  3427. }
  3428. }
  3429. while (++n1 < it1 && equal_a(g, a, a1) == 0 /* FALSE */ );
  3430. ch2 += phase2_up(g, a);
  3431. n1 = 0;
  3432. do {
  3433. copy_a(g, a, a1);
  3434. ch1 += phase1_up(g, a);
  3435. k = number_of_crossings_a(g, a);
  3436. if (k < ks) {
  3437. ks = k;
  3438. copy_a(g, a, as);
  3439. }
  3440. ch1 += phase1_down(g, a);
  3441. k = number_of_crossings_a(g, a);
  3442. if (k < ks) {
  3443. ks = k;
  3444. copy_a(g, a, as);
  3445. }
  3446. cht += ch1;
  3447. if (ks == 0) {
  3448. break;
  3449. }
  3450. /* check if number of crossings changed */
  3451. rr1 = rr2;
  3452. rr2 = rr3;
  3453. rr3 = ks;
  3454. if (rr1 == rr2) {
  3455. if (rr2 == rr3) {
  3456. break;
  3457. }
  3458. }
  3459. }
  3460. while (++n1 < it1 && equal_a(g, a, a1) == 0 /* FALSE */ );
  3461. cht += ch1;
  3462. cht += ch2;
  3463. if (ks == 0) {
  3464. break;
  3465. }
  3466. /* check if number of crossings changed */
  3467. r1 = r2;
  3468. r2 = r3;
  3469. r3 = ks;
  3470. if (r1 == r2) {
  3471. if (r2 == r3) {
  3472. break;
  3473. }
  3474. }
  3475. }
  3476. while (++n2 < it2 && equal_a(g, a, a2) == 0 /* FALSE */ );
  3477. }
  3478. }
  3479. /* sugiyama final crossings */
  3480. g->sugi_fcrossings = ks;
  3481. /* sugiyama changes made */
  3482. g->sugi_changes = cht;
  3483. for (i = 0; i < g->maxlevel; i += 2) {
  3484. /* set new node positions for 2 levels */
  3485. store_new_positions(g, as[i], i);
  3486. }
  3487. if (i == g->maxlevel) {
  3488. store_new_positions(g, as[g->maxlevel - 1], (g->maxlevel - 1));
  3489. }
  3490. for (i = 0; i < g->maxlevel; i++) {
  3491. if (a[i]) {
  3492. a[i]->b = (double *) sfg_free(a[i]->b);
  3493. a[i]->mi0 = (int *) sfg_free(a[i]->mi0);
  3494. a[i]->m0i = (int *) sfg_free(a[i]->m0i);
  3495. free(a[i]->bits);
  3496. }
  3497. if (a1[i]) {
  3498. a1[i]->b = (double *) sfg_free(a1[i]->b);
  3499. a1[i]->mi0 = (int *) sfg_free(a1[i]->mi0);
  3500. a1[i]->m0i = (int *) sfg_free(a1[i]->m0i);
  3501. free(a1[i]->bits);
  3502. }
  3503. if (a2[i]) {
  3504. a2[i]->b = (double *) sfg_free(a2[i]->b);
  3505. a2[i]->mi0 = (int *) sfg_free(a2[i]->mi0);
  3506. a2[i]->m0i = (int *) sfg_free(a2[i]->m0i);
  3507. free(a2[i]->bits);
  3508. }
  3509. if (as[i]) {
  3510. as[i]->b = (double *) sfg_free(as[i]->b);
  3511. as[i]->mi0 = (int *) sfg_free(as[i]->mi0);
  3512. as[i]->m0i = (int *) sfg_free(as[i]->m0i);
  3513. free(as[i]->bits);
  3514. }
  3515. }
  3516. for (i = 0; i < g->maxlevel; i++) {
  3517. a[i] = (struct mmatrix *) sfg_free(a[i]);
  3518. a1[i] = (struct mmatrix *) sfg_free(a1[i]);
  3519. a2[i] = (struct mmatrix *) sfg_free(a2[i]);
  3520. as[i] = (struct mmatrix *) sfg_free(as[i]);
  3521. }
  3522. a = (struct mmatrix **) sfg_free(a);
  3523. a1 = (struct mmatrix **) sfg_free(a1);
  3524. a2 = (struct mmatrix **) sfg_free(a2);
  3525. as = (struct mmatrix **) sfg_free(as);
  3526. return;
  3527. }
  3528. /*
  3529. This algorithm is for routing hierarchies of elements. A "good route" is
  3530. one that has a minimum number of link crossings. An algorithm that was
  3531. truly optimal (for minimizing link crossings) would be combinatorial and
  3532. therefore cost prohibitive; therefore, this algorithm uses a heuristic
  3533. approach that finds a route with close to the minimum number of crossings
  3534. in a reasonable amount of time.
  3535. This algorithm assumes that all the elements form a directed acyclic graph
  3536. (DAG), which means (1) that links flow one way between elements and (2) for
  3537. any given node there is no way to get back to the node if, starting at the
  3538. node, you traverse the links going from node to node. This algorithm also
  3539. assumes that AT MOST only ONE link may exist between a pair of nodes.
  3540. -------------------------------------------------------------------------------
  3541. OVERVIEW OF ALGORITHM
  3542. All elements that do not have any parents are placed in the first row (row 0).
  3543. Elements are assigned to rows, where the row number for each child is equal to
  3544. the [maximum(row number of all its parents) + 1]. Crossovers are determined
  3545. by examining links between elements on adjacent rows, so if a parent is in a
  3546. row that is not adjacent to its child's row, "dummy" nodes are created on the
  3547. rows in between the parent and child, and the parent and child are connected
  3548. via these dummy nodes.
  3549. Once the elements (now called nodes) are assigned to individual rows, the
  3550. rows are sorted (repeatedly) in order to minimize link crossings. The
  3551. sort criteria involves attempting to both center children under parents and
  3552. to center parents over children. The sort orders are then tweaked by swapping
  3553. nodes that have the same sort value.
  3554. After the column orders are finalized, the nodes are spread out so they are
  3555. more or less centered above their children and below their parents. When
  3556. centering children below parents, a row of children is sorted by which node
  3557. has the greatest number of parents. These get first choice of where to be
  3558. placed under the parents (actually, dummy nodes get first preference, then
  3559. all of the others). Centering parents above children is analogous.
  3560. When done with node placement, there may be some empty columns, and the
  3561. numbering scheme may not start at 0. Therefore, the empty columns must
  3562. be eliminated and every node needs its column renumbered, starting at 0.
  3563. Then you are done.
  3564. -------------------------------------------------------------------------------
  3565. REALIZATION MATRIX
  3566. When it comes to both sorting nodes and horizontally spacing the nodes, two
  3567. adjacent rows are always involved. For example, if we are sorting row[i]
  3568. based on the children of row[i]'s nodes, then row[i+1] is also involved
  3569. at this step. These two rows are called the "i-th realization", and form
  3570. the "i-th realization matrix". A realization matrix shows the parent-child
  3571. relationships between adjacent rows, with the parents on the rows and the
  3572. children on the columns. If there is a parent-child relationship, a 1 is
  3573. stored in the matrix at the position, else a 0 is stored.
  3574. An example:
  3575. A B C D
  3576. \ \ / \ / / |
  3577. \ /\ / \ / |
  3578. /\ / \ / \ |
  3579. / /\ /\ \ |
  3580. // \ / \ \|
  3581. E F G H
  3582. E F G H
  3583. A 0 1 1 0 In this example, parent 'A' has children 'F' and 'G',
  3584. B 1 0 0 1 parent 'B' has children 'E' and 'H',
  3585. C 1 1 0 0 parent 'C' has children 'E' and 'F',
  3586. D 0 0 0 1 and parent 'D' has child 'H'.
  3587. -------------------------------------------------------------------------------
  3588. ROW AND COLUMN BARYCENTERS
  3589. Two other important concepts are the "row barycenter" and the "column
  3590. barycenter" for a node. The "row barycenter" is the basically the average
  3591. of the positions of a node's children. The "column barycenter" is the average
  3592. of the positions of a node's parents. These numbers tell us where a node
  3593. would like to be positioned in its row, depending whether we are positioning
  3594. relative to children or parents.
  3595. For example, using the above realization matrix, we can calculate the row
  3596. barycenters for A, B, C, and D, and the column barycenters for E, F, G, and H.
  3597. Since the row barycenter of a node is equal to the sum of the positions of
  3598. the node's children divided by the number of children of the node, the row
  3599. barycenter for A is (1 + 2)/2 = 1.5. This assumes that we start numbering
  3600. rows and columns at 0. Similarly, the column barycenter of a node is equal
  3601. to the sum of the positions of the node's parents divided by the number of
  3602. parents of the node. So, the column barycenter of F is (0 + 2)/2 = 1.0.
  3603. The complete example is as follows:
  3604. Row
  3605. | E F G H | Barys
  3606. ------+--------------------+-----
  3607. A | 0 1 1 0 | 1.5
  3608. B | 1 0 0 1 | 1.5
  3609. C | 1 1 0 0 | 0.5
  3610. D | 0 0 0 1 | 3.0
  3611. ------+--------------------+-----
  3612. Col | 1.5 1.0 0.0 2.0 |
  3613. Barys | |
  3614. If we were to sort the child nodes here by their column barycenters, the new
  3615. order would be G, F, E, H. If we were to sort the parent nodes here by their
  3616. row barycenters, then the order would be C, A, B, D (if two or more nodes have
  3617. the same value, be sure to keep the same precedence that already exists
  3618. between them, e.g., make sure that order after sorting is not C, B, A, D).
  3619. If a node has no parents then it can't have a column barycenter. This case
  3620. should never happen, as all nodes that have no parents should be in the first
  3621. level of the hierarchy, and these nodes would only be represented in
  3622. realization matrix 0, and they would only have row barycenters.
  3623. If a node has no children then it can't have a row barycenter. In this case,
  3624. while sorting based on row barycenters, sort AROUND these nodes, i.e., do
  3625. not change their positions at all. For example, if we had the following:
  3626. Row
  3627. | W X Y Z | Barys
  3628. ------+--------------------+-----
  3629. Q | 0 1 1 1 | 2.0
  3630. R | 0 0 0 0 | ???
  3631. S | 1 0 0 0 | 0.0
  3632. T | 0 1 0 1 | 2.0
  3633. ------+--------------------+-----
  3634. Col | 2.0 1.5 0.0 1.5 |
  3635. Barys | |
  3636. and we were to sort by row barycenters, the resulting order should be S, R,
  3637. Q, T. Notice how R stayed in its position, and even though Q and T had the
  3638. same barycentric value, Q stayed before T.
  3639. The whole reason for sorting rows and columns by their barycenters is to
  3640. decrease the number of crossovers.
  3641. -------------------------------------------------------------------------------
  3642. CROSSOVERS
  3643. The realization matrix is also used to count the number of crossovers between
  3644. two adjacent rows of nodes. For each row, starting with the second row, if
  3645. a row element has a 1, then sum up all of the matrix elements that are above
  3646. AND to the right of this element. Looking again at the first example:
  3647. A B C D
  3648. \ \ / \ / / |
  3649. \ /\ / \ / |
  3650. /\ / \ / \ |
  3651. / /\ /\ \ |
  3652. // \ / \ \|
  3653. E F G H
  3654. Row
  3655. | E F G H | Barys
  3656. ------+--------------------+-----
  3657. A | 0 1 1 0 | 1.5
  3658. B | 1 0 0 1 | 1.5
  3659. C | 1 1 0 0 | 0.5
  3660. D | 0 0 0 1 | 3.0
  3661. ------+--------------------+-----
  3662. Col | 1.5 1.0 0.0 2.0 |
  3663. Barys | |
  3664. Starting with the second row (parent B's row), position B-E has a 1. Looking
  3665. at positions above and to the right, we see positions A-F and A-G both have
  3666. a 1, so the number of crossovers is currently = 2. Position B-H has a 1, but
  3667. there are no elements above and to the right, so crossovers is still = 2.
  3668. For parent row of C, position C-E crosses over with B-H, A-F, and A-G, so
  3669. crossovers = 5. C-F crosses over with B-H and A-G, so crossovers = 7. For
  3670. parent row D, position D-H doesn't cross over with any other link. So for
  3671. this realization matrix representing these two rows, the number of crossovers
  3672. is 7.
  3673. The total number of crossovers for the whole graph would be the sum of the
  3674. crossovers from each matrix realization.
  3675. -------------------------------------------------------------------------------
  3676. NODE CENTERING
  3677. After the nodes for each row have their final sort order, the nodes need to
  3678. be assigned to grid positions. Their initial grid position will be their
  3679. column position, by which we mean their array position in the row. From now
  3680. on, when we take a row or column barycenter, we will be using grid positions
  3681. instead of column positions.
  3682. Note: The following examples will be based on centering children with respect
  3683. to their parents' positions. Centering parents based on their children's
  3684. positions is analogous.
  3685. When positioning the nodes on a row based on their parents' positions, the
  3686. nodes must be initially sorted to see which nodes get first choice. The dummy
  3687. nodes go first, and the rest of nodes are sorted in descending order based on
  3688. the number of parents the node has. If a dummy node has a parent that has
  3689. multiple dummy nodes, all of these dummy nodes are again sorted by how close
  3690. to the center of the parent's children they are. This is a confusing
  3691. statement, best illustrated by example:
  3692. P1 P2
  3693. \ |
  3694. \ __________^__________
  3695. \| | | | |
  3696. C1 D1 D2 C2 D3
  3697. Here, parent P1 has one child, C1. Parent P2 has five children, and three of
  3698. the child nodes are dummy nodes: D1, D2, and D3. C1 is child 0 of P2, D1 is
  3699. child 1 of P2, D2 is child 2 of P2, C2 is child 3 of P2, and D3 is child 4 of
  3700. P2. The child midpoint underneath the parent is equal to
  3701. (the number of children - 1) / 2, so (5 - 1) / 2 = 2. Since the dummy nodes
  3702. go first, the initial order is D1, D2, D3, C1 (because it has 2 parents), and
  3703. finally C2. All of the dummy nodes have the same parent, so we will sort them
  3704. based on how far away they are from the parent's child midpoint. D1 is child
  3705. 1 of P2, so it is 1 away. D2 is child 2 of P2, so it is 0 away. D3 is child
  3706. 4 of P2, so it is 2 away. Therefore, the final order for choosing positions
  3707. is D2, D1, D3, C1, C2.
  3708. In a situation similar to the dummy nodes, if a non-dummy node has a only one
  3709. parent, and that parent has other children with just one parent, then these
  3710. one parent child nodes that have the same parent need additional sorting in
  3711. the exact same manner that we just did the dummy nodes.
  3712. The whole purpose behind this is so that the left most node doesn't get first
  3713. choice. If it did, we would get graphs that look like:
  3714. A A
  3715. | |
  3716. |_________ instead of _____^_____
  3717. | | | | | |
  3718. B C D B C D
  3719. Anyway, once we have a sort order for the nodes of a row, we place the nodes
  3720. in their preferred positions. Using the previous example, assume that P1
  3721. is in grid position 2 and P2 is in grid position 5. D2 gets first choice,
  3722. and its column barycenter (based now on parent grid positions, not column
  3723. positions) is 5, so we place D2 in position 5. D1 is next, its barycenter
  3724. is also 5. We can't give it 5 since that position is occupied, so we give
  3725. it the closest possible position we can, which in this case is 4. D3 is next,
  3726. and its barycenter is also 5. The closest position that we can give it is
  3727. position 7, since we must allow room for C2. C1 is next, and its barycenter
  3728. is (2 + 5)/2 = 3.5, which we round to 3. Position 3 is open, so we go ahead
  3729. and give it position 3. C2 is last, and its barycenter is 5. However, the
  3730. first position available to it based on its left neighbor is position 6, so
  3731. we assign it position 6.
  3732. -------------------------------------------------------------------------------
  3733. GOING 'UP' OR 'DOWN' THE GRAPH
  3734. "Going down the graph" means taking each realization matrix situation,
  3735. starting with Realization Matrix 0, and performing some action on it, then
  3736. going to the next realization matrix, and continuing until all of the
  3737. realization matrices have been visited.
  3738. "Going up the graph" is analogous, except you start at the bottom with the
  3739. last realization matrix and work up to Realization Matrix 0.
  3740. */
  3741. static void barycenter(struct gml_graph *g, int it1v, int it2v)
  3742. {
  3743. /* number of crossing edges at level */
  3744. if (g->numce == NULL) {
  3745. g->numce = (int *) sfg_calloc(1, (g->maxlevel + 1) * sizeof(int));
  3746. }
  3747. if (g->maxlevel == 0) {
  3748. /* if graph has only 1 or more nodes */
  3749. return;
  3750. }
  3751. if (g->nnodes < 2) {
  3752. return;
  3753. }
  3754. if (g->nedges < 2) {
  3755. return;
  3756. }
  3757. bc_n(g, it1v, it2v);
  3758. return;
  3759. }
  3760. /* min. distance between 2 nodes */
  3761. static int mindist = 1;
  3762. /* current startnode nr field */
  3763. static int csn = 0;
  3764. /* node list of part of graph */
  3765. static struct gml_nlist *cnodelist = NULL;
  3766. static struct gml_nlist *cnodelisttail = NULL;
  3767. /* number of nodes at level */
  3768. static int *cnnodes_of_level = NULL;
  3769. /* max. x,y in part of graph */
  3770. static int cmaxx = 0;
  3771. static int cmaxy = 0;
  3772. /* widest x level */
  3773. static int cwidestnnodes = 0;
  3774. /* x width at position */
  3775. static int *cwpos = NULL;
  3776. /* lists per pos. */
  3777. static struct gml_nlist **cposnodes = NULL;
  3778. /* hor pos */
  3779. static int *chpos = NULL;
  3780. /* hor pos */
  3781. static struct gml_nlist **clevelnodes = NULL;
  3782. /* (x,y) spacing */
  3783. static int xspacing = 0;
  3784. static int yspacing = 0;
  3785. /* */
  3786. struct node_data {
  3787. struct gml_node *node;
  3788. int priority;
  3789. int done;
  3790. };
  3791. /* nodes in one level */
  3792. static struct node_data *nl = NULL;
  3793. static int is_dummy(struct gml_node *node)
  3794. {
  3795. if (node->dummy) {
  3796. return (1);
  3797. } else {
  3798. return (0);
  3799. }
  3800. }
  3801. /* how many connection edges from previous level */
  3802. static int upper_connectivity(struct gml_node *node)
  3803. {
  3804. struct gml_elist *el = NULL;
  3805. int result = 0;
  3806. result = 0;
  3807. if (node == NULL) {
  3808. /* shouldnothappen */
  3809. return (0);
  3810. }
  3811. /* incoming edges for_targetlist(node,edge) */
  3812. el = node->incoming_e;
  3813. while (el) {
  3814. /* skip hor. edges */
  3815. if (el->edge->hedge == 0) {
  3816. /* only in this part of graph */
  3817. if (el->edge->from_node->startnode == csn) {
  3818. result++;
  3819. }
  3820. }
  3821. el = el->next;
  3822. }
  3823. return (result);
  3824. }
  3825. /* how many connection edges to next level */
  3826. static int lower_connectivity(struct gml_node *node)
  3827. {
  3828. struct gml_elist *el = NULL;
  3829. int result = 0;
  3830. result = 0;
  3831. if (node == NULL) {
  3832. /* shouldnothappen */
  3833. return (0);
  3834. }
  3835. /* outgoing edges for_sourcelist(node,edge) */
  3836. el = node->outgoing_e;
  3837. while (el) {
  3838. /* skip hor. edges */
  3839. if (el->edge->hedge == 0) {
  3840. /* only in this part of graph */
  3841. if (el->edge->to_node->startnode == csn) {
  3842. result++;
  3843. }
  3844. }
  3845. el = el->next;
  3846. }
  3847. return (result);
  3848. }
  3849. /* simple floor() function */
  3850. static double do_floor(double num)
  3851. {
  3852. double ret = 0.0;
  3853. if (num < 0) {
  3854. ret = (int)(num - 1);
  3855. } else {
  3856. ret = (int)num;
  3857. }
  3858. return (ret);
  3859. }
  3860. /* avg x pos of incoming edges */
  3861. static int upper_barycenter(struct gml_node *node)
  3862. {
  3863. struct gml_elist *el = NULL;
  3864. int result = 0;
  3865. double r = 0.0;
  3866. if (node == NULL) {
  3867. /* shouldnothappen */
  3868. return (0);
  3869. }
  3870. /* incoming edges x sum for_targetlist(node,edge) */
  3871. el = node->incoming_e;
  3872. while (el) {
  3873. /* skip hor. edges */
  3874. if (el->edge->hedge == 0) {
  3875. /* only in this part of graph */
  3876. if (el->edge->from_node->startnode == csn) {
  3877. result += (el->edge->from_node->absx);
  3878. }
  3879. }
  3880. el = el->next;
  3881. }
  3882. if (result == 0) {
  3883. r = (0.0);
  3884. } else {
  3885. if (upper_connectivity(node) == 0) {
  3886. r = 0.0;
  3887. } else {
  3888. r = (result / upper_connectivity(node));
  3889. }
  3890. }
  3891. r = do_floor(r + 0.5);
  3892. return ((int)r);
  3893. }
  3894. /* avg x pos of outgoing edges */
  3895. static int lower_barycenter(struct gml_node *node)
  3896. {
  3897. struct gml_elist *el = NULL;
  3898. int result = 0;
  3899. double r = 0.0;
  3900. if (node == NULL) {
  3901. /* shouldnothappen */
  3902. return (0);
  3903. }
  3904. /* get avg. x pos of outgoing edges for_sourcelist(node,edge) */
  3905. el = node->outgoing_e;
  3906. while (el) {
  3907. /* skip hor. edges */
  3908. if (el->edge->hedge == 0) {
  3909. /* only in this part of graph */
  3910. if (el->edge->to_node->startnode == csn) {
  3911. result += (el->edge->to_node->absx);
  3912. }
  3913. }
  3914. el = el->next;
  3915. }
  3916. if (result == 0) {
  3917. r = (0.0);
  3918. } else {
  3919. if (lower_connectivity(node) == 0) {
  3920. r = 0.0;
  3921. } else {
  3922. r = (result / lower_connectivity(node));
  3923. }
  3924. }
  3925. r = do_floor(r + 0.5);
  3926. return ((int)r);
  3927. }
  3928. static void sort(int n)
  3929. {
  3930. int i = 0;
  3931. int j = 0;
  3932. struct node_data h;
  3933. for (j = n - 1; j > 0; j--) {
  3934. for (i = 0; i < j; i++) {
  3935. /* issue here */
  3936. if (nl[i].node && nl[i + 1].node) {
  3937. if (nl[i].node->relx > nl[i + 1].node->relx) {
  3938. /* swap */
  3939. h = nl[i];
  3940. nl[i] = nl[i + 1];
  3941. nl[i + 1] = h;
  3942. }
  3943. }
  3944. }
  3945. }
  3946. return;
  3947. }
  3948. /* */
  3949. static void make_node_list_up(int l)
  3950. {
  3951. struct gml_nlist *gnl = NULL;
  3952. struct gml_node *n = NULL;
  3953. int i = 0;
  3954. /* for_all_nodes(g,n) */
  3955. gnl = cnodelist;
  3956. i = 0;
  3957. while (gnl) {
  3958. n = gnl->node;
  3959. if (n->absy == l) {
  3960. nl[i].node = n;
  3961. nl[i].done = 0; /* FALSE */
  3962. if (is_dummy(n) == 1) { /* */
  3963. /* higer value then the highest node in this level */
  3964. /*old nl[i].priority = (cnnodes_of_level[l + 1] + 1000 */
  3965. nl[i].priority = (100000 - n->relx);
  3966. } else {
  3967. nl[i].priority = lower_connectivity(n);
  3968. }
  3969. i++;
  3970. }
  3971. gnl = gnl->next;
  3972. }
  3973. sort(cnnodes_of_level[l]);
  3974. return;
  3975. }
  3976. /* */
  3977. static void make_node_list_down(int l)
  3978. {
  3979. struct gml_nlist *gnl = NULL;
  3980. struct gml_node *n = NULL;
  3981. int i = 0;
  3982. /* for_all_nodes(g,n) */
  3983. gnl = cnodelist;
  3984. while (gnl) {
  3985. n = gnl->node;
  3986. if (n->absy == l) {
  3987. nl[i].node = n;
  3988. nl[i].done = 0; /* FALSE */
  3989. if (is_dummy(n) == 1) { /* */
  3990. /* give dummy node uniq high number */
  3991. /*old nl[i].priority = (cnnodes_of_level[l - 1] + 1000 */
  3992. nl[i].priority = (100000 - n->relx);
  3993. } else {
  3994. nl[i].priority = upper_connectivity(n);
  3995. }
  3996. i++;
  3997. }
  3998. gnl = gnl->next;
  3999. }
  4000. sort(cnnodes_of_level[l]);
  4001. return;
  4002. }
  4003. /* get number of node with highest prio which is not done yet */
  4004. static int find_next(int n)
  4005. {
  4006. int index = 0;
  4007. int i = 0;
  4008. int highest_priority = 0;
  4009. for (i = 0; i < n; i++) {
  4010. if ((nl[i].priority >= highest_priority)
  4011. && (nl[i].done == 0 /* FALSE */ )) {
  4012. index = i;
  4013. highest_priority = nl[i].priority;
  4014. }
  4015. }
  4016. return (index);
  4017. }
  4018. static void do_down(int l)
  4019. {
  4020. int i = 0;
  4021. int index = 0;
  4022. int j = 0;
  4023. int optimal_position = 0;
  4024. int distance = 0;
  4025. int possible_distance = 0;
  4026. for (i = 0; i < cnnodes_of_level[l]; i++) {
  4027. index = find_next(cnnodes_of_level[l]);
  4028. if (nl[index].node) {
  4029. optimal_position = upper_barycenter(nl[index].node);
  4030. if (optimal_position == 0) {
  4031. optimal_position = nl[index].node->absx;
  4032. }
  4033. if (optimal_position < nl[index].node->absx) {
  4034. distance = nl[index].node->absx - optimal_position;
  4035. possible_distance = 0;
  4036. j = index;
  4037. do {
  4038. if (j > 0) {
  4039. possible_distance += nl[j].node->absx - nl[j - 1].node->absx - mindist;
  4040. } else {
  4041. /* j==0, no nodes at left */
  4042. possible_distance += nl[j].node->absx - mindist;
  4043. }
  4044. j--;
  4045. }
  4046. while ((j >= 0) && !(nl[j].done));
  4047. if (possible_distance < distance) {
  4048. distance = possible_distance;
  4049. }
  4050. j = index;
  4051. while (distance > 0) {
  4052. int d = 0;
  4053. int k = 0;
  4054. if (j == 0) {
  4055. d = distance;
  4056. } else {
  4057. if (nl[j].node->absx - nl[j - 1].node->absx - mindist < distance) {
  4058. d = nl[j].node->absx - nl[j - 1].node->absx - mindist;
  4059. } else {
  4060. d = distance;
  4061. }
  4062. }
  4063. for (k = j; k <= index; k++) {
  4064. nl[k].node->absx -= d;
  4065. }
  4066. j--;
  4067. distance -= d;
  4068. }
  4069. } else {
  4070. distance = optimal_position - nl[index].node->absx;
  4071. possible_distance = 0;
  4072. j = index;
  4073. do {
  4074. if (j < cnnodes_of_level[l] - 1) {
  4075. possible_distance += nl[j + 1].node->absx - nl[j].node->absx - mindist;
  4076. } else {
  4077. /* j == cnnodes_of_level[l]-1, no nodes rechts */
  4078. possible_distance += distance;
  4079. }
  4080. j++;
  4081. }
  4082. while ((j < cnnodes_of_level[l]) && !(nl[j].done));
  4083. if (possible_distance < distance) {
  4084. distance = possible_distance;
  4085. }
  4086. j = index;
  4087. while (distance > 0) {
  4088. int d = 0;
  4089. int k = 0;
  4090. if (j == cnnodes_of_level[l] - 1) {
  4091. d = distance;
  4092. } else {
  4093. if (nl[j + 1].node->absx - nl[j].node->absx - mindist < distance) {
  4094. d = nl[j + 1].node->absx - nl[j].node->absx - mindist;
  4095. } else {
  4096. d = distance;
  4097. }
  4098. }
  4099. for (k = index; k <= j; k++) {
  4100. nl[k].node->absx += d;
  4101. }
  4102. j++;
  4103. distance -= d;
  4104. }
  4105. }
  4106. nl[index].done = 1; /* TRUE */
  4107. }
  4108. }
  4109. return;
  4110. }
  4111. static void do_up(int l)
  4112. {
  4113. int i = 0;
  4114. int index = 0;
  4115. int j = 0;
  4116. int optimal_position = 0;
  4117. int distance = 0;
  4118. int possible_distance = 0;
  4119. for (i = 0; i < cnnodes_of_level[l]; i++) {
  4120. index = find_next(cnnodes_of_level[l]);
  4121. if (nl[index].node) {
  4122. optimal_position = lower_barycenter(nl[index].node);
  4123. if (optimal_position == 0) {
  4124. optimal_position = nl[index].node->absx;
  4125. }
  4126. if (optimal_position < nl[index].node->absx) {
  4127. distance = nl[index].node->absx - optimal_position;
  4128. possible_distance = 0;
  4129. j = index;
  4130. do {
  4131. if (j > 0) {
  4132. possible_distance += nl[j].node->absx - nl[j - 1].node->absx - mindist;
  4133. } else {
  4134. /* j == 0, no nodes links */
  4135. possible_distance += nl[0].node->absx - mindist;
  4136. }
  4137. j--;
  4138. }
  4139. while ((j >= 0) && !(nl[j].done));
  4140. if (possible_distance < distance) {
  4141. distance = possible_distance;
  4142. }
  4143. j = index;
  4144. while (distance > 0) {
  4145. int d = 0;
  4146. int k = 0;
  4147. if (j == 0) {
  4148. d = distance;
  4149. } else {
  4150. if (nl[j].node->absx - nl[j - 1].node->absx - mindist < distance) {
  4151. d = nl[j].node->absx - nl[j - 1].node->absx - mindist;
  4152. } else {
  4153. d = distance;
  4154. }
  4155. }
  4156. for (k = j; k <= index; k++) {
  4157. nl[k].node->absx -= d;
  4158. }
  4159. j--;
  4160. distance -= d;
  4161. }
  4162. } else {
  4163. /* optimal_position >= nl[index].node->absx */
  4164. distance = optimal_position - nl[index].node->absx;
  4165. possible_distance = 0;
  4166. j = index;
  4167. do {
  4168. if (j < cnnodes_of_level[l] - 1) {
  4169. possible_distance += nl[j + 1].node->absx - nl[j].node->absx - mindist;
  4170. } else {
  4171. /* j == cnnodes_of_level[l]-1, no nodes rechts */
  4172. possible_distance += distance;
  4173. }
  4174. j++;
  4175. }
  4176. while ((j < cnnodes_of_level[l]) && !(nl[j].done));
  4177. if (possible_distance < distance) {
  4178. distance = possible_distance;
  4179. }
  4180. j = index;
  4181. while (distance > 0) {
  4182. int d = 0;
  4183. int k = 0;
  4184. if (j == cnnodes_of_level[l] - 1) {
  4185. d = distance;
  4186. } else {
  4187. if (nl[j + 1].node->absx - nl[j].node->absx - mindist < distance) {
  4188. d = nl[j + 1].node->absx - nl[j].node->absx - mindist;
  4189. } else {
  4190. d = distance;
  4191. }
  4192. }
  4193. for (k = index; k <= j; k++) {
  4194. nl[k].node->absx += d;
  4195. }
  4196. j++;
  4197. distance -= d;
  4198. }
  4199. }
  4200. nl[index].done = 1; /* TRUE */
  4201. }
  4202. }
  4203. return;
  4204. }
  4205. /* determine relative node pos. from the barycenter rel. node pos. */
  4206. static void improve_positions2local(struct gml_graph *g)
  4207. {
  4208. int i = 0;
  4209. int count = 0;
  4210. int ii = 0;
  4211. int sl = 0;
  4212. /* start level is 0 */
  4213. sl = 0;
  4214. /* min. node dist */
  4215. mindist = 1;
  4216. /* number of up/down sweeps */
  4217. count = 1;
  4218. for (ii = 0; ii < count; ii++) {
  4219. /* DOWN */
  4220. for (i = sl; i < g->maxlevel; i++) {
  4221. if (cnnodes_of_level[i]) {
  4222. nl = (struct node_data *) sfg_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  4223. make_node_list_down(i);
  4224. do_down(i);
  4225. nl = (struct node_data *) sfg_free(nl);
  4226. }
  4227. }
  4228. /* UP */
  4229. for (i = (g->maxlevel - 1); i >= sl; i--) {
  4230. if (cnnodes_of_level[i]) {
  4231. nl = (struct node_data *) sfg_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  4232. make_node_list_up(i);
  4233. do_up(i);
  4234. nl = (struct node_data *) sfg_free(nl);
  4235. }
  4236. }
  4237. }
  4238. /* top+bottom update */
  4239. if ((sl + 2) < g->maxlevel) {
  4240. for (i = sl + 2; i >= sl; i--) {
  4241. if (cnnodes_of_level[i]) {
  4242. nl = (struct node_data *) sfg_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  4243. make_node_list_up(i);
  4244. do_up(i);
  4245. nl = (struct node_data *) sfg_free(nl);
  4246. }
  4247. }
  4248. }
  4249. for (i = (g->maxlevel - 2); i <= g->maxlevel; i++) {
  4250. if (i >= 0) {
  4251. if (cnnodes_of_level[i]) {
  4252. nl = (struct node_data *) sfg_calloc(1, cnnodes_of_level[i] * sizeof(struct node_data));
  4253. make_node_list_down(i);
  4254. do_down(i);
  4255. nl = (struct node_data *) sfg_free(nl);
  4256. }
  4257. }
  4258. }
  4259. return;
  4260. }
  4261. /* create nodes-at-level-count */
  4262. static void make_cnnodes_at_level(struct gml_graph *g)
  4263. {
  4264. struct gml_nlist *gnl = NULL;
  4265. cnnodes_of_level = (int *) sfg_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  4266. gnl = cnodelist;
  4267. while (gnl) {
  4268. cnnodes_of_level[gnl->node->rely] = cnnodes_of_level[gnl->node->rely] + 1;
  4269. gnl = gnl->next;
  4270. }
  4271. return;
  4272. }
  4273. /* clear nodes-at-level-count */
  4274. static void clear_cnnodes_at_level(void)
  4275. {
  4276. /* number of nodes at level */
  4277. if (cnnodes_of_level) {
  4278. cnnodes_of_level = (int *) sfg_free(cnnodes_of_level);
  4279. }
  4280. /* number of nodes at level */
  4281. cnnodes_of_level = NULL;
  4282. return;
  4283. }
  4284. /* copy part of graph */
  4285. static void make_cnodelist(struct gml_graph *g)
  4286. {
  4287. struct gml_nlist *gnl = NULL;
  4288. struct gml_nlist *newnl = NULL;
  4289. gnl = g->nodelist;
  4290. while (gnl) {
  4291. /* check if node belongs to part of graph */
  4292. if (gnl->node->startnode == csn) {
  4293. /* copy node in new list */
  4294. newnl = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  4295. newnl->node = gnl->node;
  4296. if (cnodelist == NULL) {
  4297. cnodelist = newnl;
  4298. cnodelisttail = newnl;
  4299. } else {
  4300. cnodelisttail->next = newnl;
  4301. cnodelisttail = newnl;
  4302. }
  4303. }
  4304. gnl = gnl->next;
  4305. }
  4306. return;
  4307. }
  4308. /* done with this part of graph */
  4309. static void clear_cnodelist(void)
  4310. {
  4311. struct gml_nlist *gnl = NULL;
  4312. struct gml_nlist *gnlnext = NULL;
  4313. gnl = cnodelist;
  4314. while (gnl) {
  4315. gnlnext = gnl->next;
  4316. gnl = (struct gml_nlist *) sfg_free(gnl);
  4317. gnl = gnlnext;
  4318. }
  4319. /* node list of part of graph */
  4320. cnodelist = NULL;
  4321. cnodelisttail = NULL;
  4322. return;
  4323. }
  4324. /* move image of this part of graph */
  4325. static void move0(void)
  4326. {
  4327. struct gml_nlist *gnl = NULL;
  4328. int mx = 0;
  4329. /* find min. x pos in-use */
  4330. mx = 1000 * 1000; /* just some high value */
  4331. gnl = cnodelist;
  4332. while (gnl) {
  4333. if (gnl->node->absx < mx) {
  4334. mx = gnl->node->absx;
  4335. }
  4336. gnl = gnl->next;
  4337. }
  4338. /* move whole drawing to the left */
  4339. gnl = cnodelist;
  4340. while (gnl) {
  4341. gnl->node->absx = (gnl->node->absx - mx);
  4342. gnl = gnl->next;
  4343. }
  4344. return;
  4345. }
  4346. /* */
  4347. static void make_cposnodes(void)
  4348. {
  4349. struct gml_nlist *lnl = NULL;
  4350. struct gml_nlist *newl = NULL;
  4351. int i = 0;
  4352. int lmaxw = 0;
  4353. int maxrx = 0;
  4354. /* widest x level */
  4355. cwidestnnodes = 0;
  4356. /* x width at position */
  4357. cwpos = NULL;
  4358. /* lists per pos. */
  4359. cposnodes = NULL;
  4360. /* extra check max rel. x pos. */
  4361. lnl = cnodelist;
  4362. while (lnl) {
  4363. if (lnl->node->absx > maxrx) {
  4364. maxrx = lnl->node->absx;
  4365. }
  4366. lnl = lnl->next;
  4367. }
  4368. /* pos2.c has moved node in x dir. */
  4369. cwidestnnodes = maxrx;
  4370. /* x width at position */
  4371. cwpos = (int *) sfg_calloc(1, (cwidestnnodes + 1) * sizeof(int));
  4372. if (cwpos == NULL) {
  4373. return;
  4374. }
  4375. /* lists with nodes up to down at position */
  4376. cposnodes = (struct gml_nlist **) sfg_calloc(1, (cwidestnnodes + 1) * sizeof(struct gml_nlist *));
  4377. if (cposnodes == NULL) {
  4378. return;
  4379. }
  4380. /* create for every postion the list of nodes at that position */
  4381. lnl = cnodelist;
  4382. while (lnl) {
  4383. i = lnl->node->absx;
  4384. newl = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  4385. if (newl == NULL) {
  4386. return;
  4387. }
  4388. newl->node = lnl->node;
  4389. if (cposnodes[i] == NULL) {
  4390. cposnodes[i] = newl;
  4391. newl->next = NULL;
  4392. } else {
  4393. newl->next = cposnodes[i];
  4394. cposnodes[i] = newl;
  4395. }
  4396. lnl = lnl->next;
  4397. }
  4398. /* determine the max width of a element at vertical pos. */
  4399. for (i = 0; i < (cwidestnnodes + 1); i++) {
  4400. lmaxw = 0;
  4401. /* lists per pos. */
  4402. lnl = cposnodes[i];
  4403. while (lnl) {
  4404. if (lnl->node->bbx > lmaxw) {
  4405. lmaxw = lnl->node->bbx;
  4406. }
  4407. lnl = lnl->next;
  4408. }
  4409. cwpos[i] = lmaxw;
  4410. }
  4411. return;
  4412. }
  4413. /* */
  4414. static void clear_cposnodes(void)
  4415. {
  4416. int i = 0;
  4417. struct gml_nlist *lnl = NULL;
  4418. struct gml_nlist *nlnext = NULL;
  4419. /* width of positions */
  4420. if (cwpos) {
  4421. cwpos = (int *) sfg_free(cwpos);
  4422. }
  4423. for (i = 0; i < (cwidestnnodes + 1); i++) {
  4424. /* lists per pos. */
  4425. lnl = cposnodes[i];
  4426. while (lnl) {
  4427. nlnext = lnl->next;
  4428. lnl = (struct gml_nlist *) sfg_free(lnl);
  4429. lnl = nlnext;
  4430. }
  4431. cposnodes[i] = NULL;
  4432. }
  4433. cposnodes = (struct gml_nlist **) sfg_free(cposnodes);
  4434. return;
  4435. }
  4436. /* y positioning */
  4437. static void make_clevelnodes(struct gml_graph *g)
  4438. {
  4439. struct gml_nlist *lnl = NULL;
  4440. struct gml_nlist *newl = NULL;
  4441. int i = 0;
  4442. int lmaxh = 0;
  4443. chpos = (int *) sfg_calloc(1, (g->maxlevel + 1) * sizeof(int));
  4444. if (chpos == NULL) {
  4445. return;
  4446. }
  4447. clevelnodes = (struct gml_nlist **) sfg_calloc(1, (g->maxlevel + 1) * sizeof(struct gml_nlist *));
  4448. if (clevelnodes == NULL) {
  4449. return;
  4450. }
  4451. lnl = cnodelist;
  4452. while (lnl) {
  4453. i = lnl->node->absy;
  4454. newl = (struct gml_nlist *) sfg_calloc(1, sizeof(struct gml_nlist));
  4455. if (newl == NULL) {
  4456. return;
  4457. }
  4458. newl->node = lnl->node;
  4459. if (clevelnodes[i] == NULL) {
  4460. clevelnodes[i] = newl;
  4461. newl->next = NULL;
  4462. } else {
  4463. newl->next = clevelnodes[i];
  4464. clevelnodes[i] = newl;
  4465. }
  4466. lnl = lnl->next;
  4467. }
  4468. /* determine the max width of a element at vertical pos. */
  4469. for (i = 0; i < (g->maxlevel + 1); i++) {
  4470. lmaxh = 0;
  4471. /* lists per pos. */
  4472. lnl = clevelnodes[i];
  4473. while (lnl) {
  4474. if (lnl->node->bby > lmaxh) {
  4475. lmaxh = lnl->node->bby;
  4476. }
  4477. lnl = lnl->next;
  4478. }
  4479. chpos[i] = lmaxh;
  4480. }
  4481. return;
  4482. }
  4483. static void clear_clevelnodes(struct gml_graph *g)
  4484. {
  4485. int i = 0;
  4486. struct gml_nlist *lnl = NULL;
  4487. struct gml_nlist *nlnext = NULL;
  4488. /* width of positions */
  4489. if (chpos) {
  4490. chpos = (int *) sfg_free(chpos);
  4491. }
  4492. for (i = 0; i < (g->maxlevel + 1); i++) {
  4493. /* lists per pos. */
  4494. lnl = clevelnodes[i];
  4495. while (lnl) {
  4496. nlnext = lnl->next;
  4497. lnl = (struct gml_nlist *) sfg_free(lnl);
  4498. lnl = nlnext;
  4499. }
  4500. clevelnodes[i] = NULL;
  4501. }
  4502. clevelnodes = (struct gml_nlist **) sfg_free(clevelnodes);
  4503. return;
  4504. }
  4505. /* determine final (x,y) pos */
  4506. static void cfinalxy(struct gml_graph *g)
  4507. {
  4508. struct gml_nlist *lnl = NULL;
  4509. int hw = 0;
  4510. int xoff = 0;
  4511. int yoff = 0;
  4512. int i = 0;
  4513. int ecount = 0;
  4514. /* x positioning */
  4515. make_cposnodes();
  4516. cmaxx = 0;
  4517. xoff = 0;
  4518. /* scan hor. to adjust the x positions. */
  4519. for (i = 0; i < (cwidestnnodes + 1); i++) {
  4520. /* x spacing between the hor. levels */
  4521. if (0) {
  4522. xoff = xoff + xspacing;
  4523. }
  4524. /* determine half-way of the xpos. */
  4525. if (cwpos[i] == 0) {
  4526. /* if only dummy nodes */
  4527. hw = xspacing / 2;
  4528. } else {
  4529. hw = (cwpos[i] / 2);
  4530. }
  4531. /* update with current x */
  4532. hw = hw + xoff;
  4533. lnl = cposnodes[i];
  4534. /* scan the nodes at this x pos. */
  4535. while (lnl) {
  4536. /* center the node around the half-way */
  4537. lnl->node->finx = (hw - (lnl->node->bbx / 2));
  4538. if ((lnl->node->finx + lnl->node->bbx) > cmaxx) {
  4539. cmaxx = (lnl->node->finx + lnl->node->bbx);
  4540. }
  4541. lnl = lnl->next;
  4542. }
  4543. /* set x0,x1 pos in the nodes */
  4544. lnl = cposnodes[i];
  4545. /* scan the nodes at this x pos. */
  4546. while (lnl) {
  4547. /* */
  4548. lnl->node->lx0 = xoff;
  4549. lnl->node->lx1 = xoff + cwpos[i];
  4550. lnl = lnl->next;
  4551. }
  4552. /* x spacing between the hor. levels */
  4553. xoff = xoff + xspacing;
  4554. /* x to next pos. */
  4555. xoff = xoff + cwpos[i];
  4556. }
  4557. /* */
  4558. clear_cposnodes();
  4559. /* y positioning */
  4560. make_clevelnodes(g);
  4561. cmaxy = 0;
  4562. yoff = 0;
  4563. /* number of edges between level n and n+1 */
  4564. g->nume = (int *) sfg_calloc(1, (g->maxlevel + 1) * sizeof(int));
  4565. /* scan vert. to adjust the y positions. */
  4566. for (i = 0; i < (g->maxlevel + 1); i++) {
  4567. /* y spacing between the vert. levels */
  4568. if (0) {
  4569. yoff = (yoff + yspacing);
  4570. }
  4571. /* determine half-way of the ypos. */
  4572. if (chpos[i] == 0) {
  4573. /* if only dummy nodes */
  4574. hw = (yspacing / 2);
  4575. } else {
  4576. hw = (chpos[i] / 2);
  4577. }
  4578. /* update with current y */
  4579. hw = hw + yoff;
  4580. lnl = clevelnodes[i];
  4581. ecount = 0;
  4582. /* scan the nodes at this y pos. */
  4583. while (lnl) {
  4584. /* set start, end of y level */
  4585. lnl->node->ly0 = yoff;
  4586. lnl->node->ly1 = (yoff + chpos[i]);
  4587. /* center the node around the half-way */
  4588. lnl->node->finy = (hw - (lnl->node->bby / 2));
  4589. /* update drawing max y pos used */
  4590. if ((lnl->node->finy + lnl->node->bby) > cmaxy) {
  4591. cmaxy = (lnl->node->finy + lnl->node->bby);
  4592. }
  4593. /* give dummy nodes a vertical size of the level */
  4594. if (lnl->node->dummy) {
  4595. lnl->node->bby = chpos[i];
  4596. /* if only dummy nodes at level, use spacing */
  4597. if (chpos[i] == 0) {
  4598. lnl->node->bby = yspacing;
  4599. }
  4600. }
  4601. /* number of edges between level n and n+1 */
  4602. ecount = ecount + lnl->node->outdegree;
  4603. lnl = lnl->next;
  4604. }
  4605. g->nume[i] = ecount;
  4606. /* y spacing between the vert. levels */
  4607. yoff = yoff + yspacing;
  4608. /* yspacing depends on number of edges at this level
  4609. * turned off, does increase y too much
  4610. * yoff = yoff + (ecount * 2);
  4611. */
  4612. /* yspacing depends on number of crossing edges at this level
  4613. * temp test
  4614. */
  4615. yoff = yoff + (1 * (g->numce[i] / 16));
  4616. /* y to next pos. */
  4617. yoff = yoff + chpos[i];
  4618. }
  4619. clear_clevelnodes(g);
  4620. /* clear number of edges between level n and n+1 */
  4621. if (g->nume) {
  4622. g->nume = (int *) sfg_free(g->nume);
  4623. }
  4624. return;
  4625. }
  4626. static void movefinal(int xoffset)
  4627. {
  4628. struct gml_nlist *gnl = NULL;
  4629. gnl = cnodelist;
  4630. while (gnl) {
  4631. gnl->node->finx = gnl->node->finx + xoffset;
  4632. gnl->node->lx0 = gnl->node->lx0 + xoffset;
  4633. gnl->node->lx1 = gnl->node->lx1 + xoffset;
  4634. gnl = gnl->next;
  4635. }
  4636. return;
  4637. }
  4638. /* dummy nodes can be centered, or left/right most placed */
  4639. static void tunedummy(struct gml_graph *g)
  4640. {
  4641. struct gml_nlist *gnl = NULL;
  4642. int x1 = 0;
  4643. int x2 = 0;
  4644. int x3 = 0;
  4645. gnl = g->nodelist;
  4646. while (gnl) {
  4647. if (gnl->node->dummy) {
  4648. x1 = gnl->node->finx;
  4649. x2 = gnl->node->incoming_e->edge->from_node->finx + gnl->node->incoming_e->edge->from_node->bbx / 2;
  4650. x3 = gnl->node->outgoing_e->edge->to_node->finx + gnl->node->outgoing_e->edge->to_node->bbx / 2;
  4651. if ((x1 == x2) && (x1 == x3)) {
  4652. /* no move */
  4653. } else {
  4654. if ((x2 < x1) && (x3 < x1)) {
  4655. /* to left */
  4656. gnl->node->finx = gnl->node->lx0;
  4657. }
  4658. if ((x2 > x1) && (x3 > x1)) {
  4659. /* to right */
  4660. gnl->node->finx = gnl->node->lx1;
  4661. }
  4662. }
  4663. }
  4664. gnl = gnl->next;
  4665. }
  4666. return;
  4667. }
  4668. /* move some nodes up/down */
  4669. static void tunenodes(struct gml_graph *g)
  4670. {
  4671. struct gml_nlist *gnl = NULL;
  4672. gnl = g->nodelist;
  4673. while (gnl) {
  4674. /* only at real nodes */
  4675. if (gnl->node->dummy == 0) {
  4676. if (gnl->node->hashedge) {
  4677. /* do not move node with hor. edge */
  4678. } else {
  4679. if (gnl->node->indegree > 0 && gnl->node->outdegree == 0) {
  4680. /* move up */
  4681. gnl->node->finy = gnl->node->ly0;
  4682. }
  4683. if (gnl->node->indegree == 0 && gnl->node->outdegree > 0) {
  4684. /* move down */
  4685. gnl->node->finy = (gnl->node->ly1 - gnl->node->bby);
  4686. }
  4687. if (gnl->node->indegree > 0 && gnl->node->outdegree > 0) {
  4688. if (gnl->node->indegree == gnl->node->outdegree) {
  4689. /* no movement
  4690. *
  4691. */
  4692. } else {
  4693. if (gnl->node->indegree > gnl->node->outdegree) {
  4694. /* move up */
  4695. gnl->node->finy = gnl->node->ly0;
  4696. }
  4697. if (gnl->node->outdegree > gnl->node->indegree) {
  4698. /* move down */
  4699. gnl->node->finy = (gnl->node->ly1 - gnl->node->bby);
  4700. }
  4701. }
  4702. }
  4703. }
  4704. }
  4705. gnl = gnl->next;
  4706. }
  4707. return;
  4708. }
  4709. /* position in parts of graph at each step */
  4710. static void improve_positions(struct gml_graph *g)
  4711. {
  4712. struct gml_nlist *gnl = NULL;
  4713. int i = 0;
  4714. int xoffset = 0;
  4715. xspacing = g->xspacing;
  4716. yspacing = g->yspacing;
  4717. /* copy the rel(x,y) pos into abs(x,y) and modify the absx pos here */
  4718. gnl = g->nodelist;
  4719. while (gnl) {
  4720. gnl->node->bbx = gnl->node->tx;
  4721. gnl->node->bby = gnl->node->ty;
  4722. gnl->node->absx = gnl->node->relx;
  4723. gnl->node->absy = gnl->node->rely;
  4724. gnl->node->finx = 0;
  4725. gnl->node->finy = 0;
  4726. gnl = gnl->next;
  4727. }
  4728. /* offset in drawing of part of graph */
  4729. xoffset = 0;
  4730. for (i = 0; i < g->nstartnodes; i++) {
  4731. /* set current startnode */
  4732. csn = g->startnodes[i];
  4733. /* print progress info */
  4734. if ((i == 0) || (i == g->nstartnodes / 2) || (i == g->nstartnodes - 1)) {
  4735. }
  4736. /* max. x in part of graph */
  4737. cmaxx = 0;
  4738. /* copy part of graph */
  4739. make_cnodelist(g);
  4740. /* create nodes-at-level-count */
  4741. make_cnnodes_at_level(g);
  4742. /* run up/down placement */
  4743. improve_positions2local(g);
  4744. /* move image of this part of graph */
  4745. move0();
  4746. /* set final x,y */
  4747. cfinalxy(g);
  4748. /* tune dummy nodes */
  4749. tunedummy(g);
  4750. /* tune nodes */
  4751. tunenodes(g);
  4752. /* move */
  4753. movefinal(xoffset);
  4754. /* update for next */
  4755. xoffset = xoffset + cmaxx + xspacing;
  4756. /* clear nodes-at-level-count */
  4757. clear_cnnodes_at_level();
  4758. /* done with this part of graph */
  4759. clear_cnodelist();
  4760. }
  4761. /* position level 0, single nodes if any */
  4762. if (g->nsinglenodes) {
  4763. /* done in finalxy() in main.c */
  4764. }
  4765. return;
  4766. }
  4767. /* for pos2.c which does set finx,finy */
  4768. static void finalxy(struct gml_graph *g)
  4769. {
  4770. struct gml_nlist *lnl = NULL;
  4771. int maxx = 0;
  4772. int maxy = 0;
  4773. int curx = 0;
  4774. int my = 0;
  4775. /* position the single nodes */
  4776. if (g->nsinglenodes) {
  4777. lnl = maingraph->singlenodelist;
  4778. while (lnl) {
  4779. lnl->node->finx = curx;
  4780. curx = curx + g->xspacing + lnl->node->bbx;
  4781. if (lnl->node->bby > my) {
  4782. my = lnl->node->bby;
  4783. }
  4784. lnl = lnl->next;
  4785. }
  4786. my = my + g->yspacing;
  4787. /* update level data for singlenodes */
  4788. lnl = maingraph->singlenodelist;
  4789. while (lnl) {
  4790. lnl->node->ly0 = 0;
  4791. lnl->node->ly1 = my;
  4792. lnl = lnl->next;
  4793. }
  4794. }
  4795. /* determine max. x pos in use */
  4796. lnl = maingraph->nodelist;
  4797. while (lnl) {
  4798. if ((lnl->node->finx + lnl->node->bbx) > maxx) {
  4799. maxx = lnl->node->finx + lnl->node->bbx;
  4800. }
  4801. /* correct for height of single nodes if any */
  4802. if (lnl->node->indegree || lnl->node->outdegree) {
  4803. lnl->node->finy = lnl->node->finy + my;
  4804. }
  4805. /* update drawing max y pos used */
  4806. if ((lnl->node->finy + lnl->node->bby) > maxy) {
  4807. maxy = (lnl->node->finy + lnl->node->bby);
  4808. }
  4809. lnl = lnl->next;
  4810. }
  4811. g->maxx = maxx;
  4812. g->maxy = maxy;
  4813. return;
  4814. }
  4815. static struct gml_edge *findedge(int num)
  4816. {
  4817. struct gml_elist *el = NULL;
  4818. struct gml_edge *e = NULL;
  4819. if (maingraph == NULL) {
  4820. return (NULL);
  4821. }
  4822. el = maingraph->edgelist;
  4823. while (el) {
  4824. e = el->edge;
  4825. if (e->nr == num) {
  4826. break;
  4827. }
  4828. el = el->next;
  4829. }
  4830. return (e);
  4831. }
  4832. /* update node min/max and edge min/max */
  4833. static void setminmax(struct gml_graph *g)
  4834. {
  4835. struct gml_nlist *nl = NULL;
  4836. struct gml_elist *el = NULL;
  4837. int count = 0;
  4838. g->nodemin = 0;
  4839. g->nodemax = 0;
  4840. g->edgemin = 0;
  4841. g->edgemax = 0;
  4842. nl = g->nodelist;
  4843. count = 0;
  4844. while (nl) {
  4845. if (count == 0) {
  4846. g->nodemin = nl->node->nr;
  4847. g->nodemax = nl->node->nr;
  4848. } else {
  4849. if (nl->node->nr < g->nodemin) {
  4850. g->nodemin = nl->node->nr;
  4851. }
  4852. if (nl->node->nr > g->nodemax) {
  4853. g->nodemax = nl->node->nr;
  4854. }
  4855. }
  4856. count++;
  4857. nl = nl->next;
  4858. }
  4859. el = g->edgelist;
  4860. count = 0;
  4861. while (el) {
  4862. if (count == 0) {
  4863. g->edgemin = el->edge->nr;
  4864. g->edgemax = el->edge->nr;
  4865. } else {
  4866. if (el->edge->nr < g->edgemin) {
  4867. g->edgemin = el->edge->nr;
  4868. }
  4869. if (el->edge->nr > g->edgemax) {
  4870. g->edgemax = el->edge->nr;
  4871. }
  4872. }
  4873. count++;
  4874. el = el->next;
  4875. }
  4876. return;
  4877. }
  4878. /* end zzzz */
  4879. __END_DECLS