/* SimpleLinebreaker.java * * Copyright (c) 2000-2001, Ted Nelson and Tuomas Lukka * * This file is part of Gzz. * * Gzz is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Gzz is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with Gzz; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * */ /* * Written by Tuomas Lukka */ package org.nongnu.libvob.linebreaking; import org.nongnu.libvob.*; import java.util.*; /** A not too capable, if not conceptually simple, implementation of the * Linebreaker interface. ;-) */ public class DefaultLinebreaker implements Linebreaker { String rcsid = "$Id: DefaultLinebreaker.java,v 1.1 2003/03/16 15:55:04 benja Exp $"; // Trivial linebreaker implementation // XXX refactor public int chompTriv(LinebreakableChain ch, int start, int w, float scale) { double prev = 1000000000; int prevAccept = -1; for(int end=start+1; end<=ch.nboxes; end++) { if(ch.glues[end*3 + GLUE_LENGTH] == 0) // Can we break here? continue; double sf = LinebreakingUtil.stretchFactor(ch, start, end, scale, w); // System.out.println("SF: "+start+" "+w+" "+scale+" "+sf); if(sf < 0) { if((sf < -1 && end > start + 1) // prefer loose lines to overtight || (prev < -sf)) // getting worse { if(prevAccept >= 0) return prevAccept; else return end; } else return end; } prev = sf; prevAccept = end; } return ch.nboxes; } /** Perform simple line-breaking. * @param lines An array of line widths in pixels * @param scales an array of the scales of the individual lines * @param ctoken The index of the cursor in this lbchain. * @param crow The index of the row in lines that the token * indicated by ctoken should land on * @param into An array that contains the starts of the lines * in terms of tokens in this box. * @return A configuration of lines as a Broken object. */ public Linebreaker.Broken breakLines(LinebreakableChain ch, int[] lines, float[] scales, int ctoken, int crow) { int cur = 0; int line; Linebreaker.Broken bro = new Linebreaker.Broken(); bro.ch = ch; bro.lineWidths = lines; bro.lineScales = scales; bro.tokenStarts = new int[lines.length+1]; bro.firstLine = crow; bro.lineHeights = new int[lines.length+1]; int height = 0; for(line = crow; line < lines.length && cur < ch.nboxes; line ++) { bro.tokenStarts[line] = cur; int w = lines[line]; float scale; if(line >= scales.length) scale = scales[scales.length-1]; else scale = scales[line]; cur = chompTriv(ch, cur, w, scale); int h = (int)ch.getAscent(bro.tokenStarts[line], cur, scale); bro.lineHeights[line] += h; height += h; int d = (int)ch.getDescent(bro.tokenStarts[line], cur, scale); bro.lineHeights[line+1] += d; height += d; } bro.tokenStarts[line] = cur; bro.endLine = line; // one past end. bro.height = height; return bro; } }