/* TextVob.java * * Copyright (c) 2001-2002, 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 Benja Fallenstein and Tuomas Lukka */ package gzz.vob.vobs; import gzz.vob.*; import gzz.vob.impl.awt.*; import gzz.vob.impl.gl.*; import gzz.vob.linebreaking.*; import gzz.gfx.gl.*; import java.awt.Rectangle; import java.awt.Shape; import gzz.client.*; /** A single contiguous text string as a Vob. * This vob implements the HBox interface so it is * possible to create a paragraph * from these and use a LineBreaker. *

* A note on the relationship between this class and TextStyle: * TextStyle can be constructed from GraphicsAPI by giving a size. * That size is the virtual point or pixel size. * However, since * we are in a flexibly scaling world, that size has no bearing * on how tall the text in a TextVob will appear: only the height of the coordinate * system into which the textvob is placed affects that. *

* To get text the right way, give an isotropic coordinate system, i.e. one that * keeps squares squares. * XXX Diagram! */ public class TextVob extends HBox.VobHBox { String rcsid = "$Id: TextVob.java,v 1.1 2002/11/02 01:23:46 benja Exp $"; public static boolean dbg = false; private static void pa(String s) { System.err.println(s); } protected final TextStyle style; protected final String text; protected final boolean baselined; protected Object key; /** Create a new TextVob. * @param style The textstyle to use. * @param text The text that the Vob should show * @param baselined If true, the baseline of the text will be at * the bottom of the unit square of the coordinate system. * If false, the text will be comfortably within the box. */ public TextVob(TextStyle style, String text, boolean baselined) { super(); this.style = style; this.baselined = baselined; this.text = text; } /** Create a non-baselined text vob. */ public TextVob(TextStyle style, String text) { this(style, text, false); } public TextVob(TextStyle style, String text, boolean baselined, Object key) { this(style, text, baselined); this.key = key; } public String getText() { return text; } public Object getKey() { return key; } public float getScale() { return scale; } ////////////////////////////// // IMPLEMENTATION OF Vob static Rectangle rect = new Rectangle(); public void render(java.awt.Graphics g, boolean fast, RenderInfo info1, RenderInfo info2) { // XXX Needs adjusting to baselined! g.setColor(info1.getMixedFgColor()); //info1.getClipRect(rect); info1.getExtRect(rect); float x = rect.x, y = rect.y; info2.getExtRect(rect); float w = rect.width, h = rect.height; Shape oldClip = g.getClip(); /*g.clipRect(rect.x, rect.y, rect.width, rect.height + 3);*/ float scale = style.getScaleByHeight(h-3); if(dbg) pa("Render @ scale " + scale + ": '"+text+"' "+x+" "+y+" "+w+" "+h); float fasc = style.getAscent(scale); float fdsc = style.getDescent(scale); float fh = fasc + fdsc; float ty = y + h/2 + fasc/2; if(dbg) g.drawRect((int)x, (int)y, (int)w, (int)h); ((AWTTextStyle)style).render(g, (int)x, (int)ty, text, scale, null); g.setClip(oldClip); } static private Vob start, stop; static public Vob getStartCode() { if(start == null) { if (GL.hasExtension("GL_NV_register_combiners")) { start = GLCache.getCallList( " PushAttrib ENABLE_BIT TEXTURE_BIT \n"+ " Enable REGISTER_COMBINERS_NV \n" + " CombinerParameterNV NUM_GENERAL_COMBINERS_NV 1 \n" + " CombinerParameterNV CONSTANT_COLOR0_NV 0 0 0 0.4 \n" + " CombinerInputNV COMBINER0_NV ALPHA VARIABLE_A_NV TEXTURE0 UNSIGNED_IDENTITY_NV ALPHA \n" + " CombinerInputNV COMBINER0_NV ALPHA VARIABLE_B_NV CONSTANT_COLOR0_NV UNSIGNED_IDENTITY_NV ALPHA \n" + " CombinerOutputNV COMBINER0_NV ALPHA SPARE0_NV DISCARD_NV DISCARD_NV SCALE_BY_FOUR_NV NONE FALSE FALSE FALSE \n" + " \n" + " FinalCombinerInputNV VARIABLE_A_NV ZERO UNSIGNED_IDENTITY_NV RGB \n" + " FinalCombinerInputNV VARIABLE_B_NV ZERO UNSIGNED_IDENTITY_NV RGB \n" + " FinalCombinerInputNV VARIABLE_C_NV ZERO UNSIGNED_IDENTITY_NV RGB \n" + " FinalCombinerInputNV VARIABLE_D_NV PRIMARY_COLOR_NV UNSIGNED_IDENTITY_NV RGB \n" + " \n" + " FinalCombinerInputNV VARIABLE_G_NV SPARE0_NV UNSIGNED_IDENTITY_NV ALPHA \n" + ""); } else { start = GLCache.getCallList( " PushAttrib ENABLE_BIT TEXTURE_BIT"); } } return start; } static public Vob getStopCode() { if(stop == null) { stop = GLCache.getCallList("PopAttrib"); } return stop; } /** The OpenGL renderable for this TextVob. */ private Vob ht; public int addToListGL(GraphicsAPI.Window win, int[] list, int curs, int coordsys1, int coordsys2) { if(dbg) pa("Addtolistgl text "+text); if(ht == null) { GLTextStyle gls = (GLTextStyle)style; ht = GLRen.createHorizText( gls.theFont, text, 0, (baselined ? 1 : gls.theFont.getYOffs()), 0, 1, 1); } curs = getStartCode().addToListGL(win, list, curs, 0, 0); curs = ht.addToListGL(win, list, curs, coordsys1, coordsys2); curs = getStopCode().addToListGL(win, list, curs, 0, 0); return curs; } ////////////////////////////// // HBox implementation // public float getWidth(float scale) { return style.getWidth(text, scale); } public float getHeight(float scale) { return style.getAscent(scale); } public float getDepth(float scale) { return style.getDescent(scale); } public void setPrev(HBox b) { } public void setPosition(int depth, int x, int y, int w, int h) { } public String toString() { return super.toString() + " '"+text+"' "; } }