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.

PresentationTextObject.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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.modca;
  19. import java.io.IOException;
  20. import java.io.OutputStream;
  21. import java.io.UnsupportedEncodingException;
  22. import java.util.List;
  23. import org.apache.fop.afp.AFPLineDataInfo;
  24. import org.apache.fop.afp.AFPTextDataInfo;
  25. import org.apache.fop.afp.ptoca.LineDataInfoProducer;
  26. import org.apache.fop.afp.ptoca.PtocaBuilder;
  27. import org.apache.fop.afp.ptoca.PtocaProducer;
  28. import org.apache.fop.afp.ptoca.TextDataInfoProducer;
  29. /**
  30. * The Presentation Text object is the data object used in document processing
  31. * environments for representing text which has been prepared for presentation.
  32. * Text, as used here, means an ordered string of characters, such as graphic
  33. * symbols, numbers, and letters, that are suitable for the specific purpose of
  34. * representing coherent information. Text which has been prepared for
  35. * presentation has been reduced to a primitive form through explicit
  36. * specification of the characters and their placement in the presentation
  37. * space. Control sequences which designate specific control functions may be
  38. * embedded within the text. These functions extend the primitive form by
  39. * applying specific characteristics to the text when it is presented. The
  40. * collection of the graphic characters and control codes is called Presentation
  41. * Text, and the object that contains the Presentation Text is called the
  42. * PresentationText object.
  43. * <p>
  44. * The content for this object can be created using {@link PtocaBuilder}.
  45. */
  46. public class PresentationTextObject extends AbstractNamedAFPObject {
  47. /**
  48. * The current presentation text data
  49. */
  50. private PresentationTextData currentPresentationTextData;
  51. /**
  52. * The presentation text data list
  53. */
  54. private List/*<PresentationTextData>*/ presentationTextDataList;
  55. private PtocaBuilder builder = new DefaultBuilder();
  56. /**
  57. * Construct a new PresentationTextObject for the specified name argument,
  58. * the name should be an 8 character identifier.
  59. *
  60. * @param name the name of this presentation object
  61. */
  62. public PresentationTextObject(String name) {
  63. super(name);
  64. }
  65. /**
  66. * Create the presentation text data for the byte array of data.
  67. *
  68. * @param textDataInfo
  69. * The afp text data
  70. * @throws UnsupportedEncodingException thrown if character encoding is not supported
  71. */
  72. public void createTextData(AFPTextDataInfo textDataInfo) throws UnsupportedEncodingException {
  73. createControlSequences(new TextDataInfoProducer(textDataInfo));
  74. }
  75. /**
  76. * Creates a chain of control sequences using a producer.
  77. * @param producer the producer
  78. * @throws UnsupportedEncodingException thrown if character encoding is not supported
  79. */
  80. public void createControlSequences(PtocaProducer producer)
  81. throws UnsupportedEncodingException {
  82. if (currentPresentationTextData == null) {
  83. startPresentationTextData();
  84. }
  85. try {
  86. producer.produce(builder);
  87. } catch (UnsupportedEncodingException e) {
  88. endPresentationTextData();
  89. throw e;
  90. } catch (IOException ioe) {
  91. endPresentationTextData();
  92. handleUnexpectedIOError(ioe);
  93. }
  94. }
  95. private class DefaultBuilder extends PtocaBuilder {
  96. protected OutputStream getOutputStreamForControlSequence(int length) {
  97. if (length > currentPresentationTextData.getBytesAvailable()) {
  98. endPresentationTextData();
  99. startPresentationTextData();
  100. }
  101. return currentPresentationTextData.getOutputStream();
  102. }
  103. }
  104. /**
  105. * Drawing of lines using the starting and ending coordinates, thickness and
  106. * orientation arguments.
  107. *
  108. * @param lineDataInfo the line data information.
  109. */
  110. public void createLineData(AFPLineDataInfo lineDataInfo) {
  111. try {
  112. createControlSequences(new LineDataInfoProducer(lineDataInfo));
  113. } catch (UnsupportedEncodingException e) {
  114. handleUnexpectedIOError(e); //Won't happen for lines
  115. }
  116. }
  117. /**
  118. * Helper method to mark the start of the presentation text data
  119. */
  120. private void startPresentationTextData() {
  121. if (presentationTextDataList == null) {
  122. presentationTextDataList = new java.util.ArrayList/*<PresentationTextData>*/();
  123. }
  124. if (presentationTextDataList.size() == 0) {
  125. currentPresentationTextData = new PresentationTextData(true);
  126. } else {
  127. currentPresentationTextData = new PresentationTextData();
  128. }
  129. presentationTextDataList.add(currentPresentationTextData);
  130. }
  131. /**
  132. * Helper method to mark the end of the presentation text data
  133. */
  134. private void endPresentationTextData() {
  135. this.currentPresentationTextData = null;
  136. }
  137. /** {@inheritDoc} */
  138. protected void writeStart(OutputStream os) throws IOException {
  139. byte[] data = new byte[17];
  140. copySF(data, Type.BEGIN, Category.PRESENTATION_TEXT);
  141. os.write(data);
  142. }
  143. /** {@inheritDoc} */
  144. protected void writeContent(OutputStream os) throws IOException {
  145. writeObjects(this.presentationTextDataList, os);
  146. }
  147. /** {@inheritDoc} */
  148. protected void writeEnd(OutputStream os) throws IOException {
  149. byte[] data = new byte[17];
  150. copySF(data, Type.END, Category.PRESENTATION_TEXT);
  151. os.write(data);
  152. }
  153. /**
  154. * A control sequence is a sequence of bytes that specifies a control
  155. * function. A control sequence consists of a control sequence introducer
  156. * and zero or more parameters. The control sequence can extend multiple
  157. * presentation text data objects, but must eventually be terminated. This
  158. * method terminates the control sequence.
  159. */
  160. public void endControlSequence() {
  161. if (currentPresentationTextData == null) {
  162. startPresentationTextData();
  163. }
  164. try {
  165. builder.endChainedControlSequence();
  166. } catch (IOException ioe) {
  167. endPresentationTextData();
  168. handleUnexpectedIOError(ioe);
  169. //Should not occur since we're writing to byte arrays
  170. }
  171. }
  172. private void handleUnexpectedIOError(IOException ioe) {
  173. //"Unexpected" since we're currently dealing with ByteArrayOutputStreams here.
  174. throw new RuntimeException("Unexpected I/O error: " + ioe.getMessage(), ioe);
  175. }
  176. /** {@inheritDoc} */
  177. public String toString() {
  178. if (presentationTextDataList != null) {
  179. return presentationTextDataList.toString();
  180. }
  181. return super.toString();
  182. }
  183. }