Lines 36-41
Link Here
|
36 |
import org.apache.fop.fo.Constants; |
36 |
import org.apache.fop.fo.Constants; |
37 |
import org.apache.fop.fo.flow.Block; |
37 |
import org.apache.fop.fo.flow.Block; |
38 |
import org.apache.fop.fo.properties.CommonHyphenation; |
38 |
import org.apache.fop.fo.properties.CommonHyphenation; |
|
|
39 |
import org.apache.fop.fo.properties.KeepProperty; |
39 |
import org.apache.fop.fonts.Font; |
40 |
import org.apache.fop.fonts.Font; |
40 |
import org.apache.fop.fonts.FontInfo; |
41 |
import org.apache.fop.fonts.FontInfo; |
41 |
import org.apache.fop.fonts.FontTriplet; |
42 |
import org.apache.fop.fonts.FontTriplet; |
Lines 46-52
Link Here
|
46 |
import org.apache.fop.layoutmgr.BreakingAlgorithm; |
47 |
import org.apache.fop.layoutmgr.BreakingAlgorithm; |
47 |
import org.apache.fop.layoutmgr.ElementListObserver; |
48 |
import org.apache.fop.layoutmgr.ElementListObserver; |
48 |
import org.apache.fop.layoutmgr.InlineKnuthSequence; |
49 |
import org.apache.fop.layoutmgr.InlineKnuthSequence; |
49 |
import org.apache.fop.layoutmgr.KeepUtil; |
50 |
import org.apache.fop.layoutmgr.Keep; |
50 |
import org.apache.fop.layoutmgr.KnuthBlockBox; |
51 |
import org.apache.fop.layoutmgr.KnuthBlockBox; |
51 |
import org.apache.fop.layoutmgr.KnuthBox; |
52 |
import org.apache.fop.layoutmgr.KnuthBox; |
52 |
import org.apache.fop.layoutmgr.KnuthElement; |
53 |
import org.apache.fop.layoutmgr.KnuthElement; |
Lines 169-175
Link Here
|
169 |
private AlignmentContext alignmentContext = null; |
170 |
private AlignmentContext alignmentContext = null; |
170 |
|
171 |
|
171 |
private List knuthParagraphs = null; |
172 |
private List knuthParagraphs = null; |
172 |
private int iReturnedLBP = 0; |
|
|
173 |
|
173 |
|
174 |
// parameters of Knuth's algorithm: |
174 |
// parameters of Knuth's algorithm: |
175 |
// penalty value for flagged penalties |
175 |
// penalty value for flagged penalties |
Lines 605-638
Link Here
|
605 |
|
605 |
|
606 |
//PHASE 2: Create line breaks |
606 |
//PHASE 2: Create line breaks |
607 |
return createLineBreaks(context.getBPAlignment(), context); |
607 |
return createLineBreaks(context.getBPAlignment(), context); |
608 |
/* |
|
|
609 |
LineBreakPosition lbp = null; |
610 |
if (breakpoints == null) { |
611 |
// find the optimal line breaking points for each paragraph |
612 |
breakpoints = new ArrayList(); |
613 |
ListIterator paragraphsIterator |
614 |
= knuthParagraphs.listIterator(knuthParagraphs.size()); |
615 |
Paragraph currPar = null; |
616 |
while (paragraphsIterator.hasPrevious()) { |
617 |
currPar = (Paragraph) paragraphsIterator.previous(); |
618 |
findBreakingPoints(currPar, context.getStackLimit().opt); |
619 |
} |
620 |
}*/ |
621 |
|
622 |
//PHASE 3: Return lines |
623 |
|
624 |
/* |
625 |
// get a break point from the list |
626 |
lbp = (LineBreakPosition) breakpoints.get(iReturnedLBP ++); |
627 |
if (iReturnedLBP == breakpoints.size()) { |
628 |
setFinished(true); |
629 |
} |
630 |
|
631 |
BreakPoss curLineBP = new BreakPoss(lbp); |
632 |
curLineBP.setFlag(BreakPoss.ISLAST, isFinished()); |
633 |
curLineBP.setStackingSize(new MinOptMax(lbp.lineHeight)); |
634 |
return curLineBP; |
635 |
*/ |
636 |
} |
608 |
} |
637 |
|
609 |
|
638 |
/** |
610 |
/** |
Lines 767-900
Link Here
|
767 |
} |
739 |
} |
768 |
|
740 |
|
769 |
/** |
741 |
/** |
770 |
* Find a set of breaking points. |
|
|
771 |
* This method is called only once by getNextBreakPoss, and it |
772 |
* subsequently calls the other findBreakingPoints() method with |
773 |
* different parameters, until a set of breaking points is found. |
774 |
* |
775 |
* @param par the list of elements that must be parted |
776 |
* into lines |
777 |
* @param lineWidth the desired length ot the lines |
778 |
*/ |
779 |
/* |
780 |
private void findBreakingPoints(Paragraph par, int lineWidth) { |
781 |
// maximum adjustment ratio permitted |
782 |
float maxAdjustment = 1; |
783 |
|
784 |
// first try |
785 |
if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) { |
786 |
// the first try failed, now try something different |
787 |
log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment); |
788 |
if (hyphenationProperties.hyphenate == Constants.EN_TRUE) { |
789 |
// consider every hyphenation point as a legal break |
790 |
findHyphenationPoints(par); |
791 |
} else { |
792 |
// try with a higher threshold |
793 |
maxAdjustment = 5; |
794 |
} |
795 |
|
796 |
if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) { |
797 |
// the second try failed too, try with a huge threshold; |
798 |
// if this fails too, use a different algorithm |
799 |
log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment |
800 |
+ (hyphenationProperties.hyphenate == Constants.EN_TRUE ? " and hyphenation" : "")); |
801 |
maxAdjustment = 20; |
802 |
if (!findBreakingPoints(par, lineWidth, maxAdjustment, true)) { |
803 |
log.debug("No set of breaking points found, using first-fit algorithm"); |
804 |
} |
805 |
} |
806 |
} |
807 |
} |
808 |
|
809 |
private boolean findBreakingPoints(Paragraph par, int lineWidth, |
810 |
double threshold, boolean force) { |
811 |
KnuthParagraph knuthPara = new KnuthParagraph(par); |
812 |
int lines = knuthPara.findBreakPoints(lineWidth, threshold, force); |
813 |
if (lines == 0) { |
814 |
return false; |
815 |
} |
816 |
|
817 |
for (int i = lines-1; i >= 0; i--) { |
818 |
int line = i+1; |
819 |
if (log.isTraceEnabled()) { |
820 |
log.trace("Making line from " + knuthPara.getStart(i) + " to " + |
821 |
knuthPara.getEnd(i)); |
822 |
} |
823 |
// compute indent and adjustment ratio, according to |
824 |
// the value of text-align and text-align-last |
825 |
|
826 |
int difference = knuthPara.getDifference(i); |
827 |
if (line == lines) { |
828 |
difference += par.lineFillerWidth; |
829 |
} |
830 |
int textAlign = (line < lines) |
831 |
? textAlignment : textAlignmentLast; |
832 |
int indent = (textAlign == EN_CENTER) |
833 |
? difference / 2 |
834 |
: (textAlign == EN_END) ? difference : 0; |
835 |
indent += (line == 1 && knuthParagraphs.indexOf(par) == 0) |
836 |
? textIndent.getValue(this) : 0; |
837 |
double ratio = (textAlign == EN_JUSTIFY) |
838 |
? knuthPara.getAdjustRatio(i) : 0; |
839 |
|
840 |
int start = knuthPara.getStart(i); |
841 |
int end = knuthPara.getEnd(i); |
842 |
makeLineBreakPosition(par, start, end, 0, ratio, indent); |
843 |
} |
844 |
return true; |
845 |
} |
846 |
|
847 |
private void makeLineBreakPosition(Paragraph par, |
848 |
int firstElementIndex, int lastElementIndex, |
849 |
int insertIndex, double ratio, int indent) { |
850 |
// line height calculation |
851 |
|
852 |
int halfLeading = (lineHeight - lead - follow) / 2; |
853 |
// height above the main baseline |
854 |
int lineLead = lead + halfLeading; |
855 |
// maximum size of top and bottom alignment |
856 |
int lineFollow = follow + halfLeading; |
857 |
|
858 |
ListIterator inlineIterator |
859 |
= par.listIterator(firstElementIndex); |
860 |
for (int j = firstElementIndex; |
861 |
j <= lastElementIndex; |
862 |
j++) { |
863 |
KnuthElement element = (KnuthElement) inlineIterator.next(); |
864 |
if (element.isBox()) { |
865 |
KnuthInlineBox box = (KnuthInlineBox)element; |
866 |
if (box.getLead() > lineLead) { |
867 |
lineLead = box.getLead(); |
868 |
} |
869 |
if (box.getTotal() > lineFollow) { |
870 |
lineFollow = box.getTotal(); |
871 |
} |
872 |
if (box.getMiddle() > lineLead + middleShift) { |
873 |
lineLead += box.getMiddle() |
874 |
- lineLead - middleShift; |
875 |
} |
876 |
if (box.getMiddle() > middlefollow - middleShift) { |
877 |
middlefollow += box.getMiddle() |
878 |
- middlefollow + middleShift; |
879 |
} |
880 |
} |
881 |
} |
882 |
|
883 |
if (lineFollow - lineLead > middlefollow) { |
884 |
middlefollow = lineFollow - lineLead; |
885 |
} |
886 |
|
887 |
breakpoints.add(insertIndex, |
888 |
new LineBreakPosition(this, |
889 |
knuthParagraphs.indexOf(par), |
890 |
lastElementIndex , |
891 |
ratio, 0, indent, |
892 |
lineLead + middlefollow, |
893 |
lineLead)); |
894 |
}*/ |
895 |
|
896 |
|
897 |
/** |
898 |
* Phase 2 of Knuth algorithm: find optimal break points. |
742 |
* Phase 2 of Knuth algorithm: find optimal break points. |
899 |
* @param alignment alignment in BP direction of the paragraph |
743 |
* @param alignment alignment in BP direction of the paragraph |
900 |
* @param context the layout context |
744 |
* @param context the layout context |
Lines 1054-1065
Link Here
|
1054 |
for (int p = 0; p < knuthParagraphs.size(); p++) { |
898 |
for (int p = 0; p < knuthParagraphs.size(); p++) { |
1055 |
// penalty between paragraphs |
899 |
// penalty between paragraphs |
1056 |
if (p > 0) { |
900 |
if (p > 0) { |
1057 |
int strength = getKeepTogetherStrength(); |
901 |
Keep keep = getKeepTogether(); |
1058 |
int penalty = KeepUtil.getPenaltyForKeep(strength); |
902 |
returnList.add(new BreakElement( |
1059 |
if (penalty < KnuthElement.INFINITE) { |
903 |
new Position(this), |
1060 |
returnList.add(new BreakElement( |
904 |
keep.getPenalty(), |
1061 |
new Position(this), penalty, context)); |
905 |
keep.getContext(), |
1062 |
} |
906 |
context)); |
1063 |
} |
907 |
} |
1064 |
|
908 |
|
1065 |
LineLayoutPossibilities llPoss; |
909 |
LineLayoutPossibilities llPoss; |
Lines 1098-1109
Link Here
|
1098 |
&& i >= fobj.getOrphans() |
942 |
&& i >= fobj.getOrphans() |
1099 |
&& i <= llPoss.getChosenLineCount() - fobj.getWidows()) { |
943 |
&& i <= llPoss.getChosenLineCount() - fobj.getWidows()) { |
1100 |
// penalty allowing a page break between lines |
944 |
// penalty allowing a page break between lines |
1101 |
int strength = getKeepTogetherStrength(); |
945 |
Keep keep = getKeepTogether(); |
1102 |
int penalty = KeepUtil.getPenaltyForKeep(strength); |
946 |
returnList.add(new BreakElement( |
1103 |
if (penalty < KnuthElement.INFINITE) { |
947 |
new Position(this), |
1104 |
returnList.add(new BreakElement( |
948 |
keep.getPenalty(), |
1105 |
returnPosition, penalty, context)); |
949 |
keep.getContext(), |
1106 |
} |
950 |
context)); |
1107 |
} |
951 |
} |
1108 |
int endIndex |
952 |
int endIndex |
1109 |
= ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos(); |
953 |
= ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos(); |
Lines 1283-1310
Link Here
|
1283 |
} |
1127 |
} |
1284 |
|
1128 |
|
1285 |
/** {@inheritDoc} */ |
1129 |
/** {@inheritDoc} */ |
1286 |
public int getKeepTogetherStrength() { |
1130 |
public KeepProperty getKeepTogetherProperty() { |
1287 |
return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength(); |
1131 |
return ((BlockLevelLayoutManager) getParent()).getKeepTogetherProperty(); |
1288 |
} |
1132 |
} |
1289 |
|
1133 |
|
1290 |
/** {@inheritDoc} */ |
1134 |
/** {@inheritDoc} */ |
|
|
1135 |
public KeepProperty getKeepWithPreviousProperty() { |
1136 |
return ((BlockLevelLayoutManager) getParent()).getKeepWithPreviousProperty(); |
1137 |
} |
1138 |
|
1139 |
/** {@inheritDoc} */ |
1140 |
public KeepProperty getKeepWithNextProperty() { |
1141 |
return ((BlockLevelLayoutManager) getParent()).getKeepWithNextProperty(); |
1142 |
} |
1143 |
|
1144 |
/** {@inheritDoc} */ |
1145 |
public Keep getKeepTogether() { |
1146 |
return ((BlockLevelLayoutManager) getParent()).getKeepTogether(); |
1147 |
} |
1148 |
|
1149 |
/** {@inheritDoc} */ |
1291 |
public boolean mustKeepWithPrevious() { |
1150 |
public boolean mustKeepWithPrevious() { |
1292 |
return getKeepWithPreviousStrength() > KEEP_AUTO; |
1151 |
return !getKeepWithPrevious().isAuto(); |
1293 |
} |
1152 |
} |
1294 |
|
1153 |
|
1295 |
/** {@inheritDoc} */ |
1154 |
/** {@inheritDoc} */ |
1296 |
public boolean mustKeepWithNext() { |
1155 |
public boolean mustKeepWithNext() { |
1297 |
return getKeepWithNextStrength() > KEEP_AUTO; |
1156 |
return !getKeepWithNext().isAuto(); |
1298 |
} |
1157 |
} |
1299 |
|
1158 |
|
1300 |
/** {@inheritDoc} */ |
1159 |
/** {@inheritDoc} */ |
1301 |
public int getKeepWithNextStrength() { |
1160 |
public Keep getKeepWithNext() { |
1302 |
return KEEP_AUTO; |
1161 |
return Keep.KEEP_AUTO; |
1303 |
} |
1162 |
} |
1304 |
|
1163 |
|
1305 |
/** {@inheritDoc} */ |
1164 |
/** {@inheritDoc} */ |
1306 |
public int getKeepWithPreviousStrength() { |
1165 |
public Keep getKeepWithPrevious() { |
1307 |
return KEEP_AUTO; |
1166 |
return Keep.KEEP_AUTO; |
1308 |
} |
1167 |
} |
1309 |
|
1168 |
|
1310 |
/** {@inheritDoc} */ |
1169 |
/** {@inheritDoc} */ |
Lines 1409-1414
Link Here
|
1409 |
break; |
1268 |
break; |
1410 |
} |
1269 |
} |
1411 |
//TODO Something's not right here. See block_hyphenation_linefeed_preserve.xml |
1270 |
//TODO Something's not right here. See block_hyphenation_linefeed_preserve.xml |
|
|
1271 |
//for more info: see also https://issues.apache.org/bugzilla/show_bug.cgi?id=38264 |
1412 |
|
1272 |
|
1413 |
// collect word fragments, ignoring auxiliary elements; |
1273 |
// collect word fragments, ignoring auxiliary elements; |
1414 |
// each word fragment was created by a different TextLM |
1274 |
// each word fragment was created by a different TextLM |