Added: poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java?rev=1711171&view=auto ============================================================================== --- poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java (added) +++ poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java Thu Oct 29 01:05:27 2015 @@ -0,0 +1,1831 @@ +/* ==================================================================== + 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 org.apache.poi.sl.draw; + + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.RoundRectangle2D; +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.text.AttributedCharacterIterator; +import java.util.Map; + +import org.apache.poi.sl.usermodel.FreeformShape; +import org.apache.poi.sl.usermodel.GroupShape; +import org.apache.poi.sl.usermodel.Insets2D; +import org.apache.poi.sl.usermodel.SimpleShape; +import org.apache.poi.sl.usermodel.StrokeStyle; +import org.apache.poi.sl.usermodel.TextBox; +import org.apache.poi.sl.usermodel.TextRun; +import org.apache.poi.sl.usermodel.VerticalAlignment; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.SuppressForbidden; + +/** + * Translates Graphics2D calls into PowerPoint. + * + * @author Yegor Kozlov + */ +public final class SLGraphics extends Graphics2D implements Cloneable { + + protected POILogger log = POILogFactory.getLogger(this.getClass()); + + //The ppt object to write into. + private GroupShape<?,?> _group; + + private AffineTransform _transform; + private Stroke _stroke; + private Paint _paint; + private Font _font; + private Color _foreground; + private Color _background; + private RenderingHints _hints; + + /** + * Construct Java Graphics object which translates graphic calls in ppt drawing layer. + * + * @param group The shape group to write the graphics calls into. + */ + public SLGraphics(GroupShape<?,?> group){ + this._group = group; + + _transform = new AffineTransform(); + _stroke = new BasicStroke(); + _paint = Color.black; + _font = new Font("Arial", Font.PLAIN, 12); + _background = Color.black; + _foreground = Color.white; + _hints = new RenderingHints(null); + } + + /** + * @return the shape group being used for drawing + */ + public GroupShape<?,?> getShapeGroup(){ + return _group; + } + + /** + * Gets the current font. + * @return this graphics context's current font. + * @see java.awt.Font + * @see java.awt.Graphics#setFont(Font) + */ + public Font getFont(){ + return _font; + } + + /** + * Sets this graphics context's font to the specified font. + * All subsequent text operations using this graphics context + * use this font. + * @param font the font. + * @see java.awt.Graphics#getFont + * @see java.awt.Graphics#drawString(java.lang.String, int, int) + * @see java.awt.Graphics#drawBytes(byte[], int, int, int, int) + * @see java.awt.Graphics#drawChars(char[], int, int, int, int) + */ + public void setFont(Font font){ + this._font = font; + } + + /** + * Gets this graphics context's current color. + * @return this graphics context's current color. + * @see java.awt.Color + * @see java.awt.Graphics#setColor + */ + public Color getColor(){ + return _foreground; + } + + /** + * Sets this graphics context's current color to the specified + * color. All subsequent graphics operations using this graphics + * context use this specified color. + * @param c the new rendering color. + * @see java.awt.Color + * @see java.awt.Graphics#getColor + */ + public void setColor(Color c) { + setPaint(c); + } + + /** + * Returns the current <code>Stroke</code> in the + * <code>Graphics2D</code> context. + * @return the current <code>Graphics2D</code> <code>Stroke</code>, + * which defines the line style. + * @see #setStroke + */ + public Stroke getStroke(){ + return _stroke; + } + + /** + * Sets the <code>Stroke</code> for the <code>Graphics2D</code> context. + * @param s the <code>Stroke</code> object to be used to stroke a + * <code>Shape</code> during the rendering process + */ + public void setStroke(Stroke s){ + this._stroke = s; + } + + /** + * Returns the current <code>Paint</code> of the + * <code>Graphics2D</code> context. + * @return the current <code>Graphics2D</code> <code>Paint</code>, + * which defines a color or pattern. + * @see #setPaint + * @see java.awt.Graphics#setColor + */ + public Paint getPaint(){ + return _paint; + } + + /** + * Sets the <code>Paint</code> attribute for the + * <code>Graphics2D</code> context. Calling this method + * with a <code>null</code> <code>Paint</code> object does + * not have any effect on the current <code>Paint</code> attribute + * of this <code>Graphics2D</code>. + * @param paint the <code>Paint</code> object to be used to generate + * color during the rendering process, or <code>null</code> + * @see java.awt.Graphics#setColor + */ + public void setPaint(Paint paint){ + if(paint == null) return; + + this._paint = paint; + if (paint instanceof Color) _foreground = (Color)paint; + } + + /** + * Returns a copy of the current <code>Transform</code> in the + * <code>Graphics2D</code> context. + * @return the current <code>AffineTransform</code> in the + * <code>Graphics2D</code> context. + * @see #_transform + * @see #setTransform + */ + public AffineTransform getTransform(){ + return new AffineTransform(_transform); + } + + /** + * Sets the <code>Transform</code> in the <code>Graphics2D</code> + * context. + * @param Tx the <code>AffineTransform</code> object to be used in the + * rendering process + * @see #_transform + * @see AffineTransform + */ + public void setTransform(AffineTransform Tx) { + _transform = new AffineTransform(Tx); + } + + /** + * Strokes the outline of a <code>Shape</code> using the settings of the + * current <code>Graphics2D</code> context. The rendering attributes + * applied include the <code>Clip</code>, <code>Transform</code>, + * <code>Paint</code>, <code>Composite</code> and + * <code>Stroke</code> attributes. + * @param shape the <code>Shape</code> to be rendered + * @see #setStroke + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #_transform + * @see #setTransform + * @see #clip + * @see #setClip + * @see #setComposite + */ + public void draw(Shape shape){ + GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape)); + FreeformShape<?,?> p = _group.createFreeform(); + p.setPath(path); + p.setFillColor(null); + applyStroke(p); + if (_paint instanceof Color) { + p.setStrokeStyle((Color)_paint); + } + } + + /** + * Renders the text specified by the specified <code>String</code>, + * using the current text attribute state in the <code>Graphics2D</code> context. + * The baseline of the first character is at position + * (<i>x</i>, <i>y</i>) in the User Space. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and + * <code>Composite</code> attributes. For characters in script systems + * such as Hebrew and Arabic, the glyphs can be rendered from right to + * left, in which case the coordinate supplied is the location of the + * leftmost character on the baseline. + * @param s the <code>String</code> to be rendered + * @param x the x coordinate of the location where the + * <code>String</code> should be rendered + * @param y the y coordinate of the location where the + * <code>String</code> should be rendered + * @throws NullPointerException if <code>str</code> is + * <code>null</code> + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see java.awt.Graphics#setFont + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(String s, float x, float y) { + TextBox<?,?> txt = _group.createTextBox(); + + TextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0); + rt.setFontSize((double)_font.getSize()); + rt.setFontFamily(_font.getFamily()); + + if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor())); + if (_font.isBold()) rt.setBold(true); + if (_font.isItalic()) rt.setItalic(true); + + txt.setText(s); + + txt.setInsets(new Insets2D(0,0,0,0)); + txt.setWordWrap(false); + txt.setHorizontalCentered(false); + txt.setVerticalAlignment(VerticalAlignment.MIDDLE); + + + TextLayout layout = new TextLayout(s, _font, getFontRenderContext()); + float ascent = layout.getAscent(); + + float width = (float) Math.floor(layout.getAdvance()); + /** + * Even if top and bottom margins are set to 0 PowerPoint + * always sets extra space between the text and its bounding box. + * + * The approximation height = ascent*2 works good enough in most cases + */ + float height = ascent * 2; + + /* + In powerpoint anchor of a shape is its top left corner. + Java graphics sets string coordinates by the baseline of the first character + so we need to shift up by the height of the textbox + */ + y -= height / 2 + ascent / 2; + + /* + In powerpoint anchor of a shape is its top left corner. + Java graphics sets string coordinates by the baseline of the first character + so we need to shift down by the height of the textbox + */ + txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height)); + } + + /** + * Fills the interior of a <code>Shape</code> using the settings of the + * <code>Graphics2D</code> context. The rendering attributes applied + * include the <code>Clip</code>, <code>Transform</code>, + * <code>Paint</code>, and <code>Composite</code>. + * @param shape the <code>Shape</code> to be filled + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #_transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void fill(Shape shape){ + GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape)); + FreeformShape<?,?> p = _group.createFreeform(); + p.setPath(path); + applyPaint(p); + p.setStrokeStyle(); //Fills must be "No Line" + } + + /** + * Translates the origin of the graphics context to the point + * (<i>x</i>, <i>y</i>) in the current coordinate system. + * Modifies this graphics context so that its new origin corresponds + * to the point (<i>x</i>, <i>y</i>) in this graphics context's + * original coordinate system. All coordinates used in subsequent + * rendering operations on this graphics context will be relative + * to this new origin. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + */ + public void translate(int x, int y){ + _transform.translate(x, y); + } + + /** + * Intersects the current <code>Clip</code> with the interior of the + * specified <code>Shape</code> and sets the <code>Clip</code> to the + * resulting intersection. The specified <code>Shape</code> is + * transformed with the current <code>Graphics2D</code> + * <code>Transform</code> before being intersected with the current + * <code>Clip</code>. This method is used to make the current + * <code>Clip</code> smaller. + * To make the <code>Clip</code> larger, use <code>setClip</code>. + * The <i>user clip</i> modified by this method is independent of the + * clipping associated with device bounds and visibility. If no clip has + * previously been set, or if the clip has been cleared using + * {@link java.awt.Graphics#setClip(Shape) setClip} with a + * <code>null</code> argument, the specified <code>Shape</code> becomes + * the new user clip. + * @param s the <code>Shape</code> to be intersected with the current + * <code>Clip</code>. If <code>s</code> is <code>null</code>, + * this method clears the current <code>Clip</code>. + */ + public void clip(Shape s){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Gets the current clipping area. + * This method returns the user clip, which is independent of the + * clipping associated with device bounds and window visibility. + * If no clip has previously been set, or if the clip has been + * cleared using <code>setClip(null)</code>, this method returns + * <code>null</code>. + * @return a <code>Shape</code> object representing the + * current clipping area, or <code>null</code> if + * no clip is set. + * @see java.awt.Graphics#getClipBounds() + * @see java.awt.Graphics#clipRect + * @see java.awt.Graphics#setClip(int, int, int, int) + * @see java.awt.Graphics#setClip(Shape) + * @since JDK1.1 + */ + public Shape getClip(){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return null; + } + + /** + * Concatenates the current <code>Graphics2D</code> + * <code>Transform</code> with a scaling transformation + * Subsequent rendering is resized according to the specified scaling + * factors relative to the previous scaling. + * This is equivalent to calling <code>transform(S)</code>, where S is an + * <code>AffineTransform</code> represented by the following matrix: + * <pre> + * [ sx 0 0 ] + * [ 0 sy 0 ] + * [ 0 0 1 ] + * </pre> + * @param sx the amount by which X coordinates in subsequent + * rendering operations are multiplied relative to previous + * rendering operations. + * @param sy the amount by which Y coordinates in subsequent + * rendering operations are multiplied relative to previous + * rendering operations. + */ + public void scale(double sx, double sy){ + _transform.scale(sx, sy); + } + + /** + * Draws an outlined round-cornered rectangle using this graphics + * context's current color. The left and right edges of the rectangle + * are at <code>x</code> and <code>x + width</code>, + * respectively. The top and bottom edges of the rectangle are at + * <code>y</code> and <code>y + height</code>. + * @param x the <i>x</i> coordinate of the rectangle to be drawn. + * @param y the <i>y</i> coordinate of the rectangle to be drawn. + * @param width the width of the rectangle to be drawn. + * @param height the height of the rectangle to be drawn. + * @param arcWidth the horizontal diameter of the arc + * at the four corners. + * @param arcHeight the vertical diameter of the arc + * at the four corners. + * @see java.awt.Graphics#fillRoundRect + */ + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight){ + RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); + draw(rect); + } + + /** + * Draws the text given by the specified string, using this + * graphics context's current font and color. The baseline of the + * first character is at position (<i>x</i>, <i>y</i>) in this + * graphics context's coordinate system. + * @param str the string to be drawn. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @see java.awt.Graphics#drawBytes + * @see java.awt.Graphics#drawChars + */ + public void drawString(String str, int x, int y){ + drawString(str, (float)x, (float)y); + } + + /** + * Fills an oval bounded by the specified rectangle with the + * current color. + * @param x the <i>x</i> coordinate of the upper left corner + * of the oval to be filled. + * @param y the <i>y</i> coordinate of the upper left corner + * of the oval to be filled. + * @param width the width of the oval to be filled. + * @param height the height of the oval to be filled. + * @see java.awt.Graphics#drawOval + */ + public void fillOval(int x, int y, int width, int height){ + Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); + fill(oval); + } + + /** + * Fills the specified rounded corner rectangle with the current color. + * The left and right edges of the rectangle + * are at <code>x</code> and <code>x + width - 1</code>, + * respectively. The top and bottom edges of the rectangle are at + * <code>y</code> and <code>y + height - 1</code>. + * @param x the <i>x</i> coordinate of the rectangle to be filled. + * @param y the <i>y</i> coordinate of the rectangle to be filled. + * @param width the width of the rectangle to be filled. + * @param height the height of the rectangle to be filled. + * @param arcWidth the horizontal diameter + * of the arc at the four corners. + * @param arcHeight the vertical diameter + * of the arc at the four corners. + * @see java.awt.Graphics#drawRoundRect + */ + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight){ + + RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); + fill(rect); + } + + /** + * Fills a circular or elliptical arc covering the specified rectangle. + * <p> + * The resulting arc begins at <code>startAngle</code> and extends + * for <code>arcAngle</code> degrees. + * Angles are interpreted such that 0 degrees + * is at the 3 o'clock position. + * A positive value indicates a counter-clockwise rotation + * while a negative value indicates a clockwise rotation. + * <p> + * The center of the arc is the center of the rectangle whose origin + * is (<i>x</i>, <i>y</i>) and whose size is specified by the + * <code>width</code> and <code>height</code> arguments. + * <p> + * The resulting arc covers an area + * <code>width + 1</code> pixels wide + * by <code>height + 1</code> pixels tall. + * <p> + * The angles are specified relative to the non-square extents of + * the bounding rectangle such that 45 degrees always falls on the + * line from the center of the ellipse to the upper right corner of + * the bounding rectangle. As a result, if the bounding rectangle is + * noticeably longer in one axis than the other, the angles to the + * start and end of the arc segment will be skewed farther along the + * longer axis of the bounds. + * @param x the <i>x</i> coordinate of the + * upper-left corner of the arc to be filled. + * @param y the <i>y</i> coordinate of the + * upper-left corner of the arc to be filled. + * @param width the width of the arc to be filled. + * @param height the height of the arc to be filled. + * @param startAngle the beginning angle. + * @param arcAngle the angular extent of the arc, + * relative to the start angle. + * @see java.awt.Graphics#drawArc + */ + public void fillArc(int x, int y, int width, int height, + int startAngle, int arcAngle){ + Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE); + fill(arc); + } + + /** + * Draws the outline of a circular or elliptical arc + * covering the specified rectangle. + * <p> + * The resulting arc begins at <code>startAngle</code> and extends + * for <code>arcAngle</code> degrees, using the current color. + * Angles are interpreted such that 0 degrees + * is at the 3 o'clock position. + * A positive value indicates a counter-clockwise rotation + * while a negative value indicates a clockwise rotation. + * <p> + * The center of the arc is the center of the rectangle whose origin + * is (<i>x</i>, <i>y</i>) and whose size is specified by the + * <code>width</code> and <code>height</code> arguments. + * <p> + * The resulting arc covers an area + * <code>width + 1</code> pixels wide + * by <code>height + 1</code> pixels tall. + * <p> + * The angles are specified relative to the non-square extents of + * the bounding rectangle such that 45 degrees always falls on the + * line from the center of the ellipse to the upper right corner of + * the bounding rectangle. As a result, if the bounding rectangle is + * noticeably longer in one axis than the other, the angles to the + * start and end of the arc segment will be skewed farther along the + * longer axis of the bounds. + * @param x the <i>x</i> coordinate of the + * upper-left corner of the arc to be drawn. + * @param y the <i>y</i> coordinate of the + * upper-left corner of the arc to be drawn. + * @param width the width of the arc to be drawn. + * @param height the height of the arc to be drawn. + * @param startAngle the beginning angle. + * @param arcAngle the angular extent of the arc, + * relative to the start angle. + * @see java.awt.Graphics#fillArc + */ + public void drawArc(int x, int y, int width, int height, + int startAngle, int arcAngle) { + Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN); + draw(arc); + } + + + /** + * Draws a sequence of connected lines defined by + * arrays of <i>x</i> and <i>y</i> coordinates. + * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point. + * The figure is not closed if the first point + * differs from the last point. + * @param xPoints an array of <i>x</i> points + * @param yPoints an array of <i>y</i> points + * @param nPoints the total number of points + * @see java.awt.Graphics#drawPolygon(int[], int[], int) + * @since JDK1.1 + */ + public void drawPolyline(int[] xPoints, int[] yPoints, + int nPoints){ + if(nPoints > 0){ + GeneralPath path = new GeneralPath(); + path.moveTo(xPoints[0], yPoints[0]); + for(int i=1; i<nPoints; i++) + path.lineTo(xPoints[i], yPoints[i]); + + draw(path); + } + } + + /** + * Draws the outline of an oval. + * The result is a circle or ellipse that fits within the + * rectangle specified by the <code>x</code>, <code>y</code>, + * <code>width</code>, and <code>height</code> arguments. + * <p> + * The oval covers an area that is + * <code>width + 1</code> pixels wide + * and <code>height + 1</code> pixels tall. + * @param x the <i>x</i> coordinate of the upper left + * corner of the oval to be drawn. + * @param y the <i>y</i> coordinate of the upper left + * corner of the oval to be drawn. + * @param width the width of the oval to be drawn. + * @param height the height of the oval to be drawn. + * @see java.awt.Graphics#fillOval + */ + public void drawOval(int x, int y, int width, int height){ + Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); + draw(oval); + } + + /** + * Draws as much of the specified image as is currently available. + * The image is drawn with its top-left corner at + * (<i>x</i>, <i>y</i>) in this graphics context's coordinate + * space. Transparent pixels are drawn in the specified + * background color. + * <p> + * This operation is equivalent to filling a rectangle of the + * width and height of the specified image with the given color and then + * drawing the image on top of it, but possibly more efficient. + * <p> + * This method returns immediately in all cases, even if the + * complete image has not yet been loaded, and it has not been dithered + * and converted for the current output device. + * <p> + * If the image has not yet been completely loaded, then + * <code>drawImage</code> returns <code>false</code>. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * @param img the specified image to be drawn. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @param bgcolor the background color to paint under the + * non-opaque portions of the image. + * @param observer object to be notified as more of + * the image is converted. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + Color bgcolor, + ImageObserver observer){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + + return false; + } + + /** + * Draws as much of the specified image as has already been scaled + * to fit inside the specified rectangle. + * <p> + * The image is drawn inside the specified rectangle of this + * graphics context's coordinate space, and is scaled if + * necessary. Transparent pixels are drawn in the specified + * background color. + * This operation is equivalent to filling a rectangle of the + * width and height of the specified image with the given color and then + * drawing the image on top of it, but possibly more efficient. + * <p> + * This method returns immediately in all cases, even if the + * entire image has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete then + * <code>drawImage</code> returns <code>false</code>. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * <p> + * A scaled version of an image will not necessarily be + * available immediately just because an unscaled version of the + * image has been constructed for this output device. Each size of + * the image may be cached separately and generated from the original + * data in a separate image production sequence. + * @param img the specified image to be drawn. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @param width the width of the rectangle. + * @param height the height of the rectangle. + * @param bgcolor the background color to paint under the + * non-opaque portions of the image. + * @param observer object to be notified as more of + * the image is converted. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + int width, int height, + Color bgcolor, + ImageObserver observer){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + + return false; + } + + + /** + * Draws as much of the specified area of the specified image as is + * currently available, scaling it on the fly to fit inside the + * specified area of the destination drawable surface. Transparent pixels + * do not affect whatever pixels are already there. + * <p> + * This method returns immediately in all cases, even if the + * image area to be drawn has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete then + * <code>drawImage</code> returns <code>false</code>. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * <p> + * This method always uses the unscaled version of the image + * to render the scaled rectangle and performs the required + * scaling on the fly. It does not use a cached, scaled version + * of the image for this operation. Scaling of the image from source + * to destination is performed such that the first coordinate + * of the source rectangle is mapped to the first coordinate of + * the destination rectangle, and the second source coordinate is + * mapped to the second destination coordinate. The subimage is + * scaled and flipped as needed to preserve those mappings. + * @param img the specified image to be drawn + * @param dx1 the <i>x</i> coordinate of the first corner of the + * destination rectangle. + * @param dy1 the <i>y</i> coordinate of the first corner of the + * destination rectangle. + * @param dx2 the <i>x</i> coordinate of the second corner of the + * destination rectangle. + * @param dy2 the <i>y</i> coordinate of the second corner of the + * destination rectangle. + * @param sx1 the <i>x</i> coordinate of the first corner of the + * source rectangle. + * @param sy1 the <i>y</i> coordinate of the first corner of the + * source rectangle. + * @param sx2 the <i>x</i> coordinate of the second corner of the + * source rectangle. + * @param sy2 the <i>y</i> coordinate of the second corner of the + * source rectangle. + * @param observer object to be notified as more of the image is + * scaled and converted. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + * @since JDK1.1 + */ + public boolean drawImage(Image img, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return false; + } + + /** + * Draws as much of the specified area of the specified image as is + * currently available, scaling it on the fly to fit inside the + * specified area of the destination drawable surface. + * <p> + * Transparent pixels are drawn in the specified background color. + * This operation is equivalent to filling a rectangle of the + * width and height of the specified image with the given color and then + * drawing the image on top of it, but possibly more efficient. + * <p> + * This method returns immediately in all cases, even if the + * image area to be drawn has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete then + * <code>drawImage</code> returns <code>false</code>. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * <p> + * This method always uses the unscaled version of the image + * to render the scaled rectangle and performs the required + * scaling on the fly. It does not use a cached, scaled version + * of the image for this operation. Scaling of the image from source + * to destination is performed such that the first coordinate + * of the source rectangle is mapped to the first coordinate of + * the destination rectangle, and the second source coordinate is + * mapped to the second destination coordinate. The subimage is + * scaled and flipped as needed to preserve those mappings. + * @param img the specified image to be drawn + * @param dx1 the <i>x</i> coordinate of the first corner of the + * destination rectangle. + * @param dy1 the <i>y</i> coordinate of the first corner of the + * destination rectangle. + * @param dx2 the <i>x</i> coordinate of the second corner of the + * destination rectangle. + * @param dy2 the <i>y</i> coordinate of the second corner of the + * destination rectangle. + * @param sx1 the <i>x</i> coordinate of the first corner of the + * source rectangle. + * @param sy1 the <i>y</i> coordinate of the first corner of the + * source rectangle. + * @param sx2 the <i>x</i> coordinate of the second corner of the + * source rectangle. + * @param sy2 the <i>y</i> coordinate of the second corner of the + * source rectangle. + * @param bgcolor the background color to paint under the + * non-opaque portions of the image. + * @param observer object to be notified as more of the image is + * scaled and converted. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + * @since JDK1.1 + */ + 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 (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return false; + } + + /** + * Draws as much of the specified image as is currently available. + * The image is drawn with its top-left corner at + * (<i>x</i>, <i>y</i>) in this graphics context's coordinate + * space. Transparent pixels in the image do not affect whatever + * pixels are already there. + * <p> + * This method returns immediately in all cases, even if the + * complete image has not yet been loaded, and it has not been dithered + * and converted for the current output device. + * <p> + * If the image has completely loaded and its pixels are + * no longer being changed, then + * <code>drawImage</code> returns <code>true</code>. + * Otherwise, <code>drawImage</code> returns <code>false</code> + * and as more of + * the image becomes available + * or it is time to draw another frame of animation, + * the process that loads the image notifies + * the specified image observer. + * @param img the specified image to be drawn. This method does + * nothing if <code>img</code> is null. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @param observer object to be notified as more of + * the image is converted. + * @return <code>false</code> if the image pixels are still changing; + * <code>true</code> otherwise. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + ImageObserver observer) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return false; + } + + /** + * Disposes of this graphics context and releases + * any system resources that it is using. + * A <code>Graphics</code> object cannot be used after + * <code>dispose</code>has been called. + * <p> + * When a Java program runs, a large number of <code>Graphics</code> + * objects can be created within a short time frame. + * Although the finalization process of the garbage collector + * also disposes of the same system resources, it is preferable + * to manually free the associated resources by calling this + * method rather than to rely on a finalization process which + * may not run to completion for a long period of time. + * <p> + * Graphics objects which are provided as arguments to the + * <code>paint</code> and <code>update</code> methods + * of components are automatically released by the system when + * those methods return. For efficiency, programmers should + * call <code>dispose</code> when finished using + * a <code>Graphics</code> object only if it was created + * directly from a component or another <code>Graphics</code> object. + * @see java.awt.Graphics#finalize + * @see java.awt.Component#paint + * @see java.awt.Component#update + * @see java.awt.Component#getGraphics + * @see java.awt.Graphics#create + */ + public void dispose() { + ; + } + + /** + * Draws a line, using the current color, between the points + * <code>(x1, y1)</code> and <code>(x2, y2)</code> + * in this graphics context's coordinate system. + * @param x1 the first point's <i>x</i> coordinate. + * @param y1 the first point's <i>y</i> coordinate. + * @param x2 the second point's <i>x</i> coordinate. + * @param y2 the second point's <i>y</i> coordinate. + */ + public void drawLine(int x1, int y1, int x2, int y2){ + Line2D line = new Line2D.Float(x1, y1, x2, y2); + draw(line); + } + + /** + * Fills a closed polygon defined by + * arrays of <i>x</i> and <i>y</i> coordinates. + * <p> + * This method draws the polygon defined by <code>nPoint</code> line + * segments, where the first <code>nPoint - 1</code> + * line segments are line segments from + * <code>(xPoints[i - 1], yPoints[i - 1])</code> + * to <code>(xPoints[i], yPoints[i])</code>, for + * 1 ≤ <i>i</i> ≤ <code>nPoints</code>. + * The figure is automatically closed by drawing a line connecting + * the final point to the first point, if those points are different. + * <p> + * The area inside the polygon is defined using an + * even-odd fill rule, also known as the alternating rule. + * @param xPoints a an array of <code>x</code> coordinates. + * @param yPoints a an array of <code>y</code> coordinates. + * @param nPoints a the total number of points. + * @see java.awt.Graphics#drawPolygon(int[], int[], int) + */ + public void fillPolygon(int[] xPoints, int[] yPoints, + int nPoints){ + java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); + fill(polygon); + } + + /** + * Fills the specified rectangle. + * The left and right edges of the rectangle are at + * <code>x</code> and <code>x + width - 1</code>. + * The top and bottom edges are at + * <code>y</code> and <code>y + height - 1</code>. + * The resulting rectangle covers an area + * <code>width</code> pixels wide by + * <code>height</code> pixels tall. + * The rectangle is filled using the graphics context's current color. + * @param x the <i>x</i> coordinate + * of the rectangle to be filled. + * @param y the <i>y</i> coordinate + * of the rectangle to be filled. + * @param width the width of the rectangle to be filled. + * @param height the height of the rectangle to be filled. + * @see java.awt.Graphics#clearRect + * @see java.awt.Graphics#drawRect + */ + public void fillRect(int x, int y, int width, int height){ + Rectangle rect = new Rectangle(x, y, width, height); + fill(rect); + } + + /** + * Draws the outline of the specified rectangle. + * The left and right edges of the rectangle are at + * <code>x</code> and <code>x + width</code>. + * The top and bottom edges are at + * <code>y</code> and <code>y + height</code>. + * The rectangle is drawn using the graphics context's current color. + * @param x the <i>x</i> coordinate + * of the rectangle to be drawn. + * @param y the <i>y</i> coordinate + * of the rectangle to be drawn. + * @param width the width of the rectangle to be drawn. + * @param height the height of the rectangle to be drawn. + * @see java.awt.Graphics#fillRect + * @see java.awt.Graphics#clearRect + */ + public void drawRect(int x, int y, int width, int height) { + Rectangle rect = new Rectangle(x, y, width, height); + draw(rect); + } + + /** + * Draws a closed polygon defined by + * arrays of <i>x</i> and <i>y</i> coordinates. + * Each pair of (<i>x</i>, <i>y</i>) coordinates defines a point. + * <p> + * This method draws the polygon defined by <code>nPoint</code> line + * segments, where the first <code>nPoint - 1</code> + * line segments are line segments from + * <code>(xPoints[i - 1], yPoints[i - 1])</code> + * to <code>(xPoints[i], yPoints[i])</code>, for + * 1 ≤ <i>i</i> ≤ <code>nPoints</code>. + * The figure is automatically closed by drawing a line connecting + * the final point to the first point, if those points are different. + * @param xPoints a an array of <code>x</code> coordinates. + * @param yPoints a an array of <code>y</code> coordinates. + * @param nPoints a the total number of points. + * @see java.awt.Graphics#fillPolygon(int[],int[],int) + * @see java.awt.Graphics#drawPolyline + */ + public void drawPolygon(int[] xPoints, int[] yPoints, + int nPoints){ + java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); + draw(polygon); + } + + /** + * Intersects the current clip with the specified rectangle. + * The resulting clipping area is the intersection of the current + * clipping area and the specified rectangle. If there is no + * current clipping area, either because the clip has never been + * set, or the clip has been cleared using <code>setClip(null)</code>, + * the specified rectangle becomes the new clip. + * This method sets the user clip, which is independent of the + * clipping associated with device bounds and window visibility. + * This method can only be used to make the current clip smaller. + * To set the current clip larger, use any of the setClip methods. + * Rendering operations have no effect outside of the clipping area. + * @param x the x coordinate of the rectangle to intersect the clip with + * @param y the y coordinate of the rectangle to intersect the clip with + * @param width the width of the rectangle to intersect the clip with + * @param height the height of the rectangle to intersect the clip with + * @see #setClip(int, int, int, int) + * @see #setClip(Shape) + */ + public void clipRect(int x, int y, int width, int height){ + clip(new Rectangle(x, y, width, height)); + } + + /** + * Sets the current clipping area to an arbitrary clip shape. + * Not all objects that implement the <code>Shape</code> + * interface can be used to set the clip. The only + * <code>Shape</code> objects that are guaranteed to be + * supported are <code>Shape</code> objects that are + * obtained via the <code>getClip</code> method and via + * <code>Rectangle</code> objects. This method sets the + * user clip, which is independent of the clipping associated + * with device bounds and window visibility. + * @param clip the <code>Shape</code> to use to set the clip + * @see java.awt.Graphics#getClip() + * @see java.awt.Graphics#clipRect + * @see java.awt.Graphics#setClip(int, int, int, int) + * @since JDK1.1 + */ + public void setClip(Shape clip) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Returns the bounding rectangle of the current clipping area. + * This method refers to the user clip, which is independent of the + * clipping associated with device bounds and window visibility. + * If no clip has previously been set, or if the clip has been + * cleared using <code>setClip(null)</code>, this method returns + * <code>null</code>. + * The coordinates in the rectangle are relative to the coordinate + * system origin of this graphics context. + * @return the bounding rectangle of the current clipping area, + * or <code>null</code> if no clip is set. + * @see java.awt.Graphics#getClip + * @see java.awt.Graphics#clipRect + * @see java.awt.Graphics#setClip(int, int, int, int) + * @see java.awt.Graphics#setClip(Shape) + * @since JDK1.1 + */ + public Rectangle getClipBounds(){ + Shape c = getClip(); + if (c==null) { + return null; + } + return c.getBounds(); + } + + /** + * Draws the text given by the specified iterator, using this + * graphics context's current color. The iterator has to specify a font + * for each character. The baseline of the + * first character is at position (<i>x</i>, <i>y</i>) in this + * graphics context's coordinate system. + * @param iterator the iterator whose text is to be drawn + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @see java.awt.Graphics#drawBytes + * @see java.awt.Graphics#drawChars + */ + public void drawString(AttributedCharacterIterator iterator, + int x, int y){ + drawString(iterator, (float)x, (float)y); + } + + /** + * Clears the specified rectangle by filling it with the background + * color of the current drawing surface. This operation does not + * use the current paint mode. + * <p> + * Beginning with Java 1.1, the background color + * of offscreen images may be system dependent. Applications should + * use <code>setColor</code> followed by <code>fillRect</code> to + * ensure that an offscreen image is cleared to a specific color. + * @param x the <i>x</i> coordinate of the rectangle to clear. + * @param y the <i>y</i> coordinate of the rectangle to clear. + * @param width the width of the rectangle to clear. + * @param height the height of the rectangle to clear. + * @see java.awt.Graphics#fillRect(int, int, int, int) + * @see java.awt.Graphics#drawRect + * @see java.awt.Graphics#setColor(java.awt.Color) + * @see java.awt.Graphics#setPaintMode + * @see java.awt.Graphics#setXORMode(java.awt.Color) + */ + public void clearRect(int x, int y, int width, int height) { + Paint paint = getPaint(); + setColor(getBackground()); + fillRect(x, y, width, height); + setPaint(paint); + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + ; + } + + /** + * Sets the current clip to the rectangle specified by the given + * coordinates. This method sets the user clip, which is + * independent of the clipping associated with device bounds + * and window visibility. + * Rendering operations have no effect outside of the clipping area. + * @param x the <i>x</i> coordinate of the new clip rectangle. + * @param y the <i>y</i> coordinate of the new clip rectangle. + * @param width the width of the new clip rectangle. + * @param height the height of the new clip rectangle. + * @see java.awt.Graphics#clipRect + * @see java.awt.Graphics#setClip(Shape) + * @since JDK1.1 + */ + public void setClip(int x, int y, int width, int height){ + setClip(new Rectangle(x, y, width, height)); + } + + /** + * Concatenates the current <code>Graphics2D</code> + * <code>Transform</code> with a rotation transform. + * Subsequent rendering is rotated by the specified radians relative + * to the previous origin. + * This is equivalent to calling <code>transform(R)</code>, where R is an + * <code>AffineTransform</code> represented by the following matrix: + * <pre> + * [ cos(theta) -sin(theta) 0 ] + * [ sin(theta) cos(theta) 0 ] + * [ 0 0 1 ] + * </pre> + * Rotating with a positive angle theta rotates points on the positive + * x axis toward the positive y axis. + * @param theta the angle of rotation in radians + */ + public void rotate(double theta){ + _transform.rotate(theta); + } + + /** + * Concatenates the current <code>Graphics2D</code> + * <code>Transform</code> with a translated rotation + * transform. Subsequent rendering is transformed by a transform + * which is constructed by translating to the specified location, + * rotating by the specified radians, and translating back by the same + * amount as the original translation. This is equivalent to the + * following sequence of calls: + * <pre> + * translate(x, y); + * rotate(theta); + * translate(-x, -y); + * </pre> + * Rotating with a positive angle theta rotates points on the positive + * x axis toward the positive y axis. + * @param theta the angle of rotation in radians + * @param x x coordinate of the origin of the rotation + * @param y y coordinate of the origin of the rotation + */ + public void rotate(double theta, double x, double y){ + _transform.rotate(theta, x, y); + } + + /** + * Concatenates the current <code>Graphics2D</code> + * <code>Transform</code> with a shearing transform. + * Subsequent renderings are sheared by the specified + * multiplier relative to the previous position. + * This is equivalent to calling <code>transform(SH)</code>, where SH + * is an <code>AffineTransform</code> represented by the following + * matrix: + * <pre> + * [ 1 shx 0 ] + * [ shy 1 0 ] + * [ 0 0 1 ] + * </pre> + * @param shx the multiplier by which coordinates are shifted in + * the positive X axis direction as a function of their Y coordinate + * @param shy the multiplier by which coordinates are shifted in + * the positive Y axis direction as a function of their X coordinate + */ + public void shear(double shx, double shy){ + _transform.shear(shx, shy); + } + + /** + * Get the rendering context of the <code>Font</code> within this + * <code>Graphics2D</code> context. + * The {@link FontRenderContext} + * encapsulates application hints such as anti-aliasing and + * fractional metrics, as well as target device specific information + * such as dots-per-inch. This information should be provided by the + * application when using objects that perform typographical + * formatting, such as <code>Font</code> and + * <code>TextLayout</code>. This information should also be provided + * by applications that perform their own layout and need accurate + * measurements of various characteristics of glyphs such as advance + * and line height when various rendering hints have been applied to + * the text rendering. + * + * @return a reference to an instance of FontRenderContext. + * @see java.awt.font.FontRenderContext + * @see java.awt.Font#createGlyphVector(FontRenderContext,char[]) + * @see java.awt.font.TextLayout + * @since JDK1.2 + */ + public FontRenderContext getFontRenderContext() { + boolean isAntiAliased = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals( + getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); + boolean usesFractionalMetrics = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals( + getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); + + + return new FontRenderContext(new AffineTransform(), isAntiAliased, usesFractionalMetrics); + } + + /** + * Composes an <code>AffineTransform</code> object with the + * <code>Transform</code> in this <code>Graphics2D</code> according + * to the rule last-specified-first-applied. If the current + * <code>Transform</code> is Cx, the result of composition + * with Tx is a new <code>Transform</code> Cx'. Cx' becomes the + * current <code>Transform</code> for this <code>Graphics2D</code>. + * Transforming a point p by the updated <code>Transform</code> Cx' is + * equivalent to first transforming p by Tx and then transforming + * the result by the original <code>Transform</code> Cx. In other + * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, + * so further modifications to Tx do not affect rendering. + * @param Tx the <code>AffineTransform</code> object to be composed with + * the current <code>Transform</code> + * @see #setTransform + * @see AffineTransform + */ + public void transform(AffineTransform Tx) { + _transform.concatenate(Tx); + } + + /** + * Renders a <code>BufferedImage</code> that is + * filtered with a + * {@link BufferedImageOp}. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code> + * and <code>Composite</code> attributes. This is equivalent to: + * <pre> + * img1 = op.filter(img, null); + * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null); + * </pre> + * @param img the <code>BufferedImage</code> to be rendered + * @param op the filter to be applied to the image before rendering + * @param x the x coordinate in user space where the image is rendered + * @param y the y coordinate in user space where the image is rendered + * @see #_transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip(Shape) + */ + public void drawImage(BufferedImage img, + BufferedImageOp op, + int x, + int y){ + img = op.filter(img, null); + drawImage(img, x, y, null); + } + + /** + * Sets the background color for the <code>Graphics2D</code> context. + * The background color is used for clearing a region. + * When a <code>Graphics2D</code> is constructed for a + * <code>Component</code>, the background color is + * inherited from the <code>Component</code>. Setting the background color + * in the <code>Graphics2D</code> context only affects the subsequent + * <code>clearRect</code> calls and not the background color of the + * <code>Component</code>. To change the background + * of the <code>Component</code>, use appropriate methods of + * the <code>Component</code>. + * @param color the background color that isused in + * subsequent calls to <code>clearRect</code> + * @see #getBackground + * @see java.awt.Graphics#clearRect + */ + public void setBackground(Color color) { + if(color == null) + return; + + _background = color; + } + + /** + * Returns the background color used for clearing a region. + * @return the current <code>Graphics2D</code> <code>Color</code>, + * which defines the background color. + * @see #setBackground + */ + public Color getBackground(){ + return _background; + } + + /** + * Sets the <code>Composite</code> for the <code>Graphics2D</code> context. + * The <code>Composite</code> is used in all drawing methods such as + * <code>drawImage</code>, <code>drawString</code>, <code>draw</code>, + * and <code>fill</code>. It specifies how new pixels are to be combined + * with the existing pixels on the graphics device during the rendering + * process. + * <p>If this <code>Graphics2D</code> context is drawing to a + * <code>Component</code> on the display screen and the + * <code>Composite</code> is a custom object rather than an + * instance of the <code>AlphaComposite</code> class, and if + * there is a security manager, its <code>checkPermission</code> + * method is called with an <code>AWTPermission("readDisplayPixels")</code> + * permission. + * + * @param comp the <code>Composite</code> object to be used for rendering + * @throws SecurityException + * if a custom <code>Composite</code> object is being + * used to render to the screen and a security manager + * is set and its <code>checkPermission</code> method + * does not allow the operation. + * @see java.awt.Graphics#setXORMode + * @see java.awt.Graphics#setPaintMode + * @see java.awt.AlphaComposite + */ + public void setComposite(Composite comp){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Returns the current <code>Composite</code> in the + * <code>Graphics2D</code> context. + * @return the current <code>Graphics2D</code> <code>Composite</code>, + * which defines a compositing style. + * @see #setComposite + */ + public Composite getComposite(){ + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return null; + } + + /** + * Returns the value of a single preference for the rendering algorithms. + * Hint categories include controls for rendering quality and overall + * time/quality trade-off in the rendering process. Refer to the + * <code>RenderingHints</code> class for definitions of some common + * keys and values. + * @param hintKey the key corresponding to the hint to get. + * @return an object representing the value for the specified hint key. + * Some of the keys and their associated values are defined in the + * <code>RenderingHints</code> class. + * @see RenderingHints + */ + public Object getRenderingHint(RenderingHints.Key hintKey){ + return _hints.get(hintKey); + } + + /** + * Sets the value of a single preference for the rendering algorithms. + * Hint categories include controls for rendering quality and overall + * time/quality trade-off in the rendering process. Refer to the + * <code>RenderingHints</code> class for definitions of some common + * keys and values. + * @param hintKey the key of the hint to be set. + * @param hintValue the value indicating preferences for the specified + * hint category. + * @see RenderingHints + */ + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue){ + _hints.put(hintKey, hintValue); + } + + + /** + * Renders the text of the specified + * {@link GlyphVector} using + * the <code>Graphics2D</code> context's rendering attributes. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, <code>Paint</code>, and + * <code>Composite</code> attributes. The <code>GlyphVector</code> + * specifies individual glyphs from a {@link Font}. + * The <code>GlyphVector</code> can also contain the glyph positions. + * This is the fastest way to render a set of characters to the + * screen. + * + * @param g the <code>GlyphVector</code> to be rendered + * @param x the x position in user space where the glyphs should be + * rendered + * @param y the y position in user space where the glyphs should be + * rendered + * + * @see java.awt.Font#createGlyphVector(FontRenderContext, char[]) + * @see java.awt.font.GlyphVector + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #setTransform + * @see #setComposite + * @see #setClip(Shape) + */ + public void drawGlyphVector(GlyphVector g, float x, float y) { + Shape glyphOutline = g.getOutline(x, y); + fill(glyphOutline); + } + + /** + * Returns the device configuration associated with this + * <code>Graphics2D</code>. + * @return the device configuration + */ + public GraphicsConfiguration getDeviceConfiguration() { + return GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + } + + /** + * Sets the values of an arbitrary number of preferences for the + * rendering algorithms. + * Only values for the rendering hints that are present in the + * specified <code>Map</code> object are modified. + * All other preferences not present in the specified + * object are left unmodified. + * Hint categories include controls for rendering quality and + * overall time/quality trade-off in the rendering process. + * Refer to the <code>RenderingHints</code> class for definitions of + * some common keys and values. + * @param hints the rendering hints to be set + * @see RenderingHints + */ + public void addRenderingHints(Map<?,?> hints){ + this._hints.putAll(hints); + } + + /** + * Concatenates the current + * <code>Graphics2D</code> <code>Transform</code> + * with a translation transform. + * Subsequent rendering is translated by the specified + * distance relative to the previous position. + * This is equivalent to calling transform(T), where T is an + * <code>AffineTransform</code> represented by the following matrix: + * <pre> + * [ 1 0 tx ] + * [ 0 1 ty ] + * [ 0 0 1 ] + * </pre> + * @param tx the distance to translate along the x-axis + * @param ty the distance to translate along the y-axis + */ + public void translate(double tx, double ty){ + _transform.translate(tx, ty); + } + + /** + * Renders the text of the specified iterator, using the + * <code>Graphics2D</code> context's current <code>Paint</code>. The + * iterator must specify a font + * for each character. The baseline of the + * first character is at position (<i>x</i>, <i>y</i>) in the + * User Space. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, <code>Paint</code>, and + * <code>Composite</code> attributes. + * For characters in script systems such as Hebrew and Arabic, + * the glyphs can be rendered from right to left, in which case the + * coordinate supplied is the location of the leftmost character + * on the baseline. + * @param iterator the iterator whose text is to be rendered + * @param x the x coordinate where the iterator's text is to be + * rendered + * @param y the y coordinate where the iterator's text is to be + * rendered + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(AttributedCharacterIterator iterator, float x, float y) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Checks whether or not the specified <code>Shape</code> intersects + * the specified {@link Rectangle}, which is in device + * space. If <code>onStroke</code> is false, this method checks + * whether or not the interior of the specified <code>Shape</code> + * intersects the specified <code>Rectangle</code>. If + * <code>onStroke</code> is <code>true</code>, this method checks + * whether or not the <code>Stroke</code> of the specified + * <code>Shape</code> outline intersects the specified + * <code>Rectangle</code>. + * The rendering attributes taken into account include the + * <code>Clip</code>, <code>Transform</code>, and <code>Stroke</code> + * attributes. + * @param rect the area in device space to check for a hit + * @param s the <code>Shape</code> to check for a hit + * @param onStroke flag used to choose between testing the + * stroked or the filled shape. If the flag is <code>true</code>, the + * <code>Stroke</code> oultine is tested. If the flag is + * <code>false</code>, the filled <code>Shape</code> is tested. + * @return <code>true</code> if there is a hit; <code>false</code> + * otherwise. + * @see #setStroke + * @see #fill(Shape) + * @see #draw(Shape) + * @see #_transform + * @see #setTransform + * @see #clip + * @see #setClip(Shape) + */ + public boolean hit(Rectangle rect, + Shape s, + boolean onStroke){ + if (onStroke) { + s = getStroke().createStrokedShape(s); + } + + s = getTransform().createTransformedShape(s); + + return s.intersects(rect); + } + + /** + * Gets the preferences for the rendering algorithms. Hint categories + * include controls for rendering quality and overall time/quality + * trade-off in the rendering process. + * Returns all of the hint key/value pairs that were ever specified in + * one operation. Refer to the + * <code>RenderingHints</code> class for definitions of some common + * keys and values. + * @return a reference to an instance of <code>RenderingHints</code> + * that contains the current preferences. + * @see RenderingHints + */ + public RenderingHints getRenderingHints(){ + return _hints; + } + + /** + * Replaces the values of all preferences for the rendering + * algorithms with the specified <code>hints</code>. + * The existing values for all rendering hints are discarded and + * the new set of known hints and values are initialized from the + * specified {@link Map} object. + * Hint categories include controls for rendering quality and + * overall time/quality trade-off in the rendering process. + * Refer to the <code>RenderingHints</code> class for definitions of + * some common keys and values. + * @param hints the rendering hints to be set + * @see RenderingHints + */ + public void setRenderingHints(Map<?,?> hints){ + this._hints = new RenderingHints(null); + this._hints.putAll(hints); + } + + /** + * Renders an image, applying a transform from image space into user space + * before drawing. + * The transformation from user space into device space is done with + * the current <code>Transform</code> in the <code>Graphics2D</code>. + * The specified transformation is applied to the image before the + * transform attribute in the <code>Graphics2D</code> context is applied. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, and <code>Composite</code> attributes. + * Note that no rendering is done if the specified transform is + * noninvertible. + * @param img the <code>Image</code> to be rendered + * @param xform the transformation from image space into user space + * @param obs the {@link ImageObserver} + * to be notified as more of the <code>Image</code> + * is converted + * @return <code>true</code> if the <code>Image</code> is + * fully loaded and completely rendered; + * <code>false</code> if the <code>Image</code> is still being loaded. + * @see #_transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip(Shape) + */ + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return false; + } + + /** + * Draws as much of the specified image as has already been scaled + * to fit inside the specified rectangle. + * <p> + * The image is drawn inside the specified rectangle of this + * graphics context's coordinate space, and is scaled if + * necessary. Transparent pixels do not affect whatever pixels + * are already there. + * <p> + * This method returns immediately in all cases, even if the + * entire image has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete, then + * <code>drawImage</code> returns <code>false</code>. As more of + * the image becomes available, the process that loads the image notifies + * the image observer by calling its <code>imageUpdate</code> method. + * <p> + * A scaled version of an image will not necessarily be + * available immediately just because an unscaled version of the + * image has been constructed for this output device. Each size of + * the image may be cached separately and generated from the original + * data in a separate image production sequence. + * @param img the specified image to be drawn. This method does + * nothing if <code>img</code> is null. + * @param x the <i>x</i> coordinate. + * @param y the <i>y</i> coordinate. + * @param width the width of the rectangle. + * @param height the height of the rectangle. + * @param observer object to be notified as more of + * the image is converted. + * @return <code>false</code> if the image pixels are still changing; + * <code>true</code> otherwise. + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + int width, int height, + ImageObserver observer) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + return false; + } + + /** + * Creates a new <code>Graphics</code> object that is + * a copy of this <code>Graphics</code> object. + * @return a new graphics context that is a copy of + * this graphics context. + */ + public Graphics create() { + try { + return (Graphics)clone(); + } catch (CloneNotSupportedException e){ + throw new RuntimeException(e); + } + } + + /** + * Gets the font metrics for the specified font. + * @return the font metrics for the specified font. + * @param f the specified font + * @see java.awt.Graphics#getFont + * @see java.awt.FontMetrics + * @see java.awt.Graphics#getFontMetrics() + */ + @SuppressWarnings("deprecation") + @SuppressForbidden + public FontMetrics getFontMetrics(Font f) { + return Toolkit.getDefaultToolkit().getFontMetrics(f); + } + + /** + * Sets the paint mode of this graphics context to alternate between + * this graphics context's current color and the new specified color. + * This specifies that logical pixel operations are performed in the + * XOR mode, which alternates pixels between the current color and + * a specified XOR color. + * <p> + * When drawing operations are performed, pixels which are the + * current color are changed to the specified color, and vice versa. + * <p> + * Pixels that are of colors other than those two colors are changed + * in an unpredictable but reversible manner; if the same figure is + * drawn twice, then all pixels are restored to their original values. + * @param c1 the XOR alternation color + */ + public void setXORMode(Color c1) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Sets the paint mode of this graphics context to overwrite the + * destination with this graphics context's current color. + * This sets the logical pixel operation function to the paint or + * overwrite mode. All subsequent rendering operations will + * overwrite the destination with the current color. + */ + public void setPaintMode() { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Renders a + * {@link RenderableImage}, + * applying a transform from image space into user space before drawing. + * The transformation from user space into device space is done with + * the current <code>Transform</code> in the <code>Graphics2D</code>. + * The specified transformation is applied to the image before the + * transform attribute in the <code>Graphics2D</code> context is applied. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, and <code>Composite</code> attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + *<p> + * Rendering hints set on the <code>Graphics2D</code> object might + * be used in rendering the <code>RenderableImage</code>. + * If explicit control is required over specific hints recognized by a + * specific <code>RenderableImage</code>, or if knowledge of which hints + * are used is required, then a <code>RenderedImage</code> should be + * obtained directly from the <code>RenderableImage</code> + * and rendered using + *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. + * @param img the image to be rendered. This method does + * nothing if <code>img</code> is null. + * @param xform the transformation from image space into user space + * @see #_transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + * @see #drawRenderedImage + */ + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + /** + * Renders a {@link RenderedImage}, + * applying a transform from image + * space into user space before drawing. + * The transformation from user space into device space is done with + * the current <code>Transform</code> in the <code>Graphics2D</code>. + * The specified transformation is applied to the image before the + * transform attribute in the <code>Graphics2D</code> context is applied. + * The rendering attributes applied include the <code>Clip</code>, + * <code>Transform</code>, and <code>Composite</code> attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + * @param img the image to be rendered. This method does + * nothing if <code>img</code> is null. + * @param xform the transformation from image space into user space + * @see #_transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + if (log.check(POILogger.WARN)) { + log.log(POILogger.WARN, "Not implemented"); + } + } + + protected void applyStroke(SimpleShape<?,?> shape) { + if (_stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)_stroke; + shape.setStrokeStyle((double)bs.getLineWidth()); + float[] dash = bs.getDashArray(); + if (dash != null) { + //TODO: implement more dashing styles + shape.setStrokeStyle(StrokeStyle.LineDash.DASH); + } + } + } + + protected void applyPaint(SimpleShape<?,?> shape) { + if (_paint instanceof Color) { + shape.setFillColor((Color)_paint); + } + } +}
Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java?rev=1711171&r1=1711170&r2=1711171&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java (original) +++ poi/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java Thu Oct 29 01:05:27 2015 @@ -17,6 +17,8 @@ package org.apache.poi.sl.usermodel; +import java.awt.Color; + import org.apache.poi.sl.draw.geom.CustomGeometry; import org.apache.poi.sl.draw.geom.IAdjustableShape; @@ -25,15 +27,66 @@ public interface SimpleShape< S extends Shape<S,P>, P extends TextParagraph<S,P,?> > extends Shape<S,P>, IAdjustableShape, PlaceableShape<S,P> { + + enum Placeholder { + TITLE, + BODY, + CENTERED_TITLE, + SUBTITLE, + DATETIME, + SLIDE_NUMBER, + FOOTER, + HEADER, + CONTENT, + CHART, + TABLE, + CLIP_ART, + DGM, + MEDIA, + SLIDE_IMAGE, + PICTURE + } + FillStyle getFillStyle(); + LineDecoration getLineDecoration(); + StrokeStyle getStrokeStyle(); + + /** + * Sets the line attributes. + * Possible attributes are Double (width), LineCap, LineDash, LineCompound, Color + * (implementations of PaintStyle aren't yet supported ...) + * + * If no styles are given, the line will be hidden + * + * @param styles the line attributes + */ + void setStrokeStyle(Object... styles); CustomGeometry getGeometry(); - + ShapeType getShapeType(); + void setShapeType(ShapeType type); boolean isPlaceholder(); - + Shadow<S,P> getShadow(); + + /** + * Returns the solid color fill. + * + * @return solid fill color of null if not set or fill color + * is not solid (pattern or gradient) + */ + Color getFillColor(); + + /** + * Specifies a solid color fill. The shape is filled entirely with the + * specified color. + * + * @param color the solid color fill. The value of <code>null</code> unsets + * the solid fill attribute from the underlying implementation + */ + void setFillColor(Color color); } Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java?rev=1711171&r1=1711170&r2=1711171&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java (original) +++ poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java Thu Oct 29 01:05:27 2015 @@ -48,6 +48,13 @@ public interface SlideShow< * @return the page size */ Dimension getPageSize(); + + /** + * Change the current page size + * + * @param pgsize page size (in points) + */ + void setPageSize(Dimension pgsize); /** * Returns all Pictures of this slideshow. Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java?rev=1711171&r1=1711170&r2=1711171&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java (original) +++ poi/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java Thu Oct 29 01:05:27 2015 @@ -20,18 +20,27 @@ package org.apache.poi.sl.usermodel; public interface StrokeStyle { enum LineCap { /** Rounded ends */ - ROUND(1), + ROUND(0,1), /** Square protrudes by half line width */ - SQUARE(2), + SQUARE(1,2), /** Line ends at end point*/ - FLAT(3); + FLAT(2,3); + public final int nativeId; public final int ooxmlId; - LineCap(int ooxmlId) { + LineCap(int nativeId, int ooxmlId) { + this.nativeId = nativeId; this.ooxmlId = ooxmlId; } + public static LineCap fromNativeId(int nativeId) { + for (LineCap ld : values()) { + if (ld.nativeId == nativeId) return ld; + } + return null; + } + public static LineCap fromOoxmlId(int ooxmlId) { for (LineCap lc : values()) { if (lc.ooxmlId == ooxmlId) return lc; @@ -96,20 +105,22 @@ public interface StrokeStyle { enum LineCompound { /** Single line (of width lineWidth) - native 0 / ooxml default */ - SINGLE(0), + SINGLE(0, 1), /** Double lines of equal width - native 1 / ooxml "dbl" */ - DOUBLE(1), + DOUBLE(1, 2), /** Double lines, one thick, one thin - native 2 / ooxml "thickThin" */ - THICK_THIN(2), + THICK_THIN(2, 3), /** Double lines, reverse order - native 3 / ooxml "thinThick" */ - THIN_THICK(3), + THIN_THICK(3, 4), /** Three lines, thin, thick, thin - native 4 / ooxml "tri" */ - TRIPLE(4); + TRIPLE(4, 5); public final int nativeId; + public final int ooxmlId; - LineCompound(int nativeId) { + LineCompound(int nativeId, int ooxmlId) { this.nativeId = nativeId; + this.ooxmlId = ooxmlId; } public static LineCompound fromNativeId(int nativeId) { @@ -118,6 +129,13 @@ public interface StrokeStyle { } return null; } + + public static LineCompound fromOoxmlId(int ooxmlId) { + for (LineCompound lc : values()) { + if (lc.ooxmlId == ooxmlId) return lc; + } + return null; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
