/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.ui.text2d;
import java.awt.Font;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import org.openmali.vecmath2.Colorf;
import org.openmali.vecmath2.Point2f;
import org.openmali.vecmath2.Tuple2f;
import org.openmali.vecmath2.Vector3f;
import org.xith3d.scenegraph.Transform3D;
import org.xith3d.scenegraph.TransformGroup;
import org.xith3d.scenegraph.TransparencyAttributes;
/**
* Represents a line of text in 3D space.
* This class is part of the DynamicText toolkit for Xith3D.
*
* @see <a href="DText2D.html">org.xith3d.text.DText2D</a>
*
* @author Florian Hofmann (aka Goliat)
* @author Marvin Froehlich (aka Qudus)
*
* @version 2.0
*/
public class Line2D extends TransformGroup
{
private Font font;
private String charId;
private TextAlignment align;
private Colorf color = new Colorf();
private String text = "";
private Vector< Character2D > characters;
private List< Character2D > unmodCharacters;
private Tuple2f size;
private Vector3f tmpVec = new Vector3f();
private TransparencyAttributes cachedTA = null;
/**
* @return an unmodifiable List of all contained Characters
*/
public List< Character2D > getCharacters()
{
return ( unmodCharacters );
}
/**
* replaces the text of this line fast
*
* @param newText new text
*/
public void setText( String newText )
{
// remove chars if there are too much in the old string
while ( characters.size() > newText.length() )
{
final Character2D c = characters.remove( characters.size() - 1 );
this.removeChild( c.getParent() );
}
// create a new TransformGroup for every char and put a Character2D in it
TransformGroup tg;
Transform3D t3d;
Character2D currChar;
float offsetX = 0.0f;
characters.ensureCapacity( newText.length() );
for ( int i = 0; i < newText.length(); i++ )
{
// --- check if this char has to be ignored, replaced or created
// if the old text of this line less then i children -> create and add character
if ( characters.size() <= i )
{
// load character
if ( font == null )
currChar = Character2D.loadCharacter( newText.charAt( i ), color, charId );
else
currChar = Character2D.loadCharacter( newText.charAt( i ), color, font );
/*
if ( currChar == null )
{
if ( font == null )
currChar = Character2D.loadCharacter( '?', color, charId );
else
currChar = Character2D.loadCharacter( '?', color, font );
}
*/
if ( currChar != null )
{
// add this char to the list
characters.add( currChar );
tg = new TransformGroup();
tg.addChild( currChar );
this.addChild( tg );
}
}
// check if this character has to be replaced
else if ( characters.get( i ).getChar() != newText.charAt( i ) )
{
// load new character
currChar = Character2D.loadCharacter( newText.charAt( i ), color, charId );
int oldShapeIndex = characters.get( i ).getParent().indexOf( characters.get( i ) );
characters.get( i ).getParent().setChild( currChar, oldShapeIndex );
characters.set( i, currChar );
}
else
{
currChar = characters.get( i );
}
if ( currChar != null )
{
// set translation depending on position in String
tg = (TransformGroup)currChar.getParent();
t3d = tg.getTransform();
t3d.setTranslation( offsetX, 0, 0 );
tg.setTransform( t3d );
offsetX += currChar.getWidth();
}
}
// calculate size
if ( newText.length() == 0 )
{
size.set( 0f, 0f );
}
else
{
float width = 0f;
for ( int i = 0; i < characters.size(); i++ )
{
width += characters.get( i ).getSize().getX();
}
size.set( width, characters.get( 0 ).getSize().getY() );
}
// adjust translation by (horizontal) alignment
t3d = this.getTransform();
t3d.getTranslation( tmpVec );
if ( align.isHCenterAligned() )
{
tmpVec.setX( -( size.getX() / 2.0f ) );
}
else if ( align.isRightAligned() )
{
tmpVec.setX( -size.getX() );
}
t3d.setTranslation( tmpVec );
this.setTransform( t3d );
// all characters updated or created
this.text = newText;
}
public String getText()
{
return ( text );
}
public Character2D char2DAt( int index )
{
return ( characters.get( index ) );
}
public Tuple2f getSize()
{
return ( size );
}
public Font getFont()
{
return ( font );
}
protected String getCharId()
{
return ( charId );
}
public TextAlignment getAlign()
{
return ( align );
}
/**
* Sets the color of this text fast
*
* @param r new Color
* @param g new Color
* @param b new Color
*/
public void setColor( float r, float g, float b )
{
this.color.set( r, g, b );
for ( int i = 0; i < characters.size(); i++ )
{
characters.get( i ).setColor( color );
}
}
/**
* changes the color of this text fast
* @param color new Color
*/
public void setColor( Colorf color )
{
setColor( color.getRed(), color.getGreen(), color.getBlue() );
}
/**
* @return the Line's color (actually the color of the first character).
*/
public Colorf getColor()
{
return ( color );
}
protected void setTransparency( TransparencyAttributes ta )
{
this.cachedTA = ta;
for ( int i = 0; i < characters.size(); i++ )
{
characters.get( i ).getAppearance().setTransparencyAttributes( cachedTA );
}
}
public void setTransparency( float transparency )
{
if ( cachedTA != null )
{
cachedTA.setTransparency( transparency );
return;
}
cachedTA = new TransparencyAttributes( TransparencyAttributes.BLENDED, transparency );
setTransparency( cachedTA );
}
public float getTransparency()
{
if ( cachedTA == null )
return ( 0.0f );
return ( cachedTA.getTransparency() );
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return ( super.toString() + " [" + this.getText() + "]" );
}
/**
* Constructs a new Line2D with all parameters
*
* @param string the string to set
* @param r
* @param g
* @param b
* @param charId
* @param align
*/
protected Line2D( String string, float r, float g, float b, String charId, TextAlignment align )
{
super();
this.charId = charId;
this.align = align;
this.color.set( r, g, b );
this.size = new Point2f();
this.characters = new Vector< Character2D >( string.length() );
this.unmodCharacters = Collections.unmodifiableList( characters );
setText( string );
}
/**
* Constructs a new Line2D with all parameters
*
* @param string the string to set
* @param color
* @param charId
* @param align
*/
protected Line2D( String string, Colorf color, String charId, TextAlignment align )
{
this( string, color.getRed(), color.getGreen(), color.getBlue(), charId, align );
}
/**
* Constructs a new Line2D with all parameters
*
* @param string the string to set
* @param r
* @param g
* @param b
* @param font
* @param align
*/
public Line2D( String string, float r, float g, float b, Font font, TextAlignment align )
{
super();
this.charId = font.getName() + "-" + font.getSize() + "-" + font.getStyle();
this.font = font;
this.align = align;
this.color.set( r, g, b );
this.size = new Point2f();
this.characters = new Vector< Character2D >();
this.unmodCharacters = Collections.unmodifiableList( characters );
setText( string );
}
/**
* Constructs a new Line2D with all parameters
*
* @param string the string to set
* @param font
* @param color
* @param align
*/
public Line2D( String string, Colorf color, Font font, TextAlignment align )
{
this( string, color.getRed(), color.getGreen(), color.getBlue(), font, align );
}
}