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.3KB

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