| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085 |
- // Copyright (C) 2004-2022 Artifex Software, Inc.
- //
- // This file is part of MuPDF.
- //
- // MuPDF is free software: you can redistribute it and/or modify it under the
- // terms of the GNU Affero General Public License as published by the Free
- // Software Foundation, either version 3 of the License, or (at your option)
- // any later version.
- //
- // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
- // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
- // details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
- //
- // Alternative licensing terms are available from the licensor.
- // For commercial licensing, see <https://www.artifex.com/> or contact
- // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
- // CA 94129, USA, for further information.
- package example;
- import com.artifex.mupdf.fitz.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.awt.image.*;
- import java.io.File;
- import java.io.FilenameFilter;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.lang.reflect.Field;
- import java.util.Vector;
- public class Viewer extends Frame implements WindowListener, ActionListener, ItemListener, KeyListener, MouseWheelListener, Context.Log, ViewerCore.Callback
- {
- protected Worker worker;
- protected ViewerCore doc;
- protected Location location;
- protected int chapterNumber;
- protected int pageNumber;
- protected ViewerCore.OutlineItem[] outline;
- protected int layoutWidth = 450;
- protected int layoutHeight = 600;
- protected int layoutEm = 12;
- protected String title;
- protected String author;
- protected String format;
- protected String encryption;
- protected boolean print;
- protected boolean copy;
- protected boolean edit;
- protected boolean annotate;
- protected boolean form;
- protected boolean accessibility;
- protected boolean assemble;
- protected boolean printHq;
- protected boolean reflowable;
- protected boolean linearized;
- protected int updates;
- protected int firstUpdate;
- protected int chapters;
- protected int pages;
- protected Pixmap pixmap;
- protected Rect bbox;
- protected Rect[] links;
- protected String[] linkURIs;
- protected Quad[][] hits;
- protected int pixmapWidth;
- protected int pixmapHeight;
- protected float pixelScale;
- protected int screenDPI;
- protected Dimension screenSize;
- protected int searchDirection = 1;
- protected String searchNeedle = null;
- protected final int MIN_ZOOM_DPI = 18;
- protected final int MAX_ZOOM_DPI = 288;
- protected int[] zoomList = {
- 18, 24, 36, 54, 72, 96, 120, 144, 180, 216, 288
- };
- protected boolean customZoom = false;
- protected int currentDPI = 72;
- protected int rotate = 0;
- protected boolean icc = true;
- protected int antialias = 8;
- protected boolean invert = false;
- protected boolean tint = false;
- protected int tintBlack = 0x303030;
- protected int tintWhite = 0xFFFFF0;
- protected boolean showLinks = false;
- protected boolean isFullscreen = false;
- protected ScrollPane pageScroll;
- protected Panel pageHolder;
- protected PageCanvas pageCanvas;
- protected Button firstButton, prevButton, nextButton, lastButton;
- protected TextField pageField;
- protected Label pageLabel;
- protected Button zoomInButton, zoomOutButton;
- protected Choice zoomChoice;
- protected Panel reflowPanel;
- protected Button fontIncButton, fontDecButton;
- protected Label fontSizeLabel;
- protected TextField searchField;
- protected Button searchPrevButton, searchNextButton;
- protected Panel searchStatusPanel;
- protected Label searchStatus;
- protected Panel outlinePanel;
- protected List outlineList;
- protected OCRProgressmeter OCRmeter;
- protected RenderProgressmeter renderMeter;
- protected int number = 0;
- protected class Mark {
- Location loc;
- protected Mark(Location loc) {
- this.loc = loc;
- }
- }
- protected int historyCount = 0;
- protected Mark[] history = new Mark[256];
- protected int futureCount = 0;
- protected Mark[] future = new Mark[256];
- protected Mark[] marks = new Mark[10];
- protected static void messageBox(Frame owner, String title, String message) {
- final Dialog box = new Dialog(owner, title, true);
- box.add(new Label(message), BorderLayout.CENTER);
- Panel buttonPane = new Panel(new FlowLayout());
- Button okayButton = new Button("Okay");
- okayButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- box.setVisible(false);
- }
- });
- buttonPane.add(okayButton);
- box.add(buttonPane, BorderLayout.SOUTH);
- box.pack();
- box.setVisible(true);
- box.dispose();
- }
- protected static String passwordDialog(Frame owner, String title) {
- final Dialog box = new Dialog(owner, title, true);
- final TextField textField = new TextField(20);
- textField.setEchoChar('*');
- Panel buttonPane = new Panel(new FlowLayout());
- Button cancelButton = new Button("Cancel");
- Button okayButton = new Button("Okay");
- cancelButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- textField.setText("");
- box.setVisible(false);
- }
- });
- okayButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- box.setVisible(false);
- }
- });
- box.add(new Label("Password:"), BorderLayout.NORTH);
- box.add(textField, BorderLayout.CENTER);
- buttonPane.add(cancelButton);
- buttonPane.add(okayButton);
- box.add(buttonPane, BorderLayout.SOUTH);
- box.pack();
- box.setVisible(true);
- box.dispose();
- String pwd = textField.getText();
- if (pwd.length() == 0)
- return null;
- return pwd;
- }
- public class LogDialog extends Dialog implements ActionListener, KeyListener{
- TextArea info = new TextArea("");
- Button okay = new Button("Okay");
- public LogDialog(Frame parent, String title, String message) {
- super(parent, title, true);
- setLayout(new GridLayout(2, 1));
- info.setText(message);
- info.setEnabled(false);
- add(info);
- Panel buttonPanel = new Panel(new FlowLayout(FlowLayout.CENTER));
- {
- okay.addActionListener(this);
- okay.addKeyListener(this);
- buttonPanel.add(okay);
- }
- add(buttonPanel);
- pack();
- setResizable(false);
- okay.requestFocusInWindow();
- setLocationRelativeTo(parent);
- setVisible(true);
- }
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == okay)
- dispose();
- }
- public void keyPressed(KeyEvent e) { }
- public void keyReleased(KeyEvent e) { }
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\u001b')
- dispose();
- }
- }
- public void exception(Throwable t) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- System.out.println("Exception: " + sw.toString());
- LogDialog ld = new LogDialog(this, "Exception!", "Exception: " + sw.toString());
- }
- public void error(String message) {
- LogDialog ld = new LogDialog(this, "Error!", "Error: " + message);
- }
- public void warning(String message) {
- LogDialog ld = new LogDialog(this, "Warning!", "Warning: " + message);
- }
- public Viewer(String documentPath) {
- pixelScale = getRetinaScale();
- screenDPI = getScreenDPI();
- screenSize = getScreenSize();
- currentDPI = zoomList[findNextLargerZoomLevel(screenDPI - 1)];
- setTitle("MuPDF: ");
- outlinePanel = new Panel(new BorderLayout());
- {
- outlineList = new List();
- outlineList.addItemListener(this);
- outlinePanel.add(outlineList, BorderLayout.CENTER);
- }
- this.add(outlinePanel, BorderLayout.WEST);
- outlinePanel.setMinimumSize(new Dimension(300, 300));
- outlinePanel.setPreferredSize(new Dimension(300, 300));
- outlinePanel.setVisible(false);
- Panel rightPanel = new Panel(new BorderLayout());
- {
- Panel toolpane = new Panel(new GridBagLayout());
- {
- GridBagConstraints c = new GridBagConstraints();
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.WEST;
- Panel toolbar = new Panel(new FlowLayout(FlowLayout.LEFT));
- {
- firstButton = new Button("|<");
- firstButton.addActionListener(this);
- prevButton = new Button("<");
- prevButton.addActionListener(this);
- nextButton = new Button(">");
- nextButton.addActionListener(this);
- lastButton = new Button(">|");
- lastButton.addActionListener(this);
- pageField = new TextField(4);
- pageField.addActionListener(this);
- pageLabel = new Label("/ " + pages);
- toolbar.add(firstButton);
- toolbar.add(prevButton);
- toolbar.add(pageField);
- toolbar.add(pageLabel);
- toolbar.add(nextButton);
- toolbar.add(lastButton);
- }
- c.gridy = 0;
- toolpane.add(toolbar, c);
- toolbar = new Panel(new FlowLayout(FlowLayout.LEFT));
- {
- zoomOutButton = new Button("Zoom-");
- zoomOutButton.addActionListener(this);
- zoomInButton = new Button("Zoom+");
- zoomInButton.addActionListener(this);
- zoomChoice = new Choice();
- for (int i = 0; i < zoomList.length; ++i) {
- zoomChoice.add(String.valueOf(zoomList[i]));
- if (zoomList[i] == currentDPI)
- zoomChoice.select(i);
- }
- zoomChoice.addItemListener(this);
- toolbar.add(zoomOutButton);
- toolbar.add(zoomChoice);
- toolbar.add(zoomInButton);
- }
- c.gridy += 1;
- toolpane.add(toolbar, c);
- reflowPanel = new Panel(new FlowLayout(FlowLayout.LEFT));
- {
- fontDecButton = new Button("Font-");
- fontDecButton.addActionListener(this);
- fontIncButton = new Button("Font+");
- fontIncButton.addActionListener(this);
- fontSizeLabel = new Label(String.valueOf(layoutEm));
- reflowPanel.add(fontDecButton);
- reflowPanel.add(fontSizeLabel);
- reflowPanel.add(fontIncButton);
- }
- c.gridy += 1;
- toolpane.add(reflowPanel, c);
- toolbar = new Panel(new FlowLayout(FlowLayout.LEFT));
- {
- searchField = new TextField(20);
- searchField.addActionListener(this);
- searchPrevButton = new Button("<");
- searchPrevButton.addActionListener(this);
- searchNextButton = new Button(">");
- searchNextButton.addActionListener(this);
- toolbar.add(searchField);
- toolbar.add(searchPrevButton);
- toolbar.add(searchNextButton);
- }
- searchField.addKeyListener(this);
- c.gridy += 1;
- toolpane.add(toolbar, c);
- searchStatusPanel = new Panel(new FlowLayout(FlowLayout.LEFT));
- {
- searchStatus = new Label();
- searchStatusPanel.add(searchStatus);
- }
- c.gridy += 1;
- toolpane.add(searchStatusPanel, c);
- }
- rightPanel.add(toolpane, BorderLayout.NORTH);
- }
- this.add(rightPanel, BorderLayout.EAST);
- pageScroll = new ScrollPane(ScrollPane.SCROLLBARS_NEVER);
- {
- pageHolder = new Panel(new GridBagLayout());
- {
- pageHolder.setBackground(Color.gray);
- pageCanvas = new PageCanvas(pixelScale);
- pageHolder.add(pageCanvas);
- }
- pageCanvas.addKeyListener(this);
- pageCanvas.addMouseWheelListener(this);
- pageScroll.add(pageHolder);
- }
- this.add(pageScroll, BorderLayout.CENTER);
- addWindowListener(this);
- Toolkit toolkit = Toolkit.getDefaultToolkit();
- EventQueue eq = toolkit.getSystemEventQueue();
- worker = new Worker(eq);
- worker.start();
- pack();
- pageCanvas.requestFocusInWindow();
- doc = new ViewerCore(worker, this, documentPath);
- doc.openDocument(new ViewerCore.OnException() {
- public void run(Throwable t) {
- exception(t);
- }
- });
- }
- public void dispose() {
- doc.cancelSearch(null);
- doc.worker.stop();
- super.dispose();
- }
- public void keyPressed(KeyEvent e) {
- }
- public void keyReleased(KeyEvent e) {
- if (e.getSource() == pageCanvas) {
- int c = e.getKeyCode();
- switch(c)
- {
- case KeyEvent.VK_F1: showHelp(); break;
- case KeyEvent.VK_LEFT: pan(-10, 0); break;
- case KeyEvent.VK_RIGHT: pan(+10, 0); break;
- case KeyEvent.VK_UP: pan(0, -10); break;
- case KeyEvent.VK_DOWN: pan(0, +10); break;
- case KeyEvent.VK_PAGE_UP: doc.flipPages(-number, null); break;
- case KeyEvent.VK_PAGE_DOWN: doc.flipPages(+number, null); break;
- }
- }
- }
- public void keyTyped(KeyEvent e) {
- if (e.getSource() == pageCanvas)
- canvasKeyTyped(e);
- else if (e.getSource() == searchField)
- searchFieldKeyTyped(e);
- }
- protected void searchFieldKeyTyped(KeyEvent e) {
- if (e.getExtendedKeyCodeForChar(e.getKeyChar()) == java.awt.event.KeyEvent.VK_ESCAPE)
- clearSearch();
- }
- protected void canvasKeyTyped(KeyEvent e) {
- char c = e.getKeyChar();
- switch(c)
- {
- case 'r': doc.reloadDocument(null); break;
- case 'q': dispose(); break;
- case 'S': save(); break;
- case 'f': toggleFullscreen(); break;
- case 'm': mark(number); break;
- case 't': jumpHistoryBack(number); break;
- case 'T': jumpHistoryForward(number); break;
- case '>': relayout(number > 0 ? number : +1); break;
- case '<': relayout(number > 0 ? number : -1); break;
- case 'I': toggleInvert(); break;
- case 'E': toggleICC(); break;
- case 'A': toggleAntiAlias(); break;
- case 'C': toggleTint(); break;
- case 'o': toggleOutline(); break;
- case 'L': toggleLinks(); break;
- case 'i': showInfo(); break;
- case '[': rotate(-90); break;
- case ']': rotate(+90); break;
- case '+': zoomIn(); break;
- case '-': zoomOut(); break;
- case 'z': zoomToDPI(number); break;
- case 'w': shrinkWrap(); break;
- case 'W': fitWidth(); break;
- case 'H': fitHeight(); break;
- case 'Z': fitPage(); break;
- case 'k': pan(0, pageCanvas != null ? pageCanvas.getHeight() / -10 : -10); break;
- case 'j': pan(0, pageCanvas != null ? pageCanvas.getWidth() / +10 : +10); break;
- case 'h': pan(pageCanvas != null ? pageCanvas.getHeight() / -10 : -10, 0); break;
- case 'l': pan(pageCanvas != null ? pageCanvas.getWidth() / +10 : +10, 0); break;
- case 'b': smartMove(-1, number); break;
- case ' ': smartMove(+1, number); break;
- case ',': flipPages(-number); break;
- case '.': flipPages(+number); break;
- case 'g': gotoPage(number); break;
- case 'G': gotoLastPage(); break;
- case '/': editSearchNeedle(+1); break;
- case '?': editSearchNeedle(-1); break;
- case 'N': search(-1); break;
- case 'n': search(+1); break;
- case '\u001b': clearSearch(); break;
- }
- if (c >= '0' && c <= '9')
- number = number * 10 + c - '0';
- else
- number = 0;
- }
- public void mouseWheelMoved(MouseWheelEvent e) {
- int mod = e.getModifiersEx();
- int rot = e.getWheelRotation();
- if ((mod & MouseWheelEvent.CTRL_DOWN_MASK) != 0) {
- if (rot < 0)
- zoomIn();
- else
- zoomOut();
- } else if ((mod & MouseWheelEvent.SHIFT_DOWN_MASK) != 0) {
- if (rot < 0)
- pan(pageCanvas != null ? pageCanvas.getHeight() / -10 : -10, 0);
- else
- pan(pageCanvas != null ? pageCanvas.getHeight() / +10 : +10, 0);
- } else if (mod == 0) {
- if (rot < 0)
- pan(0, pageCanvas != null ? pageCanvas.getHeight() / -10 : -10);
- else
- pan(0, pageCanvas != null ? pageCanvas.getHeight() / +10 : +10);
- }
- }
- protected void editSearchNeedle(int direction) {
- clearSearch();
- searchDirection = direction;
- searchField.requestFocusInWindow();
- }
- protected void cancelSearch() {
- doc.cancelSearch(null);
- }
- protected void clearSearch() {
- cancelSearch();
- searchField.setText("");
- searchStatus.setText("");
- searchStatusPanel.validate();
- validate();
- hits = null;
- redraw();
- }
- public void search(int direction) {
- if (searchField.isEnabled()) {
- cancelSearch();
- searchField.setEnabled(false);
- searchNextButton.setEnabled(false);
- searchPrevButton.setEnabled(false);
- pageCanvas.requestFocusInWindow();
- doc.search(searchField.getText(), direction, new ViewerCore.OnException() {
- public void run(Throwable t) {
- exception(t);
- }
- });
- }
- }
- protected void render() {
- if (bbox == null)
- return;
- float width = bbox.x1 - bbox.x0;
- float height = bbox.y1 - bbox.y0;
- float scaleX = (float) Math.floor(width * (currentDPI/72.0f) * pixelScale + 0.5f) / width;
- float scaleY = (float) Math.floor(height * (currentDPI/72.0f) * pixelScale + 0.5f) / height;
- Matrix ctm = new Matrix().scale(scaleX, scaleY).rotate(rotate);
- Rect atOrigin = new Rect(bbox).transform(ctm);
- ctm.e -= atOrigin.x0;
- ctm.f -= atOrigin.y0;
- Rect bounds = new Rect(bbox).transform(ctm);
- Cookie cookie = new Cookie();
- renderMeter = new RenderProgressmeter(this, "Rendering...", cookie, 250);
- renderMeter.setLocationRelativeTo(this);
- pageCanvas.requestFocusInWindow();
- doc.renderPage(ctm, bounds, icc, antialias, invert, tint, tintBlack, tintWhite, cookie,
- new ViewerCore.OnException() {
- public void run(Throwable t) {
- if (!renderMeter.cancelled)
- exception(t);
- }
- }
- );
- }
- protected int findExactZoomLevel(int dpi) {
- for (int level = 0; level < zoomList.length - 1; level++)
- if (zoomList[level] == dpi)
- return level;
- return -1;
- }
- protected int findNextSmallerZoomLevel(int dpi) {
- for (int level = zoomList.length - 1; level >= 0; level--)
- if (zoomList[level] < dpi)
- return level;
- return 0;
- }
- protected int findNextLargerZoomLevel(int dpi) {
- for (int level = 0; level < zoomList.length - 1; level++)
- if (zoomList[level] > dpi)
- return level;
- return zoomList.length - 1;
- }
- protected void zoomToDPI(int newDPI) {
- if (newDPI == 0)
- newDPI = screenDPI;
- if (newDPI < MIN_ZOOM_DPI)
- newDPI = MIN_ZOOM_DPI;
- if (newDPI > MAX_ZOOM_DPI)
- newDPI = MAX_ZOOM_DPI;
- if (newDPI == currentDPI)
- return;
- int level = findExactZoomLevel(newDPI);
- if (level < 0) {
- if (customZoom)
- zoomChoice.remove(0);
- customZoom = true;
- zoomChoice.insert(String.valueOf(newDPI), 0);
- zoomChoice.select(0);
- } else {
- if (customZoom) {
- customZoom = false;
- zoomChoice.remove(0);
- }
- zoomChoice.select(level);
- }
- currentDPI = newDPI;
- render();
- }
- protected void zoomToLevel(int level) {
- if (level < 0)
- level = 0;
- if (level >= zoomList.length - 1)
- level = zoomList.length - 1;
- zoomToDPI(zoomList[level]);
- }
- protected void zoomIn() {
- zoomToLevel(findNextLargerZoomLevel(currentDPI));
- }
- protected void zoomOut() {
- zoomToLevel(findNextSmallerZoomLevel(currentDPI));
- }
- protected void zoomToScale(float newZoom) {
- zoomToDPI((int)(newZoom * 72));
- }
- protected void fit(float desired, float unscaled) {
- zoomToScale(desired / unscaled);
- }
- protected float unscaledWidth() {
- return bbox != null ? bbox.x1 - bbox.x0 : 0;
- }
- protected float unscaledHeight() {
- return bbox != null ? bbox.y1 - bbox.y0 : 0;
- }
- protected void fitWidth() {
- fit(pageScroll.getSize().width, unscaledWidth());
- }
- protected void fitHeight() {
- fit(pageScroll.getSize().height, unscaledHeight());
- }
- protected void fitPage() {
- Dimension size = pageScroll.getSize();
- float width = bbox != null ? bbox.x1 - bbox.x0 : 0;
- float height = bbox != null ? bbox.y1 - bbox.y0 : 0;
- float pageAspect = (width == 0 || height == 0) ? 0 : (width / height);
- float canvasAspect = (float) size.width / (float) size.height;
- if (pageAspect > canvasAspect)
- fitWidth();
- else
- fitHeight();
- }
- protected void rotate(int change) {
- int newRotate = rotate + change;
- while (newRotate < 0) newRotate += 360;
- while (newRotate >= 360) newRotate -= 360;
- if (newRotate - rotate == 0)
- return;
- rotate = newRotate;
- render();
- }
- protected void toggleAntiAlias() {
- int newAntialias = number != 0 ? number : (antialias == 8 ? 0 : 8);
- if (newAntialias - antialias == 0)
- return;
- antialias = newAntialias;
- render();
- }
- protected void toggleICC() {
- icc = !icc;
- render();
- }
- protected void toggleInvert() {
- invert = !invert;
- render();
- }
- protected void toggleTint() {
- tint = !tint;
- render();
- }
- protected void toggleOutline() {
- if (outlineList.getItemCount() <= 0)
- return;
- outlinePanel.setVisible(!outlinePanel.isVisible());
- pack();
- validate();
- }
- protected void toggleLinks() {
- showLinks = !showLinks;
- redraw();
- }
- protected boolean isShrinkWrapped(int oldPixmapWidth, int oldPixmapHeight) {
- Dimension size = pageScroll.getSize();
- if (oldPixmapWidth == 0 && oldPixmapHeight == 0)
- return true;
- if (oldPixmapWidth + 4 == size.width && oldPixmapHeight + 4 == size.height)
- return true;
- return false;
- }
- protected void shrinkWrap() {
- Dimension newSize = new Dimension(pixmapWidth, pixmapHeight);
- newSize.width += 4;
- newSize.height += 4;
- if (newSize.width > screenSize.width)
- newSize.width = screenSize.width;
- if (newSize.height > screenSize.height)
- newSize.height = screenSize.height;
- pageScroll.setPreferredSize(newSize);
- pack();
- }
- protected void redraw() {
- boolean wasShrinkWrapped = isShrinkWrapped(pixmapWidth, pixmapHeight);
- if (pixmap != null) {
- pixmapWidth = pixmap.getWidth();
- pixmapHeight = pixmap.getHeight();
- BufferedImage image = new BufferedImage(pixmapWidth, pixmapHeight, BufferedImage.TYPE_3BYTE_BGR);
- image.setRGB(0, 0, pixmapWidth, pixmapHeight, pixmap.getPixels(), 0, pixmapWidth);
- pageCanvas.setPage(image, showLinks ? links : null, hits);
- } else {
- pixmapWidth = 0;
- pixmapHeight = 0;
- pageCanvas.setPage(null, null, null);
- }
- if (wasShrinkWrapped)
- shrinkWrap();
- pageCanvas.invalidate();
- validate();
- }
- protected static String paperSizeName(int w, int h)
- {
- /* ISO A */
- if (w == 2384 && h == 3370) return "A0";
- if (w == 1684 && h == 2384) return "A1";
- if (w == 1191 && h == 1684) return "A2";
- if (w == 842 && h == 1191) return "A3";
- if (w == 595 && h == 842) return "A4";
- if (w == 420 && h == 595) return "A5";
- if (w == 297 && h == 420) return "A6";
- /* US */
- if (w == 612 && h == 792) return "Letter";
- if (w == 612 && h == 1008) return "Legal";
- if (w == 792 && h == 1224) return "Ledger";
- if (w == 1224 && h == 792) return "Tabloid";
- return null;
- }
- protected void showHelp() {
- final Dialog box = new Dialog(this, "Help", true);
- box.addWindowListener(new WindowListener() {
- public void windowActivated(WindowEvent event) { }
- public void windowDeactivated(WindowEvent event) { }
- public void windowIconified(WindowEvent event) { }
- public void windowDeiconified(WindowEvent event) { }
- public void windowOpened(WindowEvent event) { }
- public void windowClosed(WindowEvent event) { }
- public void windowClosing(WindowEvent event) {
- box.setVisible(false);
- pageCanvas.requestFocusInWindow();
- }
- });
- String help[] = {
- "The middle mouse button (scroll wheel button) pans the document view.",
- //"The right mouse button selects a region and copies the marked text to the clipboard.",
- //"",
- //"",
- "F1 - show this message",
- "i - show document information",
- "o - show document outline",
- //"a - show annotation editor",
- "L - highlight links",
- //"F - highlight form fields",
- "r - reload file",
- "S - save file",
- "q - quit",
- "",
- "< - decrease E-book font size",
- "> - increase E-book font size",
- "A - toggle anti-aliasing",
- "I - toggle inverted color mode",
- "C - toggle tinted color mode",
- "E - toggle ICC color management",
- //"e - toggle spot color emulation",
- "",
- "f - fullscreen window",
- "w - shrink wrap window",
- "W - fit to width",
- "H - fit to height",
- "Z - fit to page",
- "z - reset zoom",
- "[number] z - set zoom resolution in DPI",
- "plus - zoom in",
- "minus - zoom out",
- "[ - rotate counter-clockwise",
- "] - rotate clockwise",
- "arrow keys - scroll in small increments",
- "h, j, k, l - scroll in small increments",
- "",
- "b - smart move backward",
- "space - smart move forward",
- "comma or page up - go backward",
- "period or page down - go forward",
- "g - go to first page",
- "G - go to last page",
- "[number] g - go to page number",
- "",
- "m - save current location in history",
- "t - go backward in history",
- "T - go forward in history",
- "[number] m - save current location in numbered bookmark",
- "[number] t - go to numbered bookmark",
- "",
- "/ - search for text forward",
- "? - search for text backward",
- "n - repeat search",
- "N - repeat search in reverse direction",
- };
- Panel helpPanel = new Panel(new GridLayout(help.length, 1));
- for (int i = 0; i < help.length; i++)
- helpPanel.add(new Label(help[i]));
- Button button = new Button("OK");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- box.setVisible(false);
- }
- });
- button.addKeyListener(new KeyListener() {
- public void keyPressed(KeyEvent e) { }
- public void keyReleased(KeyEvent e) {
- if (e.getKeyCode() == KeyEvent.VK_F1)
- box.setVisible(false);
- }
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\u001b' || e.getKeyChar() == '\r' || e.getKeyChar() == '\n')
- box.setVisible(false);
- }
- });
- Panel buttonPane = new Panel(new FlowLayout());
- buttonPane.add(button);
- box.add(helpPanel, BorderLayout.CENTER);
- box.add(buttonPane, BorderLayout.SOUTH);
- box.setResizable(false);
- box.pack();
- java.awt.Point winLoc = this.getLocation();
- Dimension winDim = this.getSize();
- int winCenterX = winLoc.x + winDim.width / 2;
- int winCenterY = winLoc.y + winDim.height / 2;
- Dimension diagDim = box.getSize();
- int x = winCenterX - diagDim.width / 2;
- int y = winCenterY - diagDim.height / 2;
- box.setLocation(x, y);
- button.requestFocusInWindow();
- box.setVisible(true);
- box.dispose();
- }
- protected void showInfo() {
- StringBuffer buffer;
- cancelSearch();
- final Dialog box = new Dialog(this, "Document info", true);
- box.addWindowListener(new WindowListener() {
- public void windowActivated(WindowEvent event) { }
- public void windowDeactivated(WindowEvent event) { }
- public void windowIconified(WindowEvent event) { }
- public void windowDeiconified(WindowEvent event) { }
- public void windowOpened(WindowEvent event) { }
- public void windowClosed(WindowEvent event) { }
- public void windowClosing(WindowEvent event) {
- box.setVisible(false);
- pageCanvas.requestFocusInWindow();
- }
- });
- Panel infoPanel = new Panel();
- int rows = 0;
- if (title != null) rows++;
- if (author != null) rows++;
- if (format != null) rows++;
- if (encryption != null) rows++;
- buffer = new StringBuffer();
- if (print)
- buffer.append("print, ");
- if (copy)
- buffer.append("copy, ");
- if (edit)
- buffer.append("edit, ");
- if (annotate)
- buffer.append("annotate, ");
- if (form)
- buffer.append("form, ");
- if (accessibility)
- buffer.append("accessibility, ");
- if (assemble)
- buffer.append("assemble, ");
- if (printHq)
- buffer.append("print-hq, ");
- if (buffer.length() > 2)
- buffer.delete(buffer.length() - 2, buffer.length());
- String permissions = buffer.length() > 0 ? buffer.toString() : null;
- if (permissions != null) rows++;
- buffer = new StringBuffer();
- if (doc.equals("PDF")) {
- buffer.append("PDF ");
- if (linearized)
- buffer.append("linearized ");
- buffer.append("document with ");
- buffer.append(updates);
- if (updates == 1)
- buffer.append(" update");
- else
- buffer.append(" updates");
- }
- String versions = buffer.length() > 0 ? buffer.toString() : null;
- if (versions != null) rows++;
- buffer = new StringBuffer();
- if (doc.equals("PDF")) {
- if (updates > 1) {
- if (firstUpdate == 0)
- buffer.append("Change firstUpdate seems valid.");
- else if (firstUpdate == 1)
- buffer.append("Invalid changes made to the document in the last update.");
- else if (firstUpdate == 2)
- buffer.append("Invalid changes made to the document in the penultimate update.");
- else {
- buffer.append("Invalid changes made to the document ");
- buffer.append(firstUpdate);
- buffer.append(" updates ago.");
- }
- }
- }
- String validation = buffer.length() > 0 ? buffer.toString() : null;
- if (validation != null) rows++;
- buffer = new StringBuffer();
- int w = 0;
- int h = 0;
- if (bbox != null) {
- w = (int)(bbox.x1 - bbox.x0 + 0.5f);
- h = (int)(bbox.y1 - bbox.y0 + 0.5f);
- }
- buffer.append(w);
- buffer.append(" x ");
- buffer.append(h);
- String name = paperSizeName(w, h);
- if (name == null)
- name = paperSizeName(h, w);
- if (name != null)
- buffer.append("(" + name + ")");
- String paperSize = buffer.length() > 0 ? buffer.toString() : null;
- if (paperSize != null) rows++;
- buffer = new StringBuffer();
- buffer.append(pageNumber + 1);
- buffer.append(" / ");
- buffer.append(pages);
- String page = buffer.length() > 0 ? buffer.toString() : null;
- if (page != null) rows++;
- String iccstring = icc ? "on" : "off";
- rows++;
- String antialiasstring = Integer.toString(antialias);
- rows++;
- infoPanel.setLayout(new GridLayout(rows, 1));
- if (title != null) infoPanel.add(new Label("Title: " + title));
- if (author != null) infoPanel.add(new Label("Author: " + author));
- if (format != null) infoPanel.add(new Label("Format: " + format));
- if (encryption != null) infoPanel.add(new Label("Encryption: " + encryption));
- if (permissions != null) infoPanel.add(new Label("Permissions: " + permissions));
- if (versions != null) infoPanel.add(new Label(versions));
- if (validation != null) infoPanel.add(new Label(validation));
- infoPanel.add(new Label("Size: " + paperSize));
- infoPanel.add(new Label("Page: " + page));
- infoPanel.add(new Label("ICC rendering: " + iccstring));
- infoPanel.add(new Label("Antialias rendering: " + antialiasstring));
- Button button = new Button("OK");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- box.setVisible(false);
- }
- });
- button.addKeyListener(new KeyListener() {
- public void keyPressed(KeyEvent e) { }
- public void keyReleased(KeyEvent e) { }
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\u001b' || e.getKeyChar() == '\r' || e.getKeyChar() == '\n')
- box.setVisible(false);
- }
- });
- Panel buttonPane = new Panel(new FlowLayout());
- buttonPane.add(button);
- box.add(infoPanel, BorderLayout.CENTER);
- box.add(buttonPane, BorderLayout.SOUTH);
- button.requestFocusInWindow();
- box.setResizable(false);
- box.pack();
- java.awt.Point winLoc = this.getLocation();
- Dimension winDim = this.getSize();
- int winCenterX = winLoc.x + winDim.width / 2;
- int winCenterY = winLoc.y + winDim.height / 2;
- Dimension diagDim = box.getSize();
- int x = winCenterX - diagDim.width / 2;
- int y = winCenterY - diagDim.height / 2;
- box.setLocation(x, y);
- box.setVisible(true);
- box.dispose();
- }
- protected void toggleFullscreen() {
- isFullscreen = !isFullscreen;
- if (isFullscreen)
- setExtendedState(Frame.MAXIMIZED_BOTH);
- else
- setExtendedState(Frame.NORMAL);
- }
- protected void mark(int number) {
- cancelSearch();
- if (number == 0)
- pushHistory();
- else if (number > 0 && number < marks.length)
- marks[number] = saveMark();
- }
- protected void jumpHistoryBack(int number) {
- cancelSearch();
- if (number == 0) {
- if (historyCount > 0)
- popHistory();
- } else if (number > 0 && number < marks.length)
- restoreMark(marks[number]);
- }
- protected void jumpHistoryForward(int number) {
- cancelSearch();
- if (number == 0) {
- if (futureCount > 0) {
- popFuture();
- }
- }
- }
- protected Mark saveMark() {
- return new Mark(location);
- }
- protected void restoreMark(Mark mark) {
- if (mark != null) {
- doc.gotoLocation(mark.loc, null);
- pageCanvas.requestFocusInWindow();
- }
- }
- protected void pushHistory() {
- if (historyCount > 0 && location.equals(history[historyCount - 1].loc))
- {
- return;
- }
- if (historyCount + 1 >= history.length) {
- for (int i = 0; i < history.length - 1; i++)
- history[i] = history[i + 1];
- history[historyCount] = saveMark();
- } else {
- history[historyCount++] = saveMark();
- }
- }
- protected void pushFuture() {
- if (futureCount + 1 >= future.length) {
- for (int i = 0; i < future.length - 1; i++)
- future[i] = future[i + 1];
- future[futureCount] = saveMark();
- } else {
- future[futureCount++] = saveMark();
- }
- }
- protected void clearFuture() {
- futureCount = 0;
- }
- protected void popHistory() {
- Location here = location;
- pushFuture();
- while (historyCount > 0 && location.equals(here))
- restoreMark(history[--historyCount]);
- }
- protected void popFuture() {
- Location here = location;
- pushHistory();
- while (futureCount > 0 && location.equals(here))
- restoreMark(future[--futureCount]);
- }
- protected void pan(int panx, int pany) {
- Adjustable hadj = pageScroll.getHAdjustable();
- Adjustable vadj = pageScroll.getVAdjustable();
- int h = hadj.getValue();
- int v = vadj.getValue();
- int newh = h + panx;
- int newv = v + pany;
- if (newh < hadj.getMinimum())
- newh = hadj.getMinimum();
- if (newh > hadj.getMaximum() - hadj.getVisibleAmount())
- newh = hadj.getMaximum() - hadj.getVisibleAmount();
- if (newv < vadj.getMinimum())
- newv = vadj.getMinimum();
- if (newv > vadj.getMaximum() - vadj.getVisibleAmount())
- newv = vadj.getMaximum() - vadj.getVisibleAmount();
- if (newh == h && newv == v)
- return;
- if (newh != h)
- hadj.setValue(newh);
- if (newv != v)
- vadj.setValue(newv);
- }
- protected void smartMove(int direction, int moves) {
- cancelSearch();
- if (moves < 1)
- moves = 1;
- while (moves-- > 0)
- {
- Adjustable hadj = pageScroll.getHAdjustable();
- Adjustable vadj = pageScroll.getVAdjustable();
- int slop_x = hadj.getMaximum() / 20;
- int slop_y = vadj.getMaximum() / 20;
- if (direction > 0) {
- int remaining_x = hadj.getMaximum() - hadj.getValue() - hadj.getVisibleAmount();
- int remaining_y = vadj.getMaximum() - vadj.getValue() - vadj.getVisibleAmount();
- if (remaining_y > slop_y) {
- int value = vadj.getValue() + vadj.getVisibleAmount() * 9 / 10;
- if (value > vadj.getMaximum())
- value = vadj.getMaximum();
- vadj.setValue(value);
- } else if (remaining_x > slop_x) {
- vadj.setValue(vadj.getMinimum());
- int value = hadj.getValue() + hadj.getVisibleAmount() * 9 / 10;
- if (value > hadj.getMaximum())
- value = hadj.getMaximum();
- hadj.setValue(value);
- } else {
- doc.flipPages(+1, null);
- vadj.setValue(vadj.getMinimum());
- hadj.setValue(hadj.getMinimum());
- }
- } else {
- int remaining_x = Math.abs(hadj.getMinimum() - hadj.getValue());
- int remaining_y = Math.abs(vadj.getMinimum() - vadj.getValue());
- if (remaining_y > slop_y) {
- int value = vadj.getValue() - vadj.getVisibleAmount() * 9 / 10;
- if (value < vadj.getMinimum())
- value = vadj.getMinimum();
- vadj.setValue(value);
- } else if (remaining_x > slop_x) {
- vadj.setValue(vadj.getMaximum());
- int value = hadj.getValue() - hadj.getVisibleAmount() * 9 / 10;
- if (value < hadj.getMinimum())
- value = hadj.getMinimum();
- hadj.setValue(value);
- } else {
- doc.flipPages(-1, null);
- vadj.setValue(vadj.getMaximum());
- hadj.setValue(hadj.getMaximum());
- }
- }
- }
- }
- protected void flipPages(int number) {
- cancelSearch();
- doc.flipPages(number, null);
- }
- protected void gotoPage(int number) {
- cancelSearch();
- doc.gotoPage(number - 1, null);
- }
- protected void gotoLastPage() {
- cancelSearch();
- doc.gotoLastPage(null);
- }
- protected void relayout(int change) {
- int newEm = layoutEm + change;
- if (newEm < 6)
- newEm = 6;
- if (newEm > 36)
- newEm = 36;
- if (newEm == layoutEm)
- return;
- layoutEm = newEm;
- fontSizeLabel.setText(String.valueOf(layoutEm));
- doc.relayoutDocument(layoutWidth, layoutHeight, layoutEm, null);
- }
- public void actionPerformed(ActionEvent event) {
- Object source = event.getSource();
- if (source == firstButton)
- doc.gotoFirstPage(null);
- if (source == lastButton)
- doc.gotoLastPage(null);
- if (source == prevButton)
- doc.flipPages(-1, null);
- if (source == nextButton)
- doc.flipPages(+1, null);
- if (source == pageField) {
- doc.gotoPage(Integer.parseInt(pageField.getText()) - 1, null);
- pageCanvas.requestFocusInWindow();
- }
- if (source == searchField)
- search(searchDirection);
- if (source == searchNextButton)
- search(+1);
- if (source == searchPrevButton)
- search(-1);
- if (source == fontIncButton && doc != null && reflowable)
- relayout(+1);
- if (source == fontDecButton && doc != null && reflowable)
- relayout(-1);
- if (source == zoomOutButton) {
- zoomOut();
- pageCanvas.requestFocusInWindow();
- }
- if (source == zoomInButton) {
- zoomIn();
- pageCanvas.requestFocusInWindow();
- }
- }
- public void itemStateChanged(ItemEvent event) {
- Object source = event.getSource();
- if (source == zoomChoice) {
- zoomToLevel(zoomChoice.getSelectedIndex());
- pageCanvas.requestFocusInWindow();
- }
- if (source == outlineList) {
- int i = outlineList.getSelectedIndex();
- doc.gotoLocation(outline[i].location, null);
- pageCanvas.requestFocusInWindow();
- }
- }
- public void windowClosing(WindowEvent event) { dispose(); }
- public void windowActivated(WindowEvent event) { }
- public void windowDeactivated(WindowEvent event) { }
- public void windowIconified(WindowEvent event) { }
- public void windowDeiconified(WindowEvent event) { }
- public void windowOpened(WindowEvent event) { }
- public void windowClosed(WindowEvent event) { }
- public void save() {
- cancelSearch();
- SaveOptionsDialog dialog = new SaveOptionsDialog(this);
- dialog.populate();
- dialog.setLocationRelativeTo(this);
- dialog.setVisible(true);
- dialog.dispose();
- final String options = dialog.getOptions();
- if (options == null)
- {
- pageCanvas.requestFocusInWindow();
- return;
- }
- FileDialog fileDialog = new FileDialog(this, "MuPDF Save File", FileDialog.SAVE);
- fileDialog.setDirectory(System.getProperty("user.dir"));
- fileDialog.setFilenameFilter(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return Document.recognize(name);
- }
- });
- fileDialog.setFile(doc.documentPath);
- fileDialog.setVisible(true);
- fileDialog.dispose();
- if (fileDialog.getFile() == null)
- {
- pageCanvas.requestFocusInWindow();
- return;
- }
- final String selectedPath = new StringBuffer(fileDialog.getDirectory()).append(File.separatorChar).append(fileDialog.getFile()).toString();
- OCRmeter = new OCRProgressmeter(this, "Saving...", pages);
- OCRmeter.setLocationRelativeTo(this);
- OCRmeter.setVisible(true);
- pageCanvas.requestFocusInWindow();
- if (options.indexOf("ocr-language=") < 0)
- doc.save(selectedPath, options, OCRmeter, new ViewerCore.OnException() {
- public void run(Throwable t) {
- if (t instanceof IOException)
- exception(t);
- else if (t instanceof RuntimeException && !OCRmeter.cancelled)
- exception(t);
- }
- });
- else
- {
- try {
- FileStream fs = new FileStream(selectedPath, "rw");
- doc.save(fs, options, OCRmeter, new ViewerCore.OnException() {
- public void run(Throwable t) {
- if (t instanceof RuntimeException && !OCRmeter.cancelled)
- exception(t);
- }
- });
- } catch (IOException e) {
- exception(e);
- }
- }
- }
- public void onSaveComplete() {
- if (OCRmeter != null)
- OCRmeter.done();
- }
- class SaveOptionsDialog extends Dialog implements ActionListener, ItemListener, KeyListener {
- Checkbox snapShot = new Checkbox("Snapshot", false);
- Checkbox highSecurity = new Checkbox("High security", false);
- Choice resolution = new Choice();
- TextField language = new TextField("eng");
- Checkbox incremental = new Checkbox("Incremental", false);
- Checkbox prettyPrint = new Checkbox("Pretty print", false);
- Checkbox ascii = new Checkbox("Ascii", false);
- Checkbox decompress = new Checkbox("Decompress", false);
- Checkbox compress = new Checkbox("Compress", true);
- Checkbox compressImages = new Checkbox("Compress images", true);
- Checkbox compressFonts = new Checkbox("Compress fonts", true);
- Checkbox linearize = new Checkbox("Linearize", false);
- Checkbox garbageCollect = new Checkbox("Garbage collect", false);
- Checkbox cleanSyntax = new Checkbox("Clean syntax", false);
- Checkbox sanitizeSyntax = new Checkbox("Sanitize syntax", false);
- Choice encryption = new Choice();
- TextField userPassword = new TextField();
- TextField ownerPassword = new TextField();
- Button cancel = new Button("Cancel");
- Button save = new Button("Save");
- String options = null;
- public SaveOptionsDialog(Frame parent) {
- super(parent, "MuPDF Save Options", true);
- resolution.add("200dpi");
- resolution.add("300dpi");
- resolution.add("600dpi");
- resolution.add("1200dpi");
- encryption.add("Keep");
- encryption.add("None");
- encryption.add("RC4, 40bit");
- encryption.add("RC4, 128bit");
- encryption.add("AES, 128bit");
- encryption.add("AES, 256bit");
- snapShot.addItemListener(this);
- highSecurity.addItemListener(this);
- resolution.addItemListener(this);
- language.addActionListener(this);
- incremental.addItemListener(this);
- prettyPrint.addItemListener(this);
- ascii.addItemListener(this);
- decompress.addItemListener(this);
- compress.addItemListener(this);
- compressImages.addItemListener(this);
- compressFonts.addItemListener(this);
- linearize.addItemListener(this);
- garbageCollect.addItemListener(this);
- cleanSyntax.addItemListener(this);
- sanitizeSyntax.addItemListener(this);
- encryption.addItemListener(this);
- userPassword.addActionListener(this);
- ownerPassword.addActionListener(this);
- cancel.addActionListener(this);
- save.addActionListener(this);
- save.addKeyListener(this);
- calculateOptions();
- }
- void populate(Container container, GridBagConstraints c, Component component) {
- GridBagLayout gbl = (GridBagLayout) container.getLayout();
- gbl.setConstraints(component, c);
- container.add(component);
- }
- void populate() {
- GridBagConstraints c = new GridBagConstraints();
- c.fill = GridBagConstraints.BOTH;
- c.weightx = 1.0;
- c.gridwidth = GridBagConstraints.REMAINDER;
- GridBagLayout gbl = new GridBagLayout();
- setLayout(gbl);
- Panel left = new Panel();
- Panel right = new Panel();
- GridBagLayout lgbl = new GridBagLayout();
- GridBagLayout rgbl = new GridBagLayout();
- left.setLayout(lgbl);
- right.setLayout(rgbl);
- populate(left, c, snapShot);
- populate(left, c, highSecurity);
- populate(left, c, resolution);
- populate(left, c, language);
- populate(left, c, incremental);
- c.weighty = 1.5;
- populate(left, c, new Panel());
- c.weighty = 0.0;
- populate(left, c, prettyPrint);
- populate(left, c, ascii);
- populate(left, c, decompress);
- populate(left, c, compress);
- populate(left, c, compressImages);
- populate(left, c, compressFonts);
- populate(right, c, linearize);
- populate(right, c, garbageCollect);
- populate(right, c, cleanSyntax);
- populate(right, c, sanitizeSyntax);
- c.weighty = 1.5;
- populate(right, c, new Panel());
- c.weighty = 0.0;
- populate(right, c, new Label("Encryption"));
- populate(right, c, encryption);
- populate(right, c, new Label("User password"));
- populate(right, c, userPassword);
- populate(right, c, new Label("Owner password"));
- populate(right, c, ownerPassword);
- c.gridwidth = GridBagConstraints.REMAINDER;
- populate(this, c, new Panel());
- c.gridwidth = 1;
- populate(this, c, left);
- c.gridwidth = GridBagConstraints.REMAINDER;
- populate(this, c, right);
- c.gridwidth = GridBagConstraints.REMAINDER;
- populate(this, c, new Panel());
- c.gridwidth = 1;
- populate(this, c, cancel);
- c.gridwidth = GridBagConstraints.REMAINDER;
- populate(this, c, save);
- pack();
- setResizable(false);
- save.requestFocusInWindow();
- }
- public void keyPressed(KeyEvent e) { }
- public void keyReleased(KeyEvent e) { }
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\u001b')
- cancel();
- else if (e.getKeyChar() == '\n')
- save();
- }
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == cancel)
- cancel();
- else if (e.getSource() == save)
- save();
- }
- void cancel() {
- options = null;
- setVisible(false);
- }
- void save() {
- setVisible(false);
- }
- public void itemStateChanged(ItemEvent e) {
- calculateOptions();
- }
- void calculateOptions() {
- boolean isPDF = false;
- boolean canBeSavedIncrementally = false;
- boolean isRedacted = false;
- if (isPDF && !canBeSavedIncrementally)
- incremental.setState(false);
- if (highSecurity.getState()) {
- incremental.setState(false);
- prettyPrint.setState(false);
- ascii.setState(false);
- decompress.setState(false);
- compress.setState(true);
- compressImages.setState(false);
- compressFonts.setState(false);
- linearize.setState(false);
- garbageCollect.setState(false);
- cleanSyntax.setState(false);
- sanitizeSyntax.setState(false);
- encryption.select("None");
- userPassword.setText("");
- ownerPassword.setText("");
- } else if (incremental.getState()) {
- linearize.setState(false);
- garbageCollect.setState(false);
- cleanSyntax.setState(false);
- sanitizeSyntax.setState(false);
- encryption.select("Keep");
- userPassword.setText("");
- ownerPassword.setText("");
- }
- highSecurity.setEnabled(snapShot.getState() == false);
- resolution.setEnabled(snapShot.getState() == false && highSecurity.getState() == true);
- language.setEnabled(snapShot.getState() == false && highSecurity.getState() == true);
- incremental.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && isPDF && canBeSavedIncrementally);
- prettyPrint.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- ascii.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- decompress.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- compress.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- compressImages.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- compressFonts.setEnabled(snapShot.getState() == false && highSecurity.getState() == false);
- linearize.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false);
- garbageCollect.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false);
- cleanSyntax.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false);
- sanitizeSyntax.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false);
- encryption.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false);
- userPassword.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false && encryption.getSelectedItem() != "Keep" && encryption.getSelectedItem() != "None");
- ownerPassword.setEnabled(snapShot.getState() == false && highSecurity.getState() == false && incremental.getState() == false && encryption.getSelectedItem() != "Keep" && encryption.getSelectedItem() != "None");
- if (incremental.getState()) {
- garbageCollect.setState(false);
- linearize.setState(false);
- cleanSyntax.setState(false);
- sanitizeSyntax.setState(false);
- encryption.select("Keep");
- }
- StringBuilder opts = new StringBuilder();
- if (highSecurity.getState()) {
- opts.append(",compression=flate");
- opts.append(",resolution=");
- opts.append(resolution.getSelectedItem());
- opts.append(",ocr-language=");
- opts.append(language.getText());
- } else {
- if (decompress.getState()) opts.append(",decompress=yes");
- if (compress.getState()) opts.append(",compress=yes");
- if (compressFonts.getState()) opts.append(",compress-fonts=yes");
- if (compressImages.getState()) opts.append(",compress-images=yes");
- if (ascii.getState()) opts.append(",ascii=yes");
- if (prettyPrint.getState()) opts.append(",pretty=yes");
- if (linearize.getState()) opts.append(",linearize=yes");
- if (cleanSyntax.getState()) opts.append(",clean=yes");
- if (sanitizeSyntax.getState()) opts.append(",sanitize=yes");
- if (encryption.getSelectedItem() == "None") opts.append(",decrypt=yes");
- if (encryption.getSelectedItem() == "Keep") opts.append(",decrypt=no");
- if (encryption.getSelectedItem() == "None") opts.append(",encrypt=no");
- if (encryption.getSelectedItem() == "Keep") opts.append(",encrypt=keep");
- if (encryption.getSelectedItem() == "RC4, 40bit") opts.append(",encrypt=rc4-40");
- if (encryption.getSelectedItem() == "RC4, 128bit") opts.append(",encrypt=rc4-128");
- if (encryption.getSelectedItem() == "AES, 128bit") opts.append(",encrypt=aes-128");
- if (encryption.getSelectedItem() == "AES, 256bit") opts.append(",encrypt=aes-256");
- if (userPassword.getText().length() > 0) {
- opts.append(",user-password=");
- opts.append(userPassword.getText());
- }
- if (ownerPassword.getText().length() > 0) {
- opts.append(",owner-password=");
- opts.append(ownerPassword.getText());
- }
- opts.append(",permissions=-1");
- if (garbageCollect.getState() && isPDF && isRedacted)
- opts.append(",garbage=yes");
- else
- opts.append(",garbage=compact");
- }
- if (opts.charAt(0) == ',')
- opts.deleteCharAt(0);
- options = opts.toString();
- }
- String getOptions() {
- return options;
- }
- }
- class Progressmeter extends Dialog implements ActionListener, KeyListener {
- Label info = new Label("", Label.CENTER);
- Button cancel = new Button("Cancel");
- boolean cancelled = false;
- boolean done = false;
- public Progressmeter(Frame parent, String title, boolean modal, String initialText) {
- super(parent, title, modal);
- setLayout(new GridLayout(2, 1));
- info.setText(initialText);
- add(info);
- cancel.addActionListener(this);
- cancel.addKeyListener(this);
- add(cancel);
- pack();
- setResizable(false);
- cancel.requestFocusInWindow();
- }
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == cancel)
- cancel();
- }
- public void keyPressed(KeyEvent e) { }
- public void keyReleased(KeyEvent e) { }
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\u001b')
- cancel();
- }
- public void cancel() {
- cancelled = true;
- }
- public void done() {
- done = true;
- }
- public boolean progress(String text) {
- info.setText(text);
- return cancelled || done;
- }
- }
- class OCRProgressmeter extends Progressmeter implements DocumentWriter.OCRListener {
- int pages;
- public OCRProgressmeter(Frame parent, String title, int pages) {
- super(parent, title, true, "Progress: Page 65535/65535: 100%");
- this.pages = pages;
- progress(-1, 0);
- setVisible(true);
- }
- public void done() {
- super.done();
- setVisible(false);
- dispose();
- }
- public boolean progress(int page, int percent) {
- StringBuilder text = new StringBuilder();
- if (page >= 0 || pages >= 0) {
- text.append("Page ");
- if (page >= 0)
- text.append(page + 1);
- else
- text.append("?");
- }
- if (pages >= 0) {
- text.append("/");
- text.append(pages);
- text.append(": ");
- }
- text.append(percent);
- text.append("%");
- return progress(text.toString());
- }
- }
- class RenderProgressmeter extends Progressmeter {
- Cookie cookie;
- public RenderProgressmeter(Frame parent, String title, Cookie cookie, final int update) {
- super(parent, title, false, "Progress: 100%");
- this.cookie = cookie;
- (new Thread() {
- public void run() {
- try {
- int slept = 0;
- while (!progress(slept))
- {
- sleep(update);
- slept += update;
- }
- } catch (InterruptedException e) {
- }
- }
- }).start();
- }
- public void cancel() {
- super.cancel();
- cookie.abort();
- }
- public boolean progress(int slept) {
- int progress = cookie.getProgress();
- int max = cookie.getProgressMax();
- if (max <= 0 && progress < 100)
- max = 100;
- else if (max <= 0 && progress > 100)
- {
- int v = progress;
- max = 10;
- while (v > 10)
- {
- v /= 10;
- max *= 10;
- }
- }
- if (progress >= max)
- done = true;
- int percent = (int) ((float) progress / max * 100.0f);
- StringBuilder text = new StringBuilder();
- text.append("Progress: ");
- text.append(percent);
- text.append("%");
- if (slept > 0)
- setVisible(true);
- if (progress(text.toString()))
- {
- setVisible(false);
- dispose();
- return true;
- }
- return false;
- }
- }
- public static void main(String[] args) {
- String selectedPath;
- if (args.length <= 0) {
- FileDialog fileDialog = new FileDialog((Frame)null, "MuPDF Open File", FileDialog.LOAD);
- fileDialog.setDirectory(System.getProperty("user.dir"));
- fileDialog.setFilenameFilter(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return Document.recognize(name);
- }
- });
- fileDialog.setVisible(true);
- if (fileDialog.getFile() == null)
- System.exit(0);
- selectedPath = new StringBuffer(fileDialog.getDirectory()).append(File.separatorChar).append(fileDialog.getFile()).toString();
- fileDialog.dispose();
- } else {
- selectedPath = args[0];
- }
- try {
- Viewer app = new Viewer(selectedPath);
- app.setVisible(true);
- } catch (Exception e) {
- messageBox(null, "MuPDF Error", "Cannot open \"" + selectedPath + "\": " + e.getMessage() + ".");
- System.exit(1);
- }
- }
- public float getRetinaScale() {
- // first try Oracle's VM (we should also test for 1.7.0_40 or higher)
- final String vendor = System.getProperty("java.vm.vendor");
- boolean isOracle = vendor != null && vendor.toLowerCase().contains("Oracle".toLowerCase());
- if (isOracle) {
- GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice device = env.getDefaultScreenDevice();
- try {
- Field field = device.getClass().getDeclaredField("scale");
- if (field != null) {
- field.setAccessible(true);
- Object scale = field.get(device);
- if (scale instanceof Integer && ((Integer)scale).intValue() == 2)
- return 2.0f;
- }
- }
- catch (Exception ignore) {
- }
- return 1.0f;
- }
- // try Apple VM
- final Float scaleFactor = (Float)Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor");
- if (scaleFactor != null && scaleFactor.intValue() == 2)
- return 2.0f;
- return 1.0f;
- }
- public int getScreenDPI() {
- try {
- return Toolkit.getDefaultToolkit().getScreenResolution();
- } catch (HeadlessException e) {
- return 72;
- }
- }
- public Dimension getScreenSize() {
- try {
- return Toolkit.getDefaultToolkit().getScreenSize();
- } catch (HeadlessException e) {
- return new Dimension(1920, 1080);
- }
- }
- protected static class OutlineItem {
- protected String title;
- protected String uri;
- protected int page;
- public OutlineItem(String title, String uri, int page) {
- this.title = title;
- this.uri = uri;
- this.page = page;
- }
- public String toString() {
- return title;
- }
- }
- public String askPassword() {
- return passwordDialog(null, "Password");
- }
- public void onChapterCountChange(int chapters) {
- this.chapters = chapters;
- }
- public void onPageCountChange(int pages) {
- this.pages = pages;
- pageLabel.setText("/ " + pages);
- }
- public void onPageChange(Location page, int chapterNumber, int pageNumber, Rect bbox) {
- this.location = page;
- this.chapterNumber = chapterNumber;
- this.pageNumber = pageNumber;
- this.bbox = bbox;
- if (pageNumber >= 0 && pageNumber < pages)
- pageField.setText(String.valueOf(pageNumber + 1));
- else
- pageField.setText("");
- render();
- }
- public void onReflowableChange(boolean reflowable) {
- this.reflowable = reflowable;
- fontIncButton.setEnabled(reflowable);
- fontDecButton.setEnabled(reflowable);
- fontSizeLabel.setEnabled(reflowable);
- }
- public void onLayoutChange(int width, int height, int em) {
- }
- public void onOutlineChange(ViewerCore.OutlineItem[] outline) {
- boolean hadOutline = this.outline != null;
- this.outline = outline;
- outlineList.removeAll();
- if (outline != null)
- for (int i = 0; i < outline.length; i++)
- outlineList.add(outline[i].title);
- if (hadOutline)
- outlinePanel.setVisible(outline != null);
- }
- public void onPageContentsChange(Pixmap pixmap, Rect[] links, String[] linkURIs, Quad[][] hits) {
- this.pixmap = pixmap;
- this.links = links;
- this.linkURIs = linkURIs;
- this.hits = hits;
- redraw();
- if (renderMeter != null)
- renderMeter.done();
- }
- public void onSearchStart(Location startPage, Location finalPage, int direction, String needle) {
- searchField.setEnabled(false);
- }
- public void onSearchPage(Location page, String needle) {
- String text;
- if (chapters > 1)
- text = "Searching " + (page.chapter + 1) + "/" + chapters + "-" + page.page + "/" + pages;
- else
- text = "Searching " + page.page + "/" + pages;
- searchStatus.setText(text);
- searchStatusPanel.validate();
- }
- public void onSearchStop(String needle, Location page) {
- searchField.setEnabled(true);
- searchNextButton.setEnabled(true);
- searchPrevButton.setEnabled(true);
- if (page != null) {
- doc.gotoLocation(page, null);
- searchStatus.setText("");
- } else if (needle != null)
- searchStatus.setText("Search text not found.");
- else
- searchStatus.setText("");
- searchStatusPanel.validate();
- pageCanvas.requestFocusInWindow();
- }
- public void onSearchCancelled() {
- searchField.setEnabled(true);
- searchNextButton.setEnabled(true);
- searchPrevButton.setEnabled(true);
- searchStatus.setText("");
- searchStatusPanel.validate();
- }
- public void onOutlineItemChange(int index) {
- if (index == -1) {
- int selected = outlineList.getSelectedIndex();
- if (selected >= 0)
- outlineList.deselect(selected);
- } else {
- outlineList.makeVisible(index);
- outlineList.select(index);
- }
- }
- public void onMetadataChange(String title, String author, String format, String encryption) {
- this.title = title;
- this.author = author;
- this.format = format;
- this.encryption = encryption;
- }
- public void onPermissionsChange(boolean print, boolean copy, boolean edit, boolean annotate, boolean form, boolean accessibility, boolean assemble, boolean printHq) {
- this.print = print;
- this.copy = copy;
- this.edit = edit;
- this.annotate = annotate;
- this.form = form;
- this.accessibility = accessibility;
- this.assemble = assemble;
- this.printHq = printHq;
- }
- public void onLinearizedChange(boolean linearized) {
- this.linearized = linearized;
- }
- public void onUpdatesChange(int updates, int firstUpdate) {
- this.updates = updates;
- this.firstUpdate = firstUpdate;
- }
- }
|