| 396 | } |
| 397 | |
| 398 | void |
| 399 | VisualNode::computeShape(const NodeAllocator& na) { |
| 400 | int numberOfShapes = getNumberOfChildren(); |
| 401 | Extent extent; |
| 402 | if (na.hasLabel(this)) { |
| 403 | int ll = na.getLabel(this).length(); |
| 404 | ll *= 7; |
| 405 | VisualNode* p = getParent(na); |
| 406 | int alt = 0; |
| 407 | int n_alt = 1; |
| 408 | if (p) { |
| 409 | alt = getAlternative(na); |
| 410 | n_alt = p->getNumberOfChildren(); |
| 411 | } |
| 412 | extent = Extent(Layout::extent); |
| 413 | if (alt==0 && n_alt > 1) { |
| 414 | extent.l = std::min(extent.l, -ll); |
| 415 | } else if (alt==n_alt-1 && n_alt > 1) { |
| 416 | extent.r = std::max(extent.r, ll); |
| 417 | } else { |
| 418 | extent.l = std::min(extent.l, -ll); |
| 419 | extent.r = std::max(extent.r, ll); |
| 420 | } |
| 421 | } else { |
| 422 | if (numberOfShapes==0) { |
| 423 | setShape(Shape::leaf); |
| 424 | return; |
| 425 | } else { |
| 426 | extent = Extent(Layout::extent); |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | int maxDepth = 0; |
| 431 | for (int i = numberOfShapes; i--;) |
| 432 | maxDepth = std::max(maxDepth, getChild(na,i)->getShape()->depth()); |
| 433 | Shape* mergedShape; |
| 434 | if (getShape() && getShape() != Shape::leaf && |
| 435 | getShape()->depth() >= maxDepth+1) { |
| 436 | mergedShape = getShape(); |
| 437 | mergedShape->setDepth(maxDepth+1); |
| 438 | } else { |
| 439 | mergedShape = Shape::allocate(maxDepth+1); |
| 440 | } |
| 441 | (*mergedShape)[0] = extent; |
| 442 | if (numberOfShapes < 1) { |
| 443 | setShape(mergedShape); |
| 444 | } else if (numberOfShapes == 1) { |
| 445 | getChild(na,0)->setOffset(0); |
| 446 | const Shape* childShape = getChild(na,0)->getShape(); |
| 447 | for (int i=childShape->depth(); i--;) |
| 448 | (*mergedShape)[i+1] = (*childShape)[i]; |
| 449 | (*mergedShape)[1].extend(- extent.l, - extent.r); |
| 450 | setShape(mergedShape); |
| 451 | } else { |
| 452 | // alpha stores the necessary distances between the |
| 453 | // axes of the shapes in the list: alpha[i].first gives the distance |
| 454 | // between shape[i] and shape[i-1], when shape[i-1] and shape[i] |
| 455 | // are merged left-to-right; alpha[i].second gives the distance between |
no test coverage detected