org.eclipse.birt.chart.device.svg.SVGGraphics2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.birt.runtime Show documentation
Show all versions of org.eclipse.birt.runtime Show documentation
A component of the BIRT runtime
/***********************************************************************
* Copyright (c) 2005, 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
***********************************************************************/
package org.eclipse.birt.chart.device.svg;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.ByteArrayOutputStream;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.birt.chart.device.ImageWriterFactory;
import org.eclipse.birt.chart.device.svg.i18n.Messages;
import org.eclipse.birt.chart.device.util.ChartGraphics2D;
import org.eclipse.birt.chart.log.ILogger;
import org.eclipse.birt.chart.log.Logger;
import org.eclipse.birt.chart.util.SecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* This class provides the graphic context to draw primitive svg drawing
* elements such as lines, rectangles, polygons, etc.
*/
public class SVGGraphics2D extends ChartGraphics2D
{
protected Document dom;
protected Paint paint;
protected Color color;
protected Font font;
protected Shape clip;
protected Stroke stroke;
protected Color background;
protected Element currentElement;
protected Stack parentStack = new Stack( );
protected Element currentParent;
protected FontRenderContext fontRenderContext;
protected AffineTransform transforms;
protected List paints = new ArrayList( );
protected Set textures = new HashSet( );
protected Element definitions;
protected Element styles;
protected Element codeScript;
protected String styleClass;
protected String id;
protected StringBuffer scriptBuffer = new StringBuffer( );
protected StringBuffer styleBuffer = new StringBuffer( );
protected Element deferStrokColor = null;
protected String primitiveId = null;
private RenderingHints renderingHints = new RenderingHints( null );
protected boolean scriptable = true;
protected static final String defaultStyles = "fill:none;stroke:none"; //$NON-NLS-1$
// Unicode Bidi Control char
protected static final char chRLE = '\u202b'; // RIGHT-TO-LEFT EMBEDDING
protected static final char chPDF = '\u202c'; // POP DIRECTIONAL FORMATTING
// Style of text to support bidi
protected static final String sStyleBidi = "direction:rtl; unicode-bidi:embed; "; //$NON-NLS-1$
private static ILogger logger = Logger.getLogger( "org.eclipse.birt.chart.device.svg/trace" ); //$NON-NLS-1$
public SVGGraphics2D( Document dom )
{
this( dom, true );
}
public SVGGraphics2D( Document dom, boolean scriptable )
{
this.dom = dom;
this.scriptable = scriptable;
fontRenderContext = new FontRenderContext( new AffineTransform( ),
true,
false );
currentElement = dom.getDocumentElement( );
parentStack.push( currentElement );
currentParent = currentElement;
// add default styles
currentElement = dom.createElement( "g" ); //$NON-NLS-1$
definitions = dom.createElement( "defs" ); //$NON-NLS-1$
// give the outer group element an ID
currentElement.setAttribute( "id", "outerG" ); //$NON-NLS-1$ //$NON-NLS-2$
currentElement.appendChild( definitions );
currentElement.setAttribute( "style", defaultStyles ); //$NON-NLS-1$
pushParent( currentElement );
transforms = new AffineTransform( );
initializeScriptStyles( );
}
public void pushParent( Element parent )
{
appendChild( parent );
parentStack.push( parent );
currentParent = parent;
}
public Element popParent( )
{
Element popElement = null;
if ( !parentStack.isEmpty( ) )
popElement = parentStack.pop( );
if ( !parentStack.isEmpty( ) )
currentParent = parentStack.peek( );
return popElement;
}
protected void appendChild( Element child )
{
currentParent.appendChild( child );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#draw(java.awt.Shape)
*/
public void draw( Shape shape )
{
currentElement = createGeneralPath( shape );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#drawImage(java.awt.Image,
* java.awt.geom.AffineTransform, java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, AffineTransform arg1,
ImageObserver arg2 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawImage.image" ) ) ); //$NON-NLS-1$
return false;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#drawImage(java.awt.image.BufferedImage,
* java.awt.image.BufferedImageOp, int, int)
*/
public void drawImage( BufferedImage arg0, BufferedImageOp arg1, int arg2,
int arg3 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawImage.buffer" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#drawRenderedImage(java.awt.image.RenderedImage,
* java.awt.geom.AffineTransform)
*/
public void drawRenderedImage( RenderedImage arg0, AffineTransform arg1 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawRenderImage.RenderImage" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @seejava.awt.Graphics2D#drawRenderableImage(java.awt.image.renderable.
* RenderableImage, java.awt.geom.AffineTransform)
*/
public void drawRenderableImage( RenderableImage arg0, AffineTransform arg1 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawRenderableImage.RenderableImage" ) ) ); //$NON-NLS-1$
}
private void drawString( String arg0, String sX, String sY )
{
currentElement = this.createText( arg0 );
currentElement.setAttribute( "x", sX ); //$NON-NLS-1$
currentElement.setAttribute( "y", sY ); //$NON-NLS-1$
appendChild( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawString(java.lang.String, int, int)
*/
public void drawString( String arg0, int arg1, int arg2 )
{
drawString( arg0, Integer.toString( arg1 ), Integer.toString( arg2 ) );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#drawString(java.lang.String, float, float)
*/
public void drawString( String arg0, float arg1, float arg2 )
{
drawString( arg0, toString( arg1 ), toString( arg2 ) );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawString(java.text.AttributedCharacterIterator,
* int, int)
*/
public void drawString( AttributedCharacterIterator arg0, int arg1, int arg2 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawString.AttributeInt" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator,
* float, float)
*/
public void drawString( AttributedCharacterIterator arg0, float arg1,
float arg2 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.drawString.AttributeFloat" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#drawGlyphVector(java.awt.font.GlyphVector,
* float, float)
*/
public void drawGlyphVector( GlyphVector glyph, float x, float y )
{
translate( x, y );
Element currentElement = dom.createElement( "g" );//$NON-NLS-1$
Element transElement = createElement( "g" ); //$NON-NLS-1$
currentElement.appendChild( transElement );
// need to defer clipping for each glyph
setFillColor( transElement, true );
for ( int idx = 0; idx < glyph.getNumGlyphs( ); idx++ )
{
Element glyphElem = createShape( glyph.getGlyphOutline( idx ) );
transElement.appendChild( glyphElem );
}
// should add clipping to the group element that is not transformed
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
translate( -x, -y );
}
public void fill( Shape shape, boolean defered )
{
Element tempDeferred = null;
if ( !defered )
{
tempDeferred = deferStrokColor;
deferStrokColor = null;
}
currentElement = createGeneralPath( shape );
appendChild( currentElement );
setFillColor( currentElement );
if ( !defered )
{
deferStrokColor = tempDeferred;
}
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#fill(java.awt.Shape)
*/
public void fill( Shape shape )
{
currentElement = createGeneralPath( shape );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#hit(java.awt.Rectangle, java.awt.Shape, boolean)
*/
public boolean hit( Rectangle arg0, Shape arg1, boolean arg2 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.hit.Rectangle" ) ) ); //$NON-NLS-1$
return false;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getDeviceConfiguration()
*/
public GraphicsConfiguration getDeviceConfiguration( )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.getDeviceConfig" ) ) ); //$NON-NLS-1$
return null;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#setComposite(java.awt.Composite)
*/
public void setComposite( Composite arg0 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.setComposite" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#setRenderingHint(java.awt.RenderingHints.Key,
* java.lang.Object)
*/
public void setRenderingHint( Key arg0, Object arg1 )
{
renderingHints.put( arg0, arg1 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getRenderingHint(java.awt.RenderingHints.Key)
*/
public Object getRenderingHint( Key arg0 )
{
return renderingHints.get( arg0 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#setRenderingHints(java.util.Map)
*/
public void setRenderingHints( Map arg0 )
{
renderingHints = new RenderingHints( arg0 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#addRenderingHints(java.util.Map)
*/
public void addRenderingHints( Map arg0 )
{
renderingHints.add( new RenderingHints( arg0 ) );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getRenderingHints()
*/
public RenderingHints getRenderingHints( )
{
return renderingHints;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#translate(int, int)
*/
public void translate( int arg0, int arg1 )
{
String transform = currentElement.getAttribute( "transform" ); //$NON-NLS-1$
if ( transform == null )
transform = ""; //$NON-NLS-1$
currentElement.setAttribute( "transform", transform + " translate(" + arg0 + " " + arg1 + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#translate(double, double)
*/
public void translate( double arg0, double arg1 )
{
transforms.translate( arg0, arg1 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#rotate(double)
*/
public void rotate( double arg0 )
{
transforms.rotate( arg0 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#rotate(double, double, double)
*/
public void rotate( double arg0, double arg1, double arg2 )
{
transforms.rotate( arg0, arg1, arg2 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#scale(double, double)
*/
public void scale( double arg0, double arg1 )
{
transforms.scale( arg0, arg1 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#shear(double, double)
*/
public void shear( double arg0, double arg1 )
{
transforms.shear( arg0, arg1 );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#transform(java.awt.geom.AffineTransform)
*/
public void transform( AffineTransform arg0 )
{
transforms.concatenate( (AffineTransform) arg0.clone( ) );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#setTransform(java.awt.geom.AffineTransform)
*/
public void setTransform( AffineTransform transform )
{
this.transforms = transform;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getTransform()
*/
public AffineTransform getTransform( )
{
return transforms;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getPaint()
*/
public Paint getPaint( )
{
return paint;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getComposite()
*/
public Composite getComposite( )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.getComposite" ) ) ); //$NON-NLS-1$
return null;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#clip(java.awt.Shape)
*/
public void clip( Shape shape )
{
setClip( shape );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics2D#getFontRenderContext()
*/
public FontRenderContext getFontRenderContext( )
{
return fontRenderContext;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#create()
*/
public Graphics create( )
{
return new SVGGraphics2D( dom );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#setPaintMode()
*/
public void setPaintMode( )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.setPaintMode" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#setXORMode(java.awt.Color)
*/
public void setXORMode( Color xorColor )
{
if ( ( color == null ) || ( xorColor == null ) )
return;
int newColor = ( ( xorColor.getRed( ) << 16 )
+ ( xorColor.getGreen( ) << 8 ) + xorColor.getBlue( ) )
^ ( ( color.getRed( ) << 16 ) + ( color.getGreen( ) << 8 ) + color.getBlue( ) );
int r = newColor >> 16 & 0x0000FF;
int g = ( 0x00FF00 & newColor ) >> 8;
int b = 0x0000FF & newColor;
color = new Color( r, g, b );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#getFontMetrics(java.awt.Font)
*/
public FontMetrics getFontMetrics( Font arg0 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.getFontMetrics.Font" ) ) ); //$NON-NLS-1$
return null;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#getClipBounds()
*/
public Rectangle getClipBounds( )
{
return clip.getBounds( );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#clipRect(int, int, int, int)
*/
public void clipRect( int arg0, int arg1, int arg2, int arg3 )
{
Rectangle2D.Double rect = new Rectangle2D.Double( arg0,
arg1,
arg2,
arg3 );
setClip( rect );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#setClip(int, int, int, int)
*/
public void setClip( int arg0, int arg1, int arg2, int arg3 )
{
Rectangle2D.Double rect = new Rectangle2D.Double( arg0,
arg1,
arg2,
arg3 );
setClip( rect );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#copyArea(int, int, int, int, int, int)
*/
public void copyArea( int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.CopyArea.Int" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawLine(int, int, int, int)
*/
public void drawLine( int arg0, int arg1, int arg2, int arg3 )
{
drawLine( (double) arg0, (double) arg1, (double) arg2, (double) arg3 );
}
public void drawLine( double arg0, double arg1, double arg2, double arg3 )
{
currentElement = createLine( arg0, arg1, arg2, arg3 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawRect(int, int, int, int)
*/
public void drawRect( int arg0, int arg1, int arg2, int arg3 )
{
drawRect( (double) arg0, (double) arg1, (double) arg2, (double) arg3 );
}
public void drawRect( double arg0, double arg1, double arg2, double arg3 )
{
currentElement = createRect( arg0, arg1, arg2, arg3 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#fillRect(int, int, int, int)
*/
public void fillRect( int arg0, int arg1, int arg2, int arg3 )
{
fillRect( (double) arg0, (double) arg1, (double) arg2, (double) arg3 );
}
public void fillRect( double arg0, double arg1, double arg2, double arg3 )
{
currentElement = createRect( arg0, arg1, arg2, arg3 );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#clearRect(int, int, int, int)
*/
public void clearRect( int arg0, int arg1, int arg2, int arg3 )
{
logger.log( new Exception( Messages.getString( "SVGGraphics2D.clearRect.Int" ) ) ); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawRoundRect(int, int, int, int, int, int)
*/
public void drawRoundRect( int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5 )
{
currentElement = createRoundRect( arg0, arg1, arg2, arg3, arg4, arg5 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#fillRoundRect(int, int, int, int, int, int)
*/
public void fillRoundRect( int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5 )
{
currentElement = createRoundRect( arg0, arg1, arg2, arg3, arg4, arg5 );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawOval(int, int, int, int)
*/
public void drawOval( int arg0, int arg1, int arg2, int arg3 )
{
drawOval( (double) arg0, (double) arg1, (double) arg2, (double) arg3 );
}
public void drawOval( double arg0, double arg1, double arg2, double arg3 )
{
currentElement = createOval( arg0, arg1, arg2, arg3 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#fillOval(int, int, int, int)
*/
public void fillOval( int arg0, int arg1, int arg2, int arg3 )
{
fillOval( (double) arg0, (double) arg1, (double) arg2, (double) arg3 );
}
public void fillOval( double arg0, double arg1, double arg2, double arg3 )
{
currentElement = createOval( arg0, arg1, arg2, arg3 );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawArc(int, int, int, int, int, int)
*/
public void drawArc( int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5 )
{
drawArc( (double) arg0,
(double) arg1,
(double) arg2,
(double) arg3,
(double) arg4,
(double) arg5 );
}
public void drawArc( double arg0, double arg1, double arg2, double arg3,
double arg4, double arg5 )
{
currentElement = createArc( arg0, arg1, arg2, arg3, arg4, arg5 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
protected void setStrokeStyle( Element currentElement )
{
setStrokeStyle( currentElement, false );
}
/**
* Adds stroke color and style information to the element passed in.
*
* @param currentElement
* the element to add style information to.
* @param isClipped
* boolean that determines whether to defer the clipping of the
* element
*/
protected void setStrokeStyle( Element currentElement, boolean deferClipped )
{
Element element = currentElement;
if ( deferStrokColor != null )
{
// Need to get the parent element.
element = deferStrokColor;
}
String style = element.getAttribute( "style" ); //$NON-NLS-1$
if ( style == null )
style = ""; //$NON-NLS-1$
if ( color != null )
{
style += "stroke:" + serializeToString( color ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
if ( ( stroke != null ) && ( stroke instanceof BasicStroke ) )
{
BasicStroke bs = (BasicStroke) stroke;
if ( bs.getLineWidth( ) > 0 )
style += "stroke-width:" + bs.getLineWidth( ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
if ( bs.getDashArray( ) != null )
{
StringBuffer dashArrayStr = new StringBuffer( );
for ( int x = 0; x < bs.getDashArray( ).length; x++ )
{
dashArrayStr.append( " " ).append( bs.getDashArray( )[x] ); //$NON-NLS-1$
}
if ( !( dashArrayStr.toString( ).equals( "" ) ) ) //$NON-NLS-1$
style += "stroke-dasharray:" + dashArrayStr + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
style += "stroke-miterlimit:" + bs.getMiterLimit( ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
switch ( bs.getLineJoin( ) )
{
case BasicStroke.JOIN_BEVEL :
style += "stroke-linejoin:bevel;"; //$NON-NLS-1$
break;
case BasicStroke.JOIN_ROUND :
style += "stroke-linejoin:round;"; //$NON-NLS-1$
break;
}
switch ( bs.getEndCap( ) )
{
case BasicStroke.CAP_ROUND :
style += "stroke-linecap:round;"; //$NON-NLS-1$
break;
case BasicStroke.CAP_SQUARE :
style += "stroke-linecap:square;"; //$NON-NLS-1$
break;
}
}
element.setAttribute( "style", style ); //$NON-NLS-1$
if ( styleClass != null )
element.setAttribute( "class", styleClass ); //$NON-NLS-1$
if ( id != null )
element.setAttribute( "id", id ); //$NON-NLS-1$
if ( ( clip != null ) && ( !deferClipped ) )
element.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
protected void setFillColor( Element currentElement )
{
setFillColor( currentElement, false );
}
/**
* Adds no fill color and style information to the element passed in.
*
* @param currentElement
* the element to add style information to.
*/
protected void setNoFillColor( Element currentElement )
{
// should set the fill color to none on the currentElement
String style = currentElement.getAttribute( "style" ); //$NON-NLS-1$
if ( style == null )
style = ""; //$NON-NLS-1$
currentElement.setAttribute( "style", style + "fill:none;" ); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Adds fill color and style information to the element passed in.
*
* @param currentElement
* the element to add style information to.
* @param isClipped
* boolean that determines whether to defer the clipping of the
* element
*/
protected void setFillColor( Element currentElement, boolean deferClipped )
{
Element element = currentElement;
if ( deferStrokColor != null )
{
// Need to get the parent element.
element = deferStrokColor;
}
String style = element.getAttribute( "style" ); //$NON-NLS-1$
if ( style == null )
style = ""; //$NON-NLS-1$
if ( paint == null )
{
if ( color == null )
return;
String alpha = alphaToString( color );
if ( alpha != null )
style += "fill-opacity:" + alpha + ";"; //$NON-NLS-1$ //$NON-NLS-2$
element.setAttribute( "style", style + "fill:" + serializeToString( color ) + ";stroke:none;" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
else if ( paint instanceof SVGGradientPaint )
{
element.setAttribute( "style", style + "fill:url(#" + ( (SVGGradientPaint) paint ).getId( ) + ");stroke:none;fill-opacity:1.0" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
else if ( paint instanceof TexturePaint )
{
element.setAttribute( "style", style + "fill:url(#" + getTextureId( (TexturePaint) paint ) + ");stroke:none;fill-opacity:1.0" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
if ( styleClass != null )
element.setAttribute( "class", styleClass ); //$NON-NLS-1$
if ( id != null )
element.setAttribute( "id", id ); //$NON-NLS-1$
if ( ( clip != null ) && ( !deferClipped ) )
element.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* @returns the color definition in a string with the format: #RRGGBBAA:
* RRGGBB are the color components in hexa in the range 00..FF AA
* is the transparency value in hexa in the range 00..FF ex: Solid
* light gray : #777777
*/
protected String serializeToString( Color color )
{
String r = Integer.toHexString( color.getRed( ) );
if ( color.getRed( ) <= 0xF )
r = "0" + r; //$NON-NLS-1$
String g = Integer.toHexString( color.getGreen( ) );
if ( color.getGreen( ) <= 0xF )
g = "0" + g; //$NON-NLS-1$
String b = Integer.toHexString( color.getBlue( ) );
if ( color.getBlue( ) <= 0xF )
b = "0" + b; //$NON-NLS-1$
String ret = "#" + r + g + b; //$NON-NLS-1$
return ret;
}
protected String alphaToString( Color color )
{
double a = 1;
if ( color.getAlpha( ) < 0xFF )
{
a = color.getAlpha( ) / 255.0;
}
return toString( a );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#fillArc(int, int, int, int, int, int)
*/
public void fillArc( int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5 )
{
fillArc( (double) arg0,
(double) arg1,
(double) arg2,
(double) arg3,
(double) arg4,
(double) arg5 );
}
public void fillArc( double arg0, double arg1, double arg2, double arg3,
double arg4, double arg5 )
{
currentElement = createArc( arg0, arg1, arg2, arg3, arg4, arg5 );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawPolyline(int[], int[], int)
*/
public void drawPolyline( int[] arg0, int[] arg1, int arg2 )
{
currentElement = createPolyline( arg0, arg1, arg2 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
*/
public void drawPolygon( int[] arg0, int[] arg1, int arg2 )
{
currentElement = createPolygon( arg0, arg1, arg2 );
appendChild( currentElement );
setStrokeStyle( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#fillPolygon(int[], int[], int)
*/
public void fillPolygon( int[] arg0, int[] arg1, int arg2 )
{
currentElement = createPolygon( arg0, arg1, arg2 );
appendChild( currentElement );
setFillColor( currentElement );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int,
* java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, ImageObserver arg3 )
{
SVGImage image = (SVGImage) arg0;
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "xlink:href", image.getUrl( ) ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", Integer.toString( arg0.getWidth( arg3 ) ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", Integer.toString( arg0.getHeight( arg3 ) ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int,
* java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, int arg3,
int arg4, ImageObserver arg5 )
{
SVGImage image = (SVGImage) arg0;
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "xlink:href", image.getUrl( ) ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", toString( arg3 ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", toString( arg4 ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int,
* java.awt.Color, java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, Color arg3,
ImageObserver arg4 )
{
SVGImage image = (SVGImage) arg0;
image.getUrl( );
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", Integer.toString( arg0.getWidth( arg4 ) ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", Integer.toString( arg0.getHeight( arg4 ) ) ); //$NON-NLS-1$
currentElement.setAttribute( "fill", serializeToString( arg3 ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int,
* java.awt.Color, java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, int arg3,
int arg4, Color arg5, ImageObserver arg6 )
{
SVGImage image = (SVGImage) arg0;
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "xlink:href", image.getUrl( ) ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", toString( arg3 ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", toString( arg4 ) ); //$NON-NLS-1$
currentElement.setAttribute( "fill", serializeToString( arg5 ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int, int,
* int, int, int, java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8, ImageObserver arg9 )
{
SVGImage image = (SVGImage) arg0;
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "xlink:href", image.getUrl( ) ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", toString( arg3 ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", toString( arg4 ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int, int,
* int, int, int, java.awt.Color, java.awt.image.ImageObserver)
*/
public boolean drawImage( Image arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8, Color arg9,
ImageObserver arg10 )
{
SVGImage image = (SVGImage) arg0;
Element currentElement = createElement( "image" ); //$NON-NLS-1$
currentElement.setAttribute( "xlink:href", image.getUrl( ) ); //$NON-NLS-1$
currentElement.setAttribute( "x", toString( arg1 ) ); //$NON-NLS-1$
currentElement.setAttribute( "y", toString( arg2 ) ); //$NON-NLS-1$
currentElement.setAttribute( "width", toString( arg3 ) ); //$NON-NLS-1$
currentElement.setAttribute( "height", toString( arg4 ) ); //$NON-NLS-1$
currentElement.setAttribute( "fill", serializeToString( arg9 ) ); //$NON-NLS-1$
if ( clip != null )
currentElement.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
appendChild( currentElement );
return true;
}
/**
* Unload any resources associated with the graphic context
*/
public void flush( )
{
// Use a temporary buffer to ensure the original string immutable
StringBuffer buffer = new StringBuffer( EventHandlers.getJSMenuLib( ) );
codeScript.appendChild( dom.createCDATASection( buffer.append( scriptBuffer )
.toString( ) ) );
buffer = new StringBuffer( EventHandlers.STYLES.toString( ) );
styles.appendChild( dom.createCDATASection( buffer.append( styleBuffer )
.toString( ) ) );
// clear buffer
scriptBuffer = new StringBuffer( );
styleBuffer = new StringBuffer( );
}
/*
* (non-Javadoc)
*
* @see java.awt.Graphics#dispose()
*/
@Override
public void dispose( )
{
paints.clear( );
textures.clear( );
}
/**
* @return Returns the background.
*/
public Color getBackground( )
{
return background;
}
/**
* @param backgroundColor
* The backgroundColor to set.
*/
public void setBackground( Color background )
{
this.background = background;
}
/**
* @return Returns the clip.
*/
public Shape getClip( )
{
return clip;
}
/**
* @param clip
* The clip to set.
*/
public void setClip( Shape clip )
{
this.clip = clip;
if ( clip != null )
{
Element clipPath = dom.createElement( "clipPath" ); //$NON-NLS-1$
clipPath.setAttribute( "id", "clip" + clip.hashCode( ) ); //$NON-NLS-1$ //$NON-NLS-2$
clipPath.appendChild( createGeneralPath( clip ) );
definitions.appendChild( clipPath );
}
}
/**
* @return Returns the color.
*/
public Color getColor( )
{
return color;
}
/**
* @param color
* The color to set.
*/
public void setColor( Color color )
{
this.color = color;
this.paint = null;
}
/**
* @return Returns the font.
*/
public Font getFont( )
{
return font;
}
/**
* @param font
* The font to set.
*/
public void setFont( Font font )
{
this.font = font;
}
/**
* @return Returns the stroke.
*/
public Stroke getStroke( )
{
return stroke;
}
/**
* @param stroke
* The stroke to set.
*/
@Override
public void setStroke( Stroke stroke )
{
this.stroke = stroke;
}
private Element createEmbeddeImage(BufferedImage img)
{
if (img==null)
{
return null;
}
int width = img.getWidth( );
int height = img.getHeight( );
ImageWriter iw = ImageWriterFactory.instance( )
.createByFormatName( "png" ); //$NON-NLS-1$
ByteArrayOutputStream baos = new ByteArrayOutputStream( 8192*2 );
String sUrl = null;
try
{
final ImageOutputStream ios = SecurityUtil.newImageOutputStream( baos );
ImageWriteParam iwp = iw.getDefaultWriteParam( );
iw.setOutput( ios );
iw.write( (IIOMetadata) null, new IIOImage( img, null, null ), iwp );
img.flush( );
ios.close( );
sUrl = SVGImage.BASE64
+ new String( Base64.encodeBase64( baos.toByteArray( ) ) );
}
catch ( Exception ex )
{
logger.log( ex );
}
finally
{
iw.dispose( );
}
Element elemG = dom.createElement( "g" ); //$NON-NLS-1$
elemG.setAttribute( "id", "img_" + img.hashCode( ) ); //$NON-NLS-1$//$NON-NLS-2$
Element elem = dom.createElement( "image" ); //$NON-NLS-1$
elem.setAttribute( "x", "0" ); //$NON-NLS-1$//$NON-NLS-2$
elem.setAttribute( "y", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
elem.setAttribute( "width", Integer.toString( width ) ); //$NON-NLS-1$
elem.setAttribute( "height", Integer.toString( height ) ); //$NON-NLS-1$
elem.setAttribute( "xlink:href", sUrl ); //$NON-NLS-1$
elemG.appendChild( elem );
return elemG;
}
/**
* @param paint
* The paint to set.
*/
@Override
public void setPaint( Paint paint )
{
if ( paint instanceof GradientPaint )
{
SVGGradientPaint gp = new SVGGradientPaint( (GradientPaint) paint );
int index = paints.indexOf( gp );
if ( index == -1 )
{
paints.add( gp );
definitions.appendChild( createGradientPaint( gp, false ) );
definitions.appendChild( createGradientPaint( gp, true ) );
}
else
{
gp = paints.get( index );
}
this.paint = gp;
}
else if ( paint instanceof TexturePaint )
{
TexturePaint tp = (TexturePaint) paint;
if ( !textures.contains( tp ) )
{
textures.add( tp );
Element elemImg = createEmbeddeImage( tp.getImage( ) );
if ( elemImg != null )
{
definitions.appendChild( elemImg );
String imgId = elemImg.getAttribute( "id" ); //$NON-NLS-1$
definitions.appendChild( createTexturePaint( tp,
imgId,
false ) );
definitions.appendChild( createTexturePaint( tp,
imgId,
true ) );
}
}
this.paint = tp;
}
else
this.paint = paint;
}
/***************************************************************************
* Factory Methods
**************************************************************************/
protected Element createGradientPaint( SVGGradientPaint paint,
boolean highlight )
{
Element elem = dom.createElement( "linearGradient" ); //$NON-NLS-1$
if ( highlight )
elem.setAttribute( "id", paint.getId( ) + "h" ); //$NON-NLS-1$ //$NON-NLS-2$
else
elem.setAttribute( "id", paint.getId( ) ); //$NON-NLS-1$
elem.setAttribute( "x1", toString( paint.getPoint1( ).getX( ) ) ); //$NON-NLS-1$
elem.setAttribute( "y1", toString( paint.getPoint1( ).getY( ) ) ); //$NON-NLS-1$
elem.setAttribute( "x2", toString( paint.getPoint2( ).getX( ) ) ); //$NON-NLS-1$
elem.setAttribute( "y2", toString( paint.getPoint2( ).getY( ) ) ); //$NON-NLS-1$
elem.setAttribute( "gradientUnits", "userSpaceOnUse" ); //$NON-NLS-1$ //$NON-NLS-2$
if ( paint.isCyclic( ) )
elem.setAttribute( "spreadMethod", "repeat" ); //$NON-NLS-1$ //$NON-NLS-2$
Element startColor = dom.createElement( "stop" ); //$NON-NLS-1$
startColor.setAttribute( "offset", "0%" ); //$NON-NLS-1$ //$NON-NLS-2$
if ( highlight )
{
startColor.setAttribute( "stop-color", serializeHighlightToString( paint.getColor1( ) ) ); //$NON-NLS-1$
}
else
{
startColor.setAttribute( "stop-color", serializeToString( paint.getColor1( ) ) ); //$NON-NLS-1$
}
String alpha = alphaToString( paint.getColor1( ) );
if ( alpha != null )
startColor.setAttribute( "stop-opacity", alpha ); //$NON-NLS-1$
elem.appendChild( startColor );
Element endColor = dom.createElement( "stop" ); //$NON-NLS-1$
endColor.setAttribute( "offset", "100%" ); //$NON-NLS-1$ //$NON-NLS-2$
if ( highlight )
endColor.setAttribute( "stop-color", serializeHighlightToString( paint.getColor2( ) ) ); //$NON-NLS-1$
else
endColor.setAttribute( "stop-color", serializeToString( paint.getColor2( ) ) ); //$NON-NLS-1$
alpha = alphaToString( paint.getColor2( ) );
if ( alpha != null )
endColor.setAttribute( "stop-opacity", alpha ); //$NON-NLS-1$
elem.appendChild( endColor );
return elem;
}
private String getTextureId( TexturePaint paint )
{
return "tp" + paint.hashCode( ); //$NON-NLS-1$
}
protected Element createTexturePaint( TexturePaint paint, String imgId,
boolean highlight )
{
Element elem = dom.createElement( "pattern" ); //$NON-NLS-1$
if ( highlight )
elem.setAttribute( "id", getTextureId( paint ) + "h" ); //$NON-NLS-1$ //$NON-NLS-2$
else
elem.setAttribute( "id", getTextureId( paint ) ); //$NON-NLS-1$
BufferedImage img = paint.getImage( );
int width = img.getWidth( );
int height = img.getHeight( );
elem.setAttribute( "patternUnits", "userSpaceOnUse" ); //$NON-NLS-1$//$NON-NLS-2$
elem.setAttribute( "width", Integer.toString( width ) ); //$NON-NLS-1$
elem.setAttribute( "height", Integer.toString( height ) ); //$NON-NLS-1$
Element elemUse = dom.createElement( "use" ); //$NON-NLS-1$
elemUse.setAttribute( "x", "0" ); //$NON-NLS-1$//$NON-NLS-2$
elemUse.setAttribute( "y", "0" ); //$NON-NLS-1$//$NON-NLS-2$
elemUse.setAttribute( "xlink:href", "#" + imgId ); //$NON-NLS-1$//$NON-NLS-2$
elem.appendChild( elemUse );
return elem;
}
private String serializeHighlightToString( Color cd )
{
if ( cd != null )
{
int red = ( cd.getRed( ) + 255 ) / 2;
int green = ( cd.getGreen( ) + 255 ) / 2;
int blue = ( cd.getBlue( ) + 255 ) / 2;
String r = Integer.toHexString( red );
if ( red <= 0xF )
r = "0" + r; //$NON-NLS-1$
String g = Integer.toHexString( green );
if ( green <= 0xF )
g = "0" + g; //$NON-NLS-1$
String b = Integer.toHexString( blue );
if ( blue <= 0xF )
b = "0" + b; //$NON-NLS-1$
return "#" + r + g + b; //$NON-NLS-1$
}
return ""; //$NON-NLS-1$
}
protected Element createLine( double arg0, double arg1, double arg2,
double arg3 )
{
Element elem = createElement( "line" ); //$NON-NLS-1$
elem.setAttribute( "x1", toString( arg0 ) ); //$NON-NLS-1$
elem.setAttribute( "y1", toString( arg1 ) ); //$NON-NLS-1$
elem.setAttribute( "x2", toString( arg2 ) ); //$NON-NLS-1$
elem.setAttribute( "y2", toString( arg3 ) ); //$NON-NLS-1$
return elem;
}
protected Element createShape( Shape shape )
{
PathIterator pathIter = shape.getPathIterator( null );
StringBuffer pathStr = new StringBuffer( );
while ( !pathIter.isDone( ) )
{
double[] points = new double[6];
int TYPE = pathIter.currentSegment( points );
switch ( TYPE )
{
case PathIterator.SEG_CLOSE :
pathStr.append( " Z" ); //$NON-NLS-1$
break;
case PathIterator.SEG_LINETO :
pathStr.append( " L" ).append( toString( points, 2, ' ' ) ); //$NON-NLS-1$
break;
case PathIterator.SEG_QUADTO :
pathStr.append( " Q" ).append( toString( points, 4, ' ' ) ); //$NON-NLS-1$
break;
case PathIterator.SEG_CUBICTO :
pathStr.append( " C" ).append( toString( points, 6, ' ' ) ); //$NON-NLS-1$
break;
case PathIterator.SEG_MOVETO :
pathStr.append( " M" ).append( toString( points, 2, ' ' ) ); //$NON-NLS-1$
break;
}
pathIter.next( );
}
Element elem = dom.createElement( "path" ); //$NON-NLS-1$
elem.setAttribute( "d", pathStr.toString( ) ); //$NON-NLS-1$
return elem;
}
protected Element createGeneralPath( Shape path )
{
Element elem = createShape( path );
if ( transforms.getType( ) != AffineTransform.TYPE_IDENTITY )
{
double[] matrix = new double[6];
transforms.getMatrix( matrix );
elem.setAttribute( "transform", "matrix(" + toString( matrix, ',' ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return elem;
}
protected Element createText( String text )
{
// #232718 to support bidi
boolean bRtl = false;
if ( text.length( ) > 0 )
{
int iEnd = text.length( );
if ( chPDF == text.charAt( text.length( ) - 1 ) )
{
iEnd--;
}
if ( chRLE == text.charAt( 0 ) )
{
bRtl = true;
text = text.substring( 1, iEnd );
}
}
Element elem = dom.createElement( "text" ); //$NON-NLS-1$
elem.appendChild( dom.createTextNode( text ) );
switch ( getFont( ).getStyle( ) )
{
case Font.BOLD :
elem.setAttribute( "font-weight", "bold" ); //$NON-NLS-1$ //$NON-NLS-2$
break;
case Font.ITALIC :
elem.setAttribute( "font-style", "italic" ); //$NON-NLS-1$ //$NON-NLS-2$
break;
case ( Font.BOLD + Font.ITALIC ) :
elem.setAttribute( "font-style", "italic" ); //$NON-NLS-1$ //$NON-NLS-2$
elem.setAttribute( "font-weight", "bold" ); //$NON-NLS-1$ //$NON-NLS-2$
break;
}
String textDecorator = null;
Map attributes = getFont( ).getAttributes( );
if ( attributes.get( TextAttribute.UNDERLINE ) == TextAttribute.UNDERLINE_ON )
{
textDecorator = "underline"; //$NON-NLS-1$
}
if ( attributes.get( TextAttribute.STRIKETHROUGH ) == TextAttribute.STRIKETHROUGH_ON )
{
if ( textDecorator == null )
textDecorator = "line-through"; //$NON-NLS-1$
else
textDecorator += ",line-through"; //$NON-NLS-1$
}
if ( textDecorator != null )
elem.setAttribute( "text-decoration", textDecorator ); //$NON-NLS-1$
// for now just preserve space for text elements Bug 182159
elem.setAttribute( "xml:space", "preserve" ); //$NON-NLS-1$ //$NON-NLS-2$
elem.setAttribute( "stroke", "none" ); //$NON-NLS-1$ //$NON-NLS-2$
// Here we still use Font.getName() as font-family for SVG instead of
// Font.getFaimly(), since if current code is running on linux and there
// isn't a valid font family to fit the font setting in chart model,
// the call of Font.getFamily() will get a default 'Dialog' font family,
// it will caused that the svg in client system can't correct display
// mulitple-characters text(Chinese, Jpanese and so on).
// We just need to set the original font family setting of chart model
// into svg document, if the font family is valid in client system
// and can support current text character, it will correct display.
elem.setAttribute( "font-family", getFont( ).getName( ) ); //$NON-NLS-1$
elem.setAttribute( "font-size", Integer.toString( getFont( ).getSize( ) ) ); //$NON-NLS-1$
String style = getRenderingStyle( RenderingHints.KEY_TEXT_ANTIALIASING );
if ( color != null )
{
String alpha = alphaToString( color );
if ( alpha != null )
style += "fill-opacity:" + alpha + ";"; //$NON-NLS-1$ //$NON-NLS-2$
style += "fill:" + serializeToString( color ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
if ( bRtl )
{
style += sStyleBidi;
}
elem.setAttribute( "style", style ); //$NON-NLS-1$
if ( transforms.getType( ) != AffineTransform.TYPE_IDENTITY )
{
double[] matrix = new double[6];
transforms.getMatrix( matrix );
elem.setAttribute( "transform", "matrix(" + toString( matrix, ',' ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return elem;
}
protected String getRenderingStyle( Object key )
{
Object value = renderingHints.get( key );
if ( key.equals( RenderingHints.KEY_TEXT_ANTIALIASING ) )
{
if ( value.equals( RenderingHints.VALUE_TEXT_ANTIALIAS_OFF ) )
{
// Adobe SVG viewer 3 bug. Rotated text with optimizelegibility
// disappears. Replace
// with optimizespeed for rotated text.
if ( transforms.getType( ) != AffineTransform.TYPE_IDENTITY )
return "text-rendering:optimizeSpeed;";//$NON-NLS-1$
else
return "text-rendering:optimizeLegibility;";//$NON-NLS-1$
}
else
// SVG always turns on antialias
return ""; //$NON-NLS-1$
}
return "";//$NON-NLS-1$
}
protected Element createRect( double arg0, double arg1, double arg2,
double arg3 )
{
Element elem = createElement( "rect" ); //$NON-NLS-1$
elem.setAttribute( "x", toString( arg0 ) ); //$NON-NLS-1$
elem.setAttribute( "y", toString( arg1 ) ); //$NON-NLS-1$
elem.setAttribute( "width", toString( arg2 ) ); //$NON-NLS-1$
elem.setAttribute( "height", toString( arg3 ) ); //$NON-NLS-1$
return elem;
}
protected Element createRoundRect( double arg0, double arg1, double arg2,
double arg3, double arg4, double arg5 )
{
Element elem = createElement( "rect" ); //$NON-NLS-1$
elem.setAttribute( "x", toString( arg0 ) ); //$NON-NLS-1$
elem.setAttribute( "y", toString( arg1 ) ); //$NON-NLS-1$
elem.setAttribute( "width", toString( arg2 ) ); //$NON-NLS-1$
elem.setAttribute( "height", toString( arg3 ) ); //$NON-NLS-1$
elem.setAttribute( "rx", toString( arg2 ) ); //$NON-NLS-1$
elem.setAttribute( "ry", toString( arg3 ) ); //$NON-NLS-1$
return elem;
}
protected Element createOval( double arg0, double arg1, double arg2,
double arg3 )
{
Element elem = createElement( "ellipse" ); //$NON-NLS-1$
elem.setAttribute( "cx", toString( arg0 ) ); //$NON-NLS-1$
elem.setAttribute( "cy", toString( arg1 ) ); //$NON-NLS-1$
elem.setAttribute( "rx", toString( arg2 ) ); //$NON-NLS-1$
elem.setAttribute( "ry", toString( arg3 ) ); //$NON-NLS-1$
return elem;
}
protected Element createArc( double x, double y, double width,
double height, double startAngle, double arcAngle )
{
Element elem = createElement( "path" ); //$NON-NLS-1$
double startX = x * Math.cos( startAngle );
double startY = y * Math.sin( startAngle );
double endX = x * Math.cos( startAngle + arcAngle );
double endY = y * Math.sin( startAngle + arcAngle );
int sweepFlag = ( arcAngle < 0 ) ? 0 : 1;
elem.setAttribute( "d", "M" + toString( startX ) + "," + toString( startY ) + " a" + toString( width / 2 ) + "," + toString( height / 2 ) + " " + toString( Math.abs( arcAngle ) ) + " 0 " + sweepFlag + " " + toString( endX ) + " " + toString( endY ) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
return elem;
}
public Element createPolyline( int[] arg0, int[] arg1, int arg2 )
{
Element elem = createElement( "polyline" ); //$NON-NLS-1$
StringBuffer pointsStr = new StringBuffer( );;
for ( int x = 0; x < arg2; x++ )
{
pointsStr.append( arg0[x] )
.append( "," ).append( arg1[x] ).append( " " ); //$NON-NLS-1$ //$NON-NLS-2$
}
elem.setAttribute( "points", pointsStr.toString( ) ); //$NON-NLS-1$
return elem;
}
public Element createPolygon( int[] arg0, int[] arg1, int arg2 )
{
Element elem = createElement( "polygon" ); //$NON-NLS-1$
StringBuffer pointsStr = new StringBuffer( );;
for ( int x = 0; x < arg2; x++ )
{
pointsStr.append( arg0[x] )
.append( "," ).append( arg1[x] ).append( " " ); //$NON-NLS-1$ //$NON-NLS-2$
}
elem.setAttribute( "points", pointsStr.toString( ) ); //$NON-NLS-1$
return elem;
}
public Element createPolygon( double[] arg0, double[] arg1, int arg2 )
{
Element elem = createElement( "polygon" ); //$NON-NLS-1$
StringBuffer pointsStr = new StringBuffer( );;
for ( int x = 0; x < arg2; x++ )
{
pointsStr.append( arg0[x] )
.append( "," ).append( arg1[x] ).append( " " ); //$NON-NLS-1$ //$NON-NLS-2$
}
elem.setAttribute( "points", pointsStr.toString( ) ); //$NON-NLS-1$
return elem;
}
protected void initializeScriptStyles( )
{
codeScript = dom.createElement( "script" ); //$NON-NLS-1$
if ( scriptable )
appendChild( codeScript );
styles = dom.createElement( "style" ); //$NON-NLS-1$
styles.setAttribute( "type", "text/css" ); //$NON-NLS-1$ //$NON-NLS-2$
appendChild( styles );
}
protected Element createElement( String id )
{
Element elem = dom.createElement( id );
if ( this.primitiveId != null )
elem.setAttribute( "id", primitiveId ); //$NON-NLS-1$
if ( transforms.getType( ) != AffineTransform.TYPE_IDENTITY )
{
double[] matrix = new double[6];
transforms.getMatrix( matrix );
elem.setAttribute( "transform", "matrix(" + toString( matrix, ',' ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return elem;
}
public void drawTooltip( String tooltip )
{
Element title = dom.createElement( "title" ); //$NON-NLS-1$
title.appendChild( dom.createTextNode( tooltip ) );
appendChild( title );
currentParent.setAttribute( "onmouseout", "TM.remove()" ); //$NON-NLS-1$ //$NON-NLS-2$
currentParent.setAttribute( "onmouseover", "TM.show(evt)" ); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @return Returns the currentParent.
*/
public Element getCurrentParent( )
{
return currentParent;
}
/**
* @return Returns the currentElement.
*/
public Element getCurrentElement( )
{
return currentElement;
}
public String getStyleClass( )
{
return styleClass;
}
public void setStyleClass( String styleClass )
{
this.styleClass = styleClass;
}
public void addCSSStyle( String className, String styleName,
String styleValue )
{
styleBuffer.append( className )
.append( "{" ).append( styleName ).append( ":" ).append( styleValue ).append( ";}" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Inlines the script code in the generated svg output
*
* @param script
* the code that will be inlined in the generated svg output
*/
public void addScript( String script )
{
scriptBuffer.append( script );
}
/**
* Adds a script reference in the generated svg output.
*
* @param ref
* the script reference that will be added to the generated svg
* output.
*/
public void addScriptRef( String ref )
{
Element rootElem = dom.getDocumentElement( );
Element scriptElem = dom.createElement( "script" ); //$NON-NLS-1$
if ( scriptable )
rootElem.appendChild( scriptElem );
scriptElem.setAttribute( "language", "JavaScript" ); //$NON-NLS-1$ //$NON-NLS-2$
scriptElem.setAttribute( "xlink:href", ref ); //$NON-NLS-1$
}
public String getId( )
{
return id;
}
public void setId( String id )
{
this.id = id;
}
/**
* Defer setting the stroke and color on an SVG element.
*
* @return the state of the flag that ignores setting the stroke style and
* color on a svg element.
*/
public Element getDeferStrokColor( )
{
return deferStrokColor;
}
/**
* Defer setting the stroke and color on an SVG element.
*
* @param deferStrokColor
* set to true if the stroke style and color should be ignored
* when drawing the svg element.
*/
public void setDeferStrokColor( Element deferStrokColor )
{
this.deferStrokColor = deferStrokColor;
}
/**
* Returns the current id that is used to identify a svg drawing primitive
*
* @return id
*/
public String getPrimitiveId( )
{
return primitiveId;
}
/**
* Sets the current primitive id
*
* @param primitiveId
*/
public void setPrimitiveId( String primitiveId )
{
this.primitiveId = primitiveId;
}
/**
* Returns whether the generated output should contain javascript code.
*
* @return true if the generated output should contain javascript code,
* false otherwise
*/
public boolean isScriptable( )
{
return scriptable;
}
/**
* Sets the flag to determine if the output should contain javascript code
*
* @param scriptable
*/
public void setScriptable( boolean scriptable )
{
this.scriptable = scriptable;
}
static String toString( double v )
{
if ( Double.isNaN( v ) )
{
return "0"; //$NON-NLS-1$
}
return String.valueOf( v );
}
static String toString( float v )
{
if ( Float.isNaN( v ) )
{
return "0"; //$NON-NLS-1$
}
return String.valueOf( v );
}
static String toString( double[] v, char separator )
{
return toString( v, v.length, separator );
}
static String toString( double[] v, int length, char separator )
{
if ( v.length == 0 )
{
return ""; //$NON-NLS-1$
}
if ( v.length == 1 )
{
return toString( v[0] );
}
if ( length > v.length )
{
length = v.length;
}
StringBuffer buffer = new StringBuffer( toString( v[0] ) );
for ( int i = 1; i < length; i++ )
{
buffer.append( separator );
buffer.append( toString( v[i] ) );
}
return buffer.toString( );
}
}