FileDocCategorySizeDatePackage
EscherGraphics.javaAPI DocApache Poi 3.0.118567Mon Jun 04 19:20:22 BST 2007org.apache.poi.hssf.usermodel

EscherGraphics

public class EscherGraphics extends Graphics
Translates Graphics calls into escher calls. The translation is lossy so many features are not supported and some just aren't implemented yet. If in doubt test the specific calls you wish to make. Graphics calls are always performed into an EscherGroup so one will need to be created.

Important:

One important concept worth considering is that of font size. One of the difficulties in converting Graphics calls into escher drawing calls is that Excel does not have the concept of absolute pixel positions. It measures it's cell widths in 'characters' and the cell heights in points. Unfortunately it's not defined exactly what a type of character it's measuring. Presumably this is due to the fact that the Excel will be using different fonts on different platforms or even within the same platform.

Because of this constraint we've had to calculate the verticalPointsPerPixel. This the amount the font should be scaled by when you issue commands such as drawString(). A good way to calculate this is to use the follow formula:

multipler = groupHeightInPoints / heightOfGroup

The height of the group is calculated fairly simply by calculating the difference between the y coordinates of the bounding box of the shape. The height of the group can be calculated by using a convenience called HSSFClientAnchor.getAnchorHeightInPoints().

author
Glen Stampoultzis (glens at apache.org)

Fields Summary
private HSSFShapeGroup
escherGroup
private HSSFWorkbook
workbook
private float
verticalPointsPerPixel
private float
verticalPixelsPerPoint
private Color
foreground
private Color
background
private Font
font
private static POILogger
logger
Constructors Summary
public EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor, float verticalPointsPerPixel)
Construct an escher graphics object.

param
escherGroup The escher group to write the graphics calls into.
param
workbook The workbook we are using.
param
forecolor The foreground color to use as default.
param
verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).


                                                                                              
             
    
        this.escherGroup = escherGroup;
        this.workbook = workbook;
        this.verticalPointsPerPixel = verticalPointsPerPixel;
        this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
        this.font = new Font("Arial", 0, 10);
        this.foreground = forecolor;
//        background = backcolor;
    
EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color foreground, Font font, float verticalPointsPerPixel)
Constructs an escher graphics object.

param
escherGroup The escher group to write the graphics calls into.
param
workbook The workbook we are using.
param
foreground The foreground color to use as default.
param
verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).
param
font The font to use.

        this.escherGroup = escherGroup;
        this.workbook = workbook;
        this.foreground = foreground;
//        this.background = background;
        this.font = font;
        this.verticalPointsPerPixel = verticalPointsPerPixel;
        this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
    
Methods Summary
private int[]addToAll(int[] values, int amount)

        int[] result = new int[values.length];
        for ( int i = 0; i < values.length; i++ )
            result[i] = values[i] + amount;
        return result;
    
public voidclearRect(int x, int y, int width, int height)

        Color color = foreground;
        setColor(background);
        fillRect(x,y,width,height);
        setColor(color);
    
public voidclipRect(int x, int y, int width, int height)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"clipRect not supported");
    
public voidcopyArea(int x, int y, int width, int height, int dx, int dy)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"copyArea not supported");
    
public java.awt.Graphicscreate()

        EscherGraphics g = new EscherGraphics(escherGroup, workbook,
                foreground, font, verticalPointsPerPixel );
        return g;
    
public voiddispose()

    
public voiddrawArc(int x, int y, int width, int height, int startAngle, int arcAngle)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawArc not supported");
    
public booleandrawImage(java.awt.Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, java.awt.image.ImageObserver observer)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawImage not supported");
        return true;
    
public booleandrawImage(java.awt.Image image, int i, int j, int k, int l, java.awt.Color color, java.awt.image.ImageObserver imageobserver)

        return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
    
public booleandrawImage(java.awt.Image image, int i, int j, int k, int l, java.awt.image.ImageObserver imageobserver)

        return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
    
public booleandrawImage(java.awt.Image image, int i, int j, java.awt.Color color, java.awt.image.ImageObserver imageobserver)

        return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
    
public booleandrawImage(java.awt.Image image, int i, int j, java.awt.image.ImageObserver imageobserver)

        return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
    
public booleandrawImage(java.awt.Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, java.awt.Color bgcolor, java.awt.image.ImageObserver observer)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawImage not supported");

        return true;
    
public voiddrawLine(int x1, int y1, int x2, int y2)

        drawLine(x1,y1,x2,y2,0);
    
public voiddrawLine(int x1, int y1, int x2, int y2, int width)

        HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x1, y1, x2, y2) );
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
        shape.setLineWidth(width);
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
    
public voiddrawOval(int x, int y, int width, int height)

        HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x,y,x+width,y+height) );
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
        shape.setLineWidth(0);
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
        shape.setNoFill(true);
    
public voiddrawPolygon(int[] xPoints, int[] yPoints, int nPoints)

        int right  = findBiggest(xPoints);
        int bottom = findBiggest(yPoints);
        int left   = findSmallest(xPoints);
        int top    = findSmallest(yPoints);
        HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
        shape.setPolygonDrawArea(right - left, bottom - top);
        shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
        shape.setLineWidth(0);
        shape.setNoFill(true);
    
public voiddrawPolyline(int[] xPoints, int[] yPoints, int nPoints)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawPolyline not supported");
    
public voiddrawRect(int x, int y, int width, int height)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawRect not supported");
    
public voiddrawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawRoundRect not supported");
    
