001/* 002 * $Id: PdfViewerPreferencesImp.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf.internal; 045 046import com.itextpdf.text.pdf.PdfArray; 047import com.itextpdf.text.pdf.PdfBoolean; 048import com.itextpdf.text.pdf.PdfDictionary; 049import com.itextpdf.text.pdf.PdfName; 050import com.itextpdf.text.pdf.PdfNumber; 051import com.itextpdf.text.pdf.PdfObject; 052import com.itextpdf.text.pdf.PdfReader; 053import com.itextpdf.text.pdf.PdfWriter; 054import com.itextpdf.text.pdf.interfaces.PdfViewerPreferences; 055 056/** 057 * Stores the information concerning viewer preferences, 058 * and contains the business logic that allows you to set viewer preferences. 059 */ 060 061public class PdfViewerPreferencesImp implements PdfViewerPreferences { 062 public static final PdfName[] VIEWER_PREFERENCES = { 063 PdfName.HIDETOOLBAR, // 0 064 PdfName.HIDEMENUBAR, // 1 065 PdfName.HIDEWINDOWUI, // 2 066 PdfName.FITWINDOW, // 3 067 PdfName.CENTERWINDOW, // 4 068 PdfName.DISPLAYDOCTITLE, // 5 069 PdfName.NONFULLSCREENPAGEMODE, // 6 070 PdfName.DIRECTION, // 7 071 PdfName.VIEWAREA, // 8 072 PdfName.VIEWCLIP, // 9 073 PdfName.PRINTAREA, // 10 074 PdfName.PRINTCLIP, // 11 075 PdfName.PRINTSCALING, // 12 076 PdfName.DUPLEX, // 13 077 PdfName.PICKTRAYBYPDFSIZE, // 14 078 PdfName.PRINTPAGERANGE, // 15 079 PdfName.NUMCOPIES // 16 080 }; 081 082 083 /** A series of viewer preferences. */ 084 public static final PdfName NONFULLSCREENPAGEMODE_PREFERENCES[] = { 085 PdfName.USENONE, PdfName.USEOUTLINES, PdfName.USETHUMBS, PdfName.USEOC 086 }; 087 /** A series of viewer preferences. */ 088 public static final PdfName DIRECTION_PREFERENCES[] = { 089 PdfName.L2R, PdfName.R2L 090 }; 091 /** A series of viewer preferences. */ 092 public static final PdfName PAGE_BOUNDARIES[] = { 093 PdfName.MEDIABOX, PdfName.CROPBOX, PdfName.BLEEDBOX, PdfName.TRIMBOX, PdfName.ARTBOX 094 }; 095 /** A series of viewer preferences */ 096 public static final PdfName PRINTSCALING_PREFERENCES[] = { 097 PdfName.APPDEFAULT, PdfName.NONE 098 }; 099 /** A series of viewer preferences. */ 100 public static final PdfName DUPLEX_PREFERENCES[] = { 101 PdfName.SIMPLEX, PdfName.DUPLEXFLIPSHORTEDGE, PdfName.DUPLEXFLIPLONGEDGE 102 }; 103 104 /** This value will hold the viewer preferences for the page layout and page mode. */ 105 private int pageLayoutAndMode = 0; 106 107 /** This dictionary holds the viewer preferences (other than page layout and page mode). */ 108 private PdfDictionary viewerPreferences = new PdfDictionary(); 109 110 /** The mask to decide if a ViewerPreferences dictionary is needed */ 111 private static final int viewerPreferencesMask = 0xfff000; 112 113 /** 114 * Returns the page layout and page mode value. 115 */ 116 public int getPageLayoutAndMode() { 117 return pageLayoutAndMode; 118 } 119 120 /** 121 * Returns the viewer preferences. 122 */ 123 public PdfDictionary getViewerPreferences() { 124 return viewerPreferences; 125 } 126 127 /** 128 * Sets the viewer preferences as the sum of several constants. 129 * 130 * @param preferences 131 * the viewer preferences 132 * @see PdfViewerPreferences#setViewerPreferences 133 */ 134 public void setViewerPreferences(int preferences) { 135 this.pageLayoutAndMode |= preferences; 136 // for backwards compatibility, it is also possible 137 // to set the following viewer preferences with this method: 138 if ((preferences & viewerPreferencesMask) != 0) { 139 pageLayoutAndMode = ~viewerPreferencesMask & pageLayoutAndMode; 140 if ((preferences & PdfWriter.HideToolbar) != 0) 141 viewerPreferences.put(PdfName.HIDETOOLBAR, PdfBoolean.PDFTRUE); 142 if ((preferences & PdfWriter.HideMenubar) != 0) 143 viewerPreferences.put(PdfName.HIDEMENUBAR, PdfBoolean.PDFTRUE); 144 if ((preferences & PdfWriter.HideWindowUI) != 0) 145 viewerPreferences.put(PdfName.HIDEWINDOWUI, PdfBoolean.PDFTRUE); 146 if ((preferences & PdfWriter.FitWindow) != 0) 147 viewerPreferences.put(PdfName.FITWINDOW, PdfBoolean.PDFTRUE); 148 if ((preferences & PdfWriter.CenterWindow) != 0) 149 viewerPreferences.put(PdfName.CENTERWINDOW, PdfBoolean.PDFTRUE); 150 if ((preferences & PdfWriter.DisplayDocTitle) != 0) 151 viewerPreferences.put(PdfName.DISPLAYDOCTITLE, PdfBoolean.PDFTRUE); 152 153 if ((preferences & PdfWriter.NonFullScreenPageModeUseNone) != 0) 154 viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USENONE); 155 else if ((preferences & PdfWriter.NonFullScreenPageModeUseOutlines) != 0) 156 viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOUTLINES); 157 else if ((preferences & PdfWriter.NonFullScreenPageModeUseThumbs) != 0) 158 viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USETHUMBS); 159 else if ((preferences & PdfWriter.NonFullScreenPageModeUseOC) != 0) 160 viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOC); 161 162 if ((preferences & PdfWriter.DirectionL2R) != 0) 163 viewerPreferences.put(PdfName.DIRECTION, PdfName.L2R); 164 else if ((preferences & PdfWriter.DirectionR2L) != 0) 165 viewerPreferences.put(PdfName.DIRECTION, PdfName.R2L); 166 167 if ((preferences & PdfWriter.PrintScalingNone) != 0) 168 viewerPreferences.put(PdfName.PRINTSCALING, PdfName.NONE); 169 } 170 } 171 172 /** 173 * Given a key for a viewer preference (a PdfName object), 174 * this method returns the index in the VIEWER_PREFERENCES array. 175 * @param key a PdfName referring to a viewer preference 176 * @return an index in the VIEWER_PREFERENCES array 177 */ 178 private int getIndex(PdfName key) { 179 for (int i = 0; i < VIEWER_PREFERENCES.length; i++) { 180 if (VIEWER_PREFERENCES[i].equals(key)) 181 return i; 182 } 183 return -1; 184 } 185 186 /** 187 * Checks if some value is valid for a certain key. 188 */ 189 private boolean isPossibleValue(PdfName value, PdfName[] accepted) { 190 for (int i = 0; i < accepted.length; i++) { 191 if (accepted[i].equals(value)) { 192 return true; 193 } 194 } 195 return false; 196 } 197 198 /** 199 * Sets the viewer preferences for printing. 200 */ 201 public void addViewerPreference(PdfName key, PdfObject value) { 202 switch(getIndex(key)) { 203 case 0: // HIDETOOLBAR 204 case 1: // HIDEMENUBAR 205 case 2: // HIDEWINDOWUI 206 case 3: // FITWINDOW 207 case 4: // CENTERWINDOW 208 case 5: // DISPLAYDOCTITLE 209 case 14: // PICKTRAYBYPDFSIZE 210 if (value instanceof PdfBoolean) { 211 viewerPreferences.put(key, value); 212 } 213 break; 214 case 6: // NONFULLSCREENPAGEMODE 215 if (value instanceof PdfName 216 && isPossibleValue((PdfName)value, NONFULLSCREENPAGEMODE_PREFERENCES)) { 217 viewerPreferences.put(key, value); 218 } 219 break; 220 case 7: // DIRECTION 221 if (value instanceof PdfName 222 && isPossibleValue((PdfName)value, DIRECTION_PREFERENCES)) { 223 viewerPreferences.put(key, value); 224 } 225 break; 226 case 8: // VIEWAREA 227 case 9: // VIEWCLIP 228 case 10: // PRINTAREA 229 case 11: // PRINTCLIP 230 if (value instanceof PdfName 231 && isPossibleValue((PdfName)value, PAGE_BOUNDARIES)) { 232 viewerPreferences.put(key, value); 233 } 234 break; 235 case 12: // PRINTSCALING 236 if (value instanceof PdfName 237 && isPossibleValue((PdfName)value, PRINTSCALING_PREFERENCES)) { 238 viewerPreferences.put(key, value); 239 } 240 break; 241 case 13: // DUPLEX 242 if (value instanceof PdfName 243 && isPossibleValue((PdfName)value, DUPLEX_PREFERENCES)) { 244 viewerPreferences.put(key, value); 245 } 246 break; 247 case 15: // PRINTPAGERANGE 248 if (value instanceof PdfArray) { 249 viewerPreferences.put(key, value); 250 } 251 break; 252 case 16: // NUMCOPIES 253 if (value instanceof PdfNumber) { 254 viewerPreferences.put(key, value); 255 } 256 break; 257 } 258 } 259 260 /** 261 * Adds the viewer preferences defined in the preferences parameter to a 262 * PdfDictionary (more specifically the root or catalog of a PDF file). 263 * 264 * @param catalog 265 */ 266 public void addToCatalog(PdfDictionary catalog) { 267 // Page Layout 268 catalog.remove(PdfName.PAGELAYOUT); 269 if ((pageLayoutAndMode & PdfWriter.PageLayoutSinglePage) != 0) 270 catalog.put(PdfName.PAGELAYOUT, PdfName.SINGLEPAGE); 271 else if ((pageLayoutAndMode & PdfWriter.PageLayoutOneColumn) != 0) 272 catalog.put(PdfName.PAGELAYOUT, PdfName.ONECOLUMN); 273 else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnLeft) != 0) 274 catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNLEFT); 275 else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnRight) != 0) 276 catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNRIGHT); 277 else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageLeft) != 0) 278 catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGELEFT); 279 else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageRight) != 0) 280 catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGERIGHT); 281 282 // Page Mode 283 catalog.remove(PdfName.PAGEMODE); 284 if ((pageLayoutAndMode & PdfWriter.PageModeUseNone) != 0) 285 catalog.put(PdfName.PAGEMODE, PdfName.USENONE); 286 else if ((pageLayoutAndMode & PdfWriter.PageModeUseOutlines) != 0) 287 catalog.put(PdfName.PAGEMODE, PdfName.USEOUTLINES); 288 else if ((pageLayoutAndMode & PdfWriter.PageModeUseThumbs) != 0) 289 catalog.put(PdfName.PAGEMODE, PdfName.USETHUMBS); 290 else if ((pageLayoutAndMode & PdfWriter.PageModeFullScreen) != 0) 291 catalog.put(PdfName.PAGEMODE, PdfName.FULLSCREEN); 292 else if ((pageLayoutAndMode & PdfWriter.PageModeUseOC) != 0) 293 catalog.put(PdfName.PAGEMODE, PdfName.USEOC); 294 else if ((pageLayoutAndMode & PdfWriter.PageModeUseAttachments) != 0) 295 catalog.put(PdfName.PAGEMODE, PdfName.USEATTACHMENTS); 296 297 // viewer preferences (Table 8.1 of the PDF Reference) 298 catalog.remove(PdfName.VIEWERPREFERENCES); 299 if (viewerPreferences.size() > 0) { 300 catalog.put(PdfName.VIEWERPREFERENCES, viewerPreferences); 301 } 302 } 303 304 public static PdfViewerPreferencesImp getViewerPreferences(PdfDictionary catalog) { 305 PdfViewerPreferencesImp preferences = new PdfViewerPreferencesImp(); 306 int prefs = 0; 307 PdfName name = null; 308 // page layout 309 PdfObject obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.PAGELAYOUT)); 310 if (obj != null && obj.isName()) { 311 name = (PdfName) obj; 312 if (name.equals(PdfName.SINGLEPAGE)) 313 prefs |= PdfWriter.PageLayoutSinglePage; 314 else if (name.equals(PdfName.ONECOLUMN)) 315 prefs |= PdfWriter.PageLayoutOneColumn; 316 else if (name.equals(PdfName.TWOCOLUMNLEFT)) 317 prefs |= PdfWriter.PageLayoutTwoColumnLeft; 318 else if (name.equals(PdfName.TWOCOLUMNRIGHT)) 319 prefs |= PdfWriter.PageLayoutTwoColumnRight; 320 else if (name.equals(PdfName.TWOPAGELEFT)) 321 prefs |= PdfWriter.PageLayoutTwoPageLeft; 322 else if (name.equals(PdfName.TWOPAGERIGHT)) 323 prefs |= PdfWriter.PageLayoutTwoPageRight; 324 } 325 // page mode 326 obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.PAGEMODE)); 327 if (obj != null && obj.isName()) { 328 name = (PdfName) obj; 329 if (name.equals(PdfName.USENONE)) 330 prefs |= PdfWriter.PageModeUseNone; 331 else if (name.equals(PdfName.USEOUTLINES)) 332 prefs |= PdfWriter.PageModeUseOutlines; 333 else if (name.equals(PdfName.USETHUMBS)) 334 prefs |= PdfWriter.PageModeUseThumbs; 335 else if (name.equals(PdfName.FULLSCREEN)) 336 prefs |= PdfWriter.PageModeFullScreen; 337 else if (name.equals(PdfName.USEOC)) 338 prefs |= PdfWriter.PageModeUseOC; 339 else if (name.equals(PdfName.USEATTACHMENTS)) 340 prefs |= PdfWriter.PageModeUseAttachments; 341 } 342 // set page layout and page mode preferences 343 preferences.setViewerPreferences(prefs); 344 // other preferences 345 obj = PdfReader.getPdfObjectRelease(catalog 346 .get(PdfName.VIEWERPREFERENCES)); 347 if (obj != null && obj.isDictionary()) { 348 PdfDictionary vp = (PdfDictionary) obj; 349 for (int i = 0; i < VIEWER_PREFERENCES.length; i++) { 350 obj = PdfReader.getPdfObjectRelease(vp.get(VIEWER_PREFERENCES[i])); 351 preferences.addViewerPreference(VIEWER_PREFERENCES[i], obj); 352 } 353 } 354 return preferences; 355 } 356}