| 322 | |
| 323 | template<class S1, class S2> |
| 324 | void |
| 325 | Layouter::merge(Extent* result, |
| 326 | const S1& shape1, int depth1, |
| 327 | const S2& shape2, int depth2, int alpha) { |
| 328 | if (depth1 == 0) { |
| 329 | for (int i=depth2; i--;) |
| 330 | result[i] = shape2[i]; |
| 331 | } else if (depth2 == 0) { |
| 332 | for (int i=depth1; i--;) |
| 333 | result[i] = shape1[i]; |
| 334 | } else { |
| 335 | // Extend the topmost right extent by alpha. This, in effect, |
| 336 | // moves the second shape to the right by alpha units. |
| 337 | int topmostL = shape1[0].l; |
| 338 | int topmostR = shape2[0].r; |
| 339 | int backoffTo1 = |
| 340 | shape1[0].r - alpha - shape2[0].r; |
| 341 | int backoffTo2 = |
| 342 | shape2[0].l + alpha - shape1[0].l; |
| 343 | |
| 344 | result[0] = Extent(topmostL, topmostR+alpha); |
| 345 | |
| 346 | // Now, since extents are given in relative units, in order to |
| 347 | // compute the extents of the merged shape, we can just collect the |
| 348 | // extents of shape1 and shape2, until one of the shapes ends. If |
| 349 | // this happens, we need to "back-off" to the axis of the deeper |
| 350 | // shape in order to properly determine the remaining extents. |
| 351 | int i=1; |
| 352 | for (; i<depth1 && i<depth2; i++) { |
| 353 | Extent currentExtent1 = shape1[i]; |
| 354 | Extent currentExtent2 = shape2[i]; |
| 355 | int newExtentL = currentExtent1.l; |
| 356 | int newExtentR = currentExtent2.r; |
| 357 | result[i] = Extent(newExtentL, newExtentR); |
| 358 | backoffTo1 += currentExtent1.r - currentExtent2.r; |
| 359 | backoffTo2 += currentExtent2.l - currentExtent1.l; |
| 360 | } |
| 361 | |
| 362 | // If shape1 is deeper than shape2, back off to the axis of shape1, |
| 363 | // and process the remaining extents of shape1. |
| 364 | if (i<depth1) { |
| 365 | Extent currentExtent1 = shape1[i]; |
| 366 | int newExtentL = currentExtent1.l; |
| 367 | int newExtentR = currentExtent1.r; |
| 368 | result[i] = Extent(newExtentL, newExtentR+backoffTo1); |
| 369 | ++i; |
| 370 | for (; i<depth1; i++) { |
| 371 | result[i] = shape1[i]; |
| 372 | } |
| 373 | } |
| 374 | |
| 375 | // Vice versa, if shape2 is deeper than shape1, back off to the |
| 376 | // axis of shape2, and process the remaining extents of shape2. |
| 377 | if (i<depth2) { |
| 378 | Extent currentExtent2 = shape2[i]; |
| 379 | int newExtentL = currentExtent2.l; |
| 380 | int newExtentR = currentExtent2.r; |
| 381 | result[i] = Extent(newExtentL+backoffTo2, newExtentR); |