public voiddrawString(java.lang.String str, int x, int y)

        if (str == null || str.equals(""))
            return;

        Font excelFont = font;
        if ( font.getName().equals( "SansSerif" ) )
        {
            excelFont = new Font( "Arial", font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ) );
        }
        else
        {
            excelFont = new Font( font.getName(), font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ));
        }
        FontDetails d = StaticFontMetrics.getFontDetails( excelFont );
        int width = (int) ( (d.getStringWidth( str ) * 8)  + 12 );
        int height = (int) ( ( font.getSize() / verticalPixelsPerPoint ) + 6 ) * 2;
        y -= ( font.getSize() / verticalPixelsPerPoint ) + 2 * verticalPixelsPerPoint;    // we want to draw the shape from the top-left
        HSSFTextbox textbox = escherGroup.createTextbox( new HSSFChildAnchor( x, y, x + width, y + height ) );
        textbox.setNoFill( true );
        textbox.setLineStyle( HSSFShape.LINESTYLE_NONE );
        HSSFRichTextString s = new HSSFRichTextString( str );
        HSSFFont hssfFont = matchFont( excelFont );
        s.applyFont( hssfFont );
        textbox.setString( s );
    
public voiddrawString(java.text.AttributedCharacterIterator iterator, int x, int y)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"drawString not supported");
    
public voidfillArc(int x, int y, int width, int height, int startAngle, int arcAngle)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"fillArc not supported");
    
public voidfillOval(int x, int y, int width, int height)

        HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
        shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
        shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
    
public voidfillPolygon(int[] xPoints, int[] yPoints, int nPoints)
Fills a (closed) polygon, as defined by a pair of arrays, which hold the x and y coordinates.

This draws the polygon, with nPoint line segments. The first nPoint - 1 line segments are drawn between sequential points (xPoints[i],yPoints[i],xPoints[i+1],yPoints[i+1]). The final line segment is a closing one, from the last point to the first (assuming they are different).

The area inside of the polygon is defined by using an even-odd fill rule (also known as the alternating rule), and the area inside of it is filled.

param
xPoints array of the x coordinates.
param
yPoints array of the y coordinates.
param
nPoints the total number of points in the polygon.
see
java.awt.Graphics#drawPolygon(int[], int[], int)

        int right  = findBiggest(xPoints);
        int bottom = findBiggest(yPoints);
        int left   = findSmallest(xPoints);
        int top    = findSmallest(yPoints);
        HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
        shape.setPolygonDrawArea(right - left, bottom - top);
        shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
        shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
    
public voidfillRect(int x, int y, int width, int height)

        HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
        shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
        shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
        shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
    
public voidfillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"fillRoundRect not supported");
    
private intfindBiggest(int[] values)

        int result = Integer.MIN_VALUE;
        for ( int i = 0; i < values.length; i++ )
        {
            if (values[i] > result)
                result = values[i];
        }
        return result;
    
private intfindSmallest(int[] values)

        int result = Integer.MAX_VALUE;
        for ( int i = 0; i < values.length; i++ )
        {
            if (values[i] < result)
                result = values[i];
        }
        return result;
    
public java.awt.ColorgetBackground()

        return background;
    
public java.awt.ShapegetClip()

        return getClipBounds();
    
public java.awt.RectanglegetClipBounds()

        return null;
    
public java.awt.RectanglegetClipRect()

        return getClipBounds();
    
public java.awt.ColorgetColor()

        return foreground;
    
org.apache.poi.hssf.usermodel.HSSFShapeGroupgetEscherGraphics()

        return escherGroup;
    
public java.awt.FontgetFont()

        return font;
    
public java.awt.FontMetricsgetFontMetrics(java.awt.Font f)

        return Toolkit.getDefaultToolkit().getFontMetrics(f);
    
private org.apache.poi.hssf.usermodel.HSSFFontmatchFont(java.awt.Font font)

        HSSFColor hssfColor = workbook.getCustomPalette()
                .findColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
        if (hssfColor == null)
            hssfColor = workbook.getCustomPalette().findSimilarColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
        boolean bold = (font.getStyle() & Font.BOLD) != 0;
        boolean italic = (font.getStyle() & Font.ITALIC) != 0;
        HSSFFont hssfFont = workbook.findFont(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0,
                    hssfColor.getIndex(),
                    (short)(font.getSize() * 20),
                    font.getName(),
                    italic,
                    false,
                    (short)0,
                    (byte)0);
        if (hssfFont == null)
        {
            hssfFont = workbook.createFont();
            hssfFont.setBoldweight(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0);
            hssfFont.setColor(hssfColor.getIndex());
            hssfFont.setFontHeight((short)(font.getSize() * 20));
            hssfFont.setFontName(font.getName());
            hssfFont.setItalic(italic);
            hssfFont.setStrikeout(false);
            hssfFont.setTypeOffset((short) 0);
            hssfFont.setUnderline((byte) 0);
        }

        return hssfFont;
    
public voidsetBackground(java.awt.Color background)

        this.background = background;
    
public voidsetClip(int x, int y, int width, int height)

        setClip(((Shape) (new Rectangle(x,y,width,height))));
    
public voidsetClip(java.awt.Shape shape)

        // ignore... not implemented
    
public voidsetColor(java.awt.Color color)

        foreground = color;
    
public voidsetFont(java.awt.Font f)

        font = f;
    
public voidsetPaintMode()

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"setPaintMode not supported");
    
public voidsetXORMode(java.awt.Color color)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"setXORMode not supported");
    
public voidtranslate(int x, int y)

        if (logger.check( POILogger.WARN ))
            logger.log(POILogger.WARN,"translate not supported");