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.

AreaTree.java 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * $Id: AreaTree.java,v 1.16 2003/03/05 15:19:31 jeremias Exp $
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.area;
  52. import org.apache.fop.render.Renderer;
  53. import java.util.ArrayList;
  54. import java.util.List;
  55. import java.util.Map;
  56. import java.util.HashMap;
  57. import java.util.Set;
  58. import java.util.HashSet;
  59. import java.util.Iterator;
  60. /**
  61. * Area tree for formatting objects.
  62. *
  63. * Concepts:
  64. * The area tree is to be as small as possible. With minimal classes
  65. * and data to fully represent an area tree for formatting objects.
  66. * The area tree needs to be simple to render and follow the spec
  67. * closely.
  68. * This area tree has the concept of page sequences.
  69. * Where ever possible information is discarded or optimised to
  70. * keep memory use low. The data is also organised to make it
  71. * possible for renderers to minimise their output.
  72. * A page can be saved if not fully resolved and once rendered
  73. * a page contains only size and id reference information.
  74. * The area tree pages are organised in a model that depends on the
  75. * type of renderer.
  76. */
  77. public class AreaTree {
  78. // allows for different models to deal with adding/rendering
  79. // in different situations
  80. private AreaTreeModel model;
  81. // hashmap of arraylists containing pages with id area
  82. private Map idLocations = new HashMap();
  83. // list of id's yet to be resolved and arraylists of pages
  84. private Map resolve = new HashMap();
  85. private List treeExtensions = new ArrayList();
  86. /**
  87. * Create a render pages area tree model.
  88. * @param rend the renderer that will be used
  89. * @return RenderPagesModel the new area tree model
  90. */
  91. public static RenderPagesModel createRenderPagesModel(Renderer rend) {
  92. return new RenderPagesModel(rend);
  93. }
  94. /**
  95. * Create a new store pages model.
  96. * @return StorePagesModel the new model
  97. */
  98. public static StorePagesModel createStorePagesModel() {
  99. return new StorePagesModel();
  100. }
  101. /**
  102. * Set the tree model to use for this area tree.
  103. * The different models can have different behaviour
  104. * when pages area added and other changes.
  105. * @param m the area tree model
  106. */
  107. public void setTreeModel(AreaTreeModel m) {
  108. model = m;
  109. }
  110. /**
  111. * Get the area tree model for this area tree.
  112. *
  113. * @return AreaTreeModel the model being used for this area tree
  114. */
  115. public AreaTreeModel getAreaTreeModel() {
  116. return model;
  117. }
  118. /**
  119. * Start a new page sequence.
  120. * This signals that a new page sequence has started in the document.
  121. * @param title the title of the new page sequence or null if no title
  122. */
  123. public void startPageSequence(Title title) {
  124. model.startPageSequence(title);
  125. }
  126. /**
  127. * Add a new page to the area tree.
  128. * @param page the page to add
  129. */
  130. public void addPage(PageViewport page) {
  131. model.addPage(page);
  132. }
  133. /**
  134. * Add an id reference pointing to a page viewport.
  135. * @param id the id of the reference
  136. * @param pv the page viewport that contains the id reference
  137. */
  138. public void addIDRef(String id, PageViewport pv) {
  139. List list = (List)idLocations.get(id);
  140. if (list == null) {
  141. list = new ArrayList();
  142. idLocations.put(id, list);
  143. }
  144. list.add(pv);
  145. Set todo = (Set)resolve.get(id);
  146. if (todo != null) {
  147. for (Iterator iter = todo.iterator(); iter.hasNext();) {
  148. Resolveable res = (Resolveable)iter.next();
  149. res.resolve(id, list);
  150. }
  151. resolve.remove(id);
  152. }
  153. }
  154. /**
  155. * Get the list of id references for an id.
  156. * @param id the id to lookup
  157. * @return the list of id references.
  158. */
  159. public List getIDReferences(String id) {
  160. return (List)idLocations.get(id);
  161. }
  162. /**
  163. * Add an unresolved object with a given id.
  164. * @param id the id reference that needs resolving
  165. * @param res the Resolveable object to resolve
  166. */
  167. public void addUnresolvedID(String id, Resolveable res) {
  168. Set todo = (Set)resolve.get(id);
  169. if (todo == null) {
  170. todo = new HashSet();
  171. resolve.put(id, todo);
  172. }
  173. todo.add(res);
  174. }
  175. /**
  176. * Add a tree extension.
  177. * This checks if the extension is resolveable and attempts
  178. * to resolve or add the resolveable ids for later resolution.
  179. * @param ext the tree extension to add.
  180. */
  181. public void addTreeExtension(TreeExt ext) {
  182. treeExtensions.add(ext);
  183. if (ext.isResolveable()) {
  184. Resolveable res = (Resolveable)ext;
  185. String[] ids = res.getIDs();
  186. for (int count = 0; count < ids.length; count++) {
  187. if (idLocations.containsKey(ids[count])) {
  188. res.resolve(ids[count], (List)idLocations.get(ids[count]));
  189. } else {
  190. Set todo = (Set)resolve.get(ids[count]);
  191. if (todo == null) {
  192. todo = new HashSet();
  193. resolve.put(ids[count], todo);
  194. }
  195. todo.add(ext);
  196. }
  197. }
  198. } else {
  199. handleTreeExtension(ext, TreeExt.IMMEDIATELY);
  200. }
  201. }
  202. /**
  203. * Handle a tree extension.
  204. * This sends the extension to the model for handling.
  205. * @param ext the tree extension to handle
  206. * @param when when the extension should be handled by the model
  207. */
  208. public void handleTreeExtension(TreeExt ext, int when) {
  209. // queue tree extension according to the when
  210. model.addExtension(ext, when);
  211. }
  212. /**
  213. * Signal end of document.
  214. * This indicates that the document is complete and any unresolved
  215. * reference can be dealt with.
  216. */
  217. public void endDocument() {
  218. for (Iterator iter = resolve.keySet().iterator(); iter.hasNext();) {
  219. String id = (String)iter.next();
  220. Set list = (Set)resolve.get(id);
  221. for (Iterator resIter = list.iterator(); resIter.hasNext();) {
  222. Resolveable res = (Resolveable)resIter.next();
  223. if (!res.isResolved()) {
  224. res.resolve(id, null);
  225. }
  226. }
  227. }
  228. model.endDocument();
  229. }
  230. }