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.

PDFOutline.java 5.7KB

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.pdf;
  19. import java.io.ByteArrayOutputStream;
  20. import java.io.IOException;
  21. import java.util.List;
  22. import java.util.Set;
  23. /**
  24. * <p>This represents a single Outline object in a PDF, including the root Outlines
  25. * object. Outlines provide the bookmark bar, usually rendered to the right of
  26. * a PDF document in user agents such as Acrobat Reader.</p>
  27. *
  28. * <p>This work was authored by Kelly A. Campbell.</p>
  29. */
  30. public class PDFOutline extends PDFObject {
  31. /**
  32. * list of sub-entries (outline objects)
  33. */
  34. private List subentries;
  35. /**
  36. * parent outline object. Root Outlines parent is null
  37. */
  38. private PDFOutline parent;
  39. private PDFOutline prev;
  40. private PDFOutline next;
  41. private PDFOutline first;
  42. private PDFOutline last;
  43. private int count;
  44. // whether to show this outline item's child outline items
  45. private boolean openItem;
  46. /**
  47. * title to display for the bookmark entry
  48. */
  49. private String title;
  50. private PDFReference actionRef;
  51. /**
  52. * Create a PDF outline with the title and action.
  53. *
  54. * @param title the title of the outline entry (can only be null for root Outlines obj)
  55. * @param action the action for this outline
  56. * @param openItem indicator of whether child items are visible or not
  57. */
  58. public PDFOutline(String title, PDFReference action, boolean openItem) {
  59. super();
  60. subentries = new java.util.ArrayList();
  61. count = 0;
  62. parent = null;
  63. prev = null;
  64. next = null;
  65. first = null;
  66. last = null;
  67. this.title = title;
  68. actionRef = action;
  69. this.openItem = openItem;
  70. }
  71. /**
  72. * Set the title of this Outline object.
  73. *
  74. * @param t the title of the outline
  75. */
  76. public void setTitle(String t) {
  77. title = t;
  78. }
  79. /**
  80. * Add a sub element to this outline.
  81. *
  82. * @param outline a sub outline
  83. */
  84. public void addOutline(PDFOutline outline) {
  85. if (subentries.size() > 0) {
  86. outline.prev
  87. = (PDFOutline)subentries.get(subentries.size() - 1);
  88. outline.prev.next = outline;
  89. } else {
  90. first = outline;
  91. }
  92. subentries.add(outline);
  93. outline.parent = this;
  94. // note: count is not just the immediate children
  95. incrementCount();
  96. last = outline;
  97. }
  98. /**
  99. * Increment the number of subentries and descendants.
  100. */
  101. private void incrementCount() {
  102. // count is a total of our immediate subentries
  103. // and all descendent subentries
  104. count++;
  105. if (parent != null) {
  106. parent.incrementCount();
  107. }
  108. }
  109. /**
  110. * {@inheritDoc}
  111. */
  112. protected byte[] toPDF() {
  113. ByteArrayOutputStream bout = new ByteArrayOutputStream(128);
  114. try {
  115. bout.write(encode("<<"));
  116. if (parent == null) {
  117. // root Outlines object
  118. if (first != null && last != null) {
  119. bout.write(encode(" /First " + first.referencePDF() + "\n"));
  120. bout.write(encode(" /Last " + last.referencePDF() + "\n"));
  121. // no count... we start with the outline completely closed for now
  122. }
  123. } else {
  124. // subentry Outline item object
  125. bout.write(encode(" /Title "));
  126. bout.write(encodeText(this.title));
  127. bout.write(encode("\n"));
  128. bout.write(encode(" /Parent " + parent.referencePDF() + "\n"));
  129. if (prev != null) {
  130. bout.write(encode(" /Prev " + prev.referencePDF() + "\n"));
  131. }
  132. if (next != null) {
  133. bout.write(encode(" /Next " + next.referencePDF() + "\n"));
  134. }
  135. if (first != null && last != null) {
  136. bout.write(encode(" /First " + first.referencePDF() + "\n"));
  137. bout.write(encode(" /Last " + last.referencePDF() + "\n"));
  138. }
  139. if (count > 0) {
  140. bout.write(encode(" /Count " + (openItem ? "" : "-")
  141. + count + "\n"));
  142. }
  143. if (actionRef != null) {
  144. bout.write(encode(" /A " + actionRef + "\n"));
  145. }
  146. }
  147. bout.write(encode(">>"));
  148. } catch (IOException ioe) {
  149. log.error("Ignored I/O exception", ioe);
  150. }
  151. return bout.toByteArray();
  152. }
  153. @Override
  154. public void getChildren(Set<PDFObject> children) {
  155. if (parent != null) {
  156. children.add(parent);
  157. }
  158. if (first != null && last != null) {
  159. children.add(first);
  160. children.add(last);
  161. first.getChildren(children);
  162. last.getChildren(children);
  163. }
  164. if (actionRef != null) {
  165. children.add(actionRef.getObject());
  166. }
  167. }
  168. }