in fop-core/src/main/java/org/apache/fop/layoutmgr/table/OverPaintBorders.java [87:187]
private void mergeBordersOfType(List<Block> newBlocks, List<?> childAreas, int[] borderTraits) {
Map<Integer, Map<Point, Block>> mergeMap = new HashMap<Integer, Map<Point, Block>>();
for (int traitType : borderTraits) {
mergeMap.put(traitType, null);
}
for (Object child : childAreas) {
Block childBlock = (Block) child;
BorderProps startBps = (BorderProps) childBlock.getTrait(Trait.BORDER_START);
BorderProps endBps = (BorderProps) childBlock.getTrait(Trait.BORDER_END);
BorderProps beforeBps = (BorderProps) childBlock.getTrait(Trait.BORDER_BEFORE);
BorderProps afterBps = (BorderProps) childBlock.getTrait(Trait.BORDER_AFTER);
for (int traitType : borderTraits) {
Block currBlock = childBlock;
BorderProps borderProps = (BorderProps) currBlock.getTrait(traitType);
if (borderProps == null) {
continue;
}
Map<Point, Block> currTraitMap = mergeMap.get(traitType);
Point endPoint = getEndMiddlePoint(currBlock, traitType, startBps, endBps, beforeBps, afterBps);
BorderProps bpsCurr = (BorderProps) currBlock.getTrait(traitType);
Block prevBlock = null;
if (currTraitMap == null) {
currTraitMap = new HashMap<Point, Block>();
mergeMap.put(traitType, currTraitMap);
} else {
Point startPoint = getStartMiddlePoint(currBlock, traitType, startBps, endBps, beforeBps, afterBps);
for (Map.Entry<Point, Block> entry : currTraitMap.entrySet()) {
Point prevEndPoint = entry.getKey();
boolean isVertical = traitType == Trait.BORDER_START || traitType == Trait.BORDER_END;
boolean isHorizontal = traitType == Trait.BORDER_BEFORE || traitType == Trait.BORDER_AFTER;
if ((isHorizontal && prevEndPoint.y == startPoint.y && prevEndPoint.x >= startPoint.x)
|| (isVertical && prevEndPoint.x == startPoint.x && prevEndPoint.y >= startPoint.y)) {
Block prevBlockCurr = entry.getValue();
currTraitMap.remove(prevEndPoint);
BorderProps bpsPrev = (BorderProps) prevBlockCurr.getTrait(traitType);
if (canMergeBorders(bpsPrev, bpsCurr)) {
prevBlock = prevBlockCurr;
}
break;
}
}
}
Block borderBlock;
if (prevBlock != null && newBlocks.contains(prevBlock)) {
borderBlock = prevBlock;
} else {
borderBlock = new Block();
borderBlock.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
borderBlock.setPositioning(Block.ABSOLUTE);
borderBlock.setBidiLevel(currBlock.getBidiLevel());
newBlocks.add(borderBlock);
BorderProps prevBeforeBps = (BorderProps) currBlock.getTrait(Trait.BORDER_BEFORE);
int prevBefore = prevBeforeBps != null ? prevBeforeBps.width : 0;
Integer prevPaddingStart = (Integer) currBlock.getTrait(Trait.PADDING_START);
Integer prevPaddingEnd = (Integer) currBlock.getTrait(Trait.PADDING_END);
Integer prevPaddingBefore = (Integer) currBlock.getTrait(Trait.PADDING_BEFORE);
Integer prevPaddingAfter = (Integer) currBlock.getTrait(Trait.PADDING_AFTER);
if (traitType == Trait.BORDER_START) {
borderBlock.setYOffset(currBlock.getYOffset() + prevBefore);
borderBlock.setXOffset(currBlock.getXOffset()
- (prevPaddingStart != null ? prevPaddingStart : 0));
} else if (traitType == Trait.BORDER_END) {
borderBlock.setYOffset(currBlock.getYOffset() + prevBefore);
borderBlock.setXOffset(currBlock.getXOffset()
- (prevPaddingStart != null ? prevPaddingStart : 0));
borderBlock.setIPD(currBlock.getIPD()
+ (prevPaddingStart != null ? prevPaddingStart : 0)
+ (prevPaddingEnd != null ? prevPaddingEnd : 0));
} else if (traitType == Trait.BORDER_BEFORE) {
borderBlock.setYOffset(currBlock.getYOffset());
borderBlock.setXOffset(currBlock.getXOffset()
- (prevPaddingStart != null ? prevPaddingStart : 0));
} else if (traitType == Trait.BORDER_AFTER) {
borderBlock.setYOffset(currBlock.getYOffset() + prevBefore);
borderBlock.setXOffset(currBlock.getXOffset()
- (prevPaddingStart != null ? prevPaddingStart : 0));
borderBlock.setBPD(currBlock.getBPD()
+ (prevPaddingBefore != null ? prevPaddingBefore : 0)
+ (prevPaddingAfter != null ? prevPaddingAfter : 0));
}
}
Integer paddingEnd = (Integer) currBlock.getTrait(Trait.PADDING_END);
Integer paddingAfter = (Integer) currBlock.getTrait(Trait.PADDING_AFTER);
if (traitType == Trait.BORDER_BEFORE || traitType == Trait.BORDER_AFTER) {
int newEndPoint = currBlock.getXOffset() + currBlock.getIPD()
+ (paddingEnd != null ? paddingEnd : 0);
borderBlock.setIPD(newEndPoint - borderBlock.getXOffset());
} else if (traitType == Trait.BORDER_START || traitType == Trait.BORDER_END) {
int newEndPoint = currBlock.getYOffset() + currBlock.getBPD()
+ currBlock.getBorderAndPaddingWidthBefore()
+ (paddingAfter != null ? paddingAfter : 0);
borderBlock.setBPD(newEndPoint - borderBlock.getYOffset());
}
BorderProps newBps = new BorderProps(bpsCurr.style, bpsCurr.width, 0, 0,
bpsCurr.color, bpsCurr.getMode());
borderBlock.addTrait(traitType, newBps);
currBlock = borderBlock;
currTraitMap.put(endPoint, currBlock);
}
}
}