super(topLevelLM, pvProvider, alignment, alignmentLast, \r
fnSeparatorLength, partOverflowRecovery);\r
this.columnCount = columnCount;\r
+ this.considerTooShort = true; //This is important!\r
}\r
\r
/** @see org.apache.fop.layoutmgr.BreakingAlgorithm */\r
protected double computeDemerits(KnuthNode activeNode,\r
KnuthElement element, int fitnessClass, double r) {\r
double dem = super.computeDemerits(activeNode, element, fitnessClass, r);\r
- log.trace("original demerit=" + dem + " " + totalWidth);\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("original demerit=" + dem + " " + totalWidth \r
+ + " line=" + activeNode.line);\r
+ }\r
+ int remParts = columnCount - activeNode.line;\r
int curPos = par.indexOf(element);\r
if (fullLen == 0) {\r
fullLen = ElementListUtils.calcContentLength(par);\r
}\r
int partLen = ElementListUtils.calcContentLength(par, activeNode.position, curPos - 1);\r
+ int restLen = ElementListUtils.calcContentLength(par, curPos - 1, par.size() - 1);\r
+ int avgRestLen = 0;\r
+ if (remParts > 0) {\r
+ avgRestLen = restLen / remParts;\r
+ }\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("remaining parts: " + remParts + " rest len: " + restLen \r
+ + " avg=" + avgRestLen);\r
+ }\r
int meanColumnLen = (fullLen / columnCount);\r
double balance = (meanColumnLen - partLen) / 1000f;\r
- log.trace("balance=" + balance);\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("balance=" + balance);\r
+ }\r
double absBalance = Math.abs(balance);\r
+ //Step 1: This does the rough balancing\r
if (balance <= 0) {\r
- dem = absBalance * absBalance;\r
+ dem = absBalance;\r
} else {\r
//shorter parts are less desired than longer ones\r
- dem = absBalance * absBalance * 2;\r
+ dem = absBalance * 1.2f;\r
}\r
+ //Step 2: This helps keep the trailing parts shorter than the previous ones \r
+ dem += (avgRestLen) / 1000f;\r
+ \r
if (activeNode.line >= columnCount) {\r
//We don't want more columns than available\r
dem = Double.MAX_VALUE;\r
}\r
- log.trace("effective dem=" + dem + " " + totalWidth);\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("effective dem=" + dem + " " + totalWidth);\r
+ }\r
return dem;\r
}\r
}\r
*/
protected int lineWidth = -1;
private boolean force = false;
+ /** If set to true, doesn't ignore break possibilities which are definitely too short. */
+ protected boolean considerTooShort = false;
protected KnuthNode lastDeactivatedNode = null;
private KnuthNode lastTooLong;
}
} else {
if (lastTooShort == null || demerits <= lastTooShort.totalDemerits) {
+ if (considerTooShort) {
+ //consider possibilities which are too short
+ best.addRecord(demerits, node, r,
+ availableShrink, availableStretch,
+ difference, fitnessClass);
+ }
lastTooShort = createNode(elementIdx, line + 1, fitnessClass,
totalWidth, totalStretch, totalShrink,
r, availableShrink, availableStretch,