ref: 2af39358346695de1ec8b5a4320da9a345016c70
parent: 92b4c1ad20c7817371a32d40e563bed6b745a41f
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon May 12 12:34:33 EDT 2014
fmt: consider the whole paragraphs before traps When breaking the line before traps (for flag 2 of .hy), take the whole paragraph into account.
--- a/fmt.c
+++ b/fmt.c
@@ -357,6 +357,12 @@
return MAX(0, f->best_pos[pos]);
}
+static int fmt_bestdep(struct fmt *f, int pos)
+{
+ fmt_findcost(f, pos);
+ return MAX(0, f->best_dep[pos]);
+}
+
/* return the last filled word */
static int fmt_breakparagraph(struct fmt *f, int pos)
{
@@ -392,16 +398,30 @@
/* extract the first nreq formatted lines before the word at pos */
static int fmt_head(struct fmt *f, int nreq, int pos)
{
- int best = -1;
- int i;
- if (nreq <= 0 || f->best_dep[pos] < nreq)
+ int best = pos; /* best line break for nreq-th line */
+ int prev, next; /* best line breaks without hyphenation */
+ if (nreq <= 0 || fmt_bestdep(f, pos) < nreq)
return pos;
- for (i = 1; i <= pos && f->best_dep[i] <= nreq; i++) {
- fmt_findcost(f, i);
- if (f->best_dep[i] == nreq && !f->words[i - 1].hy)
- best = i;
- }
- return best >= 0 ? best : i - 1;
+ /* finding the optimal line break for nreq-th line */
+ while (best > 0 && fmt_bestdep(f, best) > nreq)
+ best = fmt_bestpos(f, best);
+ prev = best;
+ next = best;
+ /* finding closest line breaks without hyphenation */
+ while (prev > 1 && f->words[prev - 1].hy &&
+ fmt_bestdep(f, prev - 1) == nreq)
+ prev--;
+ while (next < pos && f->words[next - 1].hy &&
+ fmt_bestdep(f, next + 1) == nreq)
+ next++;
+ /* choosing the best of them */
+ if (!f->words[prev - 1].hy && !f->words[next - 1].hy)
+ return fmt_findcost(f, prev) <= fmt_findcost(f, next) ? prev : next;
+ if (!f->words[prev - 1].hy)
+ return prev;
+ if (!f->words[next - 1].hy)
+ return next;
+ return best;
}
/* break f->words[0..end] into lines according to fmt_bestpos() */