/* LinebrokenTex.java * * Copyright (c) 1999-2000, 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.fenfire.view; import org.nongnu.libvob.*; import org.nongnu.libvob.linebreaking.*; import org.nongnu.libvob.vobs.*; import org.nongnu.libvob.impl.*; import org.nongnu.alph.*; import org.nongnu.alph.impl.*; import java.awt.Font; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Color; import java.util.*; /** A content view showing a text, broken into lines. * Doesn't scroll, currently. */ public class LinebrokenText extends TextHandler { public static final String rcsid = "$Id: LinebrokenText.java,v 1.1 2003/04/23 20:24:57 mudyc Exp $"; public static boolean dbg = false; private static void p(String s) { if(dbg) pa(s); } private static void pa(String s) { System.out.println("LinebrokenText::"+s); } static Object CONTENT_KEY = new Object(); static Object CURSOR_KEY = new Object(); LineVob cursorVob = new LineVob(0, 0, 0, 1, Color.black); SimpleLinebreaker breaker = new SimpleLinebreaker(); protected String widthString; protected boolean baselined = true; public LinebrokenText() { this(null); } public LinebrokenText(TextStyle style) { this(style, "XXXXXXXXXXX"); } public LinebrokenText(TextStyle style, String widthString) { super(); if (style != null) setStyle(style); this.widthString = widthString; } public LinebrokenText(TextStyle style, String widthString, boolean baselined) { this(style, widthString); this.baselined = baselined; } /** Get the height necessary to layout a range of text in a cell, * at a given width and scale. */ public float getHeight(Enfilade1D enf, float forWidth, float scale) { HChain ch = getChain(enf, scale); HBroken br = breaker.breakLines(ch, forWidth, scale); return br.getHeight(); } public void getSize(Enfilade1D enf, float[] out) { float w = style.getWidth(widthString, scale); float h; if(enf != null) h = getHeight(enf, w, scale); else h = style.getHeight(scale); out[0] = w/scale; out[1] = h/scale; } static Rectangle box = new Rectangle(); float[] boxwh = new float[2], xoffsarr = new float[1]; public void place(VobScene vs, int box, Enfilade1D enf) { //float scale = 1; // XXX getFontScale (see PEG vobcoorder_fontscale--tjl) vs.coords.getSqSize(box, boxwh); if(dbg) pa(""+boxwh[0]); int pos = getCursorOffset(); float line_height = style.getHeight(scale); float xoffs = 0, yoffs0 = 0, yoffs1 = 0; HChain ch = getChain(enf, scale); HBroken br = breaker.breakLines(ch, boxwh[0], scale); if(pos >= 0) { int line = br.getLine(pos, xoffsarr); xoffs = xoffsarr[0]; yoffs0 = br.getLineOffset(line-1); yoffs1 = br.getLineOffset(line); } float h = br.getHeight(); float middle = boxwh[1]/2; float yoffs = (yoffs0 + yoffs1) / 2; int content; if(h < boxwh[1] || yoffs < middle) content = vs.translateCS(box, CONTENT_KEY, 0, 0); else if(yoffs > h-middle) content = vs.translateCS(box, CONTENT_KEY, 0, -h + boxwh[1]); else content = vs.translateCS(box, CONTENT_KEY, 0, -yoffs + middle); br.put(vs, content); if(pos >= 0) { int cursor = vs.orthoCS(content, CURSOR_KEY, -1, xoffs, yoffs0, 1, line_height); vs.map.put(cursorVob, cursor); } } protected HChain getChain(Enfilade1D enf, float scale) { String s = enf.makeString(); return getChain(s, scale); } protected HChain getChain(String s, float scale) { if (s == null) s = ""; HChain ch = new LinebreakableChain(); int pos = 0; int last; while(pos < s.length()) { last = pos; int sp = s.indexOf(' ', pos); int br = s.indexOf('\n', pos); if(sp >= 0 && br >= 0) pos = sp
= 0) pos = sp+1; else if(br >= 0) pos = br; else pos = s.length(); addVobs(s, ch, last, pos, scale); if(pos == br) { ch.addBox(new HBox.Null(1)); ch.addBreak(); pos++; } } return ch; } protected void addVobs(String s, HChain ch, int start, int end, float scale) { Object key = new Integer(start+1472); s = s.substring(start, end); if(dbg) pa("addVobs: "+start+" "+end+" '"+s+"'"); //TextVob vob = new TextVob(style, s, baselined, key, getColor()); TextVob vob = new TextVob(style, s, baselined, key); ch.addBox(vob); } }