You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DataStream.java 23KB

* Created new AbstractState class that shares common properties and stack popping/pushing behaviour of and is now extended by AFPState and PDFState. * color, resolution and bitsPerPixel moved from AFPInfo to AFPState/AbstractState resulting in a more simplified AFPInfo and AFPSVGHandler. * Changed AFPRenderer, AFPDataStream, PresentationTextObject and PresentationTextData to use encapsulated AFPTextDataInfo instead of a chain of long parameter passing between objects. Also provided some formatting cleanup in PresentationTextData. * Use of X and Y offsets no longer used by AFPDataStream, setOffsets() is now deprecated and added setOrientation() accessor (which still remains relevant). * AFPRenderer no longer uses its own bespoke ViewPortPos mechanism and now uses the more standard state stack and AffineTransform mechanism enjoyed by the postscript and PDF Renderers. This means that there is now a proper implementation for startVParea(), endVParea(), saveGraphicsState(), restoreGraphicsState(), breakOutOfStateStack() and restoreStateStackAfterBreakOut() and it is no longer necessary to have a copy/pasted/tweaked renderBlockViewport() or renderRegionViewport(). As a result of this AFPRenderer is now much more compact (by some 500 lines) - similar work needs to be done in the PCL Renderer, any volunteers? * Added lots of helpful toString() methods for those mere mortals wishing to step through with a debugger :). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@675507 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
* Created new AbstractState class that shares common properties and stack popping/pushing behaviour of and is now extended by AFPState and PDFState. * color, resolution and bitsPerPixel moved from AFPInfo to AFPState/AbstractState resulting in a more simplified AFPInfo and AFPSVGHandler. * Changed AFPRenderer, AFPDataStream, PresentationTextObject and PresentationTextData to use encapsulated AFPTextDataInfo instead of a chain of long parameter passing between objects. Also provided some formatting cleanup in PresentationTextData. * Use of X and Y offsets no longer used by AFPDataStream, setOffsets() is now deprecated and added setOrientation() accessor (which still remains relevant). * AFPRenderer no longer uses its own bespoke ViewPortPos mechanism and now uses the more standard state stack and AffineTransform mechanism enjoyed by the postscript and PDF Renderers. This means that there is now a proper implementation for startVParea(), endVParea(), saveGraphicsState(), restoreGraphicsState(), breakOutOfStateStack() and restoreStateStackAfterBreakOut() and it is no longer necessary to have a copy/pasted/tweaked renderBlockViewport() or renderRegionViewport(). As a result of this AFPRenderer is now much more compact (by some 500 lines) - similar work needs to be done in the PCL Renderer, any volunteers? * Added lots of helpful toString() methods for those mere mortals wishing to step through with a debugger :). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@675507 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
* Created new AbstractState class that shares common properties and stack popping/pushing behaviour of and is now extended by AFPState and PDFState. * color, resolution and bitsPerPixel moved from AFPInfo to AFPState/AbstractState resulting in a more simplified AFPInfo and AFPSVGHandler. * Changed AFPRenderer, AFPDataStream, PresentationTextObject and PresentationTextData to use encapsulated AFPTextDataInfo instead of a chain of long parameter passing between objects. Also provided some formatting cleanup in PresentationTextData. * Use of X and Y offsets no longer used by AFPDataStream, setOffsets() is now deprecated and added setOrientation() accessor (which still remains relevant). * AFPRenderer no longer uses its own bespoke ViewPortPos mechanism and now uses the more standard state stack and AffineTransform mechanism enjoyed by the postscript and PDF Renderers. This means that there is now a proper implementation for startVParea(), endVParea(), saveGraphicsState(), restoreGraphicsState(), breakOutOfStateStack() and restoreStateStackAfterBreakOut() and it is no longer necessary to have a copy/pasted/tweaked renderBlockViewport() or renderRegionViewport(). As a result of this AFPRenderer is now much more compact (by some 500 lines) - similar work needs to be done in the PCL Renderer, any volunteers? * Added lots of helpful toString() methods for those mere mortals wishing to step through with a debugger :). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@675507 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
* Created new AbstractState class that shares common properties and stack popping/pushing behaviour of and is now extended by AFPState and PDFState. * color, resolution and bitsPerPixel moved from AFPInfo to AFPState/AbstractState resulting in a more simplified AFPInfo and AFPSVGHandler. * Changed AFPRenderer, AFPDataStream, PresentationTextObject and PresentationTextData to use encapsulated AFPTextDataInfo instead of a chain of long parameter passing between objects. Also provided some formatting cleanup in PresentationTextData. * Use of X and Y offsets no longer used by AFPDataStream, setOffsets() is now deprecated and added setOrientation() accessor (which still remains relevant). * AFPRenderer no longer uses its own bespoke ViewPortPos mechanism and now uses the more standard state stack and AffineTransform mechanism enjoyed by the postscript and PDF Renderers. This means that there is now a proper implementation for startVParea(), endVParea(), saveGraphicsState(), restoreGraphicsState(), breakOutOfStateStack() and restoreStateStackAfterBreakOut() and it is no longer necessary to have a copy/pasted/tweaked renderBlockViewport() or renderRegionViewport(). As a result of this AFPRenderer is now much more compact (by some 500 lines) - similar work needs to be done in the PCL Renderer, any volunteers? * Added lots of helpful toString() methods for those mere mortals wishing to step through with a debugger :). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@675507 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  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. /* $Id$ */
  18. package org.apache.fop.afp;
  19. import java.awt.Color;
  20. import java.awt.Point;
  21. import java.io.IOException;
  22. import java.io.OutputStream;
  23. import java.io.UnsupportedEncodingException;
  24. import java.util.Iterator;
  25. import java.util.Map;
  26. import org.apache.commons.logging.Log;
  27. import org.apache.commons.logging.LogFactory;
  28. import org.apache.fop.afp.fonts.AFPFont;
  29. import org.apache.fop.afp.fonts.AFPFontAttributes;
  30. import org.apache.fop.afp.fonts.CharacterSet;
  31. import org.apache.fop.afp.modca.AbstractPageObject;
  32. import org.apache.fop.afp.modca.Document;
  33. import org.apache.fop.afp.modca.InterchangeSet;
  34. import org.apache.fop.afp.modca.Overlay;
  35. import org.apache.fop.afp.modca.PageGroup;
  36. import org.apache.fop.afp.modca.PageObject;
  37. import org.apache.fop.afp.modca.ResourceGroup;
  38. import org.apache.fop.afp.modca.TagLogicalElement;
  39. import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
  40. import org.apache.fop.afp.ptoca.PtocaBuilder;
  41. import org.apache.fop.afp.ptoca.PtocaProducer;
  42. import org.apache.fop.fonts.Font;
  43. import org.apache.fop.util.CharUtilities;
  44. /**
  45. * A data stream is a continuous ordered stream of data elements and objects
  46. * conforming to a given format. Application programs can generate data streams
  47. * destined for a presentation service, archive library, presentation device or
  48. * another application program. The strategic presentation data stream
  49. * architectures used is Mixed Object Document Content Architecture (MO:DCA).
  50. *
  51. * The MO:DCA architecture defines the data stream used by applications to
  52. * describe documents and object envelopes for interchange with other
  53. * applications and application services. Documents defined in the MO:DCA format
  54. * may be archived in a database, then later retrieved, viewed, annotated and
  55. * printed in local or distributed systems environments. Presentation fidelity
  56. * is accommodated by including resource objects in the documents that reference
  57. * them.
  58. */
  59. public class DataStream {
  60. /** Static logging instance */
  61. protected static final Log LOG = LogFactory.getLog("org.apache.xmlgraphics.afp");
  62. /** Boolean completion indicator */
  63. private boolean complete;
  64. /** The AFP document object */
  65. private Document document;
  66. /** The current page group object */
  67. private PageGroup currentPageGroup;
  68. /** The current page object */
  69. private PageObject currentPageObject;
  70. /** The current overlay object */
  71. private Overlay currentOverlay;
  72. /** The current page */
  73. private AbstractPageObject currentPage;
  74. /** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */
  75. private InterchangeSet interchangeSet
  76. = InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);
  77. private final Factory factory;
  78. private OutputStream outputStream;
  79. /** the afp painting state */
  80. private final AFPPaintingState paintingState;
  81. /**
  82. * Default constructor for the AFPDocumentStream.
  83. *
  84. * @param factory the resource factory
  85. * @param paintingState the AFP painting state
  86. * @param outputStream the outputstream to write to
  87. */
  88. public DataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) {
  89. this.paintingState = paintingState;
  90. this.factory = factory;
  91. this.outputStream = outputStream;
  92. }
  93. /**
  94. * Returns the outputstream
  95. *
  96. * @return the outputstream
  97. */
  98. public OutputStream getOutputStream() {
  99. return this.outputStream;
  100. }
  101. /**
  102. * Returns the document object
  103. *
  104. * @return the document object
  105. */
  106. private Document getDocument() {
  107. return this.document;
  108. }
  109. /**
  110. * Returns the current page
  111. *
  112. * @return the current page
  113. */
  114. public AbstractPageObject getCurrentPage() {
  115. return this.currentPage;
  116. }
  117. /**
  118. * The document is started by invoking this method which creates an instance
  119. * of the AFP Document object.
  120. *
  121. * @param name
  122. * the name of this document.
  123. */
  124. public void setDocumentName(String name) {
  125. if (name != null) {
  126. getDocument().setFullyQualifiedName(
  127. FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
  128. FullyQualifiedNameTriplet.FORMAT_CHARSTR, name);
  129. }
  130. }
  131. /**
  132. * Helper method to mark the end of the current document.
  133. *
  134. * @throws IOException thrown if an I/O exception of some sort has occurred
  135. */
  136. public void endDocument() throws IOException {
  137. if (complete) {
  138. String msg = "Invalid state - document already ended.";
  139. LOG.warn("endDocument():: " + msg);
  140. throw new IllegalStateException(msg);
  141. }
  142. if (currentPageObject != null) {
  143. // End the current page if necessary
  144. endPage();
  145. }
  146. if (currentPageGroup != null) {
  147. // End the current page group if necessary
  148. endPageGroup();
  149. }
  150. // Write out document
  151. if (document != null) {
  152. document.endDocument();
  153. document.writeToStream(this.outputStream);
  154. }
  155. this.outputStream.flush();
  156. this.complete = true;
  157. this.document = null;
  158. this.outputStream = null;
  159. }
  160. /**
  161. * Start a new page. When processing has finished on the current page, the
  162. * {@link #endPage()}method must be invoked to mark the page ending.
  163. *
  164. * @param pageWidth
  165. * the width of the page
  166. * @param pageHeight
  167. * the height of the page
  168. * @param pageRotation
  169. * the rotation of the page
  170. * @param pageWidthRes
  171. * the width resolution of the page
  172. * @param pageHeightRes
  173. * the height resolution of the page
  174. */
  175. public void startPage(int pageWidth, int pageHeight, int pageRotation,
  176. int pageWidthRes, int pageHeightRes) {
  177. currentPageObject = factory.createPage(pageWidth, pageHeight,
  178. pageRotation, pageWidthRes, pageHeightRes);
  179. currentPage = currentPageObject;
  180. currentOverlay = null;
  181. }
  182. /**
  183. * Start a new overlay. When processing has finished on the current overlay,
  184. * the {@link #endOverlay()}method must be invoked to mark the overlay
  185. * ending.
  186. *
  187. * @param x
  188. * the x position of the overlay on the page
  189. * @param y
  190. * the y position of the overlay on the page
  191. * @param width
  192. * the width of the overlay
  193. * @param height
  194. * the height of the overlay
  195. * @param widthRes
  196. * the width resolution of the overlay
  197. * @param heightRes
  198. * the height resolution of the overlay
  199. * @param overlayRotation
  200. * the rotation of the overlay
  201. */
  202. public void startOverlay(int x, int y, int width, int height, int widthRes,
  203. int heightRes, int overlayRotation) {
  204. this.currentOverlay = factory.createOverlay(
  205. width, height, widthRes, heightRes, overlayRotation);
  206. String overlayName = currentOverlay.getName();
  207. currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
  208. currentPage = currentOverlay;
  209. }
  210. /**
  211. * Helper method to mark the end of the current overlay.
  212. *
  213. * @throws IOException thrown if an I/O exception of some sort has occurred
  214. */
  215. public void endOverlay() throws IOException {
  216. if (currentOverlay != null) {
  217. currentOverlay.endPage();
  218. currentOverlay = null;
  219. currentPage = currentPageObject;
  220. }
  221. }
  222. /**
  223. * Helper method to save the current page.
  224. *
  225. * @return current page object that was saved
  226. */
  227. public PageObject savePage() {
  228. PageObject pageObject = currentPageObject;
  229. if (currentPageGroup != null) {
  230. currentPageGroup.addPage(currentPageObject);
  231. } else {
  232. document.addPage(currentPageObject);
  233. }
  234. currentPageObject = null;
  235. currentPage = null;
  236. return pageObject;
  237. }
  238. /**
  239. * Helper method to restore the current page.
  240. *
  241. * @param pageObject
  242. * page object
  243. */
  244. public void restorePage(PageObject pageObject) {
  245. currentPageObject = pageObject;
  246. currentPage = pageObject;
  247. }
  248. /**
  249. * Helper method to mark the end of the current page.
  250. *
  251. * @throws IOException thrown if an I/O exception of some sort has occurred
  252. */
  253. public void endPage() throws IOException {
  254. if (currentPageObject != null) {
  255. currentPageObject.endPage();
  256. if (currentPageGroup != null) {
  257. currentPageGroup.addPage(currentPageObject);
  258. currentPageGroup.writeToStream(this.outputStream);
  259. } else {
  260. document.addPage(currentPageObject);
  261. document.writeToStream(this.outputStream);
  262. }
  263. currentPageObject = null;
  264. currentPage = null;
  265. }
  266. }
  267. /**
  268. * Creates the given page fonts in the current page
  269. *
  270. * @param pageFonts
  271. * a collection of AFP font attributes
  272. */
  273. public void addFontsToCurrentPage(Map pageFonts) {
  274. Iterator iter = pageFonts.values().iterator();
  275. while (iter.hasNext()) {
  276. AFPFontAttributes afpFontAttributes = (AFPFontAttributes) iter
  277. .next();
  278. createFont(afpFontAttributes.getFontReference(), afpFontAttributes
  279. .getFont(), afpFontAttributes.getPointSize());
  280. }
  281. }
  282. /**
  283. * Helper method to create a map coded font object on the current page, this
  284. * method delegates the construction of the map coded font object to the
  285. * active environment group on the current page.
  286. *
  287. * @param fontReference
  288. * the font number used as the resource identifier
  289. * @param font
  290. * the font
  291. * @param size
  292. * the point size of the font
  293. */
  294. public void createFont(int fontReference, AFPFont font, int size) {
  295. currentPage.createFont(fontReference, font, size);
  296. }
  297. /**
  298. * Returns a point on the current page
  299. *
  300. * @param x the X-coordinate
  301. * @param y the Y-coordinate
  302. * @return a point on the current page
  303. */
  304. private Point getPoint(int x, int y) {
  305. return paintingState.getPoint(x, y);
  306. }
  307. /**
  308. * Helper method to create text on the current page, this method delegates
  309. * to the current presentation text object in order to construct the text.
  310. *
  311. * @param textDataInfo the afp text data
  312. * @param letterSpacing letter spacing to draw text with
  313. * @param wordSpacing word Spacing to draw text with
  314. * @param font is the font to draw text with
  315. * @param charSet is the AFP Character Set to use with the text
  316. * @throws UnsupportedEncodingException thrown if character encoding is not supported
  317. */
  318. public void createText(final AFPTextDataInfo textDataInfo, final int letterSpacing,
  319. final int wordSpacing, final Font font, final CharacterSet charSet)
  320. throws UnsupportedEncodingException {
  321. int rotation = paintingState.getRotation();
  322. if (rotation != 0) {
  323. textDataInfo.setRotation(rotation);
  324. Point p = getPoint(textDataInfo.getX(), textDataInfo.getY());
  325. textDataInfo.setX(p.x);
  326. textDataInfo.setY(p.y);
  327. }
  328. // use PtocaProducer to create PTX records
  329. PtocaProducer producer = new PtocaProducer() {
  330. public void produce(PtocaBuilder builder) throws IOException {
  331. builder.setTextOrientation(textDataInfo.getRotation());
  332. builder.absoluteMoveBaseline(textDataInfo.getY());
  333. builder.absoluteMoveInline(textDataInfo.getX());
  334. builder.setExtendedTextColor(textDataInfo.getColor());
  335. builder.setCodedFont((byte)textDataInfo.getFontReference());
  336. int l = textDataInfo.getString().length();
  337. StringBuffer sb = new StringBuffer();
  338. int interCharacterAdjustment = 0;
  339. AFPUnitConverter unitConv = paintingState.getUnitConverter();
  340. if (letterSpacing != 0) {
  341. interCharacterAdjustment = Math.round(unitConv.mpt2units(letterSpacing));
  342. }
  343. builder.setInterCharacterAdjustment(interCharacterAdjustment);
  344. int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
  345. int spacing = spaceWidth + letterSpacing;
  346. int fixedSpaceCharacterIncrement = Math.round(unitConv.mpt2units(spacing));
  347. int varSpaceCharacterIncrement = fixedSpaceCharacterIncrement;
  348. if (wordSpacing != 0) {
  349. varSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
  350. spaceWidth + wordSpacing + letterSpacing));
  351. }
  352. builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);
  353. boolean fixedSpaceMode = false;
  354. for (int i = 0; i < l; i++) {
  355. char orgChar = textDataInfo.getString().charAt(i);
  356. float glyphAdjust = 0;
  357. if (CharUtilities.isFixedWidthSpace(orgChar)) {
  358. flushText(builder, sb, charSet);
  359. builder.setVariableSpaceCharacterIncrement(
  360. fixedSpaceCharacterIncrement);
  361. fixedSpaceMode = true;
  362. sb.append(CharUtilities.SPACE);
  363. int charWidth = font.getCharWidth(orgChar);
  364. glyphAdjust += (charWidth - spaceWidth);
  365. } else {
  366. if (fixedSpaceMode) {
  367. flushText(builder, sb, charSet);
  368. builder.setVariableSpaceCharacterIncrement(
  369. varSpaceCharacterIncrement);
  370. fixedSpaceMode = false;
  371. }
  372. char ch;
  373. if (orgChar == CharUtilities.NBSPACE) {
  374. ch = ' '; //converted to normal space to allow word spacing
  375. } else {
  376. ch = orgChar;
  377. }
  378. sb.append(ch);
  379. }
  380. if (glyphAdjust != 0) {
  381. flushText(builder, sb, charSet);
  382. int increment = Math.round(unitConv.mpt2units(glyphAdjust));
  383. builder.relativeMoveInline(increment);
  384. }
  385. }
  386. flushText(builder, sb, charSet);
  387. }
  388. private void flushText(PtocaBuilder builder, StringBuffer sb,
  389. final CharacterSet charSet) throws IOException {
  390. if (sb.length() > 0) {
  391. builder.addTransparentData(charSet.encodeChars(sb));
  392. sb.setLength(0);
  393. }
  394. }
  395. };
  396. currentPage.createText(producer);
  397. }
  398. /**
  399. * Method to create a line on the current page.
  400. *
  401. * @param lineDataInfo the line data information.
  402. */
  403. public void createLine(AFPLineDataInfo lineDataInfo) {
  404. currentPage.createLine(lineDataInfo);
  405. }
  406. /**
  407. * This method will create shading on the page using the specified
  408. * coordinates (the shading contrast is controlled via the red, green, blue
  409. * parameters, by converting this to grey scale).
  410. *
  411. * @param x
  412. * the x coordinate of the shading
  413. * @param y
  414. * the y coordinate of the shading
  415. * @param w
  416. * the width of the shaded area
  417. * @param h
  418. * the height of the shaded area
  419. * @param col
  420. * the shading color
  421. */
  422. public void createShading(int x, int y, int w, int h, Color col) {
  423. currentPageObject.createShading(x, y, w, h, col.getRed(), col.getGreen(), col.getBlue());
  424. }
  425. /**
  426. * Helper method which allows creation of the MPO object, via the AEG. And
  427. * the IPO via the Page. (See actual object for descriptions.)
  428. *
  429. * @param name
  430. * the name of the static overlay
  431. * @param x x-coordinate
  432. * @param y y-coordinate
  433. */
  434. public void createIncludePageOverlay(String name, int x, int y) {
  435. currentPageObject.createIncludePageOverlay(name, x, y, paintingState.getRotation());
  436. currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
  437. }
  438. /**
  439. * Helper method which allows creation of the IMM object.
  440. *
  441. * @param name
  442. * the name of the medium map
  443. */
  444. public void createInvokeMediumMap(String name) {
  445. currentPageGroup.createInvokeMediumMap(name);
  446. }
  447. /**
  448. * Creates an IncludePageSegment on the current page.
  449. *
  450. * @param name
  451. * the name of the include page segment
  452. * @param x
  453. * the x coordinate for the overlay
  454. * @param y
  455. * the y coordinate for the overlay
  456. * @param width
  457. * the width of the image
  458. * @param height
  459. * the height of the image
  460. */
  461. public void createIncludePageSegment(String name, int x, int y, int width, int height) {
  462. int xOrigin;
  463. int yOrigin;
  464. int orientation = paintingState.getRotation();
  465. switch (orientation) {
  466. case 90:
  467. xOrigin = x - height;
  468. yOrigin = y;
  469. break;
  470. case 180:
  471. xOrigin = x - width;
  472. yOrigin = y - height;
  473. break;
  474. case 270:
  475. xOrigin = x;
  476. yOrigin = y - width;
  477. break;
  478. default:
  479. xOrigin = x;
  480. yOrigin = y;
  481. break;
  482. }
  483. boolean createHardPageSegments = true;
  484. currentPage.createIncludePageSegment(name, xOrigin, yOrigin, createHardPageSegments);
  485. }
  486. /**
  487. * Creates a TagLogicalElement on the current page.
  488. *
  489. * @param attributes
  490. * the array of key value pairs.
  491. */
  492. public void createPageTagLogicalElement(TagLogicalElement.State[] attributes) {
  493. for (int i = 0; i < attributes.length; i++) {
  494. currentPage.createTagLogicalElement(attributes[i]);
  495. }
  496. }
  497. /**
  498. * Creates a TagLogicalElement on the current page group.
  499. *
  500. * @param attributes
  501. * the array of key value pairs.
  502. */
  503. public void createPageGroupTagLogicalElement(TagLogicalElement.State[] attributes) {
  504. for (int i = 0; i < attributes.length; i++) {
  505. currentPageGroup.createTagLogicalElement(attributes[i]);
  506. }
  507. }
  508. /**
  509. * Creates a TagLogicalElement on the current page or page group
  510. *
  511. * @param name
  512. * The tag name
  513. * @param value
  514. * The tag value
  515. * @param encoding The CCSID character set encoding
  516. */
  517. public void createTagLogicalElement(String name, String value, int encoding) {
  518. TagLogicalElement.State tleState = new TagLogicalElement.State(name, value, encoding);
  519. if (currentPage != null) {
  520. currentPage.createTagLogicalElement(tleState);
  521. } else {
  522. currentPageGroup.createTagLogicalElement(tleState);
  523. }
  524. }
  525. /**
  526. * Creates a NoOperation item
  527. *
  528. * @param content
  529. * byte data
  530. */
  531. public void createNoOperation(String content) {
  532. if (currentPage != null) {
  533. currentPage.createNoOperation(content);
  534. } else if (currentPageGroup != null) {
  535. currentPageGroup.createNoOperation(content);
  536. } else {
  537. document.createNoOperation(content);
  538. }
  539. }
  540. /**
  541. * Returns the current page group
  542. *
  543. * @return the current page group
  544. */
  545. public PageGroup getCurrentPageGroup() {
  546. return this.currentPageGroup;
  547. }
  548. /**
  549. * Start a new document.
  550. *
  551. * @throws IOException thrown if an I/O exception of some sort has occurred
  552. */
  553. public void startDocument() throws IOException {
  554. this.document = factory.createDocument();
  555. document.writeToStream(this.outputStream);
  556. }
  557. /**
  558. * Start a new page group. When processing has finished on the current page
  559. * group the {@link #endPageGroup()}method must be invoked to mark the page
  560. * group ending.
  561. *
  562. * @throws IOException thrown if an I/O exception of some sort has occurred
  563. */
  564. public void startPageGroup() throws IOException {
  565. endPageGroup();
  566. this.currentPageGroup = factory.createPageGroup();
  567. }
  568. /**
  569. * Helper method to mark the end of the page group.
  570. *
  571. * @throws IOException thrown if an I/O exception of some sort has occurred
  572. */
  573. public void endPageGroup() throws IOException {
  574. if (currentPageGroup != null) {
  575. currentPageGroup.endPageGroup();
  576. document.addPageGroup(currentPageGroup);
  577. currentPageGroup = null;
  578. }
  579. document.writeToStream(outputStream); //Flush objects
  580. }
  581. /**
  582. * Sets the MO:DCA interchange set to use
  583. *
  584. * @param interchangeSet the MO:DCA interchange set
  585. */
  586. public void setInterchangeSet(InterchangeSet interchangeSet) {
  587. this.interchangeSet = interchangeSet;
  588. }
  589. /**
  590. * Returns the MO:DCA interchange set in use
  591. *
  592. * @return the MO:DCA interchange set in use
  593. */
  594. public InterchangeSet getInterchangeSet() {
  595. return this.interchangeSet;
  596. }
  597. /**
  598. * Returns the resource group for a given resource info
  599. *
  600. * @param level a resource level
  601. * @return a resource group for the given resource info
  602. */
  603. public ResourceGroup getResourceGroup(AFPResourceLevel level) {
  604. ResourceGroup resourceGroup = null;
  605. if (level.isDocument()) {
  606. resourceGroup = document.getResourceGroup();
  607. } else if (level.isPageGroup()) {
  608. resourceGroup = currentPageGroup.getResourceGroup();
  609. } else if (level.isPage()) {
  610. resourceGroup = currentPageObject.getResourceGroup();
  611. }
  612. return resourceGroup;
  613. }
  614. }