/components/forks/poi/src/loci/poi/hssf/usermodel/EscherGraphics.java
Java | 530 lines | 349 code | 59 blank | 122 comment | 29 complexity | 90bc5f20331e7dcb9050bcbf7dd0d9c3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
- /*
- * #%L
- * Fork of Apache Jakarta POI.
- * %%
- * Copyright (C) 2008 - 2013 Open Microscopy Environment:
- * - Board of Regents of the University of Wisconsin-Madison
- * - Glencoe Software, Inc.
- * - University of Dundee
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
- package loci.poi.hssf.usermodel;
- import loci.poi.hssf.util.HSSFColor;
- import loci.poi.util.POILogFactory;
- import loci.poi.util.POILogger;
- import java.awt.*;
- import java.awt.image.ImageObserver;
- import java.text.AttributedCharacterIterator;
- /**
- * 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.
- * <p>
- * <b>Important:</b>
- * <blockquote>
- * 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.
- * <p>
- * 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:
- * <p>
- * <pre>
- * multipler = groupHeightInPoints / heightOfGroup
- * </pre>
- * <p>
- * 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
- * <code>HSSFClientAnchor.getAnchorHeightInPoints()</code>.
- * </blockquote>
- *
- * @author Glen Stampoultzis (glens at apache.org)
- */
- public class EscherGraphics
- extends Graphics
- {
- private HSSFShapeGroup escherGroup;
- private HSSFWorkbook workbook;
- private float verticalPointsPerPixel = 1.0f;
- private float verticalPixelsPerPoint;
- private Color foreground;
- private Color background = Color.white;
- private Font font;
- private static POILogger logger = POILogFactory.getLogger(EscherGraphics.class);
- /**
- * 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.).
- */
- public EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor, float verticalPointsPerPixel )
- {
- 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;
- }
- /**
- * 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.
- */
- EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color foreground, Font font, float verticalPointsPerPixel )
- {
- this.escherGroup = escherGroup;
- this.workbook = workbook;
- this.foreground = foreground;
- // this.background = background;
- this.font = font;
- this.verticalPointsPerPixel = verticalPointsPerPixel;
- this.verticalPixelsPerPoint = 1 / 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 forecolor The default foreground color.
- // */
- // public EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor)
- // {
- // this(escherGroup, workbook, forecolor, 1.0f);
- // }
- public void clearRect(int x, int y, int width, int height)
- {
- Color color = foreground;
- setColor(background);
- fillRect(x,y,width,height);
- setColor(color);
- }
- public void clipRect(int x, int y, int width, int height)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"clipRect not supported");
- }
- public void copyArea(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 Graphics create()
- {
- EscherGraphics g = new EscherGraphics(escherGroup, workbook,
- foreground, font, verticalPointsPerPixel );
- return g;
- }
- public void dispose()
- {
- }
- public void drawArc(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 boolean drawImage(Image img,
- int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- Color bgcolor,
- ImageObserver observer)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"drawImage not supported");
- return true;
- }
- public boolean drawImage(Image img,
- int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- ImageObserver observer)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"drawImage not supported");
- return true;
- }
- public boolean drawImage(Image image, int i, int j, int k, int l, Color color, ImageObserver imageobserver)
- {
- return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
- }
- public boolean drawImage(Image image, int i, int j, int k, int l, ImageObserver imageobserver)
- {
- return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
- }
- public boolean drawImage(Image image, int i, int j, Color color, ImageObserver imageobserver)
- {
- return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
- }
- public boolean drawImage(Image image, int i, int j, ImageObserver imageobserver)
- {
- return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
- }
- public void drawLine(int x1, int y1, int x2, int y2)
- {
- drawLine(x1,y1,x2,y2,0);
- }
- public void drawLine(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 void drawOval(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 void drawPolygon(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);
- }
- 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 void drawPolyline(int xPoints[], int yPoints[],
- int nPoints)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"drawPolyline not supported");
- }
- public void drawRect(int x, int y, int width, int height)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"drawRect not supported");
- }
- public void drawRoundRect(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 void drawString(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 );
- }
- private HSSFFont matchFont( 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 void drawString(AttributedCharacterIterator iterator,
- int x, int y)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"drawString not supported");
- }
- public void fillArc(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 void fillOval(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());
- }
- /**
- * Fills a (closed) polygon, as defined by a pair of arrays, which
- * hold the <i>x</i> and <i>y</i> coordinates.
- * <p>
- * This draws the polygon, with <code>nPoint</code> line segments.
- * The first <code>nPoint - 1</code> line segments are
- * drawn between sequential points
- * (<code>xPoints[i],yPoints[i],xPoints[i+1],yPoints[i+1]</code>).
- * The final line segment is a closing one, from the last point to
- * the first (assuming they are different).
- * <p>
- * 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 <code>x</code> coordinates.
- * @param yPoints array of the <code>y</code> coordinates.
- * @param nPoints the total number of points in the polygon.
- * @see java.awt.Graphics#drawPolygon(int[], int[], int)
- */
- public void fillPolygon(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.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
- }
- private int findBiggest( 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 int findSmallest( 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 void fillRect(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 void fillRoundRect(int x, int y, int width, int height,
- int arcWidth, int arcHeight)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"fillRoundRect not supported");
- }
- public Shape getClip()
- {
- return getClipBounds();
- }
- public Rectangle getClipBounds()
- {
- return null;
- }
- public Rectangle getClipRect()
- {
- return getClipBounds();
- }
- public Color getColor()
- {
- return foreground;
- }
- public Font getFont()
- {
- return font;
- }
- public FontMetrics getFontMetrics(Font f)
- {
- return Toolkit.getDefaultToolkit().getFontMetrics(f);
- }
- public void setClip(int x, int y, int width, int height)
- {
- setClip(((Shape) (new Rectangle(x,y,width,height))));
- }
- public void setClip(Shape shape)
- {
- // ignore... not implemented
- }
- public void setColor(Color color)
- {
- foreground = color;
- }
- public void setFont(Font f)
- {
- font = f;
- }
- public void setPaintMode()
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"setPaintMode not supported");
- }
- public void setXORMode(Color color)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"setXORMode not supported");
- }
- public void translate(int x, int y)
- {
- if (logger.check( POILogger.WARN ))
- logger.log(POILogger.WARN,"translate not supported");
- }
- public Color getBackground()
- {
- return background;
- }
- public void setBackground( Color background )
- {
- this.background = background;
- }
- HSSFShapeGroup getEscherGraphics()
- {
- return escherGroup;
- }
- }