| | @@ -340,19 +340,28 @@ |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | 342 | |
| 343 | 343 | /* |
| 344 | 344 | ** Compute the complete graph |
| 345 | +** |
| 346 | +** When primary or merge parents are off-screen, normally a line is drawn |
| 347 | +** from the node down to the bottom of the graph. This line is called a |
| 348 | +** "descender". But if the omitDescenders flag is true, then lines down |
| 349 | +** to the bottom of the screen are omitted. |
| 345 | 350 | */ |
| 346 | 351 | void graph_finish(GraphContext *p, int omitDescenders){ |
| 347 | 352 | GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; |
| 348 | 353 | int i, j; |
| 349 | 354 | u64 mask; |
| 350 | 355 | int hasDup = 0; /* True if one or more isDup entries */ |
| 351 | 356 | const char *zTrunk; |
| 352 | | - int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines |
| 353 | | - that enter from bottom of screen */ |
| 357 | + |
| 358 | + /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser |
| 359 | + ** coming up from the bottom of the graph from off-screen check-in Y |
| 360 | + ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0. |
| 361 | + */ |
| 362 | + int mergeRiserFrom[GR_MAX_RAIL]; |
| 354 | 363 | |
| 355 | 364 | if( p==0 || p->pFirst==0 || p->nErr ) return; |
| 356 | 365 | p->nErr = 1; /* Assume an error until proven otherwise */ |
| 357 | 366 | |
| 358 | 367 | /* Initialize all rows */ |
| | @@ -367,11 +376,11 @@ |
| 367 | 376 | pDup->isDup = 1; |
| 368 | 377 | } |
| 369 | 378 | hashInsert(p, pRow, 1); |
| 370 | 379 | } |
| 371 | 380 | p->mxRail = -1; |
| 372 | | - memset(railRid, 0, sizeof(railRid)); |
| 381 | + memset(mergeRiserFrom, 0, sizeof(mergeRiserFrom)); |
| 373 | 382 | |
| 374 | 383 | /* Purge merge-parents that are out-of-graph if descenders are not |
| 375 | 384 | ** drawn. |
| 376 | 385 | ** |
| 377 | 386 | ** Each node has one primary parent and zero or more "merge" parents. |
| | @@ -460,13 +469,10 @@ |
| 460 | 469 | } |
| 461 | 470 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 462 | 471 | mask = BIT(pRow->iRail); |
| 463 | 472 | if( !omitDescenders ){ |
| 464 | 473 | pRow->bDescender = pRow->nParent>0; |
| 465 | | - if( pRow->bDescender ){ |
| 466 | | - railRid[pRow->iRail] = pRow->aParent[0]; |
| 467 | | - } |
| 468 | 474 | for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){ |
| 469 | 475 | pLoop->railInUse |= mask; |
| 470 | 476 | } |
| 471 | 477 | } |
| 472 | 478 | assignChildrenToRail(pRow); |
| | @@ -543,19 +549,19 @@ |
| 543 | 549 | pDesc = hashFind(p, parentRid); |
| 544 | 550 | if( pDesc==0 ){ |
| 545 | 551 | /* Merge from a node that is off-screen */ |
| 546 | 552 | int iMrail = -1; |
| 547 | 553 | for(j=0; j<GR_MAX_RAIL; j++){ |
| 548 | | - if( railRid[j]==parentRid ){ |
| 554 | + if( mergeRiserFrom[j]==parentRid ){ |
| 549 | 555 | iMrail = j; |
| 550 | 556 | break; |
| 551 | 557 | } |
| 552 | 558 | } |
| 553 | 559 | if( iMrail==-1 ){ |
| 554 | 560 | iMrail = findFreeRail(p, pRow->idx, p->nRow, 0); |
| 555 | 561 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 556 | | - railRid[iMrail] = parentRid; |
| 562 | + mergeRiserFrom[iMrail] = parentRid; |
| 557 | 563 | } |
| 558 | 564 | mask = BIT(iMrail); |
| 559 | 565 | pRow->mergeIn[iMrail] = 1; |
| 560 | 566 | pRow->mergeDown |= mask; |
| 561 | 567 | for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){ |
| 562 | 568 | |