Source Code Cross Referenced for CSCreator.java in  » PDF » jPod » de » intarsys » pdf » content » common » 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 » jPod » de.intarsys.pdf.content.common 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2007, intarsys consulting GmbH
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without
0005:         * modification, are permitted provided that the following conditions are met:
0006:         *
0007:         * - Redistributions of source code must retain the above copyright notice,
0008:         *   this list of conditions and the following disclaimer.
0009:         *
0010:         * - Redistributions in binary form must reproduce the above copyright notice,
0011:         *   this list of conditions and the following disclaimer in the documentation
0012:         *   and/or other materials provided with the distribution.
0013:         *
0014:         * - Neither the name of intarsys nor the names of its contributors may be used
0015:         *   to endorse or promote products derived from this software without specific
0016:         *   prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028:         * POSSIBILITY OF SUCH DAMAGE.
0029:         */
0030:        package de.intarsys.pdf.content.common;
0031:
0032:        import java.awt.geom.AffineTransform;
0033:        import java.io.ByteArrayOutputStream;
0034:        import java.util.ArrayList;
0035:        import java.util.Iterator;
0036:        import java.util.List;
0037:
0038:        import de.intarsys.pdf.content.CSContent;
0039:        import de.intarsys.pdf.content.CSOperation;
0040:        import de.intarsys.pdf.content.CSOperators;
0041:        import de.intarsys.pdf.content.CSVirtualDevice;
0042:        import de.intarsys.pdf.content.ICSInterpreter;
0043:        import de.intarsys.pdf.content.IContentStreamProvider;
0044:        import de.intarsys.pdf.content.TextState;
0045:        import de.intarsys.pdf.cos.COSArray;
0046:        import de.intarsys.pdf.cos.COSDictionary;
0047:        import de.intarsys.pdf.cos.COSFixed;
0048:        import de.intarsys.pdf.cos.COSInteger;
0049:        import de.intarsys.pdf.cos.COSName;
0050:        import de.intarsys.pdf.cos.COSObject;
0051:        import de.intarsys.pdf.cos.COSString;
0052:        import de.intarsys.pdf.cos.COSTools;
0053:        import de.intarsys.pdf.font.PDFont;
0054:        import de.intarsys.pdf.font.PDFontTools;
0055:        import de.intarsys.pdf.pd.IResourcesProvider;
0056:        import de.intarsys.pdf.pd.PDCSDeviceCMYK;
0057:        import de.intarsys.pdf.pd.PDCSDeviceRGB;
0058:        import de.intarsys.pdf.pd.PDColorSpace;
0059:        import de.intarsys.pdf.pd.PDExtGState;
0060:        import de.intarsys.pdf.pd.PDForm;
0061:        import de.intarsys.pdf.pd.PDImage;
0062:        import de.intarsys.pdf.pd.PDObject;
0063:        import de.intarsys.pdf.pd.PDPage;
0064:        import de.intarsys.pdf.pd.PDPattern;
0065:        import de.intarsys.pdf.pd.PDResources;
0066:        import de.intarsys.pdf.pd.PDShading;
0067:        import de.intarsys.pdf.pd.PDXObject;
0068:
0069:        /**
0070:         * An implementation helping to create a PDF content stream using higher level
0071:         * abstractions than the PDF operators.
0072:         * <p>
0073:         * This object deals with two abstractions:
0074:         * <p>
0075:         * The {@link CSContent}, a sequence of PDF operators. The {@link CSContent}
0076:         * can be read from an existing object like a {@link PDPage} or a {@link PDForm}
0077:         * or can be newly created, suing the factory methods in {@link CSContent}.
0078:         * <p>
0079:         * The second abstraction is the {@link IResourcesProvider} for the
0080:         * {@link PDResources} like Fonts, XObjects, ... that are referenced in the
0081:         * {@link CSContent}. The resources of the provider are not accessed until a
0082:         * resource relevant operation is created.
0083:         * 
0084:         * <p>
0085:         * This implementation is (nearly, see AffineTransform) independent of AWT or
0086:         * any other window toolkit.
0087:         * 
0088:         */
0089:        public class CSCreator extends CSVirtualDevice {
0090:            /** a constant for the ease of circle creation with beziers */
0091:            static public final float KAPPA = 0.5522847498f;
0092:
0093:            /** local constants */
0094:            private static final float THOUSAND = 1000f;
0095:
0096:            static public final int VALUE_COLOR_PRECISION = 3;
0097:
0098:            static public final int VALUE_COORDINATE_PRECISION = 3;
0099:
0100:            static public final int VALUE_DASH_PRECISION = 2;
0101:
0102:            static public final int VALUE_FACTOR_PRECISION = 4;
0103:
0104:            static public final int VALUE_FLATNESS_PRECISION = 3;
0105:
0106:            static public final int VALUE_FONT_PRECISION = 2;
0107:
0108:            static public final int VALUE_GRAY_PRECISION = 3;
0109:
0110:            static public final int VALUE_WIDTH_PRECISION = 3;
0111:
0112:            /**
0113:             * Create a {@link CSCreator} on an existing {@link CSContent}. The content
0114:             * may be read from a PDPage or a PDForm or can be completely new.
0115:             * <p>
0116:             * This is the most basic factory method where you have the freedom to
0117:             * decide where the content comes from, where the resources come frome and
0118:             * wher the content will be used.
0119:             * 
0120:             * @param content
0121:             *            The content stream to write to.
0122:             * @param resourcesProvider
0123:             *            The provider for the {@link PDResources} that contain the
0124:             *            resources referenced in the CSContent.
0125:             * 
0126:             * @return The new {@link CSCreator}
0127:             */
0128:            static public CSCreator createFromContent(CSContent content,
0129:                    IResourcesProvider resourcesProvider) {
0130:                CSCreator result = new CSCreator(content, null,
0131:                        resourcesProvider);
0132:                return result;
0133:            }
0134:
0135:            /**
0136:             * Create a {@link CSCreator} on a newly created {@link CSContent}. The
0137:             * content is linked with the {@link IContentStreamProvider} and flushed to
0138:             * it when calling "flush".
0139:             * 
0140:             * @param provider
0141:             *            The provider whose content stream will be replaced with the
0142:             *            result of this {@link CSCreator}
0143:             * 
0144:             * @return The new {@link CSCreator}
0145:             */
0146:            static public CSCreator createNew(IContentStreamProvider provider) {
0147:                CSContent content = CSContent.createNew();
0148:                CSCreator result = new CSCreator(content, provider, provider);
0149:                return result;
0150:            }
0151:
0152:            /**
0153:             * Create a {@link CSCreator} on a newly created {@link CSContent}. The
0154:             * content is not linked with the provider, which is only used the a
0155:             * {@link IResourcesProvider}. The resulting content can be accessed using
0156:             * "getContent".
0157:             * 
0158:             * @param provider
0159:             *            The provider for resources within the new {@link CSContent}.
0160:             * 
0161:             * @return The new {@link CSCreator}
0162:             */
0163:            static public CSCreator createNewDetached(
0164:                    IResourcesProvider provider) {
0165:                CSContent content = CSContent.createNew();
0166:                CSCreator result = new CSCreator(content, null, provider);
0167:                return result;
0168:            }
0169:
0170:            /**
0171:             * Create a {@link CSCreator} on an existing {@link CSContent} that will be
0172:             * read from the {@link IContentStreamProvider}. The old contents will be
0173:             * preserved, all operations are concatenated. The content is linked with
0174:             * the {@link IContentStreamProvider} and flushed to it when calling
0175:             * "flush".
0176:             * 
0177:             * @param provider
0178:             *            The provider whose content stream will be replaced with the
0179:             *            result of this {@link CSCreator}
0180:             * 
0181:             * @return The new {@link CSCreator}
0182:             */
0183:            static public CSCreator createFromProvider(
0184:                    IContentStreamProvider provider) {
0185:                CSCreator result = new CSCreator(provider.getContentStream(),
0186:                        provider, provider);
0187:                return result;
0188:            }
0189:
0190:            /** The underlying content stream represenation. */
0191:            private final CSContent content;
0192:
0193:            /**
0194:             * The resource dictionary for the objects referenced from the content
0195:             * stream
0196:             */
0197:            private PDResources resources;
0198:
0199:            /**
0200:             * An object that will provide resources for the content stream.
0201:             * <p>
0202:             * The provider is accessed only if it is needed by kind of operations
0203:             * performed, for example "textSetFont".
0204:             */
0205:            private final IResourcesProvider resourcesProvider;
0206:
0207:            /**
0208:             * An object that will provide access to the content stream and the
0209:             * containing object.
0210:             */
0211:            private final IContentStreamProvider contentStreamProvider;
0212:
0213:            /**
0214:             * A temporary buffer for strings to be rendered.
0215:             * 
0216:             * <p>
0217:             * String objects are kept here to optimize and use the rendereing of string
0218:             * arrays if possible.
0219:             * </p>
0220:             */
0221:            private List strings;
0222:
0223:            /**
0224:             * A buffer holding text runs that are positioned in continuous sequence so
0225:             * that we can optimze and keep the string together.
0226:             */
0227:            private ByteArrayOutputStream textBuffer;
0228:
0229:            /**
0230:             * Flag if we a re currently in text mode.
0231:             * 
0232:             * <p>
0233:             * Text mode is entered via "textBegin"
0234:             * </p>
0235:             */
0236:            private boolean textMode = false;
0237:
0238:            /**
0239:             * Create a {@link CSCreator}
0240:             * 
0241:             * @param content
0242:             *            The content stream to write to.
0243:             */
0244:            protected CSCreator(CSContent content,
0245:                    IContentStreamProvider contentStreamProvider,
0246:                    IResourcesProvider resourcesProvider) {
0247:                super ();
0248:                this .content = content;
0249:                this .contentStreamProvider = contentStreamProvider;
0250:                this .resourcesProvider = resourcesProvider;
0251:                // open automagically...
0252:                open(null);
0253:            }
0254:
0255:            /*
0256:             * (non-Javadoc)
0257:             * 
0258:             * @see de.intarsys.pdf.content.CSVirtualDevice#open(de.intarsys.pdf.content.ICSInterpreter)
0259:             */
0260:            public void open(ICSInterpreter pInterpreter) {
0261:                super .open(pInterpreter);
0262:                resetStrings();
0263:            }
0264:
0265:            /*
0266:             * (non-Javadoc)
0267:             * 
0268:             * @see de.intarsys.pdf.content.CSDeviceAdapter#compatibilityBegin()
0269:             */
0270:            public void compatibilityBegin() {
0271:                super .compatibilityBegin();
0272:                CSOperation operation = new CSOperation(CSOperators.CSO_BX);
0273:                getContent().addOperation(operation);
0274:            }
0275:
0276:            /*
0277:             * (non-Javadoc)
0278:             * 
0279:             * @see de.intarsys.pdf.content.CSDeviceAdapter#compatibilityEnd()
0280:             */
0281:            public void compatibilityEnd() {
0282:                super .compatibilityEnd();
0283:                CSOperation operation = new CSOperation(CSOperators.CSO_EX);
0284:                getContent().addOperation(operation);
0285:            }
0286:
0287:            /**
0288:             * Copy all operations from <code>otherContent</code> to <code>this</code>.
0289:             * <p>
0290:             * Currently no resources are copied for <code>otherContent</code>
0291:             * 
0292:             * @param otherContent
0293:             *            The source of the graphic operations.
0294:             */
0295:            public void copy(CSContent otherContent) {
0296:                int len = otherContent.size();
0297:                for (int i = 0; i < len; i++) {
0298:                    CSOperation operation = otherContent.getOperation(i);
0299:                    operationAdd(operation);
0300:                }
0301:            }
0302:
0303:            /*
0304:             * (non-Javadoc)
0305:             * 
0306:             * @see de.intarsys.pdf.content.CSDeviceAdapter#doShading(de.intarsys.pdf.cos.COSName,
0307:             *      de.intarsys.pdf.pd.PDShading)
0308:             */
0309:            public void doShading(COSName name, PDShading shading) {
0310:                textEnd();
0311:                name = checkResource(PDResources.CN_RT_Shading, PDShading.META,
0312:                        name, shading);
0313:                CSOperation operation = new CSOperation(CSOperators.CSO_sh);
0314:                operation.addOperand(name);
0315:                getContent().addOperation(operation);
0316:            }
0317:
0318:            /*
0319:             * (non-Javadoc)
0320:             * 
0321:             * @see de.intarsys.pdf.content.CSDeviceAdapter#doXObject(de.intarsys.pdf.cos.COSName,
0322:             *      de.intarsys.pdf.pd.PDXObject)
0323:             */
0324:            public void doXObject(COSName name, PDXObject xObject) {
0325:                textEnd();
0326:                name = checkResource(PDResources.CN_RT_XObject, PDXObject.META,
0327:                        name, xObject);
0328:                // do not call super - this would "expand" the XObject
0329:                CSOperation operation = new CSOperation(CSOperators.CSO_Do);
0330:                operation.addOperand(name);
0331:                getContent().addOperation(operation);
0332:            }
0333:
0334:            /**
0335:             * Flush all pending operations on the stream.
0336:             * <p>
0337:             * This must be called before the <code>getContent</code> operation is
0338:             * valid.
0339:             */
0340:            public void flush() {
0341:                textEnd();
0342:                if (getContentStreamProvider() != null) {
0343:                    getContentStreamProvider().setContentStream(getContent());
0344:                }
0345:            }
0346:
0347:            /*
0348:             * (non-Javadoc)
0349:             * 
0350:             * @see de.intarsys.pdf.content.CSDeviceAdapter#close()
0351:             */
0352:            public void close() {
0353:                flush();
0354:                super .close();
0355:            }
0356:
0357:            /**
0358:             * The {@link CSContent} we are working on. After calling <code>flush</code>
0359:             * the {@link CSContent} contains all operations stemming from calls to
0360:             * this.
0361:             * 
0362:             * @return The {@link CSContent} we are working on.
0363:             */
0364:            public CSContent getContent() {
0365:                return content;
0366:            }
0367:
0368:            protected PDResources getResources() {
0369:                if (resources == null) {
0370:                    resources = getResourcesProvider().getResources();
0371:                    if (resources == null) {
0372:                        resources = (PDResources) PDResources.META.createNew();
0373:                        getResourcesProvider().setResources(resources);
0374:                    }
0375:                }
0376:                return resources;
0377:            }
0378:
0379:            /**
0380:             * The {@link IResourcesProvider} associated with this.
0381:             * 
0382:             * @return The {@link IResourcesProvider} associated with this.
0383:             */
0384:            public IResourcesProvider getResourcesProvider() {
0385:                return resourcesProvider;
0386:            }
0387:
0388:            protected List getStrings() {
0389:                return strings;
0390:            }
0391:
0392:            protected ByteArrayOutputStream getTextBuffer() {
0393:                return textBuffer;
0394:            }
0395:
0396:            /*
0397:             * (non-Javadoc)
0398:             * 
0399:             * @see de.intarsys.pdf.content.CSDeviceAdapter#inlineImage(de.intarsys.pdf.pd.PDImage)
0400:             */
0401:            public void inlineImage(PDImage img) {
0402:                // ignore
0403:                /*
0404:                 * CSOperation operationBI = new CSOperation(CSOperators.CSO_BI);
0405:                 * getContent().addOperation(operationBI); CSOperation operationID = new
0406:                 * CSOperation(CSOperators.CSO_ID);
0407:                 * getContent().addOperation(operationID); CSOperation operationEI = new
0408:                 * CSOperation(CSOperators.CSO_EI);
0409:                 * operationEI.addOperand(COSString.create(img.cosGetStream()
0410:                 * .getDecodedBytes())); getContent().addOperation(operationEI);
0411:                 */
0412:            }
0413:
0414:            /**
0415:             * Answer <code>true</code> if the actual font in the text state is equal
0416:             * to <code>queryFont</code> and <code>queryFontSize</code>.
0417:             * 
0418:             * @param queryFont
0419:             *            The font to query.
0420:             * @param queryFontSize
0421:             *            The font size to query.
0422:             * 
0423:             * @return true if equal
0424:             */
0425:            protected boolean isFont(PDFont queryFont, float queryFontSize) {
0426:                TextState textState = graphicsState.textState;
0427:                return ((textState.getFont() != null) && textState.getFont()
0428:                        .equals(queryFont))
0429:                        && (textState.getFontSize() == queryFontSize);
0430:            }
0431:
0432:            protected boolean isNonStrokeCMYKColor(float c, float m, float y,
0433:                    float k) {
0434:                PDColorSpace colorSpace = graphicsState
0435:                        .getNonStrokeColorSpace();
0436:                if (!(colorSpace instanceof  PDCSDeviceCMYK)) {
0437:                    return false;
0438:                }
0439:                float[] colorValues = graphicsState.getNonStrokeColorValues();
0440:                return (colorValues[0] == c) && (colorValues[1] == m)
0441:                        && (colorValues[2] == y) && (colorValues[3] == k);
0442:            }
0443:
0444:            protected boolean isNonStrokeRGBColor(float r, float g, float b) {
0445:                PDColorSpace colorSpace = graphicsState
0446:                        .getNonStrokeColorSpace();
0447:                if (!(colorSpace instanceof  PDCSDeviceRGB)) {
0448:                    return false;
0449:                }
0450:                float[] colorValues = graphicsState.getNonStrokeColorValues();
0451:                return (colorValues[0] == r) && (colorValues[1] == g)
0452:                        && (colorValues[2] == b);
0453:            }
0454:
0455:            protected boolean isStrokeCMYKColor(float c, float m, float y,
0456:                    float k) {
0457:                PDColorSpace colorSpace = graphicsState.getStrokeColorSpace();
0458:                if (!(colorSpace instanceof  PDCSDeviceCMYK)) {
0459:                    return false;
0460:                }
0461:                float[] colorValues = graphicsState.getStrokeColorValues();
0462:                return (colorValues[0] == c) && (colorValues[1] == m)
0463:                        && (colorValues[2] == y) && (colorValues[3] == k);
0464:            }
0465:
0466:            protected boolean isStrokeRGBColor(float r, float g, float b) {
0467:                PDColorSpace colorSpace = graphicsState.getStrokeColorSpace();
0468:                if (!(colorSpace instanceof  PDCSDeviceRGB)) {
0469:                    return false;
0470:                }
0471:                float[] colorValues = graphicsState.getStrokeColorValues();
0472:                return (colorValues[0] == r) && (colorValues[1] == g)
0473:                        && (colorValues[2] == b);
0474:            }
0475:
0476:            protected boolean isTextMode() {
0477:                return textMode;
0478:            }
0479:
0480:            public void markedContentBegin(COSName tag) {
0481:                CSOperation operation = new CSOperation(CSOperators.CSO_BMC);
0482:                operation.addOperand(tag.copyOptional());
0483:                getContent().addOperation(operation);
0484:            }
0485:
0486:            public void markedContentBeginProperties(COSName tag,
0487:                    COSName resourceName, COSDictionary properties) {
0488:                // ignore
0489:                /*
0490:                 * CSOperation operation = new CSOperation(CSOperators.CSO_BMC);
0491:                 * operation.addOperand(tag.copyOptional());
0492:                 * getContent().addOperation(operation);
0493:                 */
0494:            }
0495:
0496:            public void markedContentEnd() {
0497:                CSOperation operation = new CSOperation(CSOperators.CSO_EMC);
0498:                getContent().addOperation(operation);
0499:            }
0500:
0501:            public void markedContentPoint(COSName tag) {
0502:                CSOperation operation = new CSOperation(CSOperators.CSO_MP);
0503:                operation.addOperand(tag.copyOptional());
0504:                getContent().addOperation(operation);
0505:            }
0506:
0507:            public void markedContentPointProperties(COSName tag,
0508:                    COSName resourceName, COSDictionary properties) {
0509:                // ignore
0510:                /*
0511:                 * CSOperation operation = new CSOperation(CSOperators.CSO_BMC);
0512:                 * operation.addOperand(tag.copyOptional());
0513:                 * getContent().addOperation(operation);
0514:                 */
0515:            }
0516:
0517:            protected void operationAdd(CSOperation operation) {
0518:                getContent().addOperation(operation);
0519:            }
0520:
0521:            /*
0522:             * (non-Javadoc)
0523:             * 
0524:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathClipEvenOdd()
0525:             */
0526:            public void pathClipEvenOdd() {
0527:                textEnd();
0528:                CSOperation operation = new CSOperation(CSOperators.CSO_Wstar);
0529:                getContent().addOperation(operation);
0530:            }
0531:
0532:            /*
0533:             * (non-Javadoc)
0534:             * 
0535:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathClipNonZero()
0536:             */
0537:            public void pathClipNonZero() {
0538:                textEnd();
0539:                CSOperation operation = new CSOperation(CSOperators.CSO_W);
0540:                getContent().addOperation(operation);
0541:            }
0542:
0543:            /*
0544:             * (non-Javadoc)
0545:             * 
0546:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathClose()
0547:             */
0548:            public void pathClose() {
0549:                textEnd();
0550:                CSOperation operation = new CSOperation(CSOperators.CSO_h);
0551:                getContent().addOperation(operation);
0552:            }
0553:
0554:            /*
0555:             * (non-Javadoc)
0556:             * 
0557:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathCloseFillStrokeEvenOdd()
0558:             */
0559:            public void pathCloseFillStrokeEvenOdd() {
0560:                textEnd();
0561:                CSOperation operation = new CSOperation(CSOperators.CSO_bstar);
0562:                getContent().addOperation(operation);
0563:            }
0564:
0565:            /*
0566:             * (non-Javadoc)
0567:             * 
0568:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathCloseFillStrokeNonZero()
0569:             */
0570:            public void pathCloseFillStrokeNonZero() {
0571:                textEnd();
0572:                CSOperation operation = new CSOperation(CSOperators.CSO_b);
0573:                getContent().addOperation(operation);
0574:            }
0575:
0576:            /*
0577:             * (non-Javadoc)
0578:             * 
0579:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathCloseStroke()
0580:             */
0581:            public void pathCloseStroke() {
0582:                textEnd();
0583:                CSOperation operation = new CSOperation(CSOperators.CSO_s);
0584:                getContent().addOperation(operation);
0585:            }
0586:
0587:            /*
0588:             * (non-Javadoc)
0589:             * 
0590:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathEnd()
0591:             */
0592:            public void pathEnd() {
0593:                textEnd();
0594:                CSOperation operation = new CSOperation(CSOperators.CSO_n);
0595:                getContent().addOperation(operation);
0596:            }
0597:
0598:            /*
0599:             * (non-Javadoc)
0600:             * 
0601:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathFillEvenOdd()
0602:             */
0603:            public void pathFillEvenOdd() {
0604:                textEnd();
0605:                CSOperation operation = new CSOperation(CSOperators.CSO_fstar);
0606:                getContent().addOperation(operation);
0607:            }
0608:
0609:            /*
0610:             * (non-Javadoc)
0611:             * 
0612:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathFillNonZero()
0613:             */
0614:            public void pathFillNonZero() {
0615:                textEnd();
0616:                CSOperation operation = new CSOperation(CSOperators.CSO_f);
0617:                getContent().addOperation(operation);
0618:            }
0619:
0620:            /*
0621:             * (non-Javadoc)
0622:             * 
0623:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathFillStrokeEvenOdd()
0624:             */
0625:            public void pathFillStrokeEvenOdd() {
0626:                textEnd();
0627:                CSOperation operation = new CSOperation(CSOperators.CSO_Bstar);
0628:                getContent().addOperation(operation);
0629:            }
0630:
0631:            /*
0632:             * (non-Javadoc)
0633:             * 
0634:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathFillStrokeNonZero()
0635:             */
0636:            public void pathFillStrokeNonZero() {
0637:                textEnd();
0638:                CSOperation operation = new CSOperation(CSOperators.CSO_B);
0639:                getContent().addOperation(operation);
0640:            }
0641:
0642:            /*
0643:             * (non-Javadoc)
0644:             * 
0645:             * @see de.intarsys.pdf.content.CSDeviceAdapter#pathStroke()
0646:             */
0647:            public void pathStroke() {
0648:                textEnd();
0649:                CSOperation operation = new CSOperation(CSOperators.CSO_S);
0650:                getContent().addOperation(operation);
0651:            }
0652:
0653:            /**
0654:             * Draw a circle. The center of the circle is at <code>x</code>,
0655:             * <code>y</code> in user space. <code>r</code> defines the radius.
0656:             * 
0657:             * @param x
0658:             *            The x coordinate of the center.
0659:             * @param y
0660:             *            The y coordinate of the center.
0661:             * @param r
0662:             *            The radius
0663:             */
0664:            public void penCircle(float x, float y, float r) {
0665:                penEllipse(x, y, r, r);
0666:            }
0667:
0668:            /*
0669:             * (non-Javadoc)
0670:             * 
0671:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penCurveToC(float, float,
0672:             *      float, float, float, float)
0673:             */
0674:            public void penCurveToC(float x1, float y1, float x2, float y2,
0675:                    float x3, float y3) {
0676:                textEnd();
0677:                CSOperation operation = new CSOperation(CSOperators.CSO_c);
0678:                operation.addOperand(COSFixed.create(x1));
0679:                operation.addOperand(COSFixed.create(y1));
0680:                operation.addOperand(COSFixed.create(x2));
0681:                operation.addOperand(COSFixed.create(y2));
0682:                operation.addOperand(COSFixed.create(x3));
0683:                operation.addOperand(COSFixed.create(y3));
0684:                getContent().addOperation(operation);
0685:            }
0686:
0687:            /*
0688:             * (non-Javadoc)
0689:             * 
0690:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penCurveToV(float, float,
0691:             *      float, float)
0692:             */
0693:            public void penCurveToV(float x2, float y2, float x3, float y3) {
0694:                textEnd();
0695:                CSOperation operation = new CSOperation(CSOperators.CSO_v);
0696:                operation.addOperand(COSFixed.create(x2));
0697:                operation.addOperand(COSFixed.create(y2));
0698:                operation.addOperand(COSFixed.create(x3));
0699:                operation.addOperand(COSFixed.create(y3));
0700:                getContent().addOperation(operation);
0701:            }
0702:
0703:            /*
0704:             * (non-Javadoc)
0705:             * 
0706:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penCurveToY(float, float,
0707:             *      float, float)
0708:             */
0709:            public void penCurveToY(float x1, float y1, float x3, float y3) {
0710:                textEnd();
0711:                CSOperation operation = new CSOperation(CSOperators.CSO_y);
0712:                operation.addOperand(COSFixed.create(x1));
0713:                operation.addOperand(COSFixed.create(y1));
0714:                operation.addOperand(COSFixed.create(x3));
0715:                operation.addOperand(COSFixed.create(y3));
0716:                getContent().addOperation(operation);
0717:            }
0718:
0719:            /**
0720:             * Draw an ellipse. The center of the ellipse is at <code>x</code>,
0721:             * <code>y</code> in user space. <code>rx</code> and <code>ry</code>
0722:             * define the radius in x and y direction respectively.
0723:             * 
0724:             * @param x
0725:             *            The x coordinate of the center.
0726:             * @param y
0727:             *            The y coordinate of the center.
0728:             * @param rx
0729:             *            The radius in x direction
0730:             * @param ry
0731:             *            The radius in y direction
0732:             */
0733:            public void penEllipse(float x, float y, float rx, float ry) {
0734:                textEnd();
0735:                float rxkappa = rx * KAPPA;
0736:                float rykappa = ry * KAPPA;
0737:                penMoveTo(x + rx, y);
0738:                penCurveToC(x + rx, y + rykappa, x + rxkappa, y + ry, x, y + ry);
0739:                penCurveToC(x - rxkappa, y + ry, x - rx, y + rykappa, x - rx, y);
0740:                penCurveToC(x - rx, y - rykappa, x - rxkappa, y - ry, x, y - ry);
0741:                penCurveToC(x + rxkappa, y - ry, x + rx, y - rykappa, x + rx, y);
0742:            }
0743:
0744:            /*
0745:             * (non-Javadoc)
0746:             * 
0747:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penLineTo(float, float)
0748:             */
0749:            public void penLineTo(float x, float y) {
0750:                textEnd();
0751:                CSOperation operation = new CSOperation(CSOperators.CSO_l);
0752:                operation.addOperand(COSFixed.create(x,
0753:                        VALUE_COORDINATE_PRECISION));
0754:                operation.addOperand(COSFixed.create(y,
0755:                        VALUE_COORDINATE_PRECISION));
0756:                getContent().addOperation(operation);
0757:            }
0758:
0759:            /*
0760:             * (non-Javadoc)
0761:             * 
0762:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penMoveTo(float, float)
0763:             */
0764:            public void penMoveTo(float x, float y) {
0765:                textEnd();
0766:                CSOperation operation = new CSOperation(CSOperators.CSO_m);
0767:                operation.addOperand(COSFixed.create(x,
0768:                        VALUE_COORDINATE_PRECISION));
0769:                operation.addOperand(COSFixed.create(y,
0770:                        VALUE_COORDINATE_PRECISION));
0771:                getContent().addOperation(operation);
0772:            }
0773:
0774:            /*
0775:             * (non-Javadoc)
0776:             * 
0777:             * @see de.intarsys.pdf.content.CSDeviceAdapter#penRectangle(float, float,
0778:             *      float, float)
0779:             */
0780:            public void penRectangle(float x, float y, float w, float h) {
0781:                textEnd();
0782:                CSOperation operation = new CSOperation(CSOperators.CSO_re);
0783:                operation.addOperand(COSFixed.create(x,
0784:                        VALUE_COORDINATE_PRECISION));
0785:                operation.addOperand(COSFixed.create(y,
0786:                        VALUE_COORDINATE_PRECISION));
0787:                operation.addOperand(COSFixed.create(w,
0788:                        VALUE_COORDINATE_PRECISION));
0789:                operation.addOperand(COSFixed.create(h,
0790:                        VALUE_COORDINATE_PRECISION));
0791:                getContent().addOperation(operation);
0792:            }
0793:
0794:            protected void resetStrings() {
0795:                strings = new ArrayList();
0796:                resetTextBuffer();
0797:            }
0798:
0799:            protected void resetTextBuffer() {
0800:                textBuffer = new ByteArrayOutputStream();
0801:            }
0802:
0803:            /*
0804:             * (non-Javadoc)
0805:             * 
0806:             * @see de.intarsys.pdf.content.CSDeviceAdapter#restoreState()
0807:             */
0808:            public void restoreState() {
0809:                textEnd();
0810:                CSOperation operation = new CSOperation(CSOperators.CSO_Q);
0811:                getContent().addOperation(operation);
0812:                super .restoreState();
0813:            }
0814:
0815:            /*
0816:             * (non-Javadoc)
0817:             * 
0818:             * @see de.intarsys.pdf.content.CSDeviceAdapter#saveState()
0819:             */
0820:            public void saveState() {
0821:                textEnd();
0822:                CSOperation operation = new CSOperation(CSOperators.CSO_q);
0823:                getContent().addOperation(operation);
0824:                super .saveState();
0825:            }
0826:
0827:            /**
0828:             * Convenience method to access "setLineDash".
0829:             * 
0830:             * @param unitsOn
0831:             * @param unitsOff
0832:             * @param phase
0833:             */
0834:            public void setLineDash(float unitsOn, float unitsOff, float phase) {
0835:                setLineDash(new float[] { unitsOn, unitsOff }, phase);
0836:            }
0837:
0838:            /*
0839:             * (non-Javadoc)
0840:             * 
0841:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setExtendedState(de.intarsys.pdf.cos.COSName,
0842:             *      de.intarsys.pdf.pd.PDExtGState)
0843:             */
0844:            public void setExtendedState(COSName name, PDExtGState gstate) {
0845:                streamEnd();
0846:                name = checkResource(PDResources.CN_RT_ExtGState,
0847:                        PDExtGState.META, name, gstate);
0848:                super .setExtendedState(name, gstate);
0849:                CSOperation operation = new CSOperation(CSOperators.CSO_gs);
0850:                operation.addOperand(name);
0851:                getContent().addOperation(operation);
0852:            }
0853:
0854:            /*
0855:             * (non-Javadoc)
0856:             * 
0857:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setFlatnessTolerance(float)
0858:             */
0859:            public void setFlatnessTolerance(float flatness) {
0860:                streamEnd();
0861:                super .setFlatnessTolerance(flatness);
0862:                CSOperation operation = new CSOperation(CSOperators.CSO_i);
0863:                operation.addOperand(COSFixed.create(flatness,
0864:                        VALUE_FLATNESS_PRECISION));
0865:                getContent().addOperation(operation);
0866:            }
0867:
0868:            /*
0869:             * (non-Javadoc)
0870:             * 
0871:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setLineCap(int)
0872:             */
0873:            public void setLineCap(int style) {
0874:                streamEnd();
0875:                super .setLineCap(style);
0876:                CSOperation operation = new CSOperation(CSOperators.CSO_J);
0877:                operation.addOperand(COSInteger.create(style));
0878:                getContent().addOperation(operation);
0879:            }
0880:
0881:            /*
0882:             * (non-Javadoc)
0883:             * 
0884:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setDash(float[], float)
0885:             */
0886:            public void setLineDash(float[] pattern, float phase) {
0887:                streamEnd();
0888:                super .setLineDash(pattern, phase);
0889:                CSOperation operation = new CSOperation(CSOperators.CSO_d);
0890:                operation.addOperand(COSTools.createObject(pattern));
0891:                operation.addOperand(COSFixed.create(phase,
0892:                        VALUE_DASH_PRECISION));
0893:                getContent().addOperation(operation);
0894:            }
0895:
0896:            /*
0897:             * (non-Javadoc)
0898:             * 
0899:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setLineJoin(int)
0900:             */
0901:            public void setLineJoin(int style) {
0902:                streamEnd();
0903:                super .setLineJoin(style);
0904:                CSOperation operation = new CSOperation(CSOperators.CSO_j);
0905:                operation.addOperand(COSInteger.create(style));
0906:                getContent().addOperation(operation);
0907:            }
0908:
0909:            /*
0910:             * (non-Javadoc)
0911:             * 
0912:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setLineWidth(float)
0913:             */
0914:            public void setLineWidth(float w) {
0915:                if (graphicsState.getLineWidth() == w) {
0916:                    return;
0917:                }
0918:                streamEnd();
0919:                super .setLineWidth(w);
0920:                CSOperation operation = new CSOperation(CSOperators.CSO_w);
0921:                operation.addOperand(COSFixed.create(w, VALUE_WIDTH_PRECISION));
0922:                getContent().addOperation(operation);
0923:            }
0924:
0925:            /*
0926:             * (non-Javadoc)
0927:             * 
0928:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setMiterLimit(float)
0929:             */
0930:            public void setMiterLimit(float miterLimit) {
0931:                streamEnd();
0932:                super .setMiterLimit(miterLimit);
0933:                CSOperation operation = new CSOperation(CSOperators.CSO_M);
0934:                operation.addOperand(COSFixed.create(miterLimit));
0935:                getContent().addOperation(operation);
0936:            }
0937:
0938:            /*
0939:             * (non-Javadoc)
0940:             * 
0941:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorCMYK(float,
0942:             *      float, float, float)
0943:             */
0944:            public void setNonStrokeColorCMYK(float c, float m, float y, float k) {
0945:                c = Math.max(0, Math.min(1, c));
0946:                m = Math.max(0, Math.min(1, m));
0947:                y = Math.max(0, Math.min(1, y));
0948:                k = Math.max(0, Math.min(1, k));
0949:                if (isNonStrokeCMYKColor(c, m, y, k)) {
0950:                    return;
0951:                }
0952:                streamEnd();
0953:                PDColorSpace pdColorSpace = PDColorSpace
0954:                        .getSingleton(PDColorSpace.CN_CS_DeviceCMYK);
0955:                graphicsState
0956:                        .setNonStrokeColorValues(new float[] { c, m, y, k });
0957:                graphicsState.setNonStrokeColorSpace(pdColorSpace);
0958:                CSOperation operation = new CSOperation(CSOperators.CSO_k);
0959:                operation.addOperand(COSFixed.create(c, VALUE_COLOR_PRECISION));
0960:                operation.addOperand(COSFixed.create(m, VALUE_COLOR_PRECISION));
0961:                operation.addOperand(COSFixed.create(y, VALUE_COLOR_PRECISION));
0962:                operation.addOperand(COSFixed.create(k, VALUE_COLOR_PRECISION));
0963:                getContent().addOperation(operation);
0964:            }
0965:
0966:            /*
0967:             * (non-Javadoc)
0968:             * 
0969:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorGray(float)
0970:             */
0971:            public void setNonStrokeColorGray(float gray) {
0972:                streamEnd();
0973:                PDColorSpace pdColorSpace = PDColorSpace
0974:                        .getSingleton(PDColorSpace.CN_CS_DeviceGray);
0975:                graphicsState.setNonStrokeColorValues(new float[] { gray });
0976:                graphicsState.setNonStrokeColorSpace(pdColorSpace);
0977:                CSOperation operation = new CSOperation(CSOperators.CSO_g);
0978:                operation.addOperand(COSFixed
0979:                        .create(gray, VALUE_GRAY_PRECISION));
0980:                getContent().addOperation(operation);
0981:            }
0982:
0983:            /*
0984:             * (non-Javadoc)
0985:             * 
0986:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorRGB(float,
0987:             *      float, float)
0988:             */
0989:            public void setNonStrokeColorRGB(float red, float green, float blue) {
0990:                red = Math.max(0, Math.min(1, red));
0991:                green = Math.max(0, Math.min(1, green));
0992:                blue = Math.max(0, Math.min(1, blue));
0993:                if (isNonStrokeRGBColor(red, green, blue)) {
0994:                    return;
0995:                }
0996:                streamEnd();
0997:                PDColorSpace pdColorSpace = PDColorSpace
0998:                        .getSingleton(PDColorSpace.CN_CS_DeviceRGB);
0999:                graphicsState.setNonStrokeColorSpace(pdColorSpace);
1000:                graphicsState.setNonStrokeColorValues(new float[] { red, green,
1001:                        blue });
1002:                CSOperation operation = new CSOperation(CSOperators.CSO_rg);
1003:                operation.addOperand(COSFixed
1004:                        .create(red, VALUE_COLOR_PRECISION));
1005:                operation.addOperand(COSFixed.create(green,
1006:                        VALUE_COLOR_PRECISION));
1007:                operation.addOperand(COSFixed.create(blue,
1008:                        VALUE_COLOR_PRECISION));
1009:                getContent().addOperation(operation);
1010:            }
1011:
1012:            /*
1013:             * (non-Javadoc)
1014:             * 
1015:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorSpace(de.intarsys.pdf.cos.COSName,
1016:             *      de.intarsys.pdf.pd.PDColorSpace)
1017:             */
1018:            public void setNonStrokeColorSpace(COSName name,
1019:                    PDColorSpace colorSpace) {
1020:                streamEnd();
1021:                name = checkResource(PDResources.CN_RT_ColorSpace,
1022:                        PDColorSpace.META, name, colorSpace);
1023:                super .setNonStrokeColorSpace(name, colorSpace);
1024:                CSOperation operation = new CSOperation(CSOperators.CSO_cs);
1025:                operation.addOperand(name.copyOptional());
1026:                getContent().addOperation(operation);
1027:            }
1028:
1029:            /*
1030:             * (non-Javadoc)
1031:             * 
1032:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorValues(float[])
1033:             */
1034:            public void setNonStrokeColorValues(float[] values) {
1035:                streamEnd();
1036:                super .setNonStrokeColorValues(values);
1037:                CSOperation operation = new CSOperation(CSOperators.CSO_sc);
1038:                for (int i = 0; i < values.length; i++) {
1039:                    operation.addOperand(COSFixed.create(values[i],
1040:                            VALUE_COLOR_PRECISION));
1041:                }
1042:                getContent().addOperation(operation);
1043:            }
1044:
1045:            /*
1046:             * (non-Javadoc)
1047:             * 
1048:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setNonStrokeColorValues(float[],
1049:             *      de.intarsys.pdf.cos.COSName, de.intarsys.pdf.pd.PDPattern)
1050:             */
1051:            public void setNonStrokeColorValues(float[] values, COSName name,
1052:                    PDPattern pattern) {
1053:                streamEnd();
1054:                name = checkResource(PDResources.CN_RT_Pattern, PDPattern.META,
1055:                        name, pattern);
1056:                graphicsState.setNonStrokeColorValues(values);
1057:                CSOperation operation = new CSOperation(CSOperators.CSO_scn);
1058:                for (int i = 0; i < values.length; i++) {
1059:                    operation.addOperand(COSFixed.create(values[i],
1060:                            VALUE_COLOR_PRECISION));
1061:                }
1062:                if (name != null) {
1063:                    operation.addOperand(name.copyShallow());
1064:                }
1065:                getContent().addOperation(operation);
1066:            }
1067:
1068:            /*
1069:             * (non-Javadoc)
1070:             * 
1071:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setRenderingIntent(de.intarsys.pdf.cos.COSName)
1072:             */
1073:            public void setRenderingIntent(COSName intent) {
1074:                streamEnd();
1075:                CSOperation operation = new CSOperation(CSOperators.CSO_ri);
1076:                operation.addOperand(intent.copyOptional());
1077:                getContent().addOperation(operation);
1078:            }
1079:
1080:            /*
1081:             * (non-Javadoc)
1082:             * 
1083:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorCMYK(float,
1084:             *      float, float, float)
1085:             */
1086:            public void setStrokeColorCMYK(float cyan, float magenta,
1087:                    float yellow, float key) {
1088:                cyan = Math.max(0, Math.min(1, cyan));
1089:                magenta = Math.max(0, Math.min(1, magenta));
1090:                yellow = Math.max(0, Math.min(1, yellow));
1091:                key = Math.max(0, Math.min(1, key));
1092:                if (isStrokeCMYKColor(cyan, magenta, yellow, key)) {
1093:                    return;
1094:                }
1095:                streamEnd();
1096:                PDColorSpace pdColorSpace = PDColorSpace
1097:                        .getSingleton(PDColorSpace.CN_CS_DeviceCMYK);
1098:                graphicsState.setStrokeColorValues(new float[] { cyan, magenta,
1099:                        yellow, key });
1100:                graphicsState.setStrokeColorSpace(pdColorSpace);
1101:                CSOperation operation = new CSOperation(CSOperators.CSO_K);
1102:                operation.addOperand(COSFixed.create(cyan,
1103:                        VALUE_COLOR_PRECISION));
1104:                operation.addOperand(COSFixed.create(magenta,
1105:                        VALUE_COLOR_PRECISION));
1106:                operation.addOperand(COSFixed.create(yellow,
1107:                        VALUE_COLOR_PRECISION));
1108:                operation.addOperand(COSFixed
1109:                        .create(key, VALUE_COLOR_PRECISION));
1110:                getContent().addOperation(operation);
1111:            }
1112:
1113:            /*
1114:             * (non-Javadoc)
1115:             * 
1116:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorGray(float)
1117:             */
1118:            public void setStrokeColorGray(float gray) {
1119:                streamEnd();
1120:                PDColorSpace pdColorSpace = PDColorSpace
1121:                        .getSingleton(PDColorSpace.CN_CS_DeviceGray);
1122:                graphicsState.setStrokeColorValues(new float[] { gray });
1123:                graphicsState.setStrokeColorSpace(pdColorSpace);
1124:                CSOperation operation = new CSOperation(CSOperators.CSO_G);
1125:                operation.addOperand(COSFixed
1126:                        .create(gray, VALUE_GRAY_PRECISION));
1127:                getContent().addOperation(operation);
1128:            }
1129:
1130:            /*
1131:             * (non-Javadoc)
1132:             * 
1133:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorRGB(float,
1134:             *      float, float)
1135:             */
1136:            public void setStrokeColorRGB(float red, float green, float blue) {
1137:                red = Math.max(0, Math.min(1, red));
1138:                green = Math.max(0, Math.min(1, green));
1139:                blue = Math.max(0, Math.min(1, blue));
1140:                if (isStrokeRGBColor(red, green, blue)) {
1141:                    return;
1142:                }
1143:                streamEnd();
1144:                PDColorSpace pdColorSpace = PDColorSpace
1145:                        .getSingleton(PDColorSpace.CN_CS_DeviceRGB);
1146:                graphicsState.setStrokeColorValues(new float[] { red, green,
1147:                        blue });
1148:                graphicsState.setStrokeColorSpace(pdColorSpace);
1149:                CSOperation operation = new CSOperation(CSOperators.CSO_RG);
1150:                operation.addOperand(COSFixed
1151:                        .create(red, VALUE_COLOR_PRECISION));
1152:                operation.addOperand(COSFixed.create(green,
1153:                        VALUE_COLOR_PRECISION));
1154:                operation.addOperand(COSFixed.create(blue,
1155:                        VALUE_COLOR_PRECISION));
1156:                getContent().addOperation(operation);
1157:            }
1158:
1159:            /*
1160:             * (non-Javadoc)
1161:             * 
1162:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorSpace(de.intarsys.pdf.cos.COSName,
1163:             *      de.intarsys.pdf.pd.PDColorSpace)
1164:             */
1165:            public void setStrokeColorSpace(COSName name,
1166:                    PDColorSpace colorSpace) {
1167:                streamEnd();
1168:                name = checkResource(PDResources.CN_RT_ColorSpace,
1169:                        PDColorSpace.META, name, colorSpace);
1170:                super .setStrokeColorSpace(name, colorSpace);
1171:                CSOperation operation = new CSOperation(CSOperators.CSO_CS);
1172:                operation.addOperand(name);
1173:                getContent().addOperation(operation);
1174:            }
1175:
1176:            /*
1177:             * (non-Javadoc)
1178:             * 
1179:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorValues(float[])
1180:             */
1181:            public void setStrokeColorValues(float[] values) {
1182:                streamEnd();
1183:                super .setStrokeColorValues(values);
1184:                CSOperation operation = new CSOperation(CSOperators.CSO_SC);
1185:                for (int i = 0; i < values.length; i++) {
1186:                    operation.addOperand(COSFixed.create(values[i],
1187:                            VALUE_COLOR_PRECISION));
1188:                }
1189:                getContent().addOperation(operation);
1190:            }
1191:
1192:            /*
1193:             * (non-Javadoc)
1194:             * 
1195:             * @see de.intarsys.pdf.content.CSDeviceAdapter#setStrokeColorValues(float[],
1196:             *      de.intarsys.pdf.cos.COSName, de.intarsys.pdf.pd.PDPattern)
1197:             */
1198:            public void setStrokeColorValues(float[] values, COSName name,
1199:                    PDPattern pattern) {
1200:                streamEnd();
1201:                name = checkResource(PDResources.CN_RT_Pattern, PDPattern.META,
1202:                        name, pattern);
1203:                graphicsState.setStrokeColorValues(values);
1204:                CSOperation operation = new CSOperation(CSOperators.CSO_SCN);
1205:                for (int i = 0; i < values.length; i++) {
1206:                    operation.addOperand(COSFixed.create(values[i],
1207:                            VALUE_COLOR_PRECISION));
1208:                }
1209:                if (name != null) {
1210:                    operation.addOperand(name.copyShallow());
1211:                }
1212:                getContent().addOperation(operation);
1213:            }
1214:
1215:            protected void setTextMode(boolean b) {
1216:                textMode = b;
1217:            }
1218:
1219:            /**
1220:             * Close a currently open line.
1221:             */
1222:            protected void streamEnd() {
1223:                streamEndRun();
1224:                int size = getStrings().size();
1225:                if (size == 1) {
1226:                    Object element = getStrings().get(0);
1227:                    if (element instanceof  byte[]) {
1228:                        byte[] bytes = (byte[]) element;
1229:                        basicTextShow(bytes);
1230:                    }
1231:                } else {
1232:                    if (size > 1) {
1233:                        COSArray cosStrings = COSArray.create(size);
1234:                        for (Iterator i = getStrings().iterator(); i.hasNext();) {
1235:                            Object element = i.next();
1236:                            if (element instanceof  byte[]) {
1237:                                byte[] data = (byte[]) element;
1238:                                COSString cosString = COSString.create(data);
1239:                                cosStrings.add(cosString);
1240:                            } else {
1241:                                Integer move = (Integer) element;
1242:                                COSInteger cosMove = COSInteger.create(move
1243:                                        .intValue());
1244:                                cosStrings.add(cosMove);
1245:                            }
1246:                        }
1247:                        streamEndShow(cosStrings);
1248:                    }
1249:                }
1250:                resetStrings();
1251:            }
1252:
1253:            /**
1254:             * Close a currently open optimzed character sequence.
1255:             */
1256:            protected void streamEndRun() {
1257:                if (getTextBuffer().toByteArray().length > 0) {
1258:                    getStrings().add(getTextBuffer().toByteArray());
1259:                }
1260:                resetTextBuffer();
1261:            }
1262:
1263:            protected void streamEndShow(COSArray theStrings) {
1264:                CSOperation operation = new CSOperation(CSOperators.CSO_TJ);
1265:                operation.addOperand(theStrings);
1266:                getContent().addOperation(operation);
1267:                for (Iterator cosObjects = theStrings.iterator(); cosObjects
1268:                        .hasNext();) {
1269:                    COSObject cosObject = (COSObject) cosObjects.next();
1270:                    if (cosObject instanceof  COSString) {
1271:                        byte[] text = ((COSString) cosObject).byteValue();
1272:                        for (int i = 0; i < text.length; i++) {
1273:                            graphicsState.textState.getFont().setCharUsed(
1274:                                    text[i]);
1275:                        }
1276:                    }
1277:                }
1278:            }
1279:
1280:            public void textMoveTo(float x, float y) {
1281:                textBegin();
1282:                TextState textState = graphicsState.textState;
1283:                AffineTransform tm = textState.getTextMatrix();
1284:
1285:                // have we changed the baseline?
1286:                float dDeltaY = y - (float) tm.getTranslateY();
1287:                if (dDeltaY != 0) {
1288:                    // move relative to old line start
1289:                    textLineMoveTo(x, y);
1290:                    return;
1291:                }
1292:
1293:                // have we a x offset to current position?
1294:                float dDeltaX = x - (float) tm.getTranslateX();
1295:                if (dDeltaX != 0) {
1296:                    int iDelta = (int) ((-dDeltaX * 1000) / textState
1297:                            .getFontSize());
1298:                    if (iDelta != 0) {
1299:                        streamEndRun();
1300:                        // older acrobats do no support large offset values !
1301:                        if (iDelta < -10000) {
1302:                            textLineMoveTo(x, y);
1303:                        } else {
1304:                            getStrings().add(new Integer(iDelta));
1305:                            textState.tmMove(dDeltaX, 0);
1306:                        }
1307:                    }
1308:                }
1309:            }
1310:
1311:            public void textMove(float dx, float dy) {
1312:                textBegin();
1313:                // have we changed the baseline?
1314:                if (dy != 0) {
1315:                    // move relative to old line start
1316:                    textLineMove(dx, dy);
1317:                    return;
1318:                }
1319:                // have we a x offset to current position?
1320:                if (dx != 0) {
1321:                    TextState textState = graphicsState.textState;
1322:                    int iDelta = (int) ((-dx * 1000) / textState.getFontSize());
1323:                    if (iDelta != 0) {
1324:                        streamEndRun();
1325:                        // older acrobats do no support large offset values !
1326:                        if (iDelta < -10000) {
1327:                            textLineMove(dx, dy);
1328:                        } else {
1329:                            getStrings().add(new Integer(iDelta));
1330:                            textState.tmMove(dx, 0);
1331:                        }
1332:                    }
1333:                }
1334:            }
1335:
1336:            public void textShow(byte[] text, int offset, int length) {
1337:                textBegin();
1338:                getTextBuffer().write(text, offset, length);
1339:                float width = PDFontTools.getGlyphWidth(graphicsState.textState
1340:                        .getFont(), text, offset, length);
1341:                width = (graphicsState.textState.getFontSize() * width)
1342:                        / THOUSAND;
1343:                // todo 2 text rendering formula not yet complete
1344:                graphicsState.textState.tmMove(width, 0);
1345:            }
1346:
1347:            /*
1348:             * (non-Javadoc)
1349:             * 
1350:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textBegin()
1351:             */
1352:            public void textBegin() {
1353:                if (isTextMode()) {
1354:                    // ignore
1355:                    return;
1356:                }
1357:                super .textBegin();
1358:                setTextMode(true);
1359:                CSOperation operation = new CSOperation(CSOperators.CSO_BT);
1360:                getContent().addOperation(operation);
1361:            }
1362:
1363:            /*
1364:             * (non-Javadoc)
1365:             * 
1366:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textEnd()
1367:             */
1368:            public void textEnd() {
1369:                if (!isTextMode()) {
1370:                    // ignore
1371:                    return;
1372:                }
1373:                streamEnd();
1374:                super .textEnd();
1375:                setTextMode(false);
1376:                CSOperation lastOper = getContent().getLastOperation();
1377:                if ((lastOper != null)
1378:                        && lastOper.matchesOperator(CSOperators.CSO_BT)) {
1379:                    getContent().removeLastOperation();
1380:                    return;
1381:                }
1382:                CSOperation operation = new CSOperation(CSOperators.CSO_ET);
1383:                getContent().addOperation(operation);
1384:            }
1385:
1386:            /*
1387:             * (non-Javadoc)
1388:             * 
1389:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textLineMove(float, float)
1390:             */
1391:            public void textLineMove(float dx, float dy) {
1392:                textBegin();
1393:                streamEnd();
1394:                super .textLineMove(dx, dy);
1395:                CSOperation operation = new CSOperation(CSOperators.CSO_Td);
1396:                operation.addOperand(COSFixed.create(dx,
1397:                        VALUE_COORDINATE_PRECISION));
1398:                operation.addOperand(COSFixed.create(dy,
1399:                        VALUE_COORDINATE_PRECISION));
1400:                getContent().addOperation(operation);
1401:            }
1402:
1403:            /**
1404:             * Move the current text line by <code>dx</code>, <code>dy</code>. Set
1405:             * the current leading to the <code>dy</code> offset.
1406:             * <p>
1407:             * PDF graphics operator "TD"
1408:             * 
1409:             * @param dx
1410:             *            The x offset for the new glyph starting point.
1411:             * @param dy
1412:             *            The y offset for the new glyph starting point.
1413:             */
1414:            public void textLineMoveSetLeading(float dx, float dy) {
1415:                // todo check usage
1416:                textBegin();
1417:                streamEnd();
1418:                //
1419:                super .textLineMove(dx, dy);
1420:                super .textSetLeading(dy);
1421:                //
1422:                CSOperation operation = new CSOperation(CSOperators.CSO_TD);
1423:                operation.addOperand(COSFixed.create(dx,
1424:                        VALUE_COORDINATE_PRECISION));
1425:                operation.addOperand(COSFixed.create(dy,
1426:                        VALUE_COORDINATE_PRECISION));
1427:                getContent().addOperation(operation);
1428:            }
1429:
1430:            /**
1431:             * Move the current text line to absolute position <code>x</code>,
1432:             * <code>y</code>.
1433:             * <p>
1434:             * PDF graphics operator "Td"
1435:             */
1436:            public void textLineMoveTo(float x, float y) {
1437:                AffineTransform tx = graphicsState.textState
1438:                        .getTextLineMatrix();
1439:                float dx = (float) (x - tx.getTranslateX());
1440:                float dy = (float) (y - tx.getTranslateY());
1441:                textLineMove(dx, dy);
1442:            }
1443:
1444:            /*
1445:             * (non-Javadoc)
1446:             * 
1447:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textLineNew()
1448:             */
1449:            public void textLineNew() {
1450:                textBegin();
1451:                streamEnd();
1452:                super .textLineNew();
1453:                CSOperation operation = new CSOperation(CSOperators.CSO_Tstar);
1454:                getContent().addOperation(operation);
1455:            }
1456:
1457:            /*
1458:             * (non-Javadoc)
1459:             * 
1460:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetCharSpacing(float)
1461:             */
1462:            public void textSetCharSpacing(float charSpace) {
1463:                textBegin();
1464:                streamEnd();
1465:                super .textSetCharSpacing(charSpace);
1466:                CSOperation operation = new CSOperation(CSOperators.CSO_Tc);
1467:                operation.addOperand(COSFixed.create(charSpace));
1468:                getContent().addOperation(operation);
1469:            }
1470:
1471:            protected COSName checkResource(COSName resourceType,
1472:                    PDObject.MetaClass metaClass, COSName resourceName,
1473:                    PDObject resource) {
1474:                if (getResources() == null) {
1475:                    throw new IllegalStateException(
1476:                            "must have resource dictionary"); //$NON-NLS-1$
1477:                }
1478:                if (resourceName == null) {
1479:                    // no name predefined, lookup / create a new
1480:                    resourceName = getResources().createResource(resourceType,
1481:                            resource);
1482:                } else {
1483:                    PDObject temp = getResources().getResource(resourceType,
1484:                            metaClass, resourceName);
1485:                    if (temp == null) {
1486:                        getResources().addResource(resourceType, resourceName,
1487:                                resource);
1488:                    } else {
1489:                        if (resource != temp) {
1490:                            // resource conflict, create a new name...
1491:                            // this may happen when "replaying" a content stream
1492:                            // onto
1493:                            // another
1494:                            resourceName = getResources().createResource(
1495:                                    resourceType, resource);
1496:                        }
1497:                    }
1498:                }
1499:                return resourceName;
1500:            }
1501:
1502:            /*
1503:             * (non-Javadoc)
1504:             * 
1505:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetFont(de.intarsys.pdf.cos.COSName,
1506:             *      de.intarsys.pdf.font.PDFont, float)
1507:             */
1508:            public void textSetFont(COSName name, PDFont font, float size) {
1509:                if (getResources() == null) {
1510:                    throw new IllegalStateException(
1511:                            "must have resource dictionary to set font"); //$NON-NLS-1$
1512:                }
1513:                textBegin();
1514:                if (isFont(font, size)) {
1515:                    return;
1516:                }
1517:                streamEnd();
1518:                name = checkResource(PDResources.CN_RT_Font, PDFont.META, name,
1519:                        font);
1520:                super .textSetFont(name, font, size);
1521:                CSOperation operation = new CSOperation(CSOperators.CSO_Tf);
1522:                operation.addOperand(name);
1523:                operation.addOperand(COSFixed
1524:                        .create(size, VALUE_FONT_PRECISION));
1525:                getContent().addOperation(operation);
1526:            }
1527:
1528:            /*
1529:             * (non-Javadoc)
1530:             * 
1531:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetHorizontalScaling(float)
1532:             */
1533:            public void textSetHorizontalScaling(float scale) {
1534:                textBegin();
1535:                streamEnd();
1536:                super .textSetHorizontalScaling(scale);
1537:                CSOperation operation = new CSOperation(CSOperators.CSO_Tz);
1538:                operation.addOperand(COSFixed.create(scale));
1539:                getContent().addOperation(operation);
1540:            }
1541:
1542:            /*
1543:             * (non-Javadoc)
1544:             * 
1545:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetLeading(float)
1546:             */
1547:            public void textSetLeading(float leading) {
1548:                textBegin();
1549:                streamEnd();
1550:                super .textSetLeading(leading);
1551:                CSOperation operation = new CSOperation(CSOperators.CSO_TL);
1552:                operation.addOperand(COSFixed.create(leading));
1553:                getContent().addOperation(operation);
1554:            }
1555:
1556:            /*
1557:             * (non-Javadoc)
1558:             * 
1559:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetRenderingMode(int)
1560:             */
1561:            public void textSetRenderingMode(int rendering) {
1562:                textBegin();
1563:                streamEnd();
1564:                super .textSetRenderingMode(rendering);
1565:                CSOperation operation = new CSOperation(CSOperators.CSO_Tr);
1566:                operation.addOperand(COSInteger.create(rendering));
1567:                getContent().addOperation(operation);
1568:            }
1569:
1570:            /*
1571:             * (non-Javadoc)
1572:             * 
1573:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetRise(float)
1574:             */
1575:            public void textSetRise(float rise) {
1576:                textBegin();
1577:                streamEnd();
1578:                super .textSetRise(rise);
1579:                CSOperation operation = new CSOperation(CSOperators.CSO_Ts);
1580:                operation.addOperand(COSFixed.create(rise));
1581:                getContent().addOperation(operation);
1582:            }
1583:
1584:            /*
1585:             * (non-Javadoc)
1586:             * 
1587:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetTransform(float,
1588:             *      float, float, float, float, float)
1589:             */
1590:            public void textSetTransform(float a, float b, float c, float d,
1591:                    float e, float f) {
1592:                textBegin();
1593:                streamEnd();
1594:                super .textSetTransform(a, b, c, d, e, f);
1595:                CSOperation operation = new CSOperation(CSOperators.CSO_Tm);
1596:                operation
1597:                        .addOperand(COSFixed.create(a, VALUE_FACTOR_PRECISION));
1598:                operation
1599:                        .addOperand(COSFixed.create(b, VALUE_FACTOR_PRECISION));
1600:                operation
1601:                        .addOperand(COSFixed.create(c, VALUE_FACTOR_PRECISION));
1602:                operation
1603:                        .addOperand(COSFixed.create(d, VALUE_FACTOR_PRECISION));
1604:                operation.addOperand(COSFixed.create(e,
1605:                        VALUE_COORDINATE_PRECISION));
1606:                operation.addOperand(COSFixed.create(f,
1607:                        VALUE_COORDINATE_PRECISION));
1608:                getContent().addOperation(operation);
1609:            }
1610:
1611:            /*
1612:             * (non-Javadoc)
1613:             * 
1614:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textSetWordSpacing(float)
1615:             */
1616:            public void textSetWordSpacing(float wordSpace) {
1617:                textBegin();
1618:                streamEnd();
1619:                super .textSetWordSpacing(wordSpace);
1620:                CSOperation operation = new CSOperation(CSOperators.CSO_Tw);
1621:                operation.addOperand(COSFixed.create(wordSpace));
1622:                getContent().addOperation(operation);
1623:            }
1624:
1625:            protected void basicTextShow(byte[] text) {
1626:                CSOperation operation = new CSOperation(CSOperators.CSO_Tj);
1627:                operation.addOperand(COSString.create(text));
1628:                for (int i = 0; i < text.length; i++) {
1629:                    graphicsState.textState.getFont().setCharUsed(text[i]);
1630:                }
1631:                getContent().addOperation(operation);
1632:            }
1633:
1634:            /*
1635:             * (non-Javadoc)
1636:             * 
1637:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textT3SetGlyphWidth(float,
1638:             *      float)
1639:             */
1640:            public void textT3SetGlyphWidth(float x, float y) {
1641:                textBegin();
1642:                streamEnd();
1643:                super .textT3SetGlyphWidth(x, y);
1644:                CSOperation operation = new CSOperation(CSOperators.CSO_d0);
1645:                operation.addOperand(COSFixed.create(x));
1646:                operation.addOperand(COSFixed.create(y));
1647:                getContent().addOperation(operation);
1648:            }
1649:
1650:            /*
1651:             * (non-Javadoc)
1652:             * 
1653:             * @see de.intarsys.pdf.content.CSDeviceAdapter#textT3SetGlyphWidthBB(float,
1654:             *      float, float, float, float, float)
1655:             */
1656:            public void textT3SetGlyphWidthBB(float x, float y, float llx,
1657:                    float lly, float urx, float ury) {
1658:                textBegin();
1659:                streamEnd();
1660:                super .textT3SetGlyphWidthBB(x, y, llx, lly, urx, ury);
1661:                CSOperation operation = new CSOperation(CSOperators.CSO_d1);
1662:                operation.addOperand(COSFixed.create(x));
1663:                operation.addOperand(COSFixed.create(y));
1664:                operation.addOperand(COSFixed.create(llx));
1665:                operation.addOperand(COSFixed.create(lly));
1666:                operation.addOperand(COSFixed.create(urx));
1667:                operation.addOperand(COSFixed.create(ury));
1668:                getContent().addOperation(operation);
1669:            }
1670:
1671:            /*
1672:             * (non-Javadoc)
1673:             * 
1674:             * @see de.intarsys.pdf.content.CSDeviceAdapter#transform(float, float,
1675:             *      float, float, float, float)
1676:             */
1677:            public void transform(float a, float b, float c, float d, float e,
1678:                    float f) {
1679:                textEnd();
1680:                super .transform(a, b, c, d, e, f);
1681:                CSOperation operation = new CSOperation(CSOperators.CSO_cm);
1682:                operation
1683:                        .addOperand(COSFixed.create(a, VALUE_FACTOR_PRECISION));
1684:                operation
1685:                        .addOperand(COSFixed.create(b, VALUE_FACTOR_PRECISION));
1686:                operation
1687:                        .addOperand(COSFixed.create(c, VALUE_FACTOR_PRECISION));
1688:                operation
1689:                        .addOperand(COSFixed.create(d, VALUE_FACTOR_PRECISION));
1690:                operation.addOperand(COSFixed.create(e,
1691:                        VALUE_COORDINATE_PRECISION));
1692:                operation.addOperand(COSFixed.create(f,
1693:                        VALUE_COORDINATE_PRECISION));
1694:                getContent().addOperation(operation);
1695:            }
1696:
1697:            public IContentStreamProvider getContentStreamProvider() {
1698:                return contentStreamProvider;
1699:            }
1700:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.