KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > afp > modca > AFPDataStream


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: AFPDataStream.java 454018 2006-10-07 21:00:13Z pietsch $ */
19
20 package org.apache.fop.render.afp.modca;
21
22 import java.awt.Color JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.OutputStream JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.fop.render.afp.fonts.AFPFont;
29 import org.apache.fop.render.afp.tools.StringUtils;
30
31 /**
32  * A data stream is a continuous ordered stream of data elements and objects
33  * conforming to a given format. Application programs can generate data streams
34  * destined for a presentation service, archive library, presentation device or
35  * another application program. The strategic presentation data stream
36  * architectures used is Mixed Object Document Content Architecture (MO:DCA�).
37  *
38  * The MO:DCA architecture defines the data stream used by applications to
39  * describe documents and object envelopes for interchange with other
40  * applications and application services. Documents defined in the MO:DCA format
41  * may be archived in a database, then later retrieved, viewed, annotated and
42  * printed in local or distributed systems environments. Presentation fidelity
43  * is accommodated by including resource objects in the documents that reference
44  * them.
45  *
46  */

47 public class AFPDataStream {
48
49     /**
50      * Static logging instance
51      */

52     protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
53
54     /**
55      * Boolean completion indicator
56      */

57     private boolean _complete = false;
58
59     /**
60      * The application producing the AFP document
61      */

62     private String JavaDoc _producer = null;
63
64     /**
65      * The AFP document object
66      */

67     private Document _document = null;
68
69     /**
70      * The current page group object
71      */

72     private PageGroup _currentPageGroup = null;
73
74     /**
75      * The current page object
76      */

77     private PageObject _currentPageObject = null;
78
79     /**
80      * The current overlay object
81      */

82     private Overlay _currentOverlay = null;
83
84     /**
85      * The current page
86      */

87     private AbstractPageObject _currentPage = null;
88
89     /**
90      * The page count
91      */

92     private int _pageCount = 0;
93
94     /**
95      * The page group count
96      */

97     private int _pageGroupCount = 0;
98
99     /**
100      * The overlay count
101      */

102     private int _ovlCount = 0;
103
104     /**
105      * The portrait rotation
106      */

107     private int _portraitRotation = 0;
108
109     /**
110      * The landscape rotation
111      */

112     private int _landscapeRotation = 270;
113
114     /**
115      * The x offset
116      */

117     private int _xOffset = 0;
118
119     /**
120      * The y offset
121      */

122     private int _yOffset = 0;
123
124     /**
125      * The rotation
126      */

127     private int _rotation;
128
129     /**
130      * The outputstream for the data stream
131      */

132     private OutputStream JavaDoc _outputStream = null;
133
134     /**
135      * Default constructor for the AFPDataStream.
136      */

137     public AFPDataStream() {
138     }
139
140     /**
141      * The document is started by invoking this method which creates an instance
142      * of the AFP Document object.
143      */

144     public void startDocument(OutputStream JavaDoc outputStream) {
145
146         if (_document != null) {
147             String JavaDoc msg = "Invalid state - document already started.";
148             log.warn("startDocument():: " + msg);
149             throw new IllegalStateException JavaDoc(msg);
150         }
151
152         _document = new Document();
153         _outputStream = outputStream;
154
155     }
156
157     /**
158      * The document is ended by invoking this method which creates an instance
159      * of the AFP Document object and registers the start with a validation map
160      * which ensures that methods are not invoked out of the correct sequence.
161      */

162     public void endDocument()
163         throws IOException JavaDoc {
164
165         if (_complete) {
166             String JavaDoc msg = "Invalid state - document already ended.";
167             log.warn("endDocument():: " + msg);
168             throw new IllegalStateException JavaDoc(msg);
169         }
170
171         if (_currentPageObject != null) {
172             // End the current page if necessary
173
endPage();
174         }
175
176         if (_currentPageGroup != null) {
177             // End the current page group if necessary
178
endPageGroup();
179         }
180
181         _document.endDocument();
182         _document.writeDataStream(_outputStream);
183         _outputStream.flush();
184
185         _complete = true;
186
187         _document = null;
188
189         _outputStream = null;
190     }
191
192     /**
193      * Start a new page. When processing has finished on the current page, the
194      * {@link #endPage()}method must be invoked to mark the page ending.
195      *
196      * @param pageWidth
197      * the width of the page
198      * @param pageHeight
199      * the height of the page
200      * @param pageRotation
201      * the rotation of the page
202      */

203     public void startPage(int pageWidth, int pageHeight, int pageRotation) {
204
205         String JavaDoc pageName = "PGN"
206             + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
207
208         _currentPageObject = new PageObject(pageName, pageWidth, pageHeight, pageRotation);
209         _currentPage = _currentPageObject;
210         _currentOverlay = null;
211         setOffsets(0, 0, 0);
212     }
213
214     /**
215      * Start a new overlay. When processing has finished on the current overlay, the
216      * {@link #endOverlay()}method must be invoked to mark the overlay ending.
217      *
218      * @param overlayX
219      * the x position of the overlay on the page
220      * @param overlayY
221      * the y position of the overlay on the page
222      * @param overlayWidth
223      * the width of the overlay
224      * @param overlayHeight
225      * the height of the overlay
226      * @param overlayRotation
227      * the rotation of the overlay
228      */

229     public void startOverlay(int overlayX, int overlayY, int overlayWidth, int overlayHeight, int overlayRotation) {
230
231         String JavaDoc overlayName = "OVL"
232             + StringUtils.lpad(String.valueOf(_ovlCount++), '0', 5);
233
234         _currentOverlay = new Overlay(overlayName, overlayWidth, overlayHeight, overlayRotation);
235         _currentPageObject.addOverlay(_currentOverlay);
236         _currentPageObject.createIncludePageOverlay(overlayName, overlayX, overlayY, 0);
237         _currentPage = _currentOverlay;
238         setOffsets(0, 0, 0);
239     }
240
241     /**
242      * Helper method to mark the end of the current overlay.
243      */

244     public void endOverlay() {
245
246         _currentOverlay.endPage();
247         _currentOverlay = null;
248         _currentPage = _currentPageObject;
249
250     }
251
252     /**
253      * Helper method to save the current page.
254      */

255     public PageObject savePage() {
256
257         PageObject pageObject = _currentPageObject;
258         if (_currentPageGroup != null) {
259             _currentPageGroup.addPage(_currentPageObject);
260         } else {
261             _document.addPage(_currentPageObject);
262         }
263         _currentPageObject = null;
264         _currentPage = null;
265         return pageObject;
266
267     }
268
269     /**
270      * Helper method to restore the current page.
271      */

272     public void restorePage(PageObject pageObject) {
273
274         _currentPageObject = pageObject;
275         _currentPage = pageObject;
276
277     }
278
279     /**
280      * Helper method to mark the end of the current page.
281      */

282     public void endPage()
283         throws IOException JavaDoc {
284
285         _currentPageObject.endPage();
286         if (_currentPageGroup != null) {
287             _currentPageGroup.addPage(_currentPageObject);
288         } else {
289             _document.addPage(_currentPageObject);
290             _document.writeDataStream(_outputStream);
291         }
292
293         _currentPageObject = null;
294         _currentPage = null;
295
296     }
297
298     /**
299      * Sets the offsets to be used for element positioning
300      *
301      * @param xOffset
302      * the offset in the x direction
303      * @param yOffset
304      * the offset in the y direction
305      * @param rotation
306      * the rotation
307      */

308     public void setOffsets(int xOffset, int yOffset, int rotation) {
309         _xOffset = xOffset;
310         _yOffset = yOffset;
311         _rotation = rotation;
312     }
313
314     /**
315      * Helper method to create a map coded font object on the current page, this
316      * method delegates the construction of the map coded font object to the
317      * active environment group on the current page.
318      *
319      * @param fontReference
320      * the font number used as the resource identifier
321      * @param font
322      * the font
323      * @param size
324      * the point size of the font
325      */

326     public void createFont(byte fontReference, AFPFont font, int size) {
327
328         _currentPage.createFont(fontReference, font, size);
329
330     }
331
332     /**
333      * Helper method to create text on the current page, this method delegates
334      * to the current presentation text object in order to construct the text.
335      *
336      * @param fontNumber
337      * the font number used as the resource identifier
338      * @param x
339      * the x coordinate of the text
340      * @param y
341      * the y coordinate of the text
342      * @param col
343      * the text color
344      * @param vsci
345      * The variable space character increment.
346      * @param ica
347      * The inter character adjustment.
348      * @param data
349      * the text data to create
350      */

351     public void createText(int fontNumber, int x, int y, Color JavaDoc col, int vsci, int ica, byte[] data) {
352
353         _currentPage.createText(fontNumber, x + _xOffset, y + _yOffset, _rotation, col, vsci, ica, data);
354
355     }
356
357     /**
358      * Returns an ImageObject used to create an image in the datastream.
359      *
360      * @param x
361      * the x position of the image
362      * @param y
363      * the y position of the image
364      * @param w
365      * the width of the image
366      * @param h
367      * the height of the image
368      */

369     public ImageObject getImageObject(int x, int y, int w, int h) {
370
371         int xOrigin;
372         int yOrigin;
373         int width;
374         int height;
375         switch (_rotation) {
376             case 90:
377                 xOrigin = _currentPage.getWidth() - y - _yOffset;
378                 yOrigin = x + _xOffset;
379                 width = h;
380                 height = w;
381                 break;
382             case 180:
383                 xOrigin = _currentPage.getWidth() - x - _xOffset;
384                 yOrigin = _currentPage.getHeight() - y - _yOffset;
385                 width = w;
386                 height = h;
387                 break;
388             case 270:
389                 xOrigin = y + _yOffset;
390                 yOrigin = _currentPage.getHeight() - x - _xOffset;
391                 width = h;
392                 height = w;
393                 break;
394             default:
395                 xOrigin = x + _xOffset;
396                 yOrigin = y + _yOffset;
397                 width = w;
398                 height = h;
399                 break;
400         }
401         ImageObject io = _currentPage.getImageObject();
402         io.setImageViewport(xOrigin, yOrigin, width, height, _rotation);
403         return io;
404
405     }
406
407     /**
408      * Method to create a line on the current page.
409      *
410      * @param x1
411      * the first x coordinate of the line
412      * @param y1
413      * the first y coordinate of the line
414      * @param x2
415      * the second x coordinate of the line
416      * @param y2
417      * the second y coordinate of the line
418      * @param thickness
419      * the thickness of the line
420      * @param col
421      * The text color.
422      */

423     public void createLine(int x1, int y1, int x2, int y2, int thickness, Color JavaDoc col) {
424
425         _currentPage.createLine(x1 + _xOffset, y1 + _yOffset, x2 + _xOffset, y2 + _yOffset, thickness, _rotation, col);
426
427     }
428
429     /**
430      * This method will create shading on the page using the specified
431      * coordinates (the shading contrast is controlled via the red, green, blue
432      * parameters, by converting this to grey scale).
433      *
434      * @param x
435      * the x coordinate of the shading
436      * @param y
437      * the y coordinate of the shading
438      * @param w
439      * the width of the shaded area
440      * @param h
441      * the height of the shaded area
442      * @param red
443      * the red value
444      * @param green
445      * the green value
446      * @param blue
447      * the blue value
448      */

449     public void createShading(int x, int y, int w, int h, int red, int green,
450         int blue) {
451
452         _currentPage.createShading(x + _xOffset, y + _xOffset, w, h, red, green, blue);
453
454     }
455
456     /**
457      * Helper method which allows creation of the MPO object, via the AEG. And
458      * the IPO via the Page. (See actual object for descriptions.)
459      *
460      * @param name
461      * the name of the static overlay
462      */

463     public void createIncludePageOverlay(String JavaDoc name) {
464
465         _currentPageObject.createIncludePageOverlay(name, 0, 0, _rotation);
466         ActiveEnvironmentGroup aeg = _currentPageObject.getActiveEnvironmentGroup();
467         aeg.createOverlay(name);
468
469     }
470
471     /**
472      * Helper method which allows creation of the IMM object.
473      *
474      * @param name
475      * the name of the medium map
476      */

477     public void createInvokeMediumMap(String JavaDoc name) {
478
479         if (_currentPageGroup == null) {
480             startPageGroup();
481         }
482         _currentPageGroup.createInvokeMediumMap(name);
483
484     }
485
486     /**
487      * Creates an IncludePageSegment on the current page.
488      *
489      * @param name
490      * the name of the include page segment
491      * @param x
492      * the x coordinate for the overlay
493      * @param y
494      * the y coordinate for the overlay
495      */

496     public void createIncludePageSegment(String JavaDoc name, int x, int y) {
497
498         int xOrigin;
499         int yOrigin;
500         switch (_rotation) {
501             case 90:
502                 xOrigin = _currentPage.getWidth() - y - _yOffset;
503                 yOrigin = x + _xOffset;
504                 break;
505             case 180:
506                 xOrigin = _currentPage.getWidth() - x - _xOffset;
507                 yOrigin = _currentPage.getHeight() - y - _yOffset;
508                 break;
509             case 270:
510                 xOrigin = y + _yOffset;
511                 yOrigin = _currentPage.getHeight() - x - _xOffset;
512                 break;
513             default:
514                 xOrigin = x + _xOffset;
515                 yOrigin = y + _yOffset;
516                 break;
517         }
518         _currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
519
520     }
521
522     /**
523      * Creates a TagLogicalElement on the current page.
524      *
525      * @param attributes
526      * the array of key value pairs.
527      */

528     public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
529
530         for (int i = 0; i < attributes.length; i++) {
531             String JavaDoc name = (String JavaDoc) attributes[i].getKey();
532             String JavaDoc value = (String JavaDoc) attributes[i].getValue();
533             _currentPage.createTagLogicalElement(name, value);
534         }
535
536     }
537
538     /**
539      * Creates a TagLogicalElement on the current page group.
540      *
541      * @param attributes
542      * the array of key value pairs.
543      */

544     public void createPageGroupTagLogicalElement(
545         TagLogicalElementBean[] attributes) {
546
547         for (int i = 0; i < attributes.length; i++) {
548             String JavaDoc name = (String JavaDoc) attributes[i].getKey();
549             String JavaDoc value = (String JavaDoc) attributes[i].getValue();
550             _currentPageGroup.createTagLogicalElement(name, value);
551         }
552
553     }
554
555     /**
556      * Creates a TagLogicalElement on the current page or page group
557      *
558      * @param name
559      * The tag name
560      * @param value
561      * The tag value
562      */

563     public void createTagLogicalElement(String JavaDoc name, String JavaDoc value) {
564
565         if (_currentPageGroup != null) {
566             _currentPageGroup.createTagLogicalElement(name, value);
567         } else {
568             _currentPage.createTagLogicalElement(name, value);
569         }
570
571     }
572
573     /**
574      * Start a new page group. When processing has finished on the current page
575      * group the {@link #endPageGroup()}method must be invoked to mark the page
576      * group ending.
577      *
578      * @param name
579      * the name of the page group
580      */

581     public void startPageGroup() {
582
583         String JavaDoc pageGroupName = "PGP"
584             + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
585
586         _currentPageGroup = new PageGroup(pageGroupName);
587
588     }
589
590     /**
591      * Helper method to mark the end of the page group.
592      */

593     public void endPageGroup()
594         throws IOException JavaDoc {
595
596         _currentPageGroup.endPageGroup();
597         _document.addPageGroup(_currentPageGroup);
598         _document.writeDataStream(_outputStream);
599         _currentPageGroup = null;
600
601     }
602
603     /**
604      * Sets the rotation to be used for portrait pages, valid values are 0
605      * (default), 90, 180, 270.
606      *
607      * @param rotation
608      * The rotation in degrees.
609      */

610     public void setPortraitRotation(int rotation) {
611
612         if (rotation == 0 || rotation == 90 || rotation == 180
613             || rotation == 270) {
614             _portraitRotation = rotation;
615         } else {
616             throw new IllegalArgumentException JavaDoc(
617                 "The portrait rotation must be one of the values 0, 90, 180, 270");
618         }
619
620     }
621
622     /**
623      * Sets the rotation to be used for landscape pages, valid values are 0, 90,
624      * 180, 270 (default).
625      *
626      * @param rotation
627      * The rotation in degrees.
628      */

629     public void setLandscapeRotation(int rotation) {
630
631         if (rotation == 0 || rotation == 90 || rotation == 180
632             || rotation == 270) {
633             _landscapeRotation = rotation;
634         } else {
635             throw new IllegalArgumentException JavaDoc(
636                 "The landscape rotation must be one of the values 0, 90, 180, 270");
637         }
638
639     }
640
641 }
642
Popular Tags