Source Code Cross Referenced for PrimitiveFilter.java in  » PDF » PDFClown-0.0.5 » it » stefanochizzolini » clown » documents » contents » composition » 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 » PDFClown 0.0.5 » it.stefanochizzolini.clown.documents.contents.composition 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          Copyright © 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004:          Contributors:
005:         * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006:              contributed code is Copyright © 2007 by Stefano Chizzolini.
007:
008:          This file should be part of the source code distribution of "PDF Clown library"
009:          (the Program): see the accompanying README files for more info.
010:
011:          This Program is free software; you can redistribute it and/or modify it under
012:          the terms of the GNU General Public License as published by the Free Software
013:          Foundation; either version 2 of the License, or (at your option) any later version.
014:
015:          This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016:          WARRANTY, either expressed or implied; without even the implied warranty of
017:          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019:          You should have received a copy of the GNU General Public License along with this
020:          Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022:          Redistribution and use, with or without modification, are permitted provided that such
023:          redistributions retain the above copyright notice, license and disclaimer, along with
024:          this list of conditions.
025:         */
026:
027:        package it.stefanochizzolini.clown.documents.contents.composition;
028:
029:        import it.stefanochizzolini.clown.bytes.IBuffer;
030:        import it.stefanochizzolini.clown.documents.Document;
031:        import it.stefanochizzolini.clown.documents.contents.ContentScanner;
032:        import it.stefanochizzolini.clown.documents.contents.Fonts;
033:        import it.stefanochizzolini.clown.documents.contents.IContentContext;
034:        import it.stefanochizzolini.clown.documents.contents.LineCapEnum;
035:        import it.stefanochizzolini.clown.documents.contents.LineJoinEnum;
036:        import it.stefanochizzolini.clown.documents.contents.Resources;
037:        import it.stefanochizzolini.clown.documents.contents.TextRenderModeEnum;
038:        import it.stefanochizzolini.clown.documents.contents.XObjects;
039:        import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
040:        import it.stefanochizzolini.clown.documents.contents.colorSpaces.ColorSpace;
041:        import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceCMYKColorSpace;
042:        import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColorSpace;
043:        import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColorSpace;
044:        import it.stefanochizzolini.clown.documents.contents.fonts.Font;
045:        import it.stefanochizzolini.clown.documents.contents.objects.CompositeObject;
046:        import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
047:        import it.stefanochizzolini.clown.documents.contents.objects.DrawRectangle;
048:        import it.stefanochizzolini.clown.documents.contents.objects.Fill;
049:        import it.stefanochizzolini.clown.documents.contents.objects.FillStroke;
050:        import it.stefanochizzolini.clown.documents.contents.objects.LocalGraphicsState;
051:        import it.stefanochizzolini.clown.documents.contents.objects.ModifyCTM;
052:        import it.stefanochizzolini.clown.documents.contents.objects.PaintXObject;
053:        import it.stefanochizzolini.clown.documents.contents.objects.SetCharSpace;
054:        import it.stefanochizzolini.clown.documents.contents.objects.SetFillColor;
055:        import it.stefanochizzolini.clown.documents.contents.objects.SetFillColorSpace;
056:        import it.stefanochizzolini.clown.documents.contents.objects.SetFont;
057:        import it.stefanochizzolini.clown.documents.contents.objects.SetLineCap;
058:        import it.stefanochizzolini.clown.documents.contents.objects.SetLineDash;
059:        import it.stefanochizzolini.clown.documents.contents.objects.SetLineJoin;
060:        import it.stefanochizzolini.clown.documents.contents.objects.SetLineWidth;
061:        import it.stefanochizzolini.clown.documents.contents.objects.SetMiterLimit;
062:        import it.stefanochizzolini.clown.documents.contents.objects.SetStrokeColor;
063:        import it.stefanochizzolini.clown.documents.contents.objects.SetStrokeColorSpace;
064:        import it.stefanochizzolini.clown.documents.contents.objects.SetTextLead;
065:        import it.stefanochizzolini.clown.documents.contents.objects.SetTextMatrix;
066:        import it.stefanochizzolini.clown.documents.contents.objects.SetTextRenderMode;
067:        import it.stefanochizzolini.clown.documents.contents.objects.SetTextRise;
068:        import it.stefanochizzolini.clown.documents.contents.objects.SetTextScale;
069:        import it.stefanochizzolini.clown.documents.contents.objects.SetWordSpace;
070:        import it.stefanochizzolini.clown.documents.contents.objects.ShowText;
071:        import it.stefanochizzolini.clown.documents.contents.objects.Stroke;
072:        import it.stefanochizzolini.clown.documents.contents.objects.Text;
073:        import it.stefanochizzolini.clown.documents.contents.objects.TranslateTextRelative;
074:        import it.stefanochizzolini.clown.documents.contents.objects.TranslateTextToNextLine;
075:        import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
076:        import it.stefanochizzolini.clown.files.File;
077:        import it.stefanochizzolini.clown.objects.IPdfNumber;
078:        import it.stefanochizzolini.clown.objects.PdfDictionary;
079:        import it.stefanochizzolini.clown.objects.PdfLiteral;
080:        import it.stefanochizzolini.clown.objects.PdfName;
081:        import it.stefanochizzolini.clown.objects.PdfReal;
082:        import it.stefanochizzolini.clown.objects.PdfReference;
083:        import it.stefanochizzolini.clown.util.NotImplementedException;
084:
085:        import java.awt.Dimension;
086:        import java.awt.geom.Dimension2D;
087:        import java.awt.geom.Point2D;
088:        import java.awt.geom.RectangularShape;
089:        import java.util.Stack;
090:
091:        /**
092:         Content stream primitive filter. It provides the basic (primitive) operations described by the PDF
093:         specification for graphics content composition.
094:         <h3>Remarks</h3>
095:         <p>This class supersedes lower-level ContentBuilder, leveraging the all-new object-oriented content
096:         stream modelling infrastructure, which encompasses 1st-level content stream objects (operations),
097:         2nd-level content stream objects (graphics objects) and full graphics state support.</p>
098:
099:         @author Stefano Chizzolini
100:         @version 0.0.5
101:         @since 0.0.4
102:         */
103:        public class PrimitiveFilter {
104:            // <class>
105:            // <dynamic>
106:            // <fields>
107:            private ContentScanner scanner;
108:
109:            private ContentScanner currentLevel;
110:
111:            // </fields>
112:
113:            // <constructors>
114:            public PrimitiveFilter(ContentScanner scanner) {
115:                this .scanner = scanner;
116:
117:                this .currentLevel = scanner.getLeafLevel();
118:            }
119:
120:            public PrimitiveFilter(IContentContext context) {
121:                this (new ContentScanner(context.getContents()));
122:            }
123:
124:            // </constructors>
125:
126:            // <interface>
127:            // <public>
128:            /**
129:              Adds a content object.
130:              @return The added content object.
131:              @version 0.0.5
132:             */
133:            public ContentObject add(ContentObject object) {
134:                currentLevel.insert(object);
135:                currentLevel.moveNext();
136:
137:                return object;
138:            }
139:
140:            /**
141:              Applies a transformation to the coordinate system from user space to device space [PDF:1.6:4.3.3].
142:              <h3>Remarks</h3>
143:              <p>The transformation is applied to the current transformation matrix (CTM) by concatenation,
144:              i.e. it doesn't replace it.</p>
145:              @param a Item 0,0 of the matrix.
146:              @param b Item 0,1 of the matrix.
147:              @param c Item 1,0 of the matrix.
148:              @param d Item 1,1 of the matrix.
149:              @param e Item 2,0 of the matrix.
150:              @param f Item 2,1 of the matrix.
151:              @see #setMatrix(double,double,double,double,double,double)
152:             */
153:            public void applyMatrix(double a, double b, double c, double d,
154:                    double e, double f) {
155:                add(new ModifyCTM(a, b, c, d, e, f));
156:            }
157:
158:            /**
159:              Adds a composite object beginning it.
160:              @return The added composite object.
161:              @see #end()
162:             */
163:            public CompositeObject begin(CompositeObject object) {
164:                // Insert the new object at the current level!
165:                currentLevel.insert(object);
166:                // The new object's children level is the new current level!
167:                currentLevel = currentLevel.getChildLevel();
168:
169:                return object;
170:            }
171:
172:            /**
173:              Begins a new nested graphics state context [PDF:1.6:4.3.1].
174:              @return The added local graphics state object.
175:              @see #end()
176:             */
177:            public LocalGraphicsState beginLocalState() {
178:                return (LocalGraphicsState) begin(new LocalGraphicsState());
179:            }
180:
181:            /**
182:              Draws a rectangle [PDF:1.6:4.4.1].
183:              @see #fill()
184:              @see #fillStroke()
185:              @see #stroke()
186:             */
187:            public void drawRectangle(RectangularShape location) {
188:                add(new DrawRectangle(location.getX(), ((IPdfNumber) scanner
189:                        .getContentContext().getBox().get(3)).getNumberValue()
190:                        - location.getY() - location.getHeight(), location
191:                        .getWidth(), location.getHeight()));
192:            }
193:
194:            /**
195:              Ends the current (innermostly-nested) composite object.
196:              @see #begin(CompositeObject)
197:             */
198:            public void end() {
199:                currentLevel = currentLevel.getParentLevel();
200:                currentLevel.moveNext();
201:            }
202:
203:            /**
204:              Fills the path using the current color [PDF:1.6:4.4.2].
205:              @see #setFillColor(Color)
206:             */
207:            public void fill() {
208:                add(Fill.Value);
209:            }
210:
211:            /**
212:              Fills and then strokes the path using the current colors [PDF:1.6:4.4.2].
213:              @see #setFillColor(Color)
214:              @see #setStrokeColor(Color)
215:             */
216:            public void fillStroke() {
217:                add(FillStroke.Value);
218:            }
219:
220:            /**
221:              Serializes the contents into the content stream.
222:             */
223:            public void flush() {
224:                scanner.getContents().flush();
225:            }
226:
227:            /**
228:              Gets the content stream scanner.
229:             */
230:            public ContentScanner getScanner() {
231:                return scanner;
232:            }
233:
234:            /**
235:              Gets the current graphics state [PDF:1.6:4.3].
236:             */
237:            public ContentScanner.GraphicsState getState() {
238:                return currentLevel.getState();
239:            }
240:
241:            /**
242:              Applies a rotation to the coordinate system from user space to device space [PDF:1.6:4.2.2].
243:              @param angle Rotational counterclockwise angle.
244:              @see #applyMatrix(double,double,double,double,double,double)
245:             */
246:            public void rotate(double angle) {
247:                double rad = angle * Math.PI / 180;
248:                double cos = Math.cos(rad);
249:                double sin = Math.sin(rad);
250:
251:                applyMatrix(cos, sin, -sin, cos, 0, 0);
252:            }
253:
254:            /**
255:              Applies a scaling to the coordinate system from user space to device space
256:              [PDF:1.6:4.2.2].
257:              @param ratioX Horizontal scaling ratio.
258:              @param ratioY Vertical scaling ratio.
259:              @see #applyMatrix(double,double,double,double,double,double)
260:             */
261:            public void scale(double ratioX, double ratioY) {
262:                applyMatrix(ratioX, 0, 0, ratioY, 0, 0);
263:            }
264:
265:            /**
266:              Sets the character spacing parameter [PDF:1.6:5.2.1].
267:             */
268:            public void setCharSpace(double value) {
269:                add(new SetCharSpace(value));
270:            }
271:
272:            /**
273:              Sets the nonstroking color value [PDF:1.6:4.5.7].
274:              @see #setStrokeColor(Color)
275:             */
276:            public void setFillColor(Color value) {
277:                if (currentLevel.getState().getFillColorSpace() != value
278:                        .getColorSpace()) {
279:                    // Set filling color space!
280:                    add(new SetFillColorSpace(getColorSpaceName(value
281:                            .getColorSpace())));
282:                }
283:
284:                add(new SetFillColor(value));
285:            }
286:
287:            /**
288:              Sets the font [PDF:1.6:5.2].
289:              @param name Resource identifier of the font.
290:              @param size Scaling factor (points).
291:             */
292:            public void setFont(PdfName name, double size) {
293:                // Doesn't the font exist in the context resources?
294:                if (!scanner.getContentContext().getResources().getFonts()
295:                        .containsKey(name))
296:                    throw new IllegalArgumentException(
297:                            "No font resource associated to the given argument (name:'name'; value:'"
298:                                    + name + "';)");
299:
300:                add(new SetFont(name, size));
301:            }
302:
303:            /**
304:              Sets the font [PDF:1.6:5.2].
305:              <h3>Remarks</h3>
306:              <p>The <code>value</code> is checked for presence in the current resource
307:              dictionary: if it isn't available, it's automatically added. If you need to
308:              avoid such a behavior, use {@link #setFont(PdfName,double) setFont(PdfName,double)}.</p>
309:              @param value Font.
310:              @param size Scaling factor (points).
311:              @version 0.0.5
312:             */
313:            public void setFont(Font value, double size) {
314:                setFont(getFontName(value), size);
315:            }
316:
317:            /**
318:              Sets the text horizontal scaling [PDF:1.6:5.2.3].
319:             */
320:            public void setTextScale(double value) {
321:                add(new SetTextScale(value));
322:            }
323:
324:            /**
325:              Sets the text leading [PDF:1.6:5.2.4].
326:             */
327:            public void setTextLead(double value) {
328:                add(new SetTextLead(value));
329:            }
330:
331:            /**
332:              Sets the line cap style [PDF:1.6:4.3.2].
333:             */
334:            public void setLineCap(LineCapEnum value) {
335:                add(new SetLineCap(value));
336:            }
337:
338:            /**
339:              Sets the line dash pattern [PDF:1.6:4.3.2].
340:              @param phase Distance into the dash pattern at which to start the dash.
341:              @param unitsOn Length of evenly alternating dashes and gaps.
342:             */
343:            public void setLineDash(int phase, int unitsOn) {
344:                setLineDash(phase, unitsOn, unitsOn);
345:            }
346:
347:            /**
348:              Sets the line dash pattern [PDF:1.6:4.3.2].
349:              @param phase Distance into the dash pattern at which to start the dash.
350:              @param unitsOn Length of dashes.
351:              @param unitsOff Length of gaps.
352:             */
353:            public void setLineDash(int phase, int unitsOn, int unitsOff) {
354:                add(new SetLineDash(phase, unitsOn, unitsOff));
355:            }
356:
357:            /**
358:              Sets the line join style [PDF:1.6:4.3.2].
359:             */
360:            public void setLineJoin(LineJoinEnum value) {
361:                add(new SetLineJoin(value));
362:            }
363:
364:            /**
365:              Sets the line width [PDF:1.6:4.3.2].
366:             */
367:            public void setLineWidth(double value) {
368:                add(new SetLineWidth(value));
369:            }
370:
371:            /**
372:              Sets the transformation of the coordinate system from user space to device space [PDF:1.6:4.3.3].
373:              <h3>Remarks</h3>
374:              <p>The transformation replaces the current transformation matrix (CTM).</p>
375:              @param a Item 0,0 of the matrix.
376:              @param b Item 0,1 of the matrix.
377:              @param c Item 1,0 of the matrix.
378:              @param d Item 1,1 of the matrix.
379:              @param e Item 2,0 of the matrix.
380:              @param f Item 2,1 of the matrix.
381:              @see #applyMatrix(double,double,double,double,double,double)
382:             */
383:            public void setMatrix(double a, double b, double c, double d,
384:                    double e, double f) {
385:                // Reset the CTM!
386:                add(ModifyCTM.getResetCTM(scanner.getState().getCTM()));
387:                // Apply the transformation!
388:                add(new ModifyCTM(a, b, c, d, e, f));
389:            }
390:
391:            /**
392:              Sets the miter limit [PDF:1.6:4.3.2].
393:             */
394:            public void setMiterLimit(double value) {
395:                add(new SetMiterLimit(value));
396:            }
397:
398:            /**
399:              Sets the stroking color value [PDF:1.6:4.5.7].
400:              @see #setFillColor(Color)
401:             */
402:            public void setStrokeColor(Color value) {
403:                if (currentLevel.getState().getStrokeColorSpace() != value
404:                        .getColorSpace()) {
405:                    // Set stroking color space!
406:                    add(new SetStrokeColorSpace(getColorSpaceName(value
407:                            .getColorSpace())));
408:                }
409:
410:                add(new SetStrokeColor(value));
411:            }
412:
413:            /**
414:              Sets the text rendering mode [PDF:1.6:5.2.5].
415:             */
416:            public void setTextRenderMode(TextRenderModeEnum value) {
417:                add(new SetTextRenderMode(value));
418:            }
419:
420:            /**
421:              Sets the text rise [PDF:1.6:5.2.6].
422:             */
423:            public void setTextRise(double value) {
424:                add(new SetTextRise(value));
425:            }
426:
427:            /**
428:              Sets the word spacing [PDF:1.6:5.2.2].
429:             */
430:            public void setWordSpace(double value) {
431:                add(new SetWordSpace(value));
432:            }
433:
434:            /**
435:              Shows the specified text on the page at the current location [PDF:1.6:5.3.2].
436:              @param value Text to show.
437:             */
438:            public void showText(String value) {
439:                beginText();
440:                add(new ShowText(value));
441:                end();
442:            }
443:
444:            /**
445:              Shows the specified text on the page at the specified location [PDF:1.6:5.3.2].
446:              @param value Text to show.
447:              @param location Position at which showing the text.
448:             */
449:            public void showText(String value, Point2D location) {
450:                showText(value, location, AlignmentXEnum.Left,
451:                        AlignmentYEnum.Top, 0);
452:            }
453:
454:            /**
455:              Shows the specified text on the page at the specified location [PDF:1.6:5.3.2].
456:              @param value Text to show.
457:              @param location Anchor position at which showing the text.
458:              @param alignmentX Horizontal alignment.
459:              @param alignmentY Vertical alignment.
460:              @param rotation Rotational counterclockwise angle.
461:             */
462:            public void showText(String value, Point2D location,
463:                    AlignmentXEnum alignmentX, AlignmentYEnum alignmentY,
464:                    double rotation) {
465:                ContentScanner.GraphicsState.TextState state = currentLevel
466:                        .getState().getText();
467:                Font font = state.getFont();
468:                double fontSize = state.getFontSize();
469:                double x = location.getX();
470:                double y = location.getY();
471:
472:                if (alignmentX == AlignmentXEnum.Left
473:                        && alignmentY == AlignmentYEnum.Top) {
474:                    beginText();
475:
476:                    if (rotation == 0) {
477:                        translateText(x, ((IPdfNumber) scanner
478:                                .getContentContext().getBox().get(3))
479:                                .getNumberValue()
480:                                - y - font.getAscent(fontSize));
481:                    } else {
482:                        double rad = rotation * Math.PI / 180.0;
483:                        double cos = Math.cos(rad);
484:                        double sin = Math.sin(rad);
485:
486:                        setTextMatrix(cos, sin, -sin, cos, x,
487:                                ((IPdfNumber) scanner.getContentContext()
488:                                        .getBox().get(3)).getNumberValue()
489:                                        - y - font.getAscent(fontSize));
490:                    }
491:
492:                    add(new ShowText(value));
493:                    end();
494:                } else {
495:                    beginLocalState();
496:
497:                    // Coordinates transformation.
498:                    double cos, sin;
499:                    if (rotation == 0) {
500:                        cos = 1;
501:                        sin = 0;
502:                    } else {
503:                        double rad = rotation * Math.PI / 180.0;
504:                        cos = Math.cos(rad);
505:                        sin = Math.sin(rad);
506:                    }
507:                    // Apply the transformation!
508:                    applyMatrix(cos, sin, -sin, cos, x, ((IPdfNumber) scanner
509:                            .getContentContext().getBox().get(3))
510:                            .getNumberValue()
511:                            - y);
512:
513:                    // Begin the text object!
514:                    beginText();
515:
516:                    // Text coordinates adjustment.
517:                    double width = font.getKernedWidth(value, fontSize);
518:                    switch (alignmentX) {
519:                    case Left:
520:                        x = 0;
521:                        break;
522:                    case Right:
523:                        x = -width;
524:                        break;
525:                    case Center:
526:                    case Justify:
527:                        x = -width / 2;
528:                        break;
529:                    }
530:                    switch (alignmentY) {
531:                    case Bottom:
532:                        y = font.getLineHeight(fontSize)
533:                                - font.getAscent(fontSize);
534:                        break;
535:                    case Middle:
536:                        y = font.getLineHeight(fontSize) / 2
537:                                - font.getAscent(fontSize);
538:                        break;
539:                    }
540:                    // Apply the text coordinates adjustment!
541:                    translateText(x, y);
542:
543:                    // Add the text!
544:                    add(new ShowText(value));
545:                    // Close the text object!
546:                    end();
547:                    // Close the local state!
548:                    end();
549:                }
550:            }
551:
552:            /**
553:              Shows the specified external object [PDF:1.6:4.7].
554:              @param name Resource identifier of the external object.
555:             */
556:            public void showXObject(PdfName name) {
557:                add(new PaintXObject(name));
558:            }
559:
560:            /**
561:              Shows the specified external object [PDF:1.6:4.7].
562:              <h3>Remarks</h3>
563:              <p>The <code>value</code> is checked for presence in the current resource
564:              dictionary: if it isn't available, it's automatically added. If you need to
565:              avoid such a behavior, use {@link #showXObject(PdfName) #showXObject(PdfName)}.</p>
566:              @param value External object.
567:              @version 0.0.5
568:              @since 0.0.5
569:             */
570:            public void showXObject(XObject value) {
571:                showXObject(getXObjectName(value));
572:            }
573:
574:            /**
575:              Shows the specified external object at the specified position [PDF:1.6:4.7].
576:              @param name Resource identifier of the external object.
577:              @param location Position at which showing the external object.
578:              @version 0.0.5
579:             */
580:            public void showXObject(PdfName name, Point2D location) {
581:                showXObject(name, location, new Dimension(0, 0));
582:            }
583:
584:            /**
585:              Shows the specified external object at the specified position [PDF:1.6:4.7].
586:              <h3>Remarks</h3>
587:              <p>The <code>value</code> is checked for presence in the current resource
588:              dictionary: if it isn't available, it's automatically added. If you need to
589:              avoid such a behavior, use {@link #showXObject(PdfName,Point2D) #showXObject(PdfName,Point2D)}.</p>
590:              @param value External object.
591:              @param location Position at which showing the external object.
592:              @version 0.0.5
593:              @since 0.0.5
594:             */
595:            public void showXObject(XObject value, Point2D location) {
596:                showXObject(getXObjectName(value), location);
597:            }
598:
599:            /**
600:              Shows the specified external object at the specified position [PDF:1.6:4.7].
601:              @param name Resource identifier of the external object.
602:              @param location Position at which showing the external object.
603:              @param size Size of the external object.
604:              @version 0.0.5
605:              @since 0.0.5
606:             */
607:            public void showXObject(PdfName name, Point2D location,
608:                    Dimension2D size) {
609:                showXObject(name, location, size, AlignmentXEnum.Left,
610:                        AlignmentYEnum.Top, 0);
611:            }
612:
613:            /**
614:              Shows the specified external object at the specified position [PDF:1.6:4.7].
615:              <h3>Remarks</h3>
616:              <p>The <code>value</code> is checked for presence in the current resource
617:              dictionary: if it isn't available, it's automatically added. If you need to
618:              avoid such a behavior, use {@link #showXObject(PdfName,Point2D,Dimension2D) #showXObject(PdfName,Point2D,Dimension2D)}.</p>
619:              @param value External object.
620:              @param location Position at which showing the external object.
621:              @param size Size of the external object.
622:              @version 0.0.5
623:              @since 0.0.5
624:             */
625:            public void showXObject(XObject value, Point2D location,
626:                    Dimension2D size) {
627:                showXObject(getXObjectName(value), location, size);
628:            }
629:
630:            /**
631:              Shows the specified external object at the specified position [PDF:1.6:4.7].
632:              @param name Resource identifier of the external object.
633:              @param location Position at which showing the external object.
634:              @param size Size of the external object.
635:              @param alignmentX Horizontal alignment.
636:              @param alignmentY Vertical alignment.
637:              @param rotation Rotational counterclockwise angle.
638:              @version 0.0.5
639:             */
640:            public void showXObject(PdfName name, Point2D location,
641:                    Dimension2D size, AlignmentXEnum alignmentX,
642:                    AlignmentYEnum alignmentY, double rotation) {
643:                XObject xObject = scanner.getContentContext().getResources()
644:                        .getXObjects().get(name);
645:
646:                // Adjusting default dimensions...
647:                /*
648:                  NOTE: Zero-valued dimensions represent default proportional dimensions.
649:                 */
650:                Dimension2D xObjectSize = xObject.getSize();
651:                if (size.getWidth() == 0) {
652:                    if (size.getHeight() == 0) {
653:                        size.setSize(xObjectSize);
654:                    } else {
655:                        size.setSize(size.getHeight() * xObjectSize.getWidth()
656:                                / xObjectSize.getHeight(), size.getHeight());
657:                    }
658:                } else if (size.getHeight() == 0) {
659:                    size.setSize(size.getWidth(), size.getWidth()
660:                            * xObjectSize.getHeight() / xObjectSize.getWidth());
661:                }
662:
663:                // Scaling.
664:                double[] matrix = xObject.getMatrix();
665:                double scaleX, scaleY;
666:                scaleX = size.getWidth() / (xObjectSize.getWidth() * matrix[0]);
667:                scaleY = size.getHeight()
668:                        / (xObjectSize.getHeight() * matrix[3]);
669:
670:                // Alignment.
671:                double locationOffsetX, locationOffsetY;
672:                switch (alignmentX) {
673:                case Left:
674:                    locationOffsetX = 0;
675:                    break;
676:                case Right:
677:                    locationOffsetX = size.getWidth();
678:                    break;
679:                case Center:
680:                case Justify:
681:                default:
682:                    locationOffsetX = size.getWidth() / 2;
683:                    break;
684:                }
685:                switch (alignmentY) {
686:                case Top:
687:                    locationOffsetY = size.getHeight();
688:                    break;
689:                case Bottom:
690:                    locationOffsetY = 0;
691:                    break;
692:                case Middle:
693:                default:
694:                    locationOffsetY = size.getHeight() / 2;
695:                    break;
696:                }
697:
698:                beginLocalState();
699:                translate(location.getX(), ((IPdfNumber) scanner
700:                        .getContentContext().getBox().get(3)).getNumberValue()
701:                        - location.getY());
702:                if (rotation != 0) {
703:                    rotate(rotation);
704:                }
705:                applyMatrix(scaleX, 0, 0, scaleY, -locationOffsetX,
706:                        -locationOffsetY);
707:                showXObject(name);
708:                end();
709:            }
710:
711:            /**
712:              Shows the specified external object at the specified position [PDF:1.6:4.7].
713:              <h3>Remarks</h3>
714:              <p>The <code>value</code> is checked for presence in the current resource
715:              dictionary: if it isn't available, it's automatically added. If you need to
716:              avoid such a behavior, use {@link #showXObject(PdfName,Point2D,Dimension2D,AlignmentXEnum,AlignmentYEnum,double) #showXObject(PdfName,Point2D,Dimension2D,AlignmentXEnum,AlignmentYEnum,double)}.</p>
717:              @param value External object.
718:              @param location Position at which showing the external object.
719:              @param size Size of the external object.
720:              @param alignmentX Horizontal alignment.
721:              @param alignmentY Vertical alignment.
722:              @param rotation Rotational counterclockwise angle.
723:              @version 0.0.5
724:              @since 0.0.5
725:             */
726:            public void showXObject(XObject value, Point2D location,
727:                    Dimension2D size, AlignmentXEnum alignmentX,
728:                    AlignmentYEnum alignmentY, double rotation) {
729:                showXObject(getXObjectName(value), location, size, alignmentX,
730:                        alignmentY, rotation);
731:            }
732:
733:            /**
734:              Strokes the path using the current color [PDF:1.6:4.4.2].
735:              @see #setStrokeColor(Color)
736:             */
737:            public void stroke() {
738:                add(Stroke.Value);
739:            }
740:
741:            /**
742:              Applies a translation to the coordinate system from user space
743:              to device space [PDF:1.6:4.2.2].
744:              @param distanceX Horizontal distance.
745:              @param distanceY Vertical distance.
746:              @see #applyMatrix(double,double,double,double,double,double)
747:             */
748:            public void translate(double distanceX, double distanceY) {
749:                applyMatrix(1, 0, 0, 1, distanceX, distanceY);
750:            }
751:
752:            // </public>
753:
754:            // <private>
755:            /**
756:              Begins a text object [PDF:1.6:5.3].
757:              @see #end()
758:             */
759:            private Text beginText() {
760:                return (Text) begin(new Text());
761:            }
762:
763:            private PdfName getFontName(Font value) {
764:                // Ensuring that the font exists within the context resources...
765:                Resources resources = scanner.getContentContext()
766:                        .getResources();
767:                Fonts fonts = resources.getFonts();
768:                // No font resources collection?
769:                if (fonts == null) {
770:                    // Create the font resources collection!
771:                    fonts = new Fonts(scanner.getContents().getDocument());
772:                    resources.setFonts(fonts);
773:                    resources.update();
774:                }
775:                // Get the key associated to the font!
776:                PdfName name = fonts.getBaseDataObject().getKey(
777:                        value.getBaseObject());
778:                // No key found?
779:                if (name == null) {
780:                    // Insert the font within the resources!
781:                    int fontIndex = fonts.size();
782:                    do {
783:                        name = new PdfName(String.valueOf(++fontIndex));
784:                    } while (fonts.containsKey(name));
785:                    fonts.put(name, value);
786:                    fonts.update();
787:                }
788:
789:                return name;
790:            }
791:
792:            private PdfName getXObjectName(XObject value) {
793:                // Ensuring that the external object exists within the context resources...
794:                Resources resources = scanner.getContentContext()
795:                        .getResources();
796:                XObjects xObjects = resources.getXObjects();
797:                // No external object resources collection?
798:                if (xObjects == null) {
799:                    // Create the external object resources collection!
800:                    xObjects = new XObjects(scanner.getContents().getDocument());
801:                    resources.setXObjects(xObjects);
802:                    resources.update();
803:                }
804:                // Get the key associated to the external object!
805:                PdfName name = xObjects.getBaseDataObject().getKey(
806:                        value.getBaseObject());
807:                // No key found?
808:                if (name == null) {
809:                    // Insert the external object within the resources!
810:                    int xObjectIndex = xObjects.size();
811:                    do {
812:                        name = new PdfName(String.valueOf(++xObjectIndex));
813:                    } while (xObjects.containsKey(name));
814:                    xObjects.put(name, value);
815:                    xObjects.update();
816:                }
817:
818:                return name;
819:            }
820:
821:            private PdfName getColorSpaceName(ColorSpace value) {
822:                if (value instanceof  DeviceGrayColorSpace) {
823:                    return PdfName.DeviceGray;
824:                } else if (value instanceof  DeviceRGBColorSpace) {
825:                    return PdfName.DeviceRGB;
826:                } else if (value instanceof  DeviceCMYKColorSpace) {
827:                    return PdfName.DeviceCMYK;
828:                } else
829:                    throw new NotImplementedException(
830:                            "colorSpace MUST be converted to its associated name; you need to implement a method in PdfDictionary that, given a PdfDirectObject, returns its associated key.");
831:            }
832:
833:            /**
834:              Applies a rotation to the coordinate system from text space to user space [PDF:1.6:4.2.2].
835:              @param angle Rotational counterclockwise angle.
836:             */
837:            private void rotateText(double angle) {
838:                double rad = angle * Math.PI / 180;
839:                double cos = Math.cos(rad);
840:                double sin = Math.sin(rad);
841:
842:                setTextMatrix(cos, sin, -sin, cos, 0, 0);
843:            }
844:
845:            /**
846:              Applies a scaling to the coordinate system from text space to user space
847:              [PDF:1.6:4.2.2].
848:              @param ratioX Horizontal scaling ratio.
849:              @param ratioY Vertical scaling ratio.
850:             */
851:            private void scaleText(double ratioX, double ratioY) {
852:                setTextMatrix(ratioX, 0, 0, ratioY, 0, 0);
853:            }
854:
855:            /**
856:              Sets the transformation of the coordinate system from text space to user space [PDF:1.6:5.3.1].
857:              <h3>Remarks</h3>
858:              <p>The transformation replaces the current text matrix.</p>
859:              @param a Item 0,0 of the matrix.
860:              @param b Item 0,1 of the matrix.
861:              @param c Item 1,0 of the matrix.
862:              @param d Item 1,1 of the matrix.
863:              @param e Item 2,0 of the matrix.
864:              @param f Item 2,1 of the matrix.
865:             */
866:            private void setTextMatrix(double a, double b, double c, double d,
867:                    double e, double f) {
868:                add(new SetTextMatrix(a, b, c, d, e, f));
869:            }
870:
871:            /**
872:              Applies a translation to the coordinate system from text space
873:              to user space [PDF:1.6:4.2.2].
874:              @param distanceX Horizontal distance.
875:              @param distanceY Vertical distance.
876:             */
877:            private void translateText(double distanceX, double distanceY) {
878:                setTextMatrix(1, 0, 0, 1, distanceX, distanceY);
879:            }
880:
881:            /**
882:              Applies a translation to the coordinate system from text space to user space,
883:              relative to the start of the current line [PDF:1.6:5.3.1].
884:              @param offsetX Horizontal offset.
885:              @param offsetY Vertical offset.
886:             */
887:            private void translateTextRelative(double offsetX, double offsetY) {
888:                add(new TranslateTextRelative(offsetX, -offsetY));
889:            }
890:
891:            /**
892:              Applies a translation to the coordinate system from text space to user space,
893:              moving to the start of the next line [PDF:1.6:5.3.1].
894:             */
895:            private void translateTextToNextLine() {
896:                add(TranslateTextToNextLine.Value);
897:            }
898:            // </private>
899:            // </interface>
900:            // </dynamic>
901:            // </class>
902:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.