/* FTextBreaker.java * * Copyright (c) 2001, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Benjamin Fallenstein */ package org.gzigzag; import java.awt.*; import java.util.*; /** A class doing linebreaking of FTexts with the stupid first match algorithm. * @see FText */ public class FirstMatchBreaker { public static final String rcsid = "$Id$"; public static boolean dbg = false; private static final void p(String s) { if(dbg) System.out.println(s); } private static final void pa(String s) { System.out.println(s); } static class Word { FText.Part p; int start, end; /** Is a line break enforced after this word? */ boolean forced; FText.Part get() { return p.subpart(start, end); } int width() { return p.fm.stringWidth(p.s.substring(start, end)); } Word(FText.Part p, int s, int e, boolean f) { this.p=p; start=s; end=e; forced=f; } } /** Internal convenience: concatenate all adjacent words in a vector. */ private static void concat(Vector v) { int i=0; while(i+1 < v.size()) { Word w1 = (Word)v.elementAt(i), w2 = (Word)v.elementAt(i+1); if(w1.p == w2.p && w1.end == w2.start) { w1.end = w2.end; v.removeElement(w2); } else i++; } } /** Internal convenience: search a number of tokens in a string * Returns the next occurence of any of the tokens after the given * position. */ static int indOf(String s, int pos, char[] toks) { for(int i=pos+1; i= 0) { char c = s.charAt(here); v.addElement(new Word(p, last+1, here+1, c == '\n')); last = here; } v.addElement(new Word(p, last+1, s.length(), false)); } return v; } /** Internal convenience: Vector to array. */ private static FText.Part[] v2a(Vector v) { concat(v); FText.Part[] res = new FText.Part[v.size()]; for(int i=0; i linestart && x > width) { lineset.addElement(v2a(line)); line.removeAllElements(); x = w.width(); linestart = i; } line.addElement(w); if(x > width || w.forced) { /* w alone doesn't fit on our line, or forced break after w */ lineset.addElement(v2a(line)); line.removeAllElements(); x = 0; linestart = i+1; } } if(line.size() > 0) lineset.addElement(v2a(line)); FText.Part[][] res = new FText.Part[lineset.size()][]; for(int j=0; j