Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

FObjMixed.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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.fo;
  19. import org.xml.sax.Locator;
  20. import org.apache.fop.apps.FOPException;
  21. /**
  22. * Abstract base class for representation of mixed content formatting objects
  23. * (= those that can contain both child {@link FONode}s and <code>#PCDATA</code>).
  24. */
  25. public abstract class FObjMixed extends FObj {
  26. /** Represents accumulated, pending FO text. See {@link #flushText()}. */
  27. private FOText ft = null;
  28. /** Used for white-space handling; start CharIterator at node ... */
  29. protected FONode currentTextNode;
  30. /** Used in creating pointers between subsequent {@link FOText} nodes
  31. * in the same {@link org.apache.fop.fo.flow.Block}
  32. * (for handling text-transform) */
  33. protected FOText lastFOTextProcessed = null;
  34. /**
  35. * Base constructor
  36. *
  37. * @param parent FONode that is the parent of this object
  38. */
  39. protected FObjMixed(FONode parent) {
  40. super(parent);
  41. }
  42. /** {@inheritDoc} */
  43. protected void addCharacters(char[] data, int start, int length,
  44. PropertyList pList,
  45. Locator locator) throws FOPException {
  46. if (ft == null) {
  47. ft = new FOText(this);
  48. ft.setLocator(locator);
  49. if (!inMarker()) {
  50. ft.bind(pList);
  51. }
  52. }
  53. ft.addCharacters(data, start, length, null, null);
  54. }
  55. /** {@inheritDoc} */
  56. protected void endOfNode() throws FOPException {
  57. super.endOfNode();
  58. if (!inMarker() || getNameId() == FO_MARKER) {
  59. // send character[s]() events to the FOEventHandler
  60. sendCharacters();
  61. }
  62. }
  63. /**
  64. * Handles white-space for the node that is passed in,
  65. * starting at its current text-node
  66. * (used by {@link org.apache.fop.fo.flow.RetrieveMarker}
  67. * to trigger 'end-of-node' white-space handling)
  68. *
  69. * @param fobj the node for which to handle white-space
  70. * @param nextChild the next child to be added
  71. */
  72. protected static void handleWhiteSpaceFor(FObjMixed fobj, FONode nextChild) {
  73. fobj.getBuilderContext().getXMLWhiteSpaceHandler()
  74. .handleWhiteSpace(fobj, fobj.currentTextNode, nextChild);
  75. }
  76. /**
  77. * Creates block-pointers between subsequent FOText nodes
  78. * in the same Block. (used for handling text-transform)
  79. *
  80. * TODO: !! Revisit: does not take into account fo:characters !!
  81. *
  82. * @throws FOPException if there is a problem during processing
  83. */
  84. private void flushText() throws FOPException {
  85. if (ft != null) {
  86. FOText lft = ft;
  87. /* make sure nested calls to itself have no effect */
  88. ft = null;
  89. if (getNameId() == FO_BLOCK) {
  90. lft.createBlockPointers((org.apache.fop.fo.flow.Block) this);
  91. this.lastFOTextProcessed = lft;
  92. } else if (getNameId() != FO_MARKER
  93. && getNameId() != FO_TITLE
  94. && getNameId() != FO_BOOKMARK_TITLE) {
  95. FONode fo = parent;
  96. int foNameId = fo.getNameId();
  97. while (foNameId != FO_BLOCK
  98. && foNameId != FO_MARKER
  99. && foNameId != FO_TITLE
  100. && foNameId != FO_BOOKMARK_TITLE
  101. && foNameId != FO_PAGE_SEQUENCE) {
  102. fo = fo.getParent();
  103. foNameId = fo.getNameId();
  104. }
  105. if (foNameId == FO_BLOCK) {
  106. lft.createBlockPointers((org.apache.fop.fo.flow.Block) fo);
  107. ((FObjMixed) fo).lastFOTextProcessed = lft;
  108. } else if (foNameId == FO_PAGE_SEQUENCE
  109. && lft.willCreateArea()) {
  110. log.error("Could not create block pointers."
  111. + " FOText w/o Block ancestor.");
  112. }
  113. }
  114. this.addChildNode(lft);
  115. }
  116. }
  117. private void sendCharacters() throws FOPException {
  118. if (this.currentTextNode != null) {
  119. FONodeIterator nodeIter
  120. = this.getChildNodes(this.currentTextNode);
  121. FONode node;
  122. while (nodeIter.hasNext()) {
  123. node = nodeIter.nextNode();
  124. assert (node instanceof FOText
  125. || node.getNameId() == FO_CHARACTER);
  126. if (node.getNameId() == FO_CHARACTER) {
  127. node.startOfNode();
  128. }
  129. node.endOfNode();
  130. }
  131. }
  132. this.currentTextNode = null;
  133. }
  134. /** {@inheritDoc} */
  135. protected void addChildNode(FONode child) throws FOPException {
  136. flushText();
  137. if (!inMarker()) {
  138. if (child instanceof FOText || child.getNameId() == FO_CHARACTER) {
  139. if (this.currentTextNode == null) {
  140. this.currentTextNode = child;
  141. }
  142. } else {
  143. // handle white-space for all text up to here
  144. handleWhiteSpaceFor(this, child);
  145. // send character[s]() events to the FOEventHandler
  146. sendCharacters();
  147. }
  148. }
  149. super.addChildNode(child);
  150. }
  151. /** {@inheritDoc} */
  152. public void finalizeNode() throws FOPException {
  153. flushText();
  154. if (!inMarker() || getNameId() == FO_MARKER) {
  155. handleWhiteSpaceFor(this, null);
  156. }
  157. }
  158. /**
  159. * Returns a {@link CharIterator} over this FO's character content
  160. *
  161. * @return iterator for this object
  162. */
  163. public CharIterator charIterator() {
  164. return new RecursiveCharIterator(this);
  165. }
  166. }