/* TextVob.java * * Copyright (c) 2001-2002, 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 Benja Fallenstein and Tuomas Lukka */ package org.nongnu.libvob.vobs; import org.nongnu.libvob.*; import org.nongnu.libvob.impl.awt.*; import org.nongnu.libvob.impl.gl.*; import org.nongnu.libvob.linebreaking.*; import org.nongnu.libvob.gl.*; import java.awt.Rectangle; import java.awt.Shape; /** 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 2003/03/16 15:55:05 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 String textColor = null; 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) { this(style, text, baselined, null); } /** Same as another constructor but in GL side you can give the color * with string like "Color 1 0.5 0.5" * @param color OpenGL Color used to draw the text. */ public TextVob(TextStyle style, String text, boolean baselined, String color) { super(); this.style = style; this.baselined = baselined; this.text = text; this.textColor = color; } /** 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, null); } public TextVob(TextStyle style, String text, boolean baselined, Object key, String color) { this(style, text, baselined, color); this.key = key; } public TextStyle getTextStyle() { return style; } 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; info1.getClipRect(rect); float w = rect.width, h = rect.height; /* info2.getExtRect(rect); */ //Shape oldClip = g.getClip(); /*g.clipRect(rect.x, rect.y, rect.width, rect.height + 3);*/ /* float scale = style.getScaleByHeight(h-3); // Why h-3? */ float scale = style.getScaleByHeight(h); if(dbg) pa("Render @ scale " + scale + ": '"+text+"' "+getWidth(scale)+" -- pos: "+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)getWidth(scale), (int)h); ((AWTTextStyle)style).render(g, (int)x, (int)ty, text, scale, null); //g.setClip(oldClip); } static private Vob start, stop; private Vob setColor; /** static public Vob getStartCode() { if(start == null) { if (GL.hasExtension("GL_NV_register_combiners")) { start = GLCache.getCallList( " PushAttrib ENABLE_BIT TEXTURE_BIT CURRENT_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; } **/ private Vob setColor() { if(setColor == null) { setColor = GLCache.getCallList(this.textColor == null ? "" : this.textColor); } return setColor; } /** The OpenGL renderable for this TextVob. */ private Vob ht; public int putGL(VobScene vs, int coordsys1) { throw new Error("Cannot render TextVob in GL yet"); /* 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, 0); } vs.map.put(getStartCode()); vs.map.put(setColor()); vs.map.put(ht, coordsys1); vs.map.put(getStopCode()); return 0; */ } ////////////////////////////// // 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 int getLength() { return text.length(); } public float getX(int i, float scale) { return style.getWidth(text.substring(0, i), 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+"' "; } }