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.

PDFRoot.java 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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.IOException;
  20. import java.io.OutputStream;
  21. import java.util.Locale;
  22. import org.apache.fop.util.LanguageTags;
  23. /**
  24. * Class representing a Root (/Catalog) object.
  25. */
  26. public class PDFRoot extends PDFDictionary {
  27. /**
  28. * Use no page mode setting, default
  29. */
  30. public static final int PAGEMODE_USENONE = 0;
  31. /**
  32. * Use outlines page mode to show bookmarks
  33. */
  34. public static final int PAGEMODE_USEOUTLINES = 1;
  35. /**
  36. * Use thumbs page mode to show thumbnail images
  37. */
  38. public static final int PAGEMODE_USETHUMBS = 2;
  39. /**
  40. * Full screen page mode
  41. */
  42. public static final int PAGEMODE_FULLSCREEN = 3;
  43. private static final PDFName[] PAGEMODE_NAMES = new PDFName[] {
  44. new PDFName("UseNone"),
  45. new PDFName("UseOutlines"),
  46. new PDFName("UseThumbs"),
  47. new PDFName("FullScreen"),
  48. };
  49. /**
  50. * create a Root (/Catalog) object. NOTE: The PDFRoot
  51. * object must be created before the PDF document is
  52. * generated, but it is not assigned an object ID until
  53. * it is about to be written (immediately before the xref
  54. * table as part of the trailer). (mark-fop@inomial.com)
  55. *
  56. * @param objnum the object's number
  57. * @param pages the PDFPages object
  58. */
  59. public PDFRoot(int objnum, PDFPages pages) {
  60. super();
  61. setObjectNumber(objnum);
  62. put("Type", new PDFName("Catalog"));
  63. setRootPages(pages);
  64. setLanguage("x-unknown");
  65. }
  66. /** {@inheritDoc} */
  67. public int output(OutputStream stream) throws IOException {
  68. getDocument().getProfile().verifyTaggedPDF();
  69. return super.output(stream);
  70. }
  71. /**
  72. * Set the page mode for the PDF document.
  73. *
  74. * @param mode the page mode (one of PAGEMODE_*)
  75. */
  76. public void setPageMode(int mode) {
  77. put("PageMode", PAGEMODE_NAMES[mode]);
  78. }
  79. /**
  80. * Returns the currently active /PageMode.
  81. * @return the /PageMode (one of PAGEMODE_*)
  82. */
  83. public int getPageMode() {
  84. PDFName mode = (PDFName)get("PageMode");
  85. if (mode != null) {
  86. for (int i = 0; i < PAGEMODE_NAMES.length; i++) {
  87. if (PAGEMODE_NAMES[i].equals(mode)) {
  88. return i;
  89. }
  90. }
  91. throw new IllegalStateException("Unknown /PageMode encountered: " + mode);
  92. } else {
  93. return PAGEMODE_USENONE;
  94. }
  95. }
  96. /**
  97. * add a /Page object to the root /Pages object
  98. *
  99. * @param page the /Page object to add
  100. */
  101. public void addPage(PDFPage page) {
  102. PDFPages pages = getRootPages();
  103. pages.addPage(page);
  104. }
  105. /**
  106. * set the root /Pages object
  107. *
  108. * @param pages the /Pages object to set as root
  109. */
  110. public void setRootPages(PDFPages pages) {
  111. put("Pages", pages.makeReference());
  112. }
  113. /**
  114. * Returns the /PageLabels object.
  115. * @return the /PageLabels object if set, null otherwise.
  116. * @since PDF 1.3
  117. */
  118. public PDFPages getRootPages() {
  119. PDFReference ref = (PDFReference)get("Pages");
  120. return (ref != null ? (PDFPages)ref.getObject() : null);
  121. }
  122. /**
  123. * Sets the /PageLabels object.
  124. * @param pageLabels the /PageLabels object
  125. */
  126. public void setPageLabels(PDFPageLabels pageLabels) {
  127. put("PageLabels", pageLabels.makeReference());
  128. }
  129. /**
  130. * Returns the /PageLabels object.
  131. * @return the /PageLabels object if set, null otherwise.
  132. * @since PDF 1.3
  133. */
  134. public PDFPageLabels getPageLabels() {
  135. PDFReference ref = (PDFReference)get("PageLabels");
  136. return (ref != null ? (PDFPageLabels)ref.getObject() : null);
  137. }
  138. /**
  139. * Set the root outline for the PDF document.
  140. *
  141. * @param out the root PDF Outline
  142. */
  143. public void setRootOutline(PDFOutline out) {
  144. put("Outlines", out.makeReference());
  145. //Set /PageMode to /UseOutlines by default if no other mode has been set
  146. PDFName mode = (PDFName)get("PageMode");
  147. if (mode == null) {
  148. setPageMode(PAGEMODE_USEOUTLINES);
  149. }
  150. }
  151. /**
  152. * Get the root PDF outline for the document.
  153. *
  154. * @return the root PDF Outline
  155. */
  156. public PDFOutline getRootOutline() {
  157. PDFReference ref = (PDFReference)get("Outlines");
  158. return (ref != null ? (PDFOutline)ref.getObject() : null);
  159. }
  160. /**
  161. * Set the /Names object.
  162. * @param names the Names object
  163. * @since PDF 1.2
  164. */
  165. public void setNames(PDFNames names) {
  166. put("Names", names.makeReference());
  167. }
  168. /**
  169. * Returns the /Names object.
  170. * @return the Names object if set, null otherwise.
  171. * @since PDF 1.2
  172. */
  173. public PDFNames getNames() {
  174. PDFReference ref = (PDFReference)get("Names");
  175. return (ref != null ? (PDFNames)ref.getObject() : null);
  176. }
  177. /**
  178. * Set the optional Metadata object.
  179. * @param meta the Metadata object
  180. * @since PDF 1.4
  181. */
  182. public void setMetadata(PDFMetadata meta) {
  183. if (getDocumentSafely().getPDFVersion().compareTo(Version.V1_4) >= 0) {
  184. put("Metadata", meta.makeReference());
  185. }
  186. }
  187. /**
  188. * Returns the /Metadata object
  189. * @return the /Metadata object if set, null otherwise.
  190. * @since PDF 1.4
  191. */
  192. public PDFMetadata getMetadata() {
  193. PDFReference ref = (PDFReference)get("Metadata");
  194. return (ref != null ? (PDFMetadata)ref.getObject() : null);
  195. }
  196. /**
  197. * Returns the /OutputIntents array.
  198. * @return the /OutputIntents array or null if it doesn't exist
  199. * @since PDF 1.4
  200. */
  201. public PDFArray getOutputIntents() {
  202. return (PDFArray)get("OutputIntents");
  203. }
  204. /**
  205. * Adds an OutputIntent to the PDF
  206. * @param outputIntent the OutputIntent dictionary
  207. * @since PDF 1.4
  208. */
  209. public void addOutputIntent(PDFOutputIntent outputIntent) {
  210. if (getDocumentSafely().getPDFVersion().compareTo(Version.V1_4) >= 0) {
  211. PDFArray outputIntents = getOutputIntents();
  212. if (outputIntents == null) {
  213. outputIntents = new PDFArray(this);
  214. put("OutputIntents", outputIntents);
  215. }
  216. outputIntents.add(outputIntent);
  217. }
  218. }
  219. /**
  220. * Sets the "Version" entry. If this version is greater than that specified in the header, this
  221. * version takes precedence.
  222. *
  223. * @param version the PDF document version
  224. * @since PDF 1.4
  225. */
  226. void setVersion(Version version) {
  227. put("Version", new PDFName(version.toString()));
  228. }
  229. /**
  230. * Returns the language identifier of the document.
  231. * @return the language identifier of the document (or null if not set or undefined)
  232. * @since PDF 1.4
  233. */
  234. public String getLanguage() {
  235. return (String)get("Lang");
  236. }
  237. /**
  238. * Sets the locale of the document.
  239. * @param locale the locale of the document.
  240. */
  241. public void setLanguage(Locale locale) {
  242. if (locale == null) {
  243. throw new NullPointerException("locale must not be null");
  244. }
  245. setLanguage(LanguageTags.toLanguageTag(locale));
  246. }
  247. private void setLanguage(String lang) {
  248. put("Lang", lang);
  249. }
  250. /**
  251. * Sets the StructTreeRoot object. Used for accessibility.
  252. * @param structTreeRoot of this document
  253. */
  254. public void setStructTreeRoot(PDFStructTreeRoot structTreeRoot) {
  255. if (structTreeRoot == null) {
  256. throw new NullPointerException("structTreeRoot must not be null");
  257. }
  258. put("StructTreeRoot", structTreeRoot);
  259. }
  260. /**
  261. * Returns the StructTreeRoot object.
  262. * @return the structure tree root (or null if accessibility is not enabled)
  263. */
  264. public PDFStructTreeRoot getStructTreeRoot() {
  265. return (PDFStructTreeRoot)get("StructTreeRoot");
  266. }
  267. /**
  268. * Marks this document as conforming to the Tagged PDF conventions.
  269. */
  270. public void makeTagged() {
  271. PDFDictionary dict = new PDFDictionary();
  272. dict.put("Marked", Boolean.TRUE);
  273. put("MarkInfo", dict); //new PDFMarkInfo()
  274. }
  275. /**
  276. * Returns the MarkInfo dictionary.
  277. * @return the MarkInfo dictionary (or null if it's not present)
  278. */
  279. public PDFDictionary getMarkInfo() {
  280. return (PDFDictionary)get("MarkInfo");
  281. }
  282. }