Source Code Cross Referenced for PdfGraphics2D.java in  » PDF » pdf-itext » com » lowagie » text » pdf » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » PDF » pdf itext » com.lowagie.text.pdf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: PdfGraphics2D.java 2912 2007-09-06 10:30:41Z psoares33 $
0003:         *
0004:         * Copyright 2002 by Jim Moore <jim@scolamoore.com>.
0005:         *
0006:         * The contents of this file are subject to the Mozilla Public License Version 1.1
0007:         * (the "License"); you may not use this file except in compliance with the License.
0008:         * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0009:         *
0010:         * Software distributed under the License is distributed on an "AS IS" basis,
0011:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0012:         * for the specific language governing rights and limitations under the License.
0013:         *
0014:         * The Original Code is 'iText, a free JAVA-PDF library'.
0015:         *
0016:         * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
0017:         * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
0018:         * All Rights Reserved.
0019:         * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
0020:         * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
0021:         *
0022:         * Contributor(s): all the names of the contributors are added in the source code
0023:         * where applicable.
0024:         *
0025:         * Alternatively, the contents of this file may be used under the terms of the
0026:         * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
0027:         * provisions of LGPL are applicable instead of those above.  If you wish to
0028:         * allow use of your version of this file only under the terms of the LGPL
0029:         * License and not to allow others to use your version of this file under
0030:         * the MPL, indicate your decision by deleting the provisions above and
0031:         * replace them with the notice and other provisions required by the LGPL.
0032:         * If you do not delete the provisions above, a recipient may use your version
0033:         * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
0034:         *
0035:         * This library is free software; you can redistribute it and/or modify it
0036:         * under the terms of the MPL as stated above or under the terms of the GNU
0037:         * Library General Public License as published by the Free Software Foundation;
0038:         * either version 2 of the License, or any later version.
0039:         *
0040:         * This library is distributed in the hope that it will be useful, but WITHOUT
0041:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0042:         * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
0043:         * details.
0044:         *
0045:         * If you didn't download this code from the following link, you should check if
0046:         * you aren't using an obsolete version:
0047:         * http://www.lowagie.com/iText/
0048:         */
0049:
0050:        package com.lowagie.text.pdf;
0051:
0052:        import java.awt.AlphaComposite;
0053:        import java.awt.BasicStroke;
0054:        import java.awt.Color;
0055:        import java.awt.Component;
0056:        import java.awt.Composite;
0057:        import java.awt.Font;
0058:        import java.awt.FontMetrics;
0059:        import java.awt.GradientPaint;
0060:        import java.awt.Graphics;
0061:        import java.awt.Graphics2D;
0062:        import java.awt.GraphicsConfiguration;
0063:        import java.awt.Image;
0064:        import java.awt.MediaTracker;
0065:        import java.awt.Paint;
0066:        import java.awt.Polygon;
0067:        import java.awt.Rectangle;
0068:        import java.awt.RenderingHints;
0069:        import java.awt.Shape;
0070:        import java.awt.Stroke;
0071:        import java.awt.TexturePaint;
0072:        import java.awt.Transparency;
0073:        import java.awt.RenderingHints.Key;
0074:        import java.awt.font.FontRenderContext;
0075:        import java.awt.font.GlyphVector;
0076:        import java.awt.font.TextAttribute;
0077:        import java.awt.geom.AffineTransform;
0078:        import java.awt.geom.Arc2D;
0079:        import java.awt.geom.Area;
0080:        import java.awt.geom.Ellipse2D;
0081:        import java.awt.geom.Line2D;
0082:        import java.awt.geom.NoninvertibleTransformException;
0083:        import java.awt.geom.PathIterator;
0084:        import java.awt.geom.Point2D;
0085:        import java.awt.geom.Rectangle2D;
0086:        import java.awt.geom.RoundRectangle2D;
0087:        import java.awt.image.BufferedImage;
0088:        import java.awt.image.BufferedImageOp;
0089:        import java.awt.image.ColorModel;
0090:        import java.awt.image.ImageObserver;
0091:        import java.awt.image.RenderedImage;
0092:        import java.awt.image.WritableRaster;
0093:        import java.awt.image.renderable.RenderableImage;
0094:        import java.io.ByteArrayOutputStream;
0095:        import java.text.AttributedCharacterIterator;
0096:        import java.util.ArrayList;
0097:        import java.util.HashMap;
0098:        import java.util.Hashtable;
0099:        import java.util.Iterator;
0100:        import java.util.Map;
0101:        import java.util.Set;
0102:
0103:        import com.lowagie.text.pdf.internal.PolylineShape;
0104:        import java.util.Locale;
0105:        import javax.imageio.IIOImage;
0106:        import javax.imageio.ImageIO;
0107:        import javax.imageio.ImageWriteParam;
0108:        import javax.imageio.ImageWriter;
0109:        import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
0110:        import javax.imageio.stream.ImageOutputStream;
0111:
0112:        public class PdfGraphics2D extends Graphics2D {
0113:
0114:            private static final int FILL = 1;
0115:            private static final int STROKE = 2;
0116:            private static final int CLIP = 3;
0117:            private BasicStroke strokeOne = new BasicStroke(1);
0118:
0119:            private static final AffineTransform IDENTITY = new AffineTransform();
0120:
0121:            private Font font;
0122:            private BaseFont baseFont;
0123:            private float fontSize;
0124:            private AffineTransform transform;
0125:            private Paint paint;
0126:            private Color background;
0127:            private float width;
0128:            private float height;
0129:
0130:            private Area clip;
0131:
0132:            private RenderingHints rhints = new RenderingHints(null);
0133:
0134:            private Stroke stroke;
0135:            private Stroke originalStroke;
0136:
0137:            private PdfContentByte cb;
0138:
0139:            /** Storage for BaseFont objects created. */
0140:            private HashMap baseFonts;
0141:
0142:            private boolean disposeCalled = false;
0143:
0144:            private FontMapper fontMapper;
0145:
0146:            private ArrayList kids;
0147:
0148:            private boolean kid = false;
0149:
0150:            private Graphics2D dg2 = new BufferedImage(2, 2,
0151:                    BufferedImage.TYPE_INT_RGB).createGraphics();
0152:
0153:            private boolean onlyShapes = false;
0154:
0155:            private Stroke oldStroke;
0156:            private Paint paintFill;
0157:            private Paint paintStroke;
0158:
0159:            private MediaTracker mediaTracker;
0160:
0161:            // Added by Jurij Bilas
0162:            protected boolean underline; // indicates if the font style is underlined
0163:
0164:            protected PdfGState fillGState[] = new PdfGState[256];
0165:            protected PdfGState strokeGState[] = new PdfGState[256];
0166:            protected int currentFillGState = 255;
0167:            protected int currentStrokeGState = 255;
0168:
0169:            public static final int AFM_DIVISOR = 1000; // used to calculate coordinates
0170:
0171:            private boolean convertImagesToJPEG = false;
0172:            private float jpegQuality = .95f;
0173:
0174:            // Added by Alexej Suchov
0175:            private float alpha;
0176:
0177:            // Added by Alexej Suchov
0178:            private Composite composite;
0179:
0180:            // Added by Alexej Suchov
0181:            private Paint realPaint;
0182:
0183:            private PdfGraphics2D() {
0184:                dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
0185:                        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
0186:                setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
0187:                        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
0188:            }
0189:
0190:            /**
0191:             * Constructor for PDFGraphics2D.
0192:             *
0193:             */
0194:            PdfGraphics2D(PdfContentByte cb, float width, float height,
0195:                    FontMapper fontMapper, boolean onlyShapes,
0196:                    boolean convertImagesToJPEG, float quality) {
0197:                super ();
0198:                dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
0199:                        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
0200:                setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
0201:                        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
0202:                this .convertImagesToJPEG = convertImagesToJPEG;
0203:                this .jpegQuality = quality;
0204:                this .onlyShapes = onlyShapes;
0205:                this .transform = new AffineTransform();
0206:                this .baseFonts = new HashMap();
0207:                if (!onlyShapes) {
0208:                    this .fontMapper = fontMapper;
0209:                    if (this .fontMapper == null)
0210:                        this .fontMapper = new DefaultFontMapper();
0211:                }
0212:                paint = Color.black;
0213:                background = Color.white;
0214:                setFont(new Font("sanserif", Font.PLAIN, 12));
0215:                this .cb = cb;
0216:                cb.saveState();
0217:                this .width = width;
0218:                this .height = height;
0219:                clip = new Area(new Rectangle2D.Float(0, 0, width, height));
0220:                clip(clip);
0221:                originalStroke = stroke = oldStroke = strokeOne;
0222:                setStrokeDiff(stroke, null);
0223:                cb.saveState();
0224:            }
0225:
0226:            /**
0227:             * @see Graphics2D#draw(Shape)
0228:             */
0229:            public void draw(Shape s) {
0230:                followPath(s, STROKE);
0231:            }
0232:
0233:            /**
0234:             * @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver)
0235:             */
0236:            public boolean drawImage(Image img, AffineTransform xform,
0237:                    ImageObserver obs) {
0238:                return drawImage(img, null, xform, null, obs);
0239:            }
0240:
0241:            /**
0242:             * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int)
0243:             */
0244:            public void drawImage(BufferedImage img, BufferedImageOp op, int x,
0245:                    int y) {
0246:                BufferedImage result = img;
0247:                if (op != null) {
0248:                    result = op.createCompatibleDestImage(img, img
0249:                            .getColorModel());
0250:                    result = op.filter(img, result);
0251:                }
0252:                drawImage(result, x, y, null);
0253:            }
0254:
0255:            /**
0256:             * @see Graphics2D#drawRenderedImage(RenderedImage, AffineTransform)
0257:             */
0258:            public void drawRenderedImage(RenderedImage img,
0259:                    AffineTransform xform) {
0260:                BufferedImage image = null;
0261:                if (img instanceof  BufferedImage) {
0262:                    image = (BufferedImage) img;
0263:                } else {
0264:                    ColorModel cm = img.getColorModel();
0265:                    int width = img.getWidth();
0266:                    int height = img.getHeight();
0267:                    WritableRaster raster = cm.createCompatibleWritableRaster(
0268:                            width, height);
0269:                    boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
0270:                    Hashtable properties = new Hashtable();
0271:                    String[] keys = img.getPropertyNames();
0272:                    if (keys != null) {
0273:                        for (int i = 0; i < keys.length; i++) {
0274:                            properties.put(keys[i], img.getProperty(keys[i]));
0275:                        }
0276:                    }
0277:                    BufferedImage result = new BufferedImage(cm, raster,
0278:                            isAlphaPremultiplied, properties);
0279:                    img.copyData(raster);
0280:                    image = result;
0281:                }
0282:                drawImage(image, xform, null);
0283:            }
0284:
0285:            /**
0286:             * @see Graphics2D#drawRenderableImage(RenderableImage, AffineTransform)
0287:             */
0288:            public void drawRenderableImage(RenderableImage img,
0289:                    AffineTransform xform) {
0290:                drawRenderedImage(img.createDefaultRendering(), xform);
0291:            }
0292:
0293:            /**
0294:             * @see Graphics#drawString(String, int, int)
0295:             */
0296:            public void drawString(String s, int x, int y) {
0297:                drawString(s, (float) x, (float) y);
0298:            }
0299:
0300:            /**
0301:             * Calculates position and/or stroke thickness depending on the font size
0302:             * @param d value to be converted
0303:             * @param i font size
0304:             * @return position and/or stroke thickness depending on the font size
0305:             */
0306:            public static double asPoints(double d, int i) {
0307:                return (d * (double) i) / (double) AFM_DIVISOR;
0308:            }
0309:
0310:            /**
0311:             * This routine goes through the attributes and sets the font
0312:             * before calling the actual string drawing routine
0313:             * @param iter
0314:             */
0315:            protected void doAttributes(AttributedCharacterIterator iter) {
0316:                underline = false;
0317:                Set set = iter.getAttributes().keySet();
0318:                for (Iterator iterator = set.iterator(); iterator.hasNext();) {
0319:                    AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) iterator
0320:                            .next();
0321:                    if (!(attribute instanceof  TextAttribute))
0322:                        continue;
0323:                    TextAttribute textattribute = (TextAttribute) attribute;
0324:                    if (textattribute.equals(TextAttribute.FONT)) {
0325:                        Font font = (Font) iter.getAttributes().get(
0326:                                textattribute);
0327:                        setFont(font);
0328:                    } else if (textattribute.equals(TextAttribute.UNDERLINE)) {
0329:                        if (iter.getAttributes().get(textattribute) == TextAttribute.UNDERLINE_ON)
0330:                            underline = true;
0331:                    } else if (textattribute.equals(TextAttribute.SIZE)) {
0332:                        Object obj = iter.getAttributes().get(textattribute);
0333:                        if (obj instanceof  Integer) {
0334:                            int i = ((Integer) obj).intValue();
0335:                            setFont(getFont().deriveFont(getFont().getStyle(),
0336:                                    i));
0337:                        } else if (obj instanceof  Float) {
0338:                            float f = ((Float) obj).floatValue();
0339:                            setFont(getFont().deriveFont(getFont().getStyle(),
0340:                                    f));
0341:                        }
0342:                    } else if (textattribute.equals(TextAttribute.FOREGROUND)) {
0343:                        setColor((Color) iter.getAttributes()
0344:                                .get(textattribute));
0345:                    } else if (textattribute.equals(TextAttribute.FAMILY)) {
0346:                        Font font = getFont();
0347:                        Map fontAttributes = font.getAttributes();
0348:                        fontAttributes.put(TextAttribute.FAMILY, iter
0349:                                .getAttributes().get(textattribute));
0350:                        setFont(font.deriveFont(fontAttributes));
0351:                    } else if (textattribute.equals(TextAttribute.POSTURE)) {
0352:                        Font font = getFont();
0353:                        Map fontAttributes = font.getAttributes();
0354:                        fontAttributes.put(TextAttribute.POSTURE, iter
0355:                                .getAttributes().get(textattribute));
0356:                        setFont(font.deriveFont(fontAttributes));
0357:                    } else if (textattribute.equals(TextAttribute.WEIGHT)) {
0358:                        Font font = getFont();
0359:                        Map fontAttributes = font.getAttributes();
0360:                        fontAttributes.put(TextAttribute.WEIGHT, iter
0361:                                .getAttributes().get(textattribute));
0362:                        setFont(font.deriveFont(fontAttributes));
0363:                    }
0364:                }
0365:            }
0366:
0367:            /**
0368:             * @see Graphics2D#drawString(String, float, float)
0369:             */
0370:            public void drawString(String s, float x, float y) {
0371:                if (s.length() == 0)
0372:                    return;
0373:                setFillPaint();
0374:                if (onlyShapes) {
0375:                    drawGlyphVector(this .font.layoutGlyphVector(
0376:                            getFontRenderContext(), s.toCharArray(), 0, s
0377:                                    .length(),
0378:                            java.awt.Font.LAYOUT_LEFT_TO_RIGHT), x, y);
0379:                    //            Use the following line to compile in JDK 1.3    
0380:                    //            drawGlyphVector(this.font.createGlyphVector(getFontRenderContext(), s), x, y);
0381:                } else {
0382:                    boolean restoreTextRenderingMode = false;
0383:                    AffineTransform at = getTransform();
0384:                    AffineTransform at2 = getTransform();
0385:                    at2.translate(x, y);
0386:                    at2.concatenate(font.getTransform());
0387:                    setTransform(at2);
0388:                    AffineTransform inverse = this .normalizeMatrix();
0389:                    AffineTransform flipper = AffineTransform.getScaleInstance(
0390:                            1, -1);
0391:                    inverse.concatenate(flipper);
0392:                    double[] mx = new double[6];
0393:                    inverse.getMatrix(mx);
0394:                    cb.beginText();
0395:                    cb.setFontAndSize(baseFont, fontSize);
0396:                    // Check if we need to simulate an italic font.
0397:                    // When there are different fonts for italic, bold, italic bold
0398:                    // the font.getName() will be different from the font.getFontName()
0399:                    // value. When they are the same value then we are normally dealing
0400:                    // with a single font that has been made into an italic or bold
0401:                    // font.
0402:                    if (font.isItalic()
0403:                            && font.getFontName().equals(font.getName())) {
0404:                        float angle = baseFont.getFontDescriptor(
0405:                                BaseFont.ITALICANGLE, 1000);
0406:                        float angle2 = font.getItalicAngle();
0407:                        // We don't have an italic version of this font so we need
0408:                        // to set the font angle ourselves to produce an italic font.
0409:                        if (angle2 == 0) {
0410:                            // The JavaVM didn't have an angle setting for making
0411:                            // the font an italic font so use a default of
0412:                            // italic angle of 15 degrees.
0413:                            angle2 = 15.0f;
0414:                        } else {
0415:                            // This sign of the angle for Java and PDF seams
0416:                            // seams to be reversed.
0417:                            angle2 = -angle2;
0418:                        }
0419:                        if (angle == 0) {
0420:                            mx[2] = angle2 / 100.0f;
0421:                        }
0422:                    }
0423:                    cb.setTextMatrix((float) mx[0], (float) mx[1],
0424:                            (float) mx[2], (float) mx[3], (float) mx[4],
0425:                            (float) mx[5]);
0426:                    Float fontTextAttributeWidth = (Float) font.getAttributes()
0427:                            .get(TextAttribute.WIDTH);
0428:                    fontTextAttributeWidth = (fontTextAttributeWidth == null) ? TextAttribute.WIDTH_REGULAR
0429:                            : fontTextAttributeWidth;
0430:                    if (!TextAttribute.WIDTH_REGULAR
0431:                            .equals(fontTextAttributeWidth))
0432:                        cb.setHorizontalScaling(100.0f / fontTextAttributeWidth
0433:                                .floatValue());
0434:
0435:                    // Check if we need to simulate a bold font.
0436:                    // Do nothing if the BaseFont is already bold. This test is not foolproof but it will work most of the times.
0437:                    if (baseFont.getPostscriptFontName().toLowerCase().indexOf(
0438:                            "bold") < 0) {
0439:                        // Get the weight of the font so we can detect fonts with a weight
0440:                        // that makes them bold, but the Font.isBold() value is false.
0441:                        Float weight = (Float) font.getAttributes().get(
0442:                                TextAttribute.WEIGHT);
0443:                        if (weight == null) {
0444:                            weight = (font.isBold()) ? TextAttribute.WEIGHT_BOLD
0445:                                    : TextAttribute.WEIGHT_REGULAR;
0446:                        }
0447:                        if ((font.isBold() || (weight.floatValue() >= TextAttribute.WEIGHT_SEMIBOLD
0448:                                .floatValue()))
0449:                                && (font.getFontName().equals(font.getName()))) {
0450:                            // Simulate a bold font.
0451:                            float strokeWidth = font.getSize2D()
0452:                                    * (weight.floatValue() - TextAttribute.WEIGHT_REGULAR
0453:                                            .floatValue()) / 30f;
0454:                            if (strokeWidth != 1) {
0455:                                cb
0456:                                        .setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
0457:                                cb.setLineWidth(strokeWidth);
0458:                                cb.setColorStroke(getColor());
0459:                                restoreTextRenderingMode = true;
0460:                            }
0461:                        }
0462:                    }
0463:
0464:                    double width = 0;
0465:                    if (font.getSize2D() > 0) {
0466:                        float scale = 1000 / font.getSize2D();
0467:                        width = font.deriveFont(
0468:                                AffineTransform.getScaleInstance(scale, scale))
0469:                                .getStringBounds(s, getFontRenderContext())
0470:                                .getWidth()
0471:                                / scale;
0472:                    }
0473:                    if (s.length() > 1) {
0474:                        float adv = ((float) width - baseFont.getWidthPoint(s,
0475:                                fontSize))
0476:                                / (s.length() - 1);
0477:                        cb.setCharacterSpacing(adv);
0478:                    }
0479:                    cb.showText(s);
0480:                    if (s.length() > 1) {
0481:                        cb.setCharacterSpacing(0);
0482:                    }
0483:                    if (!TextAttribute.WIDTH_REGULAR
0484:                            .equals(fontTextAttributeWidth))
0485:                        cb.setHorizontalScaling(100);
0486:
0487:                    // Restore the original TextRenderingMode if needed.
0488:                    if (restoreTextRenderingMode) {
0489:                        cb
0490:                                .setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
0491:                    }
0492:
0493:                    cb.endText();
0494:                    setTransform(at);
0495:                    if (underline) {
0496:                        // These two are supposed to be taken from the .AFM file
0497:                        //int UnderlinePosition = -100;
0498:                        int UnderlineThickness = 50;
0499:                        //
0500:                        double d = asPoints((double) UnderlineThickness,
0501:                                (int) fontSize);
0502:                        setStroke(new BasicStroke((float) d));
0503:                        y = (float) ((double) (y) + asPoints(
0504:                                (double) (UnderlineThickness), (int) fontSize));
0505:                        Line2D line = new Line2D.Double((double) x, (double) y,
0506:                                (double) (width + x), (double) y);
0507:                        draw(line);
0508:                    }
0509:                }
0510:            }
0511:
0512:            /**
0513:             * @see Graphics#drawString(AttributedCharacterIterator, int, int)
0514:             */
0515:            public void drawString(AttributedCharacterIterator iterator, int x,
0516:                    int y) {
0517:                drawString(iterator, (float) x, (float) y);
0518:            }
0519:
0520:            /**
0521:             * @see Graphics2D#drawString(AttributedCharacterIterator, float, float)
0522:             */
0523:            public void drawString(AttributedCharacterIterator iter, float x,
0524:                    float y) {
0525:                /*
0526:                 StringBuffer sb = new StringBuffer();
0527:                 for(char c = iter.first(); c != AttributedCharacterIterator.DONE; c = iter.next()) {
0528:                 sb.append(c);
0529:                 }
0530:                 drawString(sb.toString(),x,y);
0531:                 */
0532:                StringBuffer stringbuffer = new StringBuffer(iter.getEndIndex());
0533:                for (char c = iter.first(); c != '\uFFFF'; c = iter.next()) {
0534:                    if (iter.getIndex() == iter.getRunStart()) {
0535:                        if (stringbuffer.length() > 0) {
0536:                            drawString(stringbuffer.toString(), x, y);
0537:                            FontMetrics fontmetrics = getFontMetrics();
0538:                            x = (float) ((double) x + fontmetrics
0539:                                    .getStringBounds(stringbuffer.toString(),
0540:                                            this ).getWidth());
0541:                            stringbuffer.delete(0, stringbuffer.length());
0542:                        }
0543:                        doAttributes(iter);
0544:                    }
0545:                    stringbuffer.append(c);
0546:                }
0547:
0548:                drawString(stringbuffer.toString(), x, y);
0549:                underline = false;
0550:            }
0551:
0552:            /**
0553:             * @see Graphics2D#drawGlyphVector(GlyphVector, float, float)
0554:             */
0555:            public void drawGlyphVector(GlyphVector g, float x, float y) {
0556:                Shape s = g.getOutline(x, y);
0557:                fill(s);
0558:            }
0559:
0560:            /**
0561:             * @see Graphics2D#fill(Shape)
0562:             */
0563:            public void fill(Shape s) {
0564:                followPath(s, FILL);
0565:            }
0566:
0567:            /**
0568:             * @see Graphics2D#hit(Rectangle, Shape, boolean)
0569:             */
0570:            public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
0571:                if (onStroke) {
0572:                    s = stroke.createStrokedShape(s);
0573:                }
0574:                s = transform.createTransformedShape(s);
0575:                Area area = new Area(s);
0576:                if (clip != null)
0577:                    area.intersect(clip);
0578:                return area.intersects(rect.x, rect.y, rect.width, rect.height);
0579:            }
0580:
0581:            /**
0582:             * @see Graphics2D#getDeviceConfiguration()
0583:             */
0584:            public GraphicsConfiguration getDeviceConfiguration() {
0585:                return dg2.getDeviceConfiguration();
0586:            }
0587:
0588:            /**
0589:             * Method contributed by Alexej Suchov
0590:             * @see Graphics2D#setComposite(Composite)
0591:             */
0592:            public void setComposite(Composite comp) {
0593:
0594:                if (comp instanceof  AlphaComposite) {
0595:
0596:                    AlphaComposite composite = (AlphaComposite) comp;
0597:
0598:                    if (composite.getRule() == 3) {
0599:
0600:                        alpha = composite.getAlpha();
0601:                        this .composite = composite;
0602:
0603:                        if (realPaint != null && (realPaint instanceof  Color)) {
0604:
0605:                            Color c = (Color) realPaint;
0606:                            paint = new Color(c.getRed(), c.getGreen(), c
0607:                                    .getBlue(),
0608:                                    (int) ((float) c.getAlpha() * alpha));
0609:                        }
0610:                        return;
0611:                    }
0612:                }
0613:
0614:                this .composite = comp;
0615:                alpha = 1.0F;
0616:
0617:            }
0618:
0619:            /**
0620:             * Method contributed by Alexej Suchov
0621:             * @see Graphics2D#setPaint(Paint)
0622:             */
0623:            public void setPaint(Paint paint) {
0624:                if (paint == null)
0625:                    return;
0626:                this .paint = paint;
0627:                realPaint = paint;
0628:
0629:                if ((composite instanceof  AlphaComposite)
0630:                        && (paint instanceof  Color)) {
0631:
0632:                    AlphaComposite co = (AlphaComposite) composite;
0633:
0634:                    if (co.getRule() == 3) {
0635:                        Color c = (Color) paint;
0636:                        this .paint = new Color(c.getRed(), c.getGreen(), c
0637:                                .getBlue(),
0638:                                (int) ((float) c.getAlpha() * alpha));
0639:                        realPaint = paint;
0640:                    }
0641:                }
0642:
0643:            }
0644:
0645:            private Stroke transformStroke(Stroke stroke) {
0646:                if (!(stroke instanceof  BasicStroke))
0647:                    return stroke;
0648:                BasicStroke st = (BasicStroke) stroke;
0649:                float scale = (float) Math.sqrt(Math.abs(transform
0650:                        .getDeterminant()));
0651:                float dash[] = st.getDashArray();
0652:                if (dash != null) {
0653:                    for (int k = 0; k < dash.length; ++k)
0654:                        dash[k] *= scale;
0655:                }
0656:                return new BasicStroke(st.getLineWidth() * scale, st
0657:                        .getEndCap(), st.getLineJoin(), st.getMiterLimit(),
0658:                        dash, st.getDashPhase() * scale);
0659:            }
0660:
0661:            private void setStrokeDiff(Stroke newStroke, Stroke oldStroke) {
0662:                if (newStroke == oldStroke)
0663:                    return;
0664:                if (!(newStroke instanceof  BasicStroke))
0665:                    return;
0666:                BasicStroke nStroke = (BasicStroke) newStroke;
0667:                boolean oldOk = (oldStroke instanceof  BasicStroke);
0668:                BasicStroke oStroke = null;
0669:                if (oldOk)
0670:                    oStroke = (BasicStroke) oldStroke;
0671:                if (!oldOk || nStroke.getLineWidth() != oStroke.getLineWidth())
0672:                    cb.setLineWidth(nStroke.getLineWidth());
0673:                if (!oldOk || nStroke.getEndCap() != oStroke.getEndCap()) {
0674:                    switch (nStroke.getEndCap()) {
0675:                    case BasicStroke.CAP_BUTT:
0676:                        cb.setLineCap(0);
0677:                        break;
0678:                    case BasicStroke.CAP_SQUARE:
0679:                        cb.setLineCap(2);
0680:                        break;
0681:                    default:
0682:                        cb.setLineCap(1);
0683:                    }
0684:                }
0685:                if (!oldOk || nStroke.getLineJoin() != oStroke.getLineJoin()) {
0686:                    switch (nStroke.getLineJoin()) {
0687:                    case BasicStroke.JOIN_MITER:
0688:                        cb.setLineJoin(0);
0689:                        break;
0690:                    case BasicStroke.JOIN_BEVEL:
0691:                        cb.setLineJoin(2);
0692:                        break;
0693:                    default:
0694:                        cb.setLineJoin(1);
0695:                    }
0696:                }
0697:                if (!oldOk
0698:                        || nStroke.getMiterLimit() != oStroke.getMiterLimit())
0699:                    cb.setMiterLimit(nStroke.getMiterLimit());
0700:                boolean makeDash;
0701:                if (oldOk) {
0702:                    if (nStroke.getDashArray() != null) {
0703:                        if (nStroke.getDashPhase() != oStroke.getDashPhase()) {
0704:                            makeDash = true;
0705:                        } else if (!java.util.Arrays.equals(nStroke
0706:                                .getDashArray(), oStroke.getDashArray())) {
0707:                            makeDash = true;
0708:                        } else
0709:                            makeDash = false;
0710:                    } else if (oStroke.getDashArray() != null) {
0711:                        makeDash = true;
0712:                    } else
0713:                        makeDash = false;
0714:                } else {
0715:                    makeDash = true;
0716:                }
0717:                if (makeDash) {
0718:                    float dash[] = nStroke.getDashArray();
0719:                    if (dash == null)
0720:                        cb.setLiteral("[]0 d\n");
0721:                    else {
0722:                        cb.setLiteral('[');
0723:                        int lim = dash.length;
0724:                        for (int k = 0; k < lim; ++k) {
0725:                            cb.setLiteral(dash[k]);
0726:                            cb.setLiteral(' ');
0727:                        }
0728:                        cb.setLiteral(']');
0729:                        cb.setLiteral(nStroke.getDashPhase());
0730:                        cb.setLiteral(" d\n");
0731:                    }
0732:                }
0733:            }
0734:
0735:            /**
0736:             * @see Graphics2D#setStroke(Stroke)
0737:             */
0738:            public void setStroke(Stroke s) {
0739:                originalStroke = s;
0740:                this .stroke = transformStroke(s);
0741:            }
0742:
0743:            /**
0744:             * Sets a rendering hint
0745:             * @param arg0
0746:             * @param arg1
0747:             */
0748:            public void setRenderingHint(Key arg0, Object arg1) {
0749:                if (arg1 != null) {
0750:                    rhints.put(arg0, arg1);
0751:                } else {
0752:                    rhints.remove(arg0);
0753:                }
0754:            }
0755:
0756:            /**
0757:             * @param arg0 a key
0758:             * @return the rendering hint
0759:             */
0760:            public Object getRenderingHint(Key arg0) {
0761:                return rhints.get(arg0);
0762:            }
0763:
0764:            /**
0765:             * @see Graphics2D#setRenderingHints(Map)
0766:             */
0767:            public void setRenderingHints(Map hints) {
0768:                rhints.clear();
0769:                rhints.putAll(hints);
0770:            }
0771:
0772:            /**
0773:             * @see Graphics2D#addRenderingHints(Map)
0774:             */
0775:            public void addRenderingHints(Map hints) {
0776:                rhints.putAll(hints);
0777:            }
0778:
0779:            /**
0780:             * @see Graphics2D#getRenderingHints()
0781:             */
0782:            public RenderingHints getRenderingHints() {
0783:                return rhints;
0784:            }
0785:
0786:            /**
0787:             * @see Graphics#translate(int, int)
0788:             */
0789:            public void translate(int x, int y) {
0790:                translate((double) x, (double) y);
0791:            }
0792:
0793:            /**
0794:             * @see Graphics2D#translate(double, double)
0795:             */
0796:            public void translate(double tx, double ty) {
0797:                transform.translate(tx, ty);
0798:            }
0799:
0800:            /**
0801:             * @see Graphics2D#rotate(double)
0802:             */
0803:            public void rotate(double theta) {
0804:                transform.rotate(theta);
0805:            }
0806:
0807:            /**
0808:             * @see Graphics2D#rotate(double, double, double)
0809:             */
0810:            public void rotate(double theta, double x, double y) {
0811:                transform.rotate(theta, x, y);
0812:            }
0813:
0814:            /**
0815:             * @see Graphics2D#scale(double, double)
0816:             */
0817:            public void scale(double sx, double sy) {
0818:                transform.scale(sx, sy);
0819:                this .stroke = transformStroke(originalStroke);
0820:            }
0821:
0822:            /**
0823:             * @see Graphics2D#shear(double, double)
0824:             */
0825:            public void shear(double shx, double shy) {
0826:                transform.shear(shx, shy);
0827:            }
0828:
0829:            /**
0830:             * @see Graphics2D#transform(AffineTransform)
0831:             */
0832:            public void transform(AffineTransform tx) {
0833:                transform.concatenate(tx);
0834:                this .stroke = transformStroke(originalStroke);
0835:            }
0836:
0837:            /**
0838:             * @see Graphics2D#setTransform(AffineTransform)
0839:             */
0840:            public void setTransform(AffineTransform t) {
0841:                transform = new AffineTransform(t);
0842:                this .stroke = transformStroke(originalStroke);
0843:            }
0844:
0845:            /**
0846:             * @see Graphics2D#getTransform()
0847:             */
0848:            public AffineTransform getTransform() {
0849:                return new AffineTransform(transform);
0850:            }
0851:
0852:            /**
0853:             * Method contributed by Alexej Suchov
0854:             * @see Graphics2D#getPaint()
0855:             */
0856:            public Paint getPaint() {
0857:                if (realPaint != null) {
0858:                    return realPaint;
0859:                } else {
0860:                    return paint;
0861:                }
0862:            }
0863:
0864:            /**
0865:             * @see Graphics2D#getComposite()
0866:             */
0867:            public Composite getComposite() {
0868:                return composite;
0869:            }
0870:
0871:            /**
0872:             * @see Graphics2D#setBackground(Color)
0873:             */
0874:            public void setBackground(Color color) {
0875:                background = color;
0876:            }
0877:
0878:            /**
0879:             * @see Graphics2D#getBackground()
0880:             */
0881:            public Color getBackground() {
0882:                return background;
0883:            }
0884:
0885:            /**
0886:             * @see Graphics2D#getStroke()
0887:             */
0888:            public Stroke getStroke() {
0889:                return originalStroke;
0890:            }
0891:
0892:            /**
0893:             * @see Graphics2D#getFontRenderContext()
0894:             */
0895:            public FontRenderContext getFontRenderContext() {
0896:                boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON
0897:                        .equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));
0898:                boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON
0899:                        .equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS));
0900:                return new FontRenderContext(new AffineTransform(), antialias,
0901:                        fractions);
0902:            }
0903:
0904:            /**
0905:             * @see Graphics#create()
0906:             */
0907:            public Graphics create() {
0908:                PdfGraphics2D g2 = new PdfGraphics2D();
0909:                g2.onlyShapes = this .onlyShapes;
0910:                g2.transform = new AffineTransform(this .transform);
0911:                g2.baseFonts = this .baseFonts;
0912:                g2.fontMapper = this .fontMapper;
0913:                g2.paint = this .paint;
0914:                g2.fillGState = this .fillGState;
0915:                g2.strokeGState = this .strokeGState;
0916:                g2.background = this .background;
0917:                g2.mediaTracker = this .mediaTracker;
0918:                g2.convertImagesToJPEG = this .convertImagesToJPEG;
0919:                g2.jpegQuality = this .jpegQuality;
0920:                g2.setFont(this .font);
0921:                g2.cb = this .cb.getDuplicate();
0922:                g2.cb.saveState();
0923:                g2.width = this .width;
0924:                g2.height = this .height;
0925:                g2.followPath(new Area(new Rectangle2D.Float(0, 0, width,
0926:                        height)), CLIP);
0927:                if (this .clip != null)
0928:                    g2.clip = new Area(this .clip);
0929:                g2.composite = composite;
0930:                g2.stroke = stroke;
0931:                g2.originalStroke = originalStroke;
0932:                g2.strokeOne = (BasicStroke) g2.transformStroke(g2.strokeOne);
0933:                g2.oldStroke = g2.strokeOne;
0934:                g2.setStrokeDiff(g2.oldStroke, null);
0935:                g2.cb.saveState();
0936:                if (g2.clip != null)
0937:                    g2.followPath(g2.clip, CLIP);
0938:                g2.kid = true;
0939:                if (this .kids == null)
0940:                    this .kids = new ArrayList();
0941:                this .kids.add(new Integer(cb.getInternalBuffer().size()));
0942:                this .kids.add(g2);
0943:                return g2;
0944:            }
0945:
0946:            public PdfContentByte getContent() {
0947:                return this .cb;
0948:            }
0949:
0950:            /**
0951:             * @see Graphics#getColor()
0952:             */
0953:            public Color getColor() {
0954:                if (paint instanceof  Color) {
0955:                    return (Color) paint;
0956:                } else {
0957:                    return Color.black;
0958:                }
0959:            }
0960:
0961:            /**
0962:             * @see Graphics#setColor(Color)
0963:             */
0964:            public void setColor(Color color) {
0965:                setPaint(color);
0966:            }
0967:
0968:            /**
0969:             * @see Graphics#setPaintMode()
0970:             */
0971:            public void setPaintMode() {
0972:            }
0973:
0974:            /**
0975:             * @see Graphics#setXORMode(Color)
0976:             */
0977:            public void setXORMode(Color c1) {
0978:
0979:            }
0980:
0981:            /**
0982:             * @see Graphics#getFont()
0983:             */
0984:            public Font getFont() {
0985:                return font;
0986:            }
0987:
0988:            /**
0989:             * @see Graphics#setFont(Font)
0990:             */
0991:            /**
0992:             * Sets the current font.
0993:             */
0994:            public void setFont(Font f) {
0995:                if (f == null)
0996:                    return;
0997:                if (onlyShapes) {
0998:                    font = f;
0999:                    return;
1000:                }
1001:                if (f == font)
1002:                    return;
1003:                font = f;
1004:                fontSize = f.getSize2D();
1005:                baseFont = getCachedBaseFont(f);
1006:            }
1007:
1008:            private BaseFont getCachedBaseFont(Font f) {
1009:                synchronized (baseFonts) {
1010:                    BaseFont bf = (BaseFont) baseFonts.get(f.getFontName());
1011:                    if (bf == null) {
1012:                        bf = fontMapper.awtToPdf(f);
1013:                        baseFonts.put(f.getFontName(), bf);
1014:                    }
1015:                    return bf;
1016:                }
1017:            }
1018:
1019:            /**
1020:             * @see Graphics#getFontMetrics(Font)
1021:             */
1022:            public FontMetrics getFontMetrics(Font f) {
1023:                return dg2.getFontMetrics(f);
1024:            }
1025:
1026:            /**
1027:             * @see Graphics#getClipBounds()
1028:             */
1029:            public Rectangle getClipBounds() {
1030:                if (clip == null)
1031:                    return null;
1032:                return getClip().getBounds();
1033:            }
1034:
1035:            /**
1036:             * @see Graphics#clipRect(int, int, int, int)
1037:             */
1038:            public void clipRect(int x, int y, int width, int height) {
1039:                Rectangle2D rect = new Rectangle2D.Double(x, y, width, height);
1040:                clip(rect);
1041:            }
1042:
1043:            /**
1044:             * @see Graphics#setClip(int, int, int, int)
1045:             */
1046:            public void setClip(int x, int y, int width, int height) {
1047:                Rectangle2D rect = new Rectangle2D.Double(x, y, width, height);
1048:                setClip(rect);
1049:            }
1050:
1051:            /**
1052:             * @see Graphics2D#clip(Shape)
1053:             */
1054:            public void clip(Shape s) {
1055:                if (s == null) {
1056:                    setClip(null);
1057:                    return;
1058:                }
1059:                s = transform.createTransformedShape(s);
1060:                if (clip == null)
1061:                    clip = new Area(s);
1062:                else
1063:                    clip.intersect(new Area(s));
1064:                followPath(s, CLIP);
1065:            }
1066:
1067:            /**
1068:             * @see Graphics#getClip()
1069:             */
1070:            public Shape getClip() {
1071:                try {
1072:                    return transform.createInverse().createTransformedShape(
1073:                            clip);
1074:                } catch (NoninvertibleTransformException e) {
1075:                    return null;
1076:                }
1077:            }
1078:
1079:            /**
1080:             * @see Graphics#setClip(Shape)
1081:             */
1082:            public void setClip(Shape s) {
1083:                cb.restoreState();
1084:                cb.saveState();
1085:                if (s != null)
1086:                    s = transform.createTransformedShape(s);
1087:                if (s == null) {
1088:                    clip = null;
1089:                } else {
1090:                    clip = new Area(s);
1091:                    followPath(s, CLIP);
1092:                }
1093:                paintFill = paintStroke = null;
1094:                currentFillGState = currentStrokeGState = 255;
1095:                oldStroke = strokeOne;
1096:            }
1097:
1098:            /**
1099:             * @see Graphics#copyArea(int, int, int, int, int, int)
1100:             */
1101:            public void copyArea(int x, int y, int width, int height, int dx,
1102:                    int dy) {
1103:
1104:            }
1105:
1106:            /**
1107:             * @see Graphics#drawLine(int, int, int, int)
1108:             */
1109:            public void drawLine(int x1, int y1, int x2, int y2) {
1110:                Line2D line = new Line2D.Double((double) x1, (double) y1,
1111:                        (double) x2, (double) y2);
1112:                draw(line);
1113:            }
1114:
1115:            /**
1116:             * @see Graphics#fillRect(int, int, int, int)
1117:             */
1118:            public void drawRect(int x, int y, int width, int height) {
1119:                draw(new Rectangle(x, y, width, height));
1120:            }
1121:
1122:            /**
1123:             * @see Graphics#fillRect(int, int, int, int)
1124:             */
1125:            public void fillRect(int x, int y, int width, int height) {
1126:                fill(new Rectangle(x, y, width, height));
1127:            }
1128:
1129:            /**
1130:             * @see Graphics#clearRect(int, int, int, int)
1131:             */
1132:            public void clearRect(int x, int y, int width, int height) {
1133:                Paint temp = paint;
1134:                setPaint(background);
1135:                fillRect(x, y, width, height);
1136:                setPaint(temp);
1137:            }
1138:
1139:            /**
1140:             * @see Graphics#drawRoundRect(int, int, int, int, int, int)
1141:             */
1142:            public void drawRoundRect(int x, int y, int width, int height,
1143:                    int arcWidth, int arcHeight) {
1144:                RoundRectangle2D rect = new RoundRectangle2D.Double(x, y,
1145:                        width, height, arcWidth, arcHeight);
1146:                draw(rect);
1147:            }
1148:
1149:            /**
1150:             * @see Graphics#fillRoundRect(int, int, int, int, int, int)
1151:             */
1152:            public void fillRoundRect(int x, int y, int width, int height,
1153:                    int arcWidth, int arcHeight) {
1154:                RoundRectangle2D rect = new RoundRectangle2D.Double(x, y,
1155:                        width, height, arcWidth, arcHeight);
1156:                fill(rect);
1157:            }
1158:
1159:            /**
1160:             * @see Graphics#drawOval(int, int, int, int)
1161:             */
1162:            public void drawOval(int x, int y, int width, int height) {
1163:                Ellipse2D oval = new Ellipse2D.Float((float) x, (float) y,
1164:                        (float) width, (float) height);
1165:                draw(oval);
1166:            }
1167:
1168:            /**
1169:             * @see Graphics#fillOval(int, int, int, int)
1170:             */
1171:            public void fillOval(int x, int y, int width, int height) {
1172:                Ellipse2D oval = new Ellipse2D.Float((float) x, (float) y,
1173:                        (float) width, (float) height);
1174:                fill(oval);
1175:            }
1176:
1177:            /**
1178:             * @see Graphics#drawArc(int, int, int, int, int, int)
1179:             */
1180:            public void drawArc(int x, int y, int width, int height,
1181:                    int startAngle, int arcAngle) {
1182:                Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle,
1183:                        arcAngle, Arc2D.OPEN);
1184:                draw(arc);
1185:
1186:            }
1187:
1188:            /**
1189:             * @see Graphics#fillArc(int, int, int, int, int, int)
1190:             */
1191:            public void fillArc(int x, int y, int width, int height,
1192:                    int startAngle, int arcAngle) {
1193:                Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle,
1194:                        arcAngle, Arc2D.PIE);
1195:                fill(arc);
1196:            }
1197:
1198:            /**
1199:             * @see Graphics#drawPolyline(int[], int[], int)
1200:             */
1201:            public void drawPolyline(int[] x, int[] y, int nPoints) {
1202:                PolylineShape polyline = new PolylineShape(x, y, nPoints);
1203:                draw(polyline);
1204:            }
1205:
1206:            /**
1207:             * @see Graphics#drawPolygon(int[], int[], int)
1208:             */
1209:            public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
1210:                Polygon poly = new Polygon(xPoints, yPoints, nPoints);
1211:                draw(poly);
1212:            }
1213:
1214:            /**
1215:             * @see Graphics#fillPolygon(int[], int[], int)
1216:             */
1217:            public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
1218:                Polygon poly = new Polygon();
1219:                for (int i = 0; i < nPoints; i++) {
1220:                    poly.addPoint(xPoints[i], yPoints[i]);
1221:                }
1222:                fill(poly);
1223:            }
1224:
1225:            /**
1226:             * @see Graphics#drawImage(Image, int, int, ImageObserver)
1227:             */
1228:            public boolean drawImage(Image img, int x, int y,
1229:                    ImageObserver observer) {
1230:                return drawImage(img, x, y, null, observer);
1231:            }
1232:
1233:            /**
1234:             * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
1235:             */
1236:            public boolean drawImage(Image img, int x, int y, int width,
1237:                    int height, ImageObserver observer) {
1238:                return drawImage(img, x, y, width, height, null, observer);
1239:            }
1240:
1241:            /**
1242:             * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
1243:             */
1244:            public boolean drawImage(Image img, int x, int y, Color bgcolor,
1245:                    ImageObserver observer) {
1246:                waitForImage(img);
1247:                return drawImage(img, x, y, img.getWidth(observer), img
1248:                        .getHeight(observer), bgcolor, observer);
1249:            }
1250:
1251:            /**
1252:             * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
1253:             */
1254:            public boolean drawImage(Image img, int x, int y, int width,
1255:                    int height, Color bgcolor, ImageObserver observer) {
1256:                waitForImage(img);
1257:                double scalex = width / (double) img.getWidth(observer);
1258:                double scaley = height / (double) img.getHeight(observer);
1259:                AffineTransform tx = AffineTransform.getTranslateInstance(x, y);
1260:                tx.scale(scalex, scaley);
1261:                return drawImage(img, null, tx, bgcolor, observer);
1262:            }
1263:
1264:            /**
1265:             * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, ImageObserver)
1266:             */
1267:            public boolean drawImage(Image img, int dx1, int dy1, int dx2,
1268:                    int dy2, int sx1, int sy1, int sx2, int sy2,
1269:                    ImageObserver observer) {
1270:                return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
1271:                        null, observer);
1272:            }
1273:
1274:            /**
1275:             * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, Color, ImageObserver)
1276:             */
1277:            public boolean drawImage(Image img, int dx1, int dy1, int dx2,
1278:                    int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
1279:                    ImageObserver observer) {
1280:                waitForImage(img);
1281:                double dwidth = (double) dx2 - dx1;
1282:                double dheight = (double) dy2 - dy1;
1283:                double swidth = (double) sx2 - sx1;
1284:                double sheight = (double) sy2 - sy1;
1285:
1286:                //if either width or height is 0, then there is nothing to draw
1287:                if (dwidth == 0 || dheight == 0 || swidth == 0 || sheight == 0)
1288:                    return true;
1289:
1290:                double scalex = dwidth / swidth;
1291:                double scaley = dheight / sheight;
1292:
1293:                double transx = sx1 * scalex;
1294:                double transy = sy1 * scaley;
1295:                AffineTransform tx = AffineTransform.getTranslateInstance(dx1
1296:                        - transx, dy1 - transy);
1297:                tx.scale(scalex, scaley);
1298:
1299:                BufferedImage mask = new BufferedImage(img.getWidth(observer),
1300:                        img.getHeight(observer), BufferedImage.TYPE_BYTE_BINARY);
1301:                Graphics g = mask.getGraphics();
1302:                g.fillRect(sx1, sy1, (int) swidth, (int) sheight);
1303:                drawImage(img, mask, tx, null, observer);
1304:                g.dispose();
1305:                return true;
1306:            }
1307:
1308:            /**
1309:             * @see Graphics#dispose()
1310:             */
1311:            public void dispose() {
1312:                if (kid)
1313:                    return;
1314:                if (!disposeCalled) {
1315:                    disposeCalled = true;
1316:                    cb.restoreState();
1317:                    cb.restoreState();
1318:                    dg2.dispose();
1319:                    dg2 = null;
1320:                    if (kids != null) {
1321:                        ByteBuffer buf = new ByteBuffer();
1322:                        internalDispose(buf);
1323:                        ByteBuffer buf2 = cb.getInternalBuffer();
1324:                        buf2.reset();
1325:                        buf2.append(buf);
1326:                    }
1327:                }
1328:            }
1329:
1330:            private void internalDispose(ByteBuffer buf) {
1331:                int last = 0;
1332:                int pos = 0;
1333:                ByteBuffer buf2 = cb.getInternalBuffer();
1334:                if (kids != null) {
1335:                    for (int k = 0; k < kids.size(); k += 2) {
1336:                        pos = ((Integer) kids.get(k)).intValue();
1337:                        PdfGraphics2D g2 = (PdfGraphics2D) kids.get(k + 1);
1338:                        g2.cb.restoreState();
1339:                        g2.cb.restoreState();
1340:                        buf.append(buf2.getBuffer(), last, pos - last);
1341:                        g2.dg2.dispose();
1342:                        g2.dg2 = null;
1343:                        g2.internalDispose(buf);
1344:                        last = pos;
1345:                    }
1346:                }
1347:                buf.append(buf2.getBuffer(), last, buf2.size() - last);
1348:            }
1349:
1350:            ///////////////////////////////////////////////
1351:            //
1352:            //
1353:            //		implementation specific methods
1354:            //
1355:            //
1356:
1357:            private void followPath(Shape s, int drawType) {
1358:                if (s == null)
1359:                    return;
1360:                if (drawType == STROKE) {
1361:                    if (!(stroke instanceof  BasicStroke)) {
1362:                        s = stroke.createStrokedShape(s);
1363:                        followPath(s, FILL);
1364:                        return;
1365:                    }
1366:                }
1367:                if (drawType == STROKE) {
1368:                    setStrokeDiff(stroke, oldStroke);
1369:                    oldStroke = stroke;
1370:                    setStrokePaint();
1371:                } else if (drawType == FILL)
1372:                    setFillPaint();
1373:                PathIterator points;
1374:                int traces = 0;
1375:                if (drawType == CLIP)
1376:                    points = s.getPathIterator(IDENTITY);
1377:                else
1378:                    points = s.getPathIterator(transform);
1379:                float[] coords = new float[6];
1380:                while (!points.isDone()) {
1381:                    ++traces;
1382:                    int segtype = points.currentSegment(coords);
1383:                    normalizeY(coords);
1384:                    switch (segtype) {
1385:                    case PathIterator.SEG_CLOSE:
1386:                        cb.closePath();
1387:                        break;
1388:
1389:                    case PathIterator.SEG_CUBICTO:
1390:                        cb.curveTo(coords[0], coords[1], coords[2], coords[3],
1391:                                coords[4], coords[5]);
1392:                        break;
1393:
1394:                    case PathIterator.SEG_LINETO:
1395:                        cb.lineTo(coords[0], coords[1]);
1396:                        break;
1397:
1398:                    case PathIterator.SEG_MOVETO:
1399:                        cb.moveTo(coords[0], coords[1]);
1400:                        break;
1401:
1402:                    case PathIterator.SEG_QUADTO:
1403:                        cb.curveTo(coords[0], coords[1], coords[2], coords[3]);
1404:                        break;
1405:                    }
1406:                    points.next();
1407:                }
1408:                switch (drawType) {
1409:                case FILL:
1410:                    if (traces > 0) {
1411:                        if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD)
1412:                            cb.eoFill();
1413:                        else
1414:                            cb.fill();
1415:                    }
1416:                    break;
1417:                case STROKE:
1418:                    if (traces > 0)
1419:                        cb.stroke();
1420:                    break;
1421:                default: //drawType==CLIP
1422:                    if (traces == 0)
1423:                        cb.rectangle(0, 0, 0, 0);
1424:                    if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD)
1425:                        cb.eoClip();
1426:                    else
1427:                        cb.clip();
1428:                    cb.newPath();
1429:                }
1430:            }
1431:
1432:            private float normalizeY(float y) {
1433:                return this .height - y;
1434:            }
1435:
1436:            private void normalizeY(float[] coords) {
1437:                coords[1] = normalizeY(coords[1]);
1438:                coords[3] = normalizeY(coords[3]);
1439:                coords[5] = normalizeY(coords[5]);
1440:            }
1441:
1442:            private AffineTransform normalizeMatrix() {
1443:                double[] mx = new double[6];
1444:                AffineTransform result = AffineTransform.getTranslateInstance(
1445:                        0, 0);
1446:                result.getMatrix(mx);
1447:                mx[3] = -1;
1448:                mx[5] = height;
1449:                result = new AffineTransform(mx);
1450:                result.concatenate(transform);
1451:                return result;
1452:            }
1453:
1454:            private boolean drawImage(Image img, Image mask,
1455:                    AffineTransform xform, Color bgColor, ImageObserver obs) {
1456:                if (xform == null)
1457:                    return true;
1458:
1459:                xform.translate(0, img.getHeight(obs));
1460:                xform.scale(img.getWidth(obs), img.getHeight(obs));
1461:
1462:                AffineTransform inverse = this .normalizeMatrix();
1463:                AffineTransform flipper = AffineTransform.getScaleInstance(1,
1464:                        -1);
1465:                inverse.concatenate(xform);
1466:                inverse.concatenate(flipper);
1467:
1468:                double[] mx = new double[6];
1469:                inverse.getMatrix(mx);
1470:                if (currentFillGState != 255) {
1471:                    PdfGState gs = fillGState[255];
1472:                    if (gs == null) {
1473:                        gs = new PdfGState();
1474:                        gs.setFillOpacity(1);
1475:                        fillGState[255] = gs;
1476:                    }
1477:                    cb.setGState(gs);
1478:                }
1479:
1480:                try {
1481:                    com.lowagie.text.Image image = null;
1482:                    if (!convertImagesToJPEG) {
1483:                        image = com.lowagie.text.Image
1484:                                .getInstance(img, bgColor);
1485:                    } else {
1486:                        BufferedImage scaled = new BufferedImage(img
1487:                                .getWidth(null), img.getHeight(null),
1488:                                BufferedImage.TYPE_INT_RGB);
1489:                        Graphics2D g3 = scaled.createGraphics();
1490:                        g3.drawImage(img, 0, 0, img.getWidth(null), img
1491:                                .getHeight(null), null);
1492:                        g3.dispose();
1493:
1494:                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1495:                        ImageWriteParam iwparam = new JPEGImageWriteParam(
1496:                                Locale.getDefault());
1497:                        iwparam
1498:                                .setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
1499:                        iwparam.setCompressionQuality(jpegQuality);//Set here your compression rate
1500:                        ImageWriter iw = (ImageWriter) ImageIO
1501:                                .getImageWritersByFormatName("jpg").next();
1502:                        ImageOutputStream ios = ImageIO
1503:                                .createImageOutputStream(baos);
1504:                        iw.setOutput(ios);
1505:                        iw.write(null, new IIOImage(scaled, null, null),
1506:                                iwparam);
1507:                        iw.dispose();
1508:                        ios.close();
1509:
1510:                        scaled.flush();
1511:                        scaled = null;
1512:                        image = com.lowagie.text.Image.getInstance(baos
1513:                                .toByteArray());
1514:
1515:                    }
1516:                    if (mask != null) {
1517:                        com.lowagie.text.Image msk = com.lowagie.text.Image
1518:                                .getInstance(mask, null, true);
1519:                        msk.makeMask();
1520:                        msk.setInverted(true);
1521:                        image.setImageMask(msk);
1522:                    }
1523:                    cb.addImage(image, (float) mx[0], (float) mx[1],
1524:                            (float) mx[2], (float) mx[3], (float) mx[4],
1525:                            (float) mx[5]);
1526:                } catch (Exception ex) {
1527:                    throw new IllegalArgumentException();
1528:                }
1529:                if (currentFillGState != 255) {
1530:                    PdfGState gs = fillGState[currentFillGState];
1531:                    cb.setGState(gs);
1532:                }
1533:                return true;
1534:            }
1535:
1536:            private boolean checkNewPaint(Paint oldPaint) {
1537:                if (paint == oldPaint)
1538:                    return false;
1539:                return !((paint instanceof  Color) && paint.equals(oldPaint));
1540:            }
1541:
1542:            private void setFillPaint() {
1543:                if (checkNewPaint(paintFill)) {
1544:                    paintFill = paint;
1545:                    setPaint(false, 0, 0, true);
1546:                }
1547:            }
1548:
1549:            private void setStrokePaint() {
1550:                if (checkNewPaint(paintStroke)) {
1551:                    paintStroke = paint;
1552:                    setPaint(false, 0, 0, false);
1553:                }
1554:            }
1555:
1556:            private void setPaint(boolean invert, double xoffset,
1557:                    double yoffset, boolean fill) {
1558:                if (paint instanceof  Color) {
1559:                    Color color = (Color) paint;
1560:                    int alpha = color.getAlpha();
1561:                    if (fill) {
1562:                        if (alpha != currentFillGState) {
1563:                            currentFillGState = alpha;
1564:                            PdfGState gs = fillGState[alpha];
1565:                            if (gs == null) {
1566:                                gs = new PdfGState();
1567:                                gs.setFillOpacity((float) alpha / 255f);
1568:                                fillGState[alpha] = gs;
1569:                            }
1570:                            cb.setGState(gs);
1571:                        }
1572:                        cb.setColorFill(color);
1573:                    } else {
1574:                        if (alpha != currentStrokeGState) {
1575:                            currentStrokeGState = alpha;
1576:                            PdfGState gs = strokeGState[alpha];
1577:                            if (gs == null) {
1578:                                gs = new PdfGState();
1579:                                gs.setStrokeOpacity((float) alpha / 255f);
1580:                                strokeGState[alpha] = gs;
1581:                            }
1582:                            cb.setGState(gs);
1583:                        }
1584:                        cb.setColorStroke(color);
1585:                    }
1586:                } else if (paint instanceof  GradientPaint) {
1587:                    GradientPaint gp = (GradientPaint) paint;
1588:                    Point2D p1 = gp.getPoint1();
1589:                    transform.transform(p1, p1);
1590:                    Point2D p2 = gp.getPoint2();
1591:                    transform.transform(p2, p2);
1592:                    Color c1 = gp.getColor1();
1593:                    Color c2 = gp.getColor2();
1594:                    PdfShading shading = PdfShading.simpleAxial(cb
1595:                            .getPdfWriter(), (float) p1.getX(),
1596:                            normalizeY((float) p1.getY()), (float) p2.getX(),
1597:                            normalizeY((float) p2.getY()), c1, c2);
1598:                    PdfShadingPattern pat = new PdfShadingPattern(shading);
1599:                    if (fill)
1600:                        cb.setShadingFill(pat);
1601:                    else
1602:                        cb.setShadingStroke(pat);
1603:                } else if (paint instanceof  TexturePaint) {
1604:                    try {
1605:                        TexturePaint tp = (TexturePaint) paint;
1606:                        BufferedImage img = tp.getImage();
1607:                        Rectangle2D rect = tp.getAnchorRect();
1608:                        com.lowagie.text.Image image = com.lowagie.text.Image
1609:                                .getInstance(img, null);
1610:                        PdfPatternPainter pattern = cb.createPattern(image
1611:                                .getWidth(), image.getHeight());
1612:                        AffineTransform inverse = this .normalizeMatrix();
1613:                        inverse.translate(rect.getX(), rect.getY());
1614:                        inverse.scale(rect.getWidth() / image.getWidth(), -rect
1615:                                .getHeight()
1616:                                / image.getHeight());
1617:                        double[] mx = new double[6];
1618:                        inverse.getMatrix(mx);
1619:                        pattern.setPatternMatrix((float) mx[0], (float) mx[1],
1620:                                (float) mx[2], (float) mx[3], (float) mx[4],
1621:                                (float) mx[5]);
1622:                        image.setAbsolutePosition(0, 0);
1623:                        pattern.addImage(image);
1624:                        if (fill)
1625:                            cb.setPatternFill(pattern);
1626:                        else
1627:                            cb.setPatternStroke(pattern);
1628:                    } catch (Exception ex) {
1629:                        if (fill)
1630:                            cb.setColorFill(Color.gray);
1631:                        else
1632:                            cb.setColorStroke(Color.gray);
1633:                    }
1634:                } else {
1635:                    try {
1636:                        BufferedImage img = null;
1637:                        int type = BufferedImage.TYPE_4BYTE_ABGR;
1638:                        if (paint.getTransparency() == Transparency.OPAQUE) {
1639:                            type = BufferedImage.TYPE_3BYTE_BGR;
1640:                        }
1641:                        img = new BufferedImage((int) width, (int) height, type);
1642:                        Graphics2D g = (Graphics2D) img.getGraphics();
1643:                        g.transform(transform);
1644:                        AffineTransform inv = transform.createInverse();
1645:                        Shape fillRect = new Rectangle2D.Double(0, 0, img
1646:                                .getWidth(), img.getHeight());
1647:                        fillRect = inv.createTransformedShape(fillRect);
1648:                        g.setPaint(paint);
1649:                        g.fill(fillRect);
1650:                        if (invert) {
1651:                            AffineTransform tx = new AffineTransform();
1652:                            tx.scale(1, -1);
1653:                            tx.translate(-xoffset, -yoffset);
1654:                            g.drawImage(img, tx, null);
1655:                        }
1656:                        g.dispose();
1657:                        g = null;
1658:                        com.lowagie.text.Image image = com.lowagie.text.Image
1659:                                .getInstance(img, null);
1660:                        PdfPatternPainter pattern = cb.createPattern(width,
1661:                                height);
1662:                        image.setAbsolutePosition(0, 0);
1663:                        pattern.addImage(image);
1664:                        if (fill)
1665:                            cb.setPatternFill(pattern);
1666:                        else
1667:                            cb.setPatternStroke(pattern);
1668:                    } catch (Exception ex) {
1669:                        if (fill)
1670:                            cb.setColorFill(Color.gray);
1671:                        else
1672:                            cb.setColorStroke(Color.gray);
1673:                    }
1674:                }
1675:            }
1676:
1677:            private synchronized void waitForImage(java.awt.Image image) {
1678:                if (mediaTracker == null)
1679:                    mediaTracker = new MediaTracker(
1680:                            new PdfGraphics2D.fakeComponent());
1681:                mediaTracker.addImage(image, 0);
1682:                try {
1683:                    mediaTracker.waitForID(0);
1684:                } catch (InterruptedException e) {
1685:                    // empty on purpose
1686:                }
1687:                mediaTracker.removeImage(image);
1688:            }
1689:
1690:            static private class fakeComponent extends Component {
1691:
1692:                private static final long serialVersionUID = 6450197945596086638L;
1693:            }
1694:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.