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 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.pdf;
  18. import java.io.ByteArrayOutputStream;
  19. import java.io.IOException;
  20. import java.util.List;
  21. /**
  22. * This represents a single Outline object in a PDF, including the root Outlines
  23. * object. Outlines provide the bookmark bar, usually rendered to the right of
  24. * a PDF document in user agents such as Acrobat Reader
  25. *
  26. * @author Kelly A. Campbell
  27. *
  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. /**
  44. * title to display for the bookmark entry
  45. */
  46. private String title;
  47. private String actionRef;
  48. /**
  49. * Create a PDF outline with the title and action.
  50. *
  51. * @param title the title of the outline entry (can only be null for root Outlines obj)
  52. * @param action the action for this outline
  53. */
  54. public PDFOutline(String title, String action) {
  55. super();
  56. subentries = new java.util.ArrayList();
  57. count = 0;
  58. parent = null;
  59. prev = null;
  60. next = null;
  61. first = null;
  62. last = null;
  63. this.title = title;
  64. actionRef = action;
  65. }
  66. /**
  67. * Set the title of this Outline object.
  68. *
  69. * @param t the title of the outline
  70. */
  71. public void setTitle(String t) {
  72. title = t;
  73. }
  74. /**
  75. * Add a sub element to this outline.
  76. *
  77. * @param outline a sub outline
  78. */
  79. public void addOutline(PDFOutline outline) {
  80. if (subentries.size() > 0) {
  81. outline.prev =
  82. (PDFOutline)subentries.get(subentries.size() - 1);
  83. outline.prev.next = outline;
  84. } else {
  85. first = outline;
  86. }
  87. subentries.add(outline);
  88. outline.parent = this;
  89. // note: count is not just the immediate children
  90. incrementCount();
  91. last = outline;
  92. }
  93. /**
  94. * Increment the number of subentries and descendants.
  95. */
  96. private void incrementCount() {
  97. // count is a total of our immediate subentries
  98. // and all descendent subentries
  99. count++;
  100. if (parent != null) {
  101. parent.incrementCount();
  102. }
  103. }
  104. /**
  105. * @see org.apache.fop.pdf.PDFObject#toPDF()
  106. */
  107. protected byte[] toPDF() {
  108. ByteArrayOutputStream bout = new ByteArrayOutputStream(128);
  109. try {
  110. bout.write(encode(getObjectID()));
  111. bout.write(encode("<<"));
  112. if (parent == null) {
  113. // root Outlines object
  114. if (first != null && last != null) {
  115. bout.write(encode(" /First " + first.referencePDF() + "\n"));
  116. bout.write(encode(" /Last " + last.referencePDF() + "\n"));
  117. // no count... we start with the outline completely closed for now
  118. }
  119. } else {
  120. // subentry Outline object
  121. bout.write(encode(" /Title "));
  122. bout.write(encodeText(this.title));
  123. bout.write(encode("\n"));
  124. bout.write(encode(" /Parent " + parent.referencePDF() + "\n"));
  125. if (first != null && last != null) {
  126. bout.write(encode(" /First " + first.referencePDF() + "\n"));
  127. bout.write(encode(" /Last " + last.referencePDF() + "\n"));
  128. }
  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 (count > 0) {
  136. bout.write(encode(" /Count -" + count + "\n"));
  137. }
  138. if (actionRef != null) {
  139. bout.write(encode(" /A " + actionRef + "\n"));
  140. }
  141. }
  142. bout.write(encode(">> endobj\n"));
  143. } catch (IOException ioe) {
  144. getDocumentSafely().getLogger().error("Ignored I/O exception", ioe);
  145. }
  146. return bout.toByteArray();
  147. }
  148. }