pax_global_header00006660000000000000000000000064126425601400014512gustar00rootroot0000000000000052 comment=4e3c5582d94af12112edcd8142020fe022200f7c djview4-4.10.5/000077500000000000000000000000001264256014000131555ustar00rootroot00000000000000djview4-4.10.5/.gitignore000066400000000000000000000002231264256014000151420ustar00rootroot00000000000000.libs/ /.pc/ /BUILD* /INSTALL /aclocal.m4 /autom4te.cache/ /config.h /config.log /config.status /configure /libtool /stamp-h1 Makefile Makefile.in djview4-4.10.5/AUTHORS000066400000000000000000000014561264256014000142330ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ djview4-4.10.5/COPYING000066400000000000000000000431051264256014000142130ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. djview4-4.10.5/COPYRIGHT000066400000000000000000000044571264256014000144620ustar00rootroot00000000000000 ==================================================================== DjView4 Copyright (c) 2006- Leon Bottou This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, either version 2 of the license or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111, USA. ==================================================================== Remark1: This program depends on the DjVuLibre library. Starting with version 3.5.19, DjVuLibre is released under the GNU General Public License, either version 2 or (at your option) any later version. Prior to version 3.5.19, DjVuLibre was released under the GNU General Public License, version 2. Remark2: Part of this software is derived from 'tiff2pdf' which comes with the following notice: | Copyright (c) 2003 Ross Finlayson | | Permission to use, copy, modify, distribute, and sell this software and | its documentation for any purpose is hereby granted without fee, provided | that (i) the above copyright notices and this permission notice appear in | all copies of the software and related documentation, and (ii) the name of | Ross Finlayson may not be used in any advertising or | publicity relating to the software without the specific, prior written | permission of Ross Finlayson. | | THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | | IN NO EVENT SHALL ROSS FINLAYSON BE LIABLE FOR | ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | OF THIS SOFTWARE. djview4-4.10.5/ChangeLog000066400000000000000000000000161264256014000147240ustar00rootroot00000000000000See file NEWS djview4-4.10.5/Makefile.am000066400000000000000000000007241264256014000152140ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I config SUBDIRS = src if WANT_NSDEJAVU SUBDIRS += nsdejavu endif if WANT_NPDJVU SUBDIRS += npdjvu endif if WANT_DESKTOPFILES SUBDIRS += desktopfiles endif if WANT_MAC SUBDIRS += mac endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status libtool EXTRA_DIST = COPYRIGHT EXTRA_DIST += README README_translations EXTRA_DIST += autogen.sh djview4.spec EXTRA_DIST += config/qmsilent.awk EXTRA_DIST += config/qmsources.awk EXTRA_DIST += debian djview4-4.10.5/NEWS000066400000000000000000000052731264256014000136630ustar00rootroot00000000000000 NEW IN VERSION 4.10 ------------------- - Bug fixes: layout, usability, preferences, locale selection - Works with both Qt4 and Qt5 - Build uses automake/qmake hybrid (instead of autoconf/qmake). - Layout annotations are honored in multipage mode - Experimental OpenGL rendering - Slideshow mode NEW IN VERSION 4.9 ------------------ - Added language selection in preference. - Added option to override printing and saving restrictions. - Automatic reloading of djvu documents when the file is changed. - New chinese translations. - Improved network code (needs Qt>=4.4.) - Remember the last visited position for the last 50 documents. NEW IN VERSION 4.8 -------------------- - Added option to invert luminance. - Added shortcut ctrl+g to go to the page combo. - Fixed export issues under win32. - Mouse wheel can be configured to control the zoom. - Animated page movements. NEW IN VERSION 4.7 -------------------- - Fix for crash on quick PgUp PgDn sequences. - Fix scrollbars in continuous mode. - Fix plugin for some webkit based browsers. NEW IN VERSION 4.6 -------------------- - Show total page number in page combo and page info box. - Decode percent encoding in annotation and outline hyperlinks. - Properly handle non-ascii filenames in export and save dialogs. - Subtle changes to PgUp/PgDn/Home/End/Space/Backspace view changes. - Fixed suffix management in export/save/print dialogs. NEW IN VERSION 4.5 -------------------- - Fixed priority of annotation options. - Fixed plugin for recent versions of gcc. - Added showposition in advanced option copyUrl. - New advanced mode to display hidden text. - Lens display annotations and hidden text. - Nsdejavu can use the XEmbed protocol when available. - Plugin is scriptable from JavaScript. NEW IN VERSION 4.4 -------------------- - Full session management under X11. - Added advanced feature check box. - Added advanced command to copy urls, outline, etc. - New translation (russian) - History in the find dialog. - Option to display hidden text in status bar. - Option to display the first page alone in side-by-side mode. - Option to display side-by-side in right-to-left mode. - Drag'n drop files into the viewer. - Support for Lizardtech's plugin option -showposition. NEW IN VERSION 4.3 ------------------ - Undo/Redo - New translations (german,czech) - Fixed double free bug in plugin mode. NEW IN VERSION 4.2 ------------------ - Better support of Qt/Mac - Escape can be used to exit full screen mode - Recent files menu - Open Location NEW IN VERSION 4.1 ------------------ - Fixes for Qt 4.2 and 4.3. - Fixes to enable compilation on Windows. - TIFF and PDF export. - New translation (ukrainian) NEW IN VERSION 4.0 ------------------ - Initial release djview4-4.10.5/README000066400000000000000000000156011264256014000140400ustar00rootroot00000000000000 1- DJVIEW4 ========== 1.1 - DJVIEW4 ------------- This package contains the djview4 viewer and browser plugin. This new viewer relies on the DjVulibre library and the Qt toolkit. Highlights: - entirely based on the public djvulibre api. - entirely written in portable Qt4/Qt5. - works natively under Unix/X11, MS Windows, and MacOS X. - continuous scrolling of pages - side-by-side display of pages - ability to specify a url to the djview command - all plugin and cgi options available from the command line - all silly annotations implemented - display thumbnails as a grid - display outlines - page names supported (see djvused command set-page-title) - metadata dialog (see djvused command set-meta) - implemented as reusable Qt widgets Prerequisites: - DjVuLibre >= 3.5.18 - Qt >= 4.4 1.2 - USING DJVIEW4 AS A PLUGIN ------------------------------- Under Unix/X11, djview4 can be used as a browser plugin by means of the small shared library named nsdejavu.so. The djview3 distributed with djvulibre uses the same approach. In fact both djview3 and djview4 communicate with nsdejavu.so with the same protocol. You can either install the file nsdejavu.so that comes with djview3 or the one that comes with djview4. The file nsdejavu.so uses the viewer specified with the environment variable NPX_DJVIEW or searches an executable viewer named djview, djview4 or djview3. 2- INSTALLATION FROM SOURCES ============================ 2.1 PREREQUISITES ----------------- You need DjVuLibre (>= 3.5.18) See http://djvu.sourceforge.net for the source code and for pointers to binary packages. Under debian type "apt-get install libdjvulibre-dev" You need Qt4 (>= 4.4.0) or QT5 (tested with 5.2) See http://trolltech.com for the source code. Select the version of Qt adapted to your platform. Under debian type "apt-get install libqt4-dev qt4-dev-tools Under Unix the configure script uses pkg-config to locate the DjVuLibre library and its ancillary files. See http://pkgconfig.freedesktop.org. If you do not have pkg-config, you will have to specify which compilation options using the variabled DDJVUAPI_CFLAGS and DDJVUAPI_LIBS. 2.2 COMPILING AND INSTALLING UNDER UNIX --------------------------------------- First run the script 'configure' to generate the makefiles. Command 'configure --help' list options and environment variables that affect the generation of makefile. The most useful ones are: --prefix= Indicate the base directory for installing djview. The default prefix is /usr/local. Binary packages are usually compiled with prefix /usr. --mandir= Indicates where the man pages go. The default is ${prefix}/man but many systems prefer to install man pages in ${prefix}/share/man. PKG_CONFIG_PATH= Indicates the path for search pkg-config description files. The default path is /usr/lib/pkgconfig:/usr/share/pkgconfig. If you have installed DjVuLibre with a prefix different from /usr, you probably want to add ${prefix}/lib/pkgconfig to this path. DDJVUAPI_CFLAGS= Compiler flags for using the DjVuLibre api. This is useful when you do not have pkg-config or when pkg-config does not locate DjVuLibre. DDJVUAPI_LIBS= Linker flags for using the DjVuLibre api. This is useful when you do not have pkg-config or when pkg-config does not locate DjVuLibre. QMAKE= Indicate the location of the Qt4 qmake executable. This is useful when configure cannot locate Qt4. Running configure creates all the required makefiles and executes command qmake in directory src. You can then compile djview4 with command % make Once the compilation is successful, install the binaries with % make install 2.3 COMPILATION HINTS FOR MAC OS X ---------------------------------- In general you can compile the standalone viewer djview4 on non unix platforms. However the browser plugin capability is currently not working on non X11 systems. We recommend the following procedure to compile on the Mac. 1) Install the Qt 5.x SDK. 2) Install Homebrew with the following packages $ brew install autoconf automake libtool pkg-config $ brew install jpeg libtiff git 4) Install the djvulibre Homebrew package $ brew install djvulibre Advanced: If you want to compile a fresh version of djvulibre, you can use the instructions found in the djvulibre tarball. An interesting alternative is to install the current djvulibre development version using the Homebrew command, $ brew install --HEAD djvulibre but you might find that the brew recipe is out of date. 5) Get the djview source from the git repository $ git clone git://git.code.sf.net/p/djvu/djview-git djvulibre-djview $ cd djvulibre-djview Configure with command $ ./autogen.sh --enable-mac QMAKE= Then compile with command $ make 6) Prepare the djview.app bundle and the dmg file $ cd mac $ ./make_djview_bundle.sh $ ./make_djview_dmg.sh 2.4 COMPILATION HINTS FOR WINDOWS ----------------------------------- In general you can compile the standalone viewer djview4 on non unix platforms. However the browser plugin capability is currently not working on non X11 systems. You will need to compile DjVuLibre. You will need the appropriate version of Qt. There are also two ways to compile djview under Windows. * Using Visual C++ - First you need to compile Qt4 using Visual C++. This used to be require patching the Qt source Starting with Qt-4.3.2, the opensource Qt version supports Visual C++ right out of the box. - Compile djvulibre using the visual C++ method. - Go to directory src - Type command $ qmake -win32 -tp vc to generate a MS Visual C++ project file. - Tweak the project file to properly link with the djvulibre library and the tiff library. One good way to do so is to open the file "djvulibre.sln" that comes with the cvs version of djvulibre. Then add the project "djview.vcproj" and insert the property sheets "dirs", "warnings", "libtiff" and "tools" found in the djvulibre-3.5/win32/djvulibre directory. You also need to add the references to libdjvulibre and libtiff. This works well despite requiring a lot of clicks. * Using the MINGW compiler (not recommended) - Install the binary version of Qt4. - Install the mingw version of zlib, libtiff, libjpeg. - Compile djvulibre using the configure method. - Go to directory djview4/src. - Type command $ qmake DEFINES+=HAVE_TIFF \ LIBS+="-L$HOME/djvulibre-3.5/libdjvu/.libs -ldjvulibre -ltiff" \ QMAKE_CXXFLAGS+="-I$HOME/djvulibre-3.5" where you replace the paths by the actual djvulibre paths. - Then compile using $ mingw32-make SHELL=cmd.exe djview4-4.10.5/README_translations000066400000000000000000000032121264256014000166340ustar00rootroot00000000000000 HOW TO CREATE NEW TRANSLATION FILES FOR DJVIEW. ----------------------------------------------- - Determine the language code for your language. Sometimes language codes have suffixes in capital letters for describing variants. But we always use lowercase. For instance, use 'zh_cn' or 'zh_tw' for the two variants of chinese. In the following explanation we assume 'de' for german. - Go to directory 'src' $ cd src - Add the following line into file 'djview.pro' TRANSLATIONS += djview_de.ts - Run the Qt program 'lupdate' $ lupdate djview.pro - A file named djview_de.ts must have been created. You must edit the translations using the Qt program 'linguist'. $ linguist djview_de.ts See the linguist documentation in the Qt documentation. Alternatively you can use 'kbabel' to edit the ts file. - Run the Qt program 'lrelease' $ lrelease djview.pro - You should have now a file named 'djview_de.qm'. To test your translations, type $ LANGUAGE=de ./djview - Once you are satisfied, send me your translation file 'djview_de.ts' by email (leonb@users.sourceforge.net) Thanks. CONTRIBUTORS ------------ Translations for djview were contributed by: djview_cs.ts Petr Pisar djview_de.ts Marc Feld djview_es.ts Mike Molina djview_fr.ts Leon Bottou djview_ru.ts Alexander Potashev djview_uk.ts Yuri Chornoivan djview_zh_CN/TW.ts Lee Chenhwa djview4-4.10.5/autogen.sh000077500000000000000000000003571264256014000151630ustar00rootroot00000000000000#! /bin/sh awk -f config/qmsources.awk < src/djview.pro > src/djview.am awk -f config/qmsources.awk < npdjvu/npdjvu.pro > npdjvu/npdjvu.am autoreconf -f -i -v --warnings=all || exit 1 if [ -z "$NOCONFIGURE" ]; then ./configure "$@" fi djview4-4.10.5/config/000077500000000000000000000000001264256014000144225ustar00rootroot00000000000000djview4-4.10.5/config/.gitignore000066400000000000000000000002601264256014000164100ustar00rootroot00000000000000/*.dh-orig /ar-lib /compile /config.guess /config.h.in /config.sub /depcomp /install-sh /libtool.m4 /ltmain.sh /ltoptions.m4 /ltsugar.m4 /ltversion.m4 /lt~obsolete.m4 /missing djview4-4.10.5/config/acinclude.m4000066400000000000000000000270371264256014000166240ustar00rootroot00000000000000dnl Copyright (c) 2002 Leon Bottou and Yann Le Cun. dnl Copyright (c) 2001 AT&T dnl dnl Most of these macros are derived from macros listed dnl at the GNU Autoconf Macro Archive dnl http://www.gnu.org/software/ac-archive/ dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111 USA dnl dnl ------------------------------------------------------- dnl @synopsis AC_DEFINE_VERSION dnl Defines a hexadecimal version number dnl ------------------------------------------------------- AC_DEFUN([AC_DEFINE_VERSION], [ IFS=. read major minor revis <<__eof__ $1 __eof__ test -z "$major" && major=0 test -z "$minor" && minor=0 test -z "$revis" && revis=0 hexversion=`printf '0x%x%02x%02x' $major $minor $revis` AC_DEFINE_UNQUOTED(DJVIEW_VERSION,[$hexversion],[hexadecimal version number]) AC_DEFINE_UNQUOTED(DJVIEW_VERSION_STR, ["$1"], [string]) AC_DEFINE_UNQUOTED(RC_VERSION,[$major,$minor,$revis,0],[rc file version number]) AC_DEFINE_UNQUOTED(RC_VERSION_STR,["$major,$minor,$revis,0\0"],[rc file version string]) ]) dnl ------------------------------------------------------- dnl @synopsis AC_CHECK_CXX_OPT(OPTION, dnl ACTION-IF-OKAY,ACTION-IF-NOT-OKAY) dnl Check if compiler accepts option OPTION. dnl ------------------------------------------------------- AC_DEFUN([AC_CHECK_CXX_OPT],[ opt="$1" AC_MSG_CHECKING([if $CXX accepts $opt]) echo 'void f(){}' > conftest.cc if test -z "`${CXX} ${CXXFLAGS} ${OPTS} $opt -c conftest.cc 2>&1`"; then AC_MSG_RESULT(yes) rm conftest.* $2 else AC_MSG_RESULT(no) rm conftest.* $3 fi ]) dnl ------------------------------------------------------- dnl @synopsis AC_CXX_OPTIMIZE dnl Setup option --enable-debug dnl Collects optimization/debug option in variable OPTS dnl Filter options from CFLAGS and CXXFLAGS dnl ------------------------------------------------------- AC_DEFUN([AC_CXX_OPTIMIZE],[ AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Compile with debugging options (default: no)]), [ac_debug=$enableval],[ac_debug=no]) OPTS= AC_SUBST(OPTS) saved_CXXFLAGS="$CXXFLAGS" saved_CFLAGS="$CFLAGS" CXXFLAGS= CFLAGS= for opt in $saved_CXXFLAGS ; do case $opt in -g*) test $ac_debug != no && OPTS="$OPTS $opt" ;; -O*) ;; *) CXXFLAGS="$CXXFLAGS $opt" ;; esac done for opt in $saved_CFLAGS ; do case $opt in -O*|-g*) ;; *) CFLAGS="$CFLAGS $opt" ;; esac done if test x$ac_debug = xno ; then OPTS=-DNDEBUG AC_CHECK_CXX_OPT([-Wall],[OPTS="$OPTS -Wall"]) AC_CHECK_CXX_OPT([-O2],[OPTS="$OPTS -O2"]) else AC_CHECK_CXX_OPT([-Wall],[OPTS="$OPTS -Wall"]) fi ]) dnl ------------------------------------------------------------------ dnl @synopsis AC_PATH_TIFF([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl Process option --with-tiff dnl Search LIBTIFF. Define HAVE_TIFF. dnl Set output variable TIFF_CFLAGS and TIFF_LIBS dnl ------------------------------------------------------------------ AC_DEFUN([AC_PATH_TIFF], [ AC_ARG_VAR(TIFF_LIBS, [Libraries for tiff]) AC_ARG_VAR(TIFF_CFLAGS, [Compilation flags for tiff]) ac_tiff=no AC_ARG_WITH(tiff, AS_HELP_STRING([--with-tiff=DIR], [where libtiff is located]), [ac_tiff=$withval], [ac_tiff=yes] ) # Process specification if test x$ac_tiff = xyes ; then test x${TIFF_LIBS+set} != xset && TIFF_LIBS="-ltiff" elif test x$ac_tiff != xno ; then test x${TIFF_LIBS+set} != xset && TIFF_LIBS="-L$ac_tiff/lib -ltiff" test x${TIFF_CFLAGS+set} != xset && TIFF_CFLAGS="-I$ac_tiff/include" fi # Try linking if test x$ac_tiff != xno ; then AC_MSG_CHECKING([for the libtiff library]) save_CFLAGS="$CFLAGS" save_CXXFLAGS="$CXXFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $TIFF_CFLAGS" CXXFLAGS="$CXXFLAGS $TIFF_CFLAGS" LIBS="$LIBS $TIFF_LIBS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef __cplusplus extern "C" { #endif #include #include #ifdef __cplusplus } #endif ]], [ TIFFOpen(0,0); ])], [ac_tiff=yes], [ac_tiff=no]) CFLAGS="$save_CFLAGS" CXXFLAGS="$save_CXXFLAGS" LIBS="$save_LIBS" AC_MSG_RESULT($ac_tiff) fi # Finish if test x$ac_tiff = xno; then TIFF_CFLAGS= ; TIFF_LIBS= ifelse([$2],,:,[$2]) else AC_DEFINE(HAVE_TIFF,1,[Define if you have libtiff.]) ifelse([$1],,:,[$1]) fi ]) dnl ------------------------------------------------------------------ dnl @synopsis AC_PROG_PKG_CONFIG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl Sets output variables PKG_CONFIG dnl ------------------------------------------------------------------ AC_DEFUN([AC_PROG_PKG_CONFIG], [ AC_ARG_VAR(PKG_CONFIG,[Location of the pkg-config program.]) AC_ARG_VAR(PKG_CONFIG_PATH, [Path for pkg-config descriptors.]) AC_PATH_PROG(PKG_CONFIG, pkg-config) if test -z "$PKG_CONFIG" ; then ifelse([$2],,:,[$2]) else ifelse([$1],,:,[$1]) fi ]) dnl ------------------------------------------------------------------ dnl @synopsis AC_PATH_DDJVUUAPI([action-if-found],[action-if-notfound]) dnl Search for ddjvuapi. Defines HAVE_DDJVUAPI. dnl Sets output variables DDJVUAPI_CFLAGS and DDJVUAPI_LIBS dnl ------------------------------------------------------------------ AC_DEFUN([AC_PATH_DDJVUAPI], [ AC_REQUIRE([AC_PROG_PKG_CONFIG]) AC_ARG_VAR(DDJVUAPI_LIBS, [Libraries for ddjvuapi]) AC_ARG_VAR(DDJVUAPI_CFLAGS, [Compilation flags for ddjvuapi]) AC_MSG_CHECKING([for ddjvuapi]) if test -n "$DDJVUAPI_LIBS" ; then AC_MSG_RESULT([user defined]) AC_MSG_RESULT([using DDJVUAPI_LIBS=$DDJVUAPI_LIBS]) AC_MSG_RESULT([using DDJVUAPI_CFLAGS=$DDJVUAPI_CFLAGS]) elif test -x "$PKG_CONFIG" ; then if $PKG_CONFIG ddjvuapi ; then ac_ddjvuapi=yes AC_MSG_RESULT([found]) DDJVUAPI_LIBS=`$PKG_CONFIG --libs ddjvuapi` DDJVUAPI_CFLAGS=`$PKG_CONFIG --cflags ddjvuapi` AC_DEFINE(HAVE_DDJVUAPI,1,[Define if you have ddjvuapi.]) ifelse([$1],,:,[$1]) else AC_MSG_RESULT([not found by pkg-config]) ac_ddjvuapi=no ifelse([$2],,:,[$2]) fi else AC_MSG_RESULT([no pkg-config]) ac_ddjvuapi=no ifelse([$2],,:,[$2]) fi ]) dnl ------------------------------------------------------------------ dnl @synopsis AC_PATH_GLIB([action-if-found],[action-if-notfound]) dnl Search for glib. Defines HAVE_GLIB. dnl Sets output variables GLIB_CFLAGS and GLIB_LIBS dnl ------------------------------------------------------------------ AC_DEFUN([AC_PATH_GLIB], [ AC_REQUIRE([AC_PROG_PKG_CONFIG]) AC_ARG_VAR(GLIB_LIBS, [Libraries for glib-2.0]) AC_ARG_VAR(GLIB_CFLAGS, [Compilation flags for glib-2.0]) AC_MSG_CHECKING([for glib]) if test -x "$PKG_CONFIG" ; then if $PKG_CONFIG glib-2.0 ; then ac_glib=yes AC_MSG_RESULT([found]) GLIB_LIBS=`$PKG_CONFIG --libs glib-2.0` GLIB_CFLAGS=`$PKG_CONFIG --cflags glib-2.0` AC_DEFINE(HAVE_GLIB,1,[Define if you have glib-2.0.]) ifelse([$1],,:,[$1]) else AC_MSG_RESULT([not found by pkg-config]) ac_glib=no ifelse([$2],,:,[$2]) fi else AC_MSG_RESULT([no pkg-config]) ac_glib=no ifelse([$2],,:,[$2]) fi ]) dnl ------------------------------------------------------------------ dnl @synopsis AC_PROGS_QT4 dnl Sets output variables QMAKE, MOC, UIC, RCC, LUPDATE, LRELEASE dnl Prints an error message if QMAKE is not found or not suitable dnl ------------------------------------------------------------------ AC_DEFUN([AC_PROGS_QT], [ AC_REQUIRE([AC_PATH_X]) AC_REQUIRE([AC_PATH_XTRA]) AC_ARG_VAR(QMAKE,[Location of the QMAKE program.]) AC_ARG_VAR(QMAKESPEC,[Location of the QMAKE specifications.]) AC_ARG_VAR(MOC,[Location of the MOC program.]) AC_ARG_VAR(UIC,[Location of the UIC program.]) AC_ARG_VAR(RCC,[Location of the RCC program.]) AC_ARG_VAR(LUPDATE,[Location of the LUPDATE program.]) AC_ARG_VAR(LRELEASE,[Location of the LRELEASE program.]) AC_ARG_VAR(QTDIR,[Location of the Qt package (deprecated).]) path=$PATH if test -n "$QTDIR" && test -d "$QTDIR/include" ; then if test -d "$QTDIR/include/Qt" ; then : elif test -f "$QTDIR/include/qobject.h" ; then AC_MSG_ERROR([We want Qt4 or Qt5 but your QTDIR variable points to a Qt3 install. Please check variables QTDIR, QMAKE, QMAKESPEC, etc.. Unsetting them is better than setting them wrong.]) fi fi if test -n "$QTDIR" && test -d "$QTDIR/bin" ; then path=$QTDIR/bin:$PATH fi if test -z "$QMAKE" ; then AC_PATH_PROGS([QMAKE], [qmake], [], [$path]) fi if test -z "$QMAKE" ; then AC_MSG_ERROR([Cannot find the Qt program qmake. Please define variable QMAKE and possibly QMAKESPEC. Defining QTDIR can help although it is deprecated.]) fi mkdir conftest.d cat > conftest.d/conftest.pro <<\EOF changequote(<<, >>)dnl message(QMAKE_UIC="$$QMAKE_UIC")dnl qt4 only message(QMAKE_MOC="$$QMAKE_MOC")dnl qt4 only message(QT_VERSION="$$[QT_VERSION]") message(QT_INSTALL_PREFIX="$$[QT_INSTALL_PREFIX]") message(QT_INSTALL_DATA="$$[QT_INSTALL_DATA]") message(QT_INSTALL_HEADERS="$$[QT_INSTALL_HEADERS]") message(QT_INSTALL_BINS="$$[QT_INSTALL_BINS]") changequote([, ])dnl EOF if ( cd conftest.d && $QMAKE > conftest.out 2>&1 ) ; then sed -e 's/^.*: *//' < conftest.d/conftest.out > conftest.d/conftest.sh . conftest.d/conftest.sh rm -rf conftest.d else rm -rf conftest.d AC_MSG_ERROR([Cannot successfully run Qt program qmake. Please define variable QMAKE to a working qmake. If you define QMAKESPEC, make sure it is correct.]) fi AC_MSG_CHECKING([Qt version]) case "$QT_VERSION" in 4.*) AC_MSG_RESULT([qt4 ($QT_VERSION)]) qtversion=qt4 ;; 5.*) AC_MSG_RESULT([qt5 ($QT_VERSION)]) qtversion=qt5 ;; *) AC_MSG_RESULT([$QT_VERSION]) AC_MSG_ERROR([Unrecognized Qt version. Please define variable QMAKE.]) ;; esac test -z "$QTDIR" && test -n "$QT_INSTALL_DATA" && \ test -d "$QT_INSTALL_DATA/bin" && QTDIR="$QT_INSTALL_DATA" path=$PATH test -n "$QTDIR" && test -d "$QTDIR/bin" && path=$QTDIR/bin:$path test -d "$QT_INSTALL_BINS" && path=$QT_INSTALL_BINS:$path if test `basename "$QMAKE"` = qmake-$qtversion ; then altmoc="moc-${qtversion}" altuic="uic-${qtversion}" altrcc="rcc-${qtversion}" altlupdate="lupdate-${qtversion}" altlrelease="lrelease-${qtversion}" else AC_MSG_CHECKING([for real qmake path]) test -x "$QT_INSTALL_BINS/qmake" && QMAKE="$QT_INSTALL_BINS/qmake" AC_MSG_RESULT([$QMAKE]) fi test -x "$QMAKE_MOC" && test -z "$MOC" && MOC="$QMAKE_MOC" test -x "$QMAKE_UIC" && test -z "$UIC" && UIC="$QMAKE_UIC" AC_PATH_PROGS([MOC], [$altmoc moc], [], [$path]) AC_PATH_PROGS([UIC], [$altuic uic], [], [$path]) AC_PATH_PROGS([RCC], [$altrcc rcc], [], [$path]) AC_PATH_PROGS([LUPDATE], [${altlupdate} lupdate], [], [$path]) AC_PATH_PROGS([LRELEASE], [${altlrelease} lrelease], [], [$path]) PATH=$path ]) djview4-4.10.5/config/qmsilent.awk000066400000000000000000000035561264256014000167730ustar00rootroot00000000000000BEGIN { print "vUIC=$(vUIC_$V)" print "vUIC_=$(vUIC_0)" print "vUIC_0=@echo \" UIC \" $@;" print "vRCC=$(vRCC_$V)" print "vRCC_=$(vRCC_0)" print "vRCC_0=@echo \" RCC \" $@;" print "vMOC=$(vMOC_$V)" print "vMOC_=$(vMOC_0)" print "vMOC_0=@echo \" MOC \" $@;" print "vCXX=$(vCXX_$V)" print "vCXX_=$(vCXX_0)" print "vCXX_0=@echo \" CXX \" $@;" print "vCC=$(vCC_$V)" print "vCC_=$(vCC_0)" print "vCC_0=@echo \" CC \" $@;" print "vLINK=$(vLINK_$V)" print "vLINK_=$(vLINK_0)" print "vLINK_0=@echo \" LINK \" $@;" print "vMISC=$(vMISC_$V)" print "vMISC_=$(vMISC_0)" print "vMISC_0=@" mayberule = 0 escaped = 0 } /^[^\t]/ { if (escaped == 0) { mayberule = 0 } } { match($0, /^[ \t]*-?/) tabs=substr($0,1,RLENGTH) line=substr($0,1+RLENGTH) if (escaped == 1) { print } else if (mayberule == 0) { print } else if ( $1 ~ /.*\/uic/ || $1 == "$(UIC)" || $1 == "${UIC}") { printf("%s$(vUIC)%s\n", tabs, line) } else if ( $1 ~ /.*\/rcc/ || $1 == "$(RCC)" || $1 == "${RCC}") { printf("%s$(vRCC)%s\n", tabs, line) } else if ( $1 ~ /.*\/moc/ || $1 == "$(MOC)" || $1 == "${MOC}") { printf("%s$(vMOC)%s\n", tabs, line) } else if ( $1 == "$(CXX)" || $1 == "${CXX}") { printf("%s$(vCXX)%s\n", tabs, line) } else if ( $1 == "$(CC)" || $1 == "${CC}") { printf("%s$(vCC)%s\n", tabs, line) } else if ( $1 == "$(LINK)" || $1 == "${LINK}") { printf("%s$(vLINK)%s\n", tabs, line) } else if ( $1 == "-$(DEL_FILE)" || $1 == "-${DEL_DIR}") { printf("%s$(vMISC)%s\n", tabs, line) } else { print } } /^[^:=\t]*:?=/ { if (escaped == 0) { mayberule = 0 } } /^[^:=\t]*:/ { if (escaped == 0) { mayberule = 1 } } /\\$/ { escaped = 1 ; next } { escaped = 0 } djview4-4.10.5/config/qmsources.awk000066400000000000000000000011721264256014000171500ustar00rootroot00000000000000 BEGIN { printf "qmake_sources=\n"; printf "qmake_ts=\n"; printf "qmake_qm=\n" srcs["SOURCES"]=1; srcs["HEADERS"]=1; srcs["FORMS"]=1; srcs["RESOURCES"]=1; srcs["QMAKE_INFO_PLIST"]=1; srcs["REZ_FILES"]=1; srcs["RC_FILE"]=1; srcs["DEF_FILE"]=1; } /^[ \t]*[A-Za-z_]+[ \t]*[+*]?=/ { gsub(/[+*]?=/," += "); if ($1 in srcs) { $1="qmake_sources"; print } if ($1 == "TRANSLATIONS") { gsub(/[+*]?=/," += "); $1="qmake_ts"; print; $1="qmake_qm"; for (i=3; i<=NF; i++) gsub(/[.]ts/,".qm", $i) ; print } } djview4-4.10.5/configure.ac000066400000000000000000000251301264256014000154440ustar00rootroot00000000000000# -*-Shell-script-*- # # DjVuLibre DjView # Copyright (c) 2006- Leon Bottou # # This software is subject to, and may be distributed under, # the GNU General Public License, either version 2 of the license # or (at your option) any later version. # The license should have accompanied the software or # you may obtain a copy of the license from the # Free Software Foundation at http://www.fsf.org . # # This program 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 General Public License for more details. # # ---------------------------------------- # Initialization # ---------------------------------------- m4_define([v_maj], [4]) m4_define([v_min], [10.5]) m4_define([v_ver], [v_maj.v_min]) AC_PREREQ([2.65]) AC_INIT([djview],[v_ver]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR([config]) AC_CONFIG_SRCDIR([src/djview.cpp]) AC_CONFIG_HEADER(config.h:config/config.h.in) AC_PREFIX_DEFAULT(/usr/local) AC_CANONICAL_HOST AM_INIT_AUTOMAKE([1.6 subdir-objects dist-bzip2 dist-xz]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) # Additional libraries AC_ARG_WITH(extra-includes, AS_HELP_STRING([--with-extra-includes=DIR],[Define an additional directory for include files]), [ if test -d "$withval" ; then CFLAGS="$CFLAGS -I$withval" CXXFLAGS="$CXXFLAGS -I$withval" else AC_MSG_ERROR([Cannot stat directory $withval]) fi ] ) AC_ARG_WITH(extra-libraries, AS_HELP_STRING([--with-extra-libraries=DIR],[Define an additional directory for library files]), [ if test -d "$withval" ; then LDFLAGS="$LDFLAGS -L$withval" else AC_MSG_ERROR([Cannot stat directory $withval]) fi ] ) # Always look into a "gnu" directory. curwd=`pwd` if test -d $curwd/gnu/include ; then CFLAGS="$CFLAGS -I$curwd/gnu/include" CXXFLAGS="$CXXFLAGS -I$curwd/gnu/include" fi if test -d $curwd/gnu/lib ; then LDFLAGS="$LDFLAGS -L$curwd/gnu/lib" fi # Special cases ismac=no case "$host" in *-darwin* | *-macos10*) ismac=yes if test -d /usr/local ; then CFLAGS="$CFLAGS -I/usr/local/include" CXXFLAGS="$CXXFLAGS -I/usr/local/include" CPPFLAGS="$CPPFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" elif test -d /opt/local ; then CFLAGS="$CFLAGS -I/opt/local/include" CXXFLAGS="$CXXFLAGS -I/opt/local/include" CPPFLAGS="$CPPFLAGS -I/opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" elif test -d /sw ; then CFLAGS="$CFLAGS -I/sw/include" CXXFLAGS="$CXXFLAGS -I/sw/include" CPPFLAGS="$CPPFLAGS -I/sw/include" LDFLAGS="$LDFLAGS -L/sw/lib" fi ;; esac # ---------------------------------------- # Programs # ---------------------------------------- # Does make set variable $(MAKE) AC_PROG_MAKE_SET # Programs AC_PROG_LN_S AC_PROG_MKDIR_P AC_PROG_SED AC_PROG_INSTALL AC_PATH_PROG(RM, rm) AC_PATH_PROG(RMDIR, rmdir) AC_PATH_PROG(TOUCH, touch) AC_PATH_PROG(MKDIR, mkdir) AC_PATH_PROG(AWK, awk) # tweak rm to make libtool happy AC_PATH_PROG(RM, rm) RM="$RM -f" # Libtool & Compilers AC_PROG_CC AC_PROG_CXX AC_PROG_OBJC AC_SUBST(LIBTOOL_DEPS) # C++ AC_LANG(C++) AC_CXX_OPTIMIZE # Only nsdejavu needs libtool. # But some combinations of libtool and autoconf # break when libtool is in a conditional path. AC_DISABLE_STATIC LT_INIT # SVG conversion tool AC_PATH_PROG([RSVG], [rsvg-convert], [false]) AC_PATH_PROG([INKSCAPE], [inkscape], [false]) AC_PATH_PROG([CONVERT], [convert], [false]) conversion_tool=no if test "x${RSVG}" != xfalse ; then conversion_tool=rsvg elif test "x${INKSCAPE}" != xfalse ; then conversion_tool=inkscape elif test "x${CONVERT}" != xfalse ; then ( ${CONVERT} --version 2>&1 | grep -q ImageMagick ) && conversion_tool=convert fi AM_CONDITIONAL([HAVE_CONVERSION_RSVG], [test x${conversion_tool} = xrsvg]) AM_CONDITIONAL([HAVE_CONVERSION_INKSCAPE], [test x${conversion_tool} = xinkscape]) AM_CONDITIONAL([HAVE_CONVERSION_CONVERT], [test x${conversion_tool} = xconvert]) AM_CONDITIONAL([HAVE_CONVERSION_TOOL], [test x${conversion_tool} != xno]) # ---------------------------------------- # Header Files # ---------------------------------------- AC_HEADER_STDC AC_HEADER_DIRENT AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(unistd.h string.h strings.h getopt.h) # ---------------------------------------- # Functions # ---------------------------------------- AC_FUNC_FORK AC_CHECK_FUNCS(sigaction strerror waitpid wait3) # ---------------------------------------- # Packages # ---------------------------------------- AC_PROG_PKG_CONFIG([],[ AC_MSG_ERROR([Cannot find required program pkg-config.]) ]) AC_PROGS_QT([],[ AC_MSG_ERROR([Cannot find required Qt programs.]) ]) AC_PATH_DDJVUAPI([],[ AC_MSG_ERROR([Cannot find required package ddjvuapi.]) ]) AC_PATH_TIFF([],[ AC_MSG_WARN([Cannot find libtiff (required for tiff export).]) ]) # ---------------------------------------- # nsdejavu # ---------------------------------------- ac_nsdejavu=yes AC_ARG_ENABLE(nsdejavu, AS_HELP_STRING([--disable-nsdejavu], [Do not compile the nsdejavu browser plugin. @<:@default=enabled@:>@]), [ac_nsdejavu=$enableval]) if test "$ac_nsdejavu" != no ; then AC_PATH_X AC_PATH_XTRA if test "$no_x" = yes; then ac_nsdejavu=no AC_MSG_WARN([Disabling plugin compilation (missing X11 include files).]) fi fi if test "$ac_nsdejavu" != no ; then ac_xt=yes ac_glib=yes AC_PATH_GLIB([],[ac_glib=no]) savedCFLAGS="$CFLAGS" CFLAGS="$CFLAGS ${X_CFLAGS}" AC_CHECK_HEADER(X11/Shell.h, [], [ac_xt=no]) AC_CHECK_HEADER(X11/IntrinsicP.h, [], [ac_xt=no]) CFLAGS="$savedCFLAGS" if test "$ac_xt" != no ; then AC_DEFINE(HAVE_XT,1,[Define if you have xt include files.]) if test "$ac_glib" = no ; then AC_MSG_WARN([GLib not found. Compiling plugin without XEmbed.]) fi elif test "$ac_glib" != no ; then AC_MSG_WARN([Xt not found. Compiling plugin with XEmbed only.]) else ac_nsdejavu=no AC_MSG_WARN([Disabling plugin compilation (need Xt and/or Glib2.)]) fi fi if test "$ac_nsdejavu" != no && test "$qtversion" == "qt4" ; then ac_qt_x11=no AC_LANG_PUSH(C++) saved_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS -I$QT_INSTALL_HEADERS -I$QT_INSTALL_HEADERS/QtCore" AC_CHECK_DECL(Q_WS_X11, ac_qt_x11=yes, , [#include ]) CXXFLAGS=$saved_CXXFLAGS AC_LANG_POP(C++) if test "$ac_qt_x11" != yes ; then ac_nsdejavu=no AC_MSG_WARN([Disabling plugin compilation (need X11-based version of Qt.)]) AC_MSG_NOTICE([If you have an X11-supporting Qt, try:]) AC_MSG_NOTICE([ CPPFLAGS=-D__USE_WS_X11__ ./configure ...]) fi fi if test "$ac_nsdejavu" != no ; then # prepare flags NSDEJAVU_LIBS= NSDEJAVU_CFLAGS="${GLIB_CFLAGS} ${X_CFLAGS}" XT_LIBS= if test "$ac_xt" = yes ; then XT_LIBS="$X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS" XT_LIBS="`echo ${XT_LIBS} | sed -e 's/-lXext/-lXt -lXext/'`" fi case "$host" in *-cygwin* | *-mingw*) NSDEJAVU_LIBS="-no-undefined $GLIB_LIBS $XT_LIBS" ;; *-darwin* | *-macos10*) NSDEJAVU_LIBS="$GLIB_LIBS $XT_LIBS" ;; esac AC_SUBST(NSDEJAVU_CFLAGS) AC_SUBST(NSDEJAVU_LIBS) fi AM_CONDITIONAL([WANT_NSDEJAVU], [test "x${ac_nsdejavu}" != "xno"]) # ---------------------------------------- # npdjvu # ---------------------------------------- ac_npdjvu=no AC_ARG_ENABLE(npdjvu, AS_HELP_STRING([--enable-npdjvu], [Compile the npdjvu browser plugin (experimental). @<:@default=disabled@:>@]), [ac_npdjvu=$enableval]) AM_CONDITIONAL([WANT_NPDJVU], [test "x${ac_npdjvu}" != "xno"]) # ---------------------------------------- # mac # ---------------------------------------- ac_mac=no AC_ARG_ENABLE(mac, AS_HELP_STRING([--enable-mac], [Compile MacOS X specific tools @<:@default=disabled@:>@]), [ac_mac=$enableval]) if test x$ac_mac != xno && test x$ismac != xyes ; then AC_MSG_WARN([Disabling mac support (not a mac).)]) ac_mac=no fi if test x$ac_mac != xno && test x$ismac = xyes ; then # hack to avoid redistributing avx specific binaries. AC_CHECK_CXX_OPT([-mno-avx],[MORE_CFLAGS="$MORE_CFLAGS -mno-avx"]) fi AM_CONDITIONAL([WANT_MAC], [test "x${ac_mac}" != "xno"]) # ---------------------------------------- # Desktop files # ---------------------------------------- ac_desktopfiles=yes test x$ismac = xyes && ac_desktopfiles=no AC_ARG_ENABLE(desktopfiles, AS_HELP_STRING([--disable-desktopfiles], [Do not install icons and mime types. @<:@kefault=enabled@:>@]), [ac_desktopfiles=$enableval]) AM_CONDITIONAL([WANT_DESKTOPFILES], [test "x${ac_desktopfiles}" != "xno"]) # ---------------------------------------- # MISC # ---------------------------------------- # Define version string AC_DEFINE_VERSION([${PACKAGE_VERSION}]) # ---------------------------------------- # Prepare qmake arguments # ---------------------------------------- QMAKELIBS="$DDJVUAPI_LIBS $TIFF_LIBS $LIBS" QMAKEFLAGS="$DDJVUAPI_CFLAGS $TIFF_CFLAGS $MORE_CFLAGS" AC_SUBST(QMAKELIBS) AC_SUBST(QMAKEFLAGS) QMAKEARG="CONFIG+=autoconf" if test "$ac_debug" = yes ; then QMAKEARG="$QMAKEARG CONFIG+=debug" else QMAKEARG="$QMAKEARG CONFIG+=release" fi QMAKEARG="$QMAKEARG PACKAGE_VERSION=${PACKAGE_VERSION}" if test -n "$QMAKESPEC" ; then QMAKEARG="-spec $QMAKESPEC $QMAKEARG" fi AC_SUBST(QMAKEARG) # ---------------------------------------- # Outputs # ---------------------------------------- AC_CONFIG_FILES([ Makefile src/Makefile nsdejavu/Makefile desktopfiles/Makefile npdjvu/Makefile mac/Makefile mac/mdimporter_src/Makefile mac/qlgenerator_src/Makefile ]) AC_OUTPUT # ---------------------------------------- # Fin # ---------------------------------------- # Final message echo echo "$PACKAGE $VERSION" echo echo "Configuration Options Summary:" echo echo " OS...................: ${host_os}" echo " Qt version...........: ${qtversion} (${QT_VERSION})" echo " TIFF support.........: ${ac_tiff}" echo " Desktop files........: ${ac_desktopfiles}" echo " Icon generation......: ${conversion_tool}" echo " Mac specific tools...: ${ac_mac}" echo " NSDEJAVU plugin......: ${ac_nsdejavu}" echo " NPDJVU plugin........: ${ac_npdjvu}" echo echo "Compilation............: make (or gmake)" echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" echo djview4-4.10.5/debian/000077500000000000000000000000001264256014000143775ustar00rootroot00000000000000djview4-4.10.5/debian/.gitignore000066400000000000000000000002001264256014000163570ustar00rootroot00000000000000/*.debhelper /*.log /*.substvars /autoreconf.after /autoreconf.before /djview-plugin/ /djview4/ /djvulibre-plugin/ /files /tmp/ djview4-4.10.5/debian/changelog000066400000000000000000000241531264256014000162560ustar00rootroot00000000000000djview4 (4.10.5-1) unstable; urgency=medium * workaround qt55 xembed bug -- Leon Bottou Mon, 01 Jan 2016 16:12:00 +0500 djview4 (4.10.4-1) unstable; urgency=medium [ Leon Bottou ] * new upstream release [ Barak A. Pearlmutter ] * add Leon to debian/control uploaders * target to unstable * remove debian/*.menu, per policy -- Barak A. Pearlmutter Wed, 25 Nov 2015 10:20:23 +0000 djview4 (4.10.3-1) unstable; urgency=medium * new upstream release, mainly UI tweaks like pinching -- Barak A. Pearlmutter Thu, 04 Jun 2015 16:15:07 +0100 djview4 (4.10-3) unstable; urgency=medium * gzip --no-name option for build reproducibility (closes: #778432) -- Barak A. Pearlmutter Sun, 15 Feb 2015 14:11:45 +0000 djview4 (4.10-2) unstable; urgency=medium * build dependency for lrelease executable -- Barak A. Pearlmutter Fri, 13 Feb 2015 09:00:51 +0000 djview4 (4.10-1) unstable; urgency=medium * bump debian standards version * new upstream release - Bug fixes: layout, usability, preferences, locale selection - Works with both Qt4 and Qt5 - Build uses automake/qmake hybrid (instead of autoconf/qmake). - Layout annotations are honored in multipage mode - Experimental OpenGL rendering - Slideshow mode * switch to qt5 -- Barak A. Pearlmutter Thu, 12 Feb 2015 22:52:34 +0000 djview4 (4.9-6) unstable; urgency=medium * accept patches to upstream from ubuntu/4.9-4ubuntu3 - debian/patches/aarch64_cpu_definitions.patch - debian/patches/ppc64el.diff * dh --with autotools_dev, to update config/config.{sub,guess}, for ports needing custom versions (closes: #744565) -- Barak A. Pearlmutter Mon, 14 Apr 2014 10:09:33 +0100 djview4 (4.9-5) unstable; urgency=low * bump policy version (no changes needed) * remove build alts libtiff{5,4,3}-dev (closes: #735996) * track upstream development branch (closes: #714225) -- Barak A. Pearlmutter Tue, 21 Jan 2014 15:14:43 +0000 djview4 (4.9-4) unstable; urgency=low * bump policy version (no changes needed) * clean some icons generated during build (closes: #679921) * update debian packaging repo urls to current naming scheme * the upstream changelog is called NEWS -- Barak A. Pearlmutter Mon, 30 Sep 2013 12:17:34 +0100 djview4 (4.9-3) unstable; urgency=low * merge upstream fixes * add qt-opengl build dependency * allow libtiff5 to satisfy build dependency -- Barak A. Pearlmutter Mon, 12 Nov 2012 12:08:53 +0000 djview4 (4.9-2) unstable; urgency=low * fix plugin bug, see https://bugs.launchpad.net/ubuntu/+source/djvulibre/+bug/940853 -- Barak A. Pearlmutter Sun, 17 Jun 2012 00:20:11 +0100 djview4 (4.9-1) unstable; urgency=low [ Leon Bottou ] * new upstream version [ Barak A. Pearlmutter ] * switch deprecated rsvg to plug-compatible rsvg-convert (closes: #666474) * bump to dh 9 * bump debian policy version -- Barak A. Pearlmutter Wed, 04 Apr 2012 09:25:22 +0100 djview4 (4.8-3) unstable; urgency=low * upstream change giving user ability to allow print/save in plugin -- Barak A. Pearlmutter Sat, 26 Nov 2011 23:11:19 +0000 djview4 (4.8-2) unstable; urgency=low * single debian patch source option (closes: #643093) * ensure rsvg in build dependencies * silence lintian regarding duplicate sections * silence lintian regarding unneeded encoding in desktop file -- Barak A. Pearlmutter Fri, 07 Oct 2011 20:28:47 +0100 djview4 (4.8-1) unstable; urgency=low * new upstream release * tweak plugin installation location * silence some lintian issues: - bump debian standards version - add build-arch build-indep as debian/rules targets - convert djvulibre-djview4.xpm from PNG to XPM - switch empty binary package djvulibre-plugin to arch independent - generate and install not PNG but XPM icon files * work around rejection-inducing lintian bug -- Barak A. Pearlmutter Fri, 29 Jul 2011 14:05:56 +0100 djview4 (4.7-1) unstable; urgency=low * New upstream release -- Barak A. Pearlmutter Mon, 07 Mar 2011 17:21:01 +0000 djview4 (4.6-3) unstable; urgency=low * changes to debian/control - fiddle with sections - have djview-plugin conflict with old versions of djvulibre-plugin which contain the same plugin library (closes: #613352, #613374) * arch patch for Renesas SH from Nobuhiro Iwamatsu (closes: #613310) -- Barak A. Pearlmutter Wed, 16 Feb 2011 17:24:16 +0000 djview4 (4.6-2) unstable; urgency=low * move some debian maintenance to git (debian/README.Debian) - point to debian collab-maint repo (debian/control) - upstream has moved to git (debian/copyright, rm debian/README.Debian) * use dh autotools-dev stuff to update config.* files * enable nsdjvu plugin - generate package djview-plugin - generate transition package djvulibre-plugin * bump to debhelper 8 * dh --parallel -- Barak A. Pearlmutter Thu, 02 Dec 2010 13:45:14 +0000 djview4 (4.6-1) unstable; urgency=low * New upstream release * switch to dpkg-source 3.0 (quilt) format * really automatically clean generated bitmaps in debian/ (debian/clean) * bump policy (debian/control) -- Barak A. Pearlmutter Mon, 16 Aug 2010 22:17:28 +0200 djview4 (4.5-6) unstable; urgency=low * source depend (debian/control) on librsvg2-bin binary used by new imagemagick, and work around failure of direct conversion by convert via step-by-step manual convertion in debian/rules (closes: #574297) * automatically clean generated bitmaps in debian/ (debian/clean) -- Barak A. Pearlmutter Thu, 18 Mar 2010 14:51:54 +0000 djview4 (4.5-5) unstable; urgency=low * rev deb std * work around autobuilder inability to install B when build-dep: A | B -- Barak A. Pearlmutter Thu, 28 Jan 2010 20:34:54 +0100 djview4 (4.5-4) unstable; urgency=low * Build dependency on libwmf-bin for wmf2eps (closes: #556813) or libmagickcore2-extra to allow convert to do the job -- Barak A. Pearlmutter Mon, 30 Nov 2009 21:09:05 +0000 djview4 (4.5-3) unstable; urgency=low * missing dh debian/control misc:depends -- Barak A. Pearlmutter Tue, 29 Sep 2009 15:40:28 -0400 djview4 (4.5-2) unstable; urgency=low * rev deb std * fancier shorter debian/rules * lintian issues (stop ignoring errors in installation scripts) -- Barak A. Pearlmutter Mon, 28 Sep 2009 10:53:40 -0400 djview4 (4.5-1) unstable; urgency=low * Upstream release 4.5 * Man page typos (closes: #526091) thanks to "A. Costa" * Ack upstream fix, open dialog allows un-narrowed list (closes: #504281) -- Barak A. Pearlmutter Wed, 29 Apr 2009 09:36:07 +0100 djview4 (4.4-1) unstable; urgency=low * Upstream release 4.4 * Fully dh7-ianize * Upstream builds PNG from SVG using /usr/bin/convert, requiring build dependency upon imagemagick * Integrate new upstream icons -- Barak A. Pearlmutter Mon, 08 Sep 2008 08:37:16 +0100 djview4 (4.3-6) unstable; urgency=low * Gentler dependencies, update x-dev dependency * Upstream mods for man and GCC 4.x warnings * Include more upstream translated text * Minor lintian issues (debian/rules clean; deb scripts w/ command path) * Fix user interaction language selection issue harder (closes: #460714) -- Barak A. Pearlmutter Tue, 19 Aug 2008 13:10:25 +0100 djview4 (4.3-5) unstable; urgency=low * Upstream fix for disappearing search box (closes: #484522) * Unable to manifrest save-as giving zero-length file (closes: #468389) * Upstream fix for user interaction language selection (closes: #460714) * Provide virtual package djvu-viewer (see: #491012) * Minor updates to debian packaging info, rev to debhelper 7 -- Barak A. Pearlmutter Mon, 04 Aug 2008 11:34:53 +0100 djview4 (4.3-4) unstable; urgency=low * Add build dependency on pkg-config (closes: #477029) * Fix update-alternatives in installation scripts (closes: #476434) -- Barak A. Pearlmutter Wed, 23 Apr 2008 07:45:17 +0100 djview4 (4.3-3) unstable; urgency=low * Conflict with old djview containing /usr/bin/djview (closes: #473341) * Raise version number of qt4 needed for build (closes: #475021) -- Barak A. Pearlmutter Mon, 07 Apr 2008 23:53:08 -0700 djview4 (4.3-2) unstable; urgency=low * Upstream __sync_... build error fixes in libdjvu/atomic.cpp for sparc, mips, arm, hppa, mipsel, armel. -- Barak A. Pearlmutter Sun, 16 Mar 2008 18:58:53 +0000 djview4 (4.3-1) unstable; urgency=low * Upstream release * New german and czech translation * Remove xlibs-dev build dependency (closes #460254) * Menu section changed from Apps to Applications * avoid empty /usr/sbin/ -- Barak A. Pearlmutter Wed, 30 Jan 2008 11:36:31 +0000 djview4 (4.2-1) unstable; urgency=low * New feature "Undo/Redo". * New entry "Open Location" in "File" menu. * Add vcs-cvs and homepage fields to debian/control * Include (treating as Debian patch) mods in upstream release 4.2-1, which includes fix for bug number 452947 which occurs here as well as in djvulibre against which it was first reported. -- Barak A. Pearlmutter Tue, 20 Nov 2007 18:02:38 +0000 djview4 (4.1-2) unstable; urgency=low * Compatibility fixes for Qt-4.2. * New entry "Open recent" in "File" menu. -- Barak A. Pearlmutter Tue, 31 Jul 2007 23:26:46 +0500 djview4 (4.1-1) unstable; urgency=low * Bug fixes for Qt-4.2 and Qt-4.3. * PDF and TIFF Export. -- Barak A. Pearlmutter Sun, 7 Jul 2007 12:00:46 +0500 djview4 (4.0-1) unstable; urgency=low * Initial release. * Binary dependency on libdjvulibre should be deb-o-matic! * License clarification of mozilla plugin code. -- Barak A. Pearlmutter Thu, 26 Apr 2007 17:50:46 +0300 djview4-4.10.5/debian/clean000066400000000000000000000001311264256014000153770ustar00rootroot00000000000000desktopfiles/hi-djview4.svgz desktopfiles/hi32-djview4.png desktopfiles/hi64-djview4.png djview4-4.10.5/debian/compat000066400000000000000000000000021264256014000155750ustar00rootroot000000000000009 djview4-4.10.5/debian/control000066400000000000000000000033551264256014000160100ustar00rootroot00000000000000Source: djview4 Section: graphics Priority: optional Maintainer: Barak A. Pearlmutter Uploaders: Leon Bottou Build-Depends: debhelper (>= 9), dh-autoreconf, autotools-dev, pkg-config, gawk | awk, libdjvulibre-dev (>= 3.5.20), x11proto-core-dev, libx11-dev, libxext-dev, libxt-dev, libglib2.0-dev, qtbase5-dev, qt5-qmake, libqt5opengl5-dev, qttools5-dev-tools, libtiff-dev, netpbm, librsvg2-bin, imagemagick Vcs-Git: git://anonscm.debian.org/collab-maint/djview4.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/djview4.git Homepage: http://djvu.sourceforge.net/ Standards-Version: 3.9.6 Package: djview4 Architecture: any Provides: djvu-viewer Conflicts: djview (<= 3.5.20-5) Depends: ${shlibs:Depends}, ${misc:Depends} Recommends: djvulibre-desktop Suggests: djvulibre-bin, djview-plugin Description: Viewer for the DjVu image format DjVu viewer djview. Package: djview-plugin Section: web Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, djview4 | djview3 Provides: djvulibre-plugin Enhances: chromium-browser, mozilla-browser, mozilla, firefox, iceweasel, iceape-browser, konqueror, rekonq, galeon Recommends: chromium-browser | mozilla-browser | mozilla | firefox | iceweasel | iceape-browser | konqueror | galeon Suggests: mime-support Conflicts: djvulibre-bin (<< 3.5.19), djvulibre-plugin (<= 3.5.23-4) Description: Browser plugin for the DjVu image format DjVu browser plugin. Package: djvulibre-plugin Section: web Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, djview-plugin Description: Transition package, djvulibre-plugin to djview-plugin Dummy dependency package to transition from djvulibre-plugin to djview-plugin. djview4-4.10.5/debian/copyright000066400000000000000000000057371264256014000163460ustar00rootroot00000000000000This package was debianized by Barak Pearlmutter on Tue, 16 Jan 2007 20:01:58 -0500. It was downloaded from http://djvu.sourceforge.net/ git://git.code.sf.net/p/djvu/djview-git Upstream Authors: Leon Bottou Copyright: DjView4, Copyright (c) 2006-2008 Leon Bottou This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, either version 2 of the license or (at your option) any later version. This program depends on the DjVuLibre library. Starting with version 3.5.19, DjVuLibre is released under the GNU General Public License, either version 2 or (at your option) any later version. Prior to version 3.5.19, DjVuLibre was released under the GNU General Public License, version 2. On Debian GNU/Linux systems, the complete text of the GNU General Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. == Upstream copyright remarks: == In directory nsdejavu/npsdk, the source distribution contains files extracted from the Mozilla project. These files are available under the Mozilla Public License version 1.1 with permission to redistribute under either the GNU General Public License version 2 or the GNU Library General Public License version 2.1. These files are NOT USED for the compilation of the program djview4 under Debian. ==================================================================== Remark1: This program depends on the DjVuLibre library. Starting with version 3.5.19, DjVuLibre is released under the GNU General Public License, either version 2 or (at your option) any later version. Prior to version 3.5.19, DjVuLibre was released under the GNU General Public License, version 2. Remark2: Part of this software is derived from 'tiff2pdf' which comes with the following notice: | Copyright (c) 2003 Ross Finlayson | | Permission to use, copy, modify, distribute, and sell this software and | its documentation for any purpose is hereby granted without fee, provided | that (i) the above copyright notices and this permission notice appear in | all copies of the software and related documentation, and (ii) the name of | Ross Finlayson may not be used in any advertising or | publicity relating to the software without the specific, prior written | permission of Ross Finlayson. | | THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | | IN NO EVENT SHALL ROSS FINLAYSON BE LIABLE FOR | ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | OF THIS SOFTWARE. djview4-4.10.5/debian/djview-plugin.install000066400000000000000000000000651264256014000205540ustar00rootroot00000000000000usr/lib/*/plugins/*.so usr/share/man/man*/nsdejavu.* djview4-4.10.5/debian/djview4.docs000066400000000000000000000000101264256014000166140ustar00rootroot00000000000000README* djview4-4.10.5/debian/djview4.install000066400000000000000000000002411264256014000173400ustar00rootroot00000000000000usr/bin/djview4 usr/share/man/*/djview4.* usr/share/djvu usr/share/icons usr/share/applications debian/djvulibre-djview4.xpm usr/share/icons/hicolor/32x32/apps/ djview4-4.10.5/debian/djview4.mime000066400000000000000000000005521264256014000166260ustar00rootroot00000000000000image/vnd.djvu; /usr/bin/djview4 '%s'; test=test -n "$DISPLAY"; description=DjVu file; nametemplate='%s.djvu'; priority=6 image/x.djvu; /usr/bin/djview4 '%s'; test=test -n "$DISPLAY"; description=DjVu file; nametemplate='%s.djvu'; priority=6 image/x-djvu; /usr/bin/djview4 '%s'; test=test -n "$DISPLAY"; description=DjVu file; nametemplate='%s.djvu'; priority=6 djview4-4.10.5/debian/djview4.postinst000066400000000000000000000004111264256014000175540ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in configure) update-alternatives --quiet \ --install /usr/bin/djview djview /usr/bin/djview4 40 \ --slave \ /usr/share/man/man1/djview.1.gz djview.1.gz \ /usr/share/man/man1/djview4.1.gz ;; esac #DEBHELPER# djview4-4.10.5/debian/djview4.prerm000066400000000000000000000002151264256014000170200ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in remove|deconfigure) update-alternatives --quiet --remove djview /usr/bin/djview4 ;; esac #DEBHELPER# djview4-4.10.5/debian/djvulibre-djview4.xpm000066400000000000000000000143651264256014000204760ustar00rootroot00000000000000/* XPM */ static char *djvulibre_djview4[] = { /* columns rows colors chars-per-pixel */ "32 32 256 2 ", " c #2F3B62", ". c #3D3165", "X c #783C54", "o c #5B2E62", "O c #443067", "+ c #4E336E", "@ c #563066", "# c #55336B", "$ c #5B316A", "% c #4E3977", "& c #453B7C", "* c #4D3B7A", "= c #523572", "- c #5A3776", "; c #672B61", ": c #64326D", "> c #78306D", ", c #713576", "< c #29436E", "1 c #2C4671", "2 c #7E475E", "3 c #764D5E", "4 c #7D495F", "5 c #6E575F", "6 c #68585A", "7 c #71525E", "8 c #6B5B61", "9 c #645364", "0 c #735F67", "q c #765966", "w c #6F6267", "e c #6D6D6D", "r c #7D616C", "t c #757575", "y c #7C7C7C", "u c #7B7875", "i c #BD7C1C", "p c #AA732A", "a c #B67A2F", "s c #C27D21", "d c #802A5E", "f c #932A58", "g c #883F5D", "h c #823853", "j c #923057", "k c #922D6A", "l c #8F3D62", "z c #973562", "x c #993967", "c c #9B3C68", "v c #863275", "b c #A12D63", "n c #A6376C", "m c #A12F72", "M c #967040", "N c #BC6648", "B c #854361", "V c #8B4866", "C c #895E6E", "Z c #A2406E", "A c #8B6C6D", "S c #8A6374", "D c #94637A", "F c #936A7C", "G c #89737D", "H c #BE822E", "J c #D9890C", "K c #C5841A", "L c #D78911", "P c #DC8C11", "I c #DE931E", "U c #C3892C", "Y c #D69D3C", "T c #EEAF3D", "R c #B08B53", "E c #A08B7E", "W c #C38F45", "Q c #D0A86F", "! c #D1AB72", "~ c #EDC574", "^ c #F1CC73", "/ c #3E3F80", "( c #643C80", ") c #7A3F80", "_ c #314586", "` c #3C4282", "' c #405599", "] c #485B9D", "[ c #585997", "{ c #794B89", "} c #725E89", "| c #57609F", " . c #5A62A3", ".. c #6565A2", "X. c #7E6DA2", "o. c #864181", "O. c #8C558A", "+. c #955D83", "@. c #976B89", "#. c #857F81", "$. c #8B7B83", "%. c #8A6D98", "&. c #7788A3", "*. c #858484", "=. c #8B8B8B", "-. c #99858C", ";. c #86869E", ":. c #9D8A93", ">. c #929292", ",. c #9B9B9B", "<. c #A49495", "1. c #8C8DA3", "2. c #9292A7", "3. c #9A9BAD", "4. c #9595A9", "5. c #9F9FB1", "6. c #959FBC", "7. c #9FA0B3", "8. c #9EA5B9", "9. c #ABA9A9", "0. c #A7A4A5", "q. c #B0AEAE", "w. c #B6A9A6", "e. c #A0A0B3", "r. c #AFAFBF", "t. c #A5AABE", "y. c #AFB0BF", "u. c #B3B3B3", "i. c #BBBBBB", "p. c #CBAF83", "a. c #DCBA87", "s. c #BAD5A9", "d. c #F5D181", "f. c #FDDE80", "g. c #CEC7BE", "h. c #C8E2BD", "j. c #C3F0BE", "k. c #94A6C6", "l. c #97A8C8", "z. c #98A9C9", "x. c #9BA7C4", "c. c #A6ADC3", "v. c #AEB1C0", "b. c #A5B3C6", "n. c #B2B2C1", "m. c #BABAC7", "M. c #B5BBCA", "N. c #BEBECB", "B. c #AFBED4", "V. c #81B6E0", "C. c #84BCE5", "Z. c #8DC0DE", "A. c #9AC9DD", "S. c #9EDCDA", "D. c #B9C3CF", "F. c #A9CDDB", "G. c #A2CADA", "H. c #B3CDDA", "J. c #B7DCDD", "K. c #A9E6DD", "L. c #8AC3EB", "P. c #93C6E1", "I. c #97CAEC", "U. c #9DD2ED", "Y. c #95CBF5", "T. c #9BCAF3", "R. c #9DD1F7", "E. c #9ED6F8", "W. c #A4CDEA", "Q. c #A8CEEB", "!. c #B5CEEA", "~. c #A5D2E2", "^. c #ACD6E5", "/. c #A2D1EA", "(. c #A6D8EC", "). c #B3DAE4", "_. c #B3DBEC", "`. c #B4D5E7", "'. c #A3D4F4", "]. c #A3D9F5", "[. c #ADDDF3", "{. c #A2DAF9", "}. c #AADDFA", "|. c #B3DFF0", " X c #B5D8F5", ".X c #A9E2EF", "XX c #A9E2E2", "oX c #B7E1EC", "OX c #B5E5E3", "+X c #B8F2E6", "@X c #ADE1FA", "#X c #BDE6F1", "$X c #B4E4FA", "%X c #BCE9FA", "&X c #BAE5F5", "*X c #C3C3C3", "=X c #C7C8CA", "-X c #CBCBCB", ";X c #C7C7D2", ":X c #CBCBD4", ">X c #D6D6D6", ",X c #D3D4DC", " :.IXwXk.!.Y.{.}.cX_.zX~.kX+X+XoXoXVXZX;XIXIXLXy 3 = UXUXUX", "UXUXk q.LXk.x.T.Y.].U.zXkXZXP.~.hXjXA.).).VXM.&.IXDXy 3 = UXUXUX", "UXUXb =XLXx.c.T.E.}.U.&X`.#XoX~.hXOXF.xXG.CXM.< KXDXy 4 = UXUXUX", "UX& z >XLXl.c.Y.].@XV./.Z.#XVX`.hX).uXBXF.CXD.1 KXSXy 2 % UXUXUX", "UX- V AXLXx.6.I.L.C.I.|.P.xXNXxXjXJ.GXJXH.sX8.< KXAX*.B % UXUXUX", "UX, S AXKXdXy.W.U././.P.~.VXNXHX7X6XPXPXFXbX3.=XLX.SXSXDXKXy.Q.$X%XmXVXCXaXGX7X9XPXLXDXe.SXKXLX>X=.l & UXUXUX", "UXn ,.DXDXSXDXAXt.Q.%X%XMXVXaXCX7X9XPXFXM.e.n.KXDX>X=.z ` UXUXUX", "* c u.SXDXSXSXDX,X8.`.#XMXVXaXHXHXGXbXy.e.r.M.DX2X-X=.c / UXUXUX", "( V i.SXSXSXSXSXDX>X5.b.`.xXxXgXiXD.1.y.N.>X:X! I ! =.c ` UXUXUX", ") r *XSXSXSXSXSXSXSXSX:X5.4.;.2.2.m.SXSXSX,Xa.^ T P R Z _ UXUXUX", "o.q *.=.=.=.,.,.,.9.i.-XAXSX*XSXSXSXSXSXSX! ^ qXd.T P N _ UXUXUX", "UX{ { O.O.+.+.D F C r 0 w *.*.*.=.>.0.q.*Xg.Y f.qXd.T P M UXUXUX", "UXUXUXUXUXUXUXUXUXUX] | .. . .X.%.%.@.@.F F A U f.qXd.T L s UXUX", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX' [ } H f.qXd.T P i UX", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXK f.qXd.T L a ", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXK f.qX^ W -.", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXK f.p.w.;.", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp <.1.UX", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX", "UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX" }; djview4-4.10.5/debian/rules000077500000000000000000000010771264256014000154640ustar00rootroot00000000000000#!/usr/bin/make -f export QT_SELECT = 5 plugindir=/usr/lib/mozilla/plugins override_dh_auto_install: dh_auto_install -- \ pluginsdir=$(plugindir) \ DESTDIR=$(CURDIR)/debian/tmp @echo "rename djview as djview4 to allow debian alternatives" mv debian/tmp/usr/bin/djview debian/tmp/usr/bin/djview4 mv debian/tmp/usr/share/man/man1/djview.1 debian/tmp/usr/share/man/man1/djview4.1 override_dh_installchangelogs: dh_installchangelogs NEWS override_dh_makeshlibs: dh_makeshlibs --version-info --exclude=/plugins %: dh $@ --with autotools_dev,autoreconf --parallel djview4-4.10.5/debian/source/000077500000000000000000000000001264256014000156775ustar00rootroot00000000000000djview4-4.10.5/debian/source/format000066400000000000000000000000141264256014000171050ustar00rootroot000000000000003.0 (quilt) djview4-4.10.5/debian/source/include-binaries000066400000000000000000000000351264256014000210350ustar00rootroot00000000000000debian/djvulibre-djview4.xpm djview4-4.10.5/debian/source/local-options000066400000000000000000000000241264256014000204010ustar00rootroot00000000000000single-debian-patch djview4-4.10.5/debian/watch000066400000000000000000000000631264256014000154270ustar00rootroot00000000000000version=3 http://sf.net/djvu/djview4-(.*)\.tar\.gz djview4-4.10.5/desktopfiles/000077500000000000000000000000001264256014000156515ustar00rootroot00000000000000djview4-4.10.5/desktopfiles/.gitignore000066400000000000000000000000331264256014000176350ustar00rootroot00000000000000/32x32/ /64x64/ /scalable/ djview4-4.10.5/desktopfiles/Makefile.am000066400000000000000000000035711264256014000177130ustar00rootroot00000000000000#icons SVGICONS = \ scalable/mimetypes/djvulibre-djview4.svgz PNGICONS = \ 32x32/mimetypes/djvulibre-djview4.png \ 64x64/mimetypes/djvulibre-djview4.png iconsdir = $(datadir)/icons/hicolor nobase_icons_DATA = $(PNGICONS) $(SVGICONS) EXTRA_DIST = \ djvu.svg \ djview.svg \ prebuilt-hi32-djview4.png \ prebuilt-hi64-djview4.png if HAVE_CONVERSION_RSVG convert_icons_process = \ s=`echo $@ | sed -e 's/[a-z]*\([0-9]*\).*/\1/'`; \ ${RSVG} \ -w $${s} \ -h $${s} -o $@ $< endif if HAVE_CONVERSION_INKSCAPE convert_icons_process = \ s=`echo $@ | sed -e 's/[a-z]*\([0-9]*\).*/\1/'`; \ ${INKSCAPE} \ --without-gui \ --export-width=$${s} \ --export-height=$${s} \ --export-png=$@ $< endif if HAVE_CONVERSION_CONVERT convert_icons_process = \ s=`echo $@ | sed -e 's/[a-z]*\([0-9]*\).*/\1/'`; \ ${CONVERT} \ -geometry $${s}x$${s} \ -depth 8 \ -background none $< $@ endif png_verbose = $(png_verbose_@AM_V@) png_verbose_ = $(png_verbose_@AM_DEFAULT_V@) png_verbose_0 = @echo " PNG " $@; ${PNGICONS}: djview.svg Makefile $(AM_V_at)$(MKDIR_P) `dirname $@` if HAVE_CONVERSION_TOOL $(png_verbose)$(convert_icons_process) else $(AM_V_at)s=`echo $@ | sed -e 's/[a-z]*\([0-9]*\).*/\1/'`; \ cp ${top_srcdir}/desktopfiles/prebuilt-hi$${s}-djview4.png $@ endif svg_process = gzip --no-name <$< >$@ svg_verbose = $(svg_verbose_@AM_V@) svg_verbose_ = $(svg_verbose_@AM_DEFAULT_V@) svg_verbose_0 = @echo " SVG " $@; $(SVGICONS): djview.svg Makefile $(AM_V_at)$(MKDIR_P) `dirname $@` $(AM_V_at)rm -f $@ $(svg_verbose)$(svg_process) # install desktop file into application dir applicationsdir = $(datadir)/applications dist_applications_DATA = djvulibre-djview4.desktop # clean MOSTLYCLEANFILES = $(PNGICONS) $(SVGICONS) mostlyclean-local: $(AM_V_at)for n in $(PNGICONS) $(SVGICONS) ; do m=`dirname "$$n"` ; \ while test "$$m" != "." ; do rmdir $$m ; m=`dirname "$$m"` ; done ; \ done djview4-4.10.5/desktopfiles/djview.svg000066400000000000000000001175701264256014000176750ustar00rootroot00000000000000 image/svg+xml djview4-4.10.5/desktopfiles/djvu.svg000066400000000000000000000417441264256014000173540ustar00rootroot00000000000000 image/svg+xml djview4-4.10.5/desktopfiles/djvulibre-djview4.desktop000066400000000000000000000053141264256014000226070ustar00rootroot00000000000000[Desktop Entry] Type=Application Categories=Qt;Graphics;Viewer; MimeType=image/x-djvu;image/x.djvu;image/vnd.djvu; Name=DjView4 Exec=djview4 %f Terminal=false Icon=djvulibre-djview4 StartupWMClass=Djview4 GenericName=DjVu Viewer GenericName[ar]=عارض Ù…Ù„ÙØ§Øª DjVu GenericName[az]=DjVu Nümayişçisi GenericName[bg]=Преглед на документи DjVu GenericName[br]=Gweler DjVu GenericName[bs]=Preglednik DjVu dokumenata GenericName[ca]=Visualitzador de DjVu GenericName[cs]=ProhlížeÄ DjVu souborů GenericName[cy]=Gwelydd DjVu GenericName[da]=DjVu-fremviser GenericName[de]=DjVu-Betrachter GenericName[el]=ΠÏοβολέας DjVu GenericName[eo]=DjVu-rigardilo GenericName[es]=Visor de DjVu GenericName[et]=DjVu-failide näitaja GenericName[eu]=DjVu ikustailua GenericName[fi]=DjVu-näytin GenericName[fr]=Afficheur DjVu GenericName[ga]=Amharcán DjVu GenericName[gl]=Visor DjVu GenericName[he]=מציג DjVu GenericName[hr]=Preglednik DjVu dokumenata GenericName[hu]=DjVu-nézegetÅ‘ GenericName[id]=Viewer DjVu GenericName[is]=DjVu sjá GenericName[it]=Visore DjVu GenericName[ja]=DjVuビューア GenericName[km]=កម្មវិធី​មើល DjVu GenericName[lt]=DjVu ŽiÅ«riklis GenericName[lv]=DjVu SkatÄ«tÄjs GenericName[mk]=Прикажувач на DjVu датотеки GenericName[ms]=Pemapar DjVu GenericName[mt]=Werrej DjVu GenericName[nb]=DjVu-fremviser GenericName[nl]=DjVu-weergaveprogramma GenericName[nn]=DjVu-lesar GenericName[pa]=DjVu ਦਰਸ਼ਕ GenericName[pl]=PrzeglÄ…darka plików DjVu GenericName[pt]=Visualizador de DjVus GenericName[pt_BR]=Visualizador de arquivos DjVu GenericName[ro]=Vizualizor DjVu GenericName[ru]=Чтение документов DjVu GenericName[rw]=Mugaragaza DjVu GenericName[se]=DjVu-Äájeheaddji GenericName[sk]=PrehliadaÄ DjVu GenericName[sl]=Pregledovalnik datotek DjVu GenericName[sr]=DjVu приказивач GenericName[sr@Latn]=DjVu prikazivaÄ GenericName[sv]=DjVu-visare GenericName[ta]=DjVu காடà¯à®šà®¿ GenericName[tg]=Хондани Ñанадоти DjVu GenericName[th]=ตัวà¹à¸ªà¸”งผล DjVu GenericName[tr]=DjVu Görüntüleyici GenericName[uk]=ПереглÑдач DjVu GenericName[uz]=DjVu кўрувчи GenericName[ven]=Tshivhoni tsha DjVu GenericName[xh]=Umboniseli we DjVu GenericName[zh_CN]=DjVu 查看器 GenericName[zh_HK]=DjVu 檢視器 GenericName[zu]=Umboniseli we DjVu Comment=Viewer for DjVu documents Comment[cs]=ProhlížeÄ dokumentů DjVu Comment[es]=Visor para documentos DjVu Comment[fr]=Afficheur pour documents DjVu Comment[ru]=Программа проÑмотра документов DjVu Comment[uk]=ПереглÑдач документів DjVu Comment[zh_CN]=DjVu文档查看工具 Comment[zh_TW]=DjVu文件檢視工具 djview4-4.10.5/desktopfiles/prebuilt-hi32-djview4.png000066400000000000000000000041241264256014000223230ustar00rootroot00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÑIDATX…½–[l\ÅÇ3s.{öêݵ×Yßâ81q”K0ˆˆ’T¥õ¥T„JU!A%D+µTB¥< D_« ©¨}¨ZÔª ¨DkA¤@P-7‰:›Å&‘;»ñÚ{ßsÎLŒW±H[ i¤£93ß÷;ÿù¾ÑÆÎÖŽ+î¹5&ƒ+-'iÙ¦8ᩈծE•ß°dXŽ:¦&&&¾ ÄÙÝWß7üÓúüÇ—=z'×íÝ”¥B¤”4›Mfgg9úþÑðàS/‘=õR÷pÂnF[–'NŸ. …7€×&&&ŠÿÀž+îy|_bé¾üg„¤¯ÕjüëÌÛØFrÕÐõùÅÅE¦§§ùèèTxüðÔâÉwŽMfÚ/ ×Í À»wL?㯮µÎØ«ƒÞÖÿ(9@½^§ê—‰8Ñ5óétšññqÆÇÇЭµÞóÐÏÚ3ùÏ©GfO'»~¸ºVž½1£õHꢡ &6ÆÐnûÔjujÍ2UYûÜõRJâ‰8•| ;Ï~×q wíOÒ÷†a<·ùüZkÊå*A Ylj*m…MŒ{œV£M½Þ$|&„ïû !Â>/€òkié³qó¦s6W*uŠKMÞœw)ú e+l 0 è#ã)¼SË$Ô"ƒƒòÜ# ‚ŒPáwVtx¶5ÃÃÃk6‹e&O´ùÛq¢P¸q›hL‰(l©ÑnŠÕbZ¤8eâLžf}k¯ý9ƒAp]³Û#•Ju^ÖëMf‹¯—]"1I2.IÅ1¸6,˜ebžbÙóÓ9Ž]“ÜC†Ÿˆ5wG [›íÞÖ½Ö†ONy½èJbIÜÄ"ЕØRIE,ªˆ;’˜#ˆ¹‚zÌ£ΜY^ûõB B¥u.@ß ?“=Z÷§FÐZ³ÿÐ4ÿúE>ªD¨iƒ ÚD#‚z¥ŠôÛŽŸB·Û¤bqG1W,1wrXÔÆÈsìØ'kÏ_J”Îë€#}:´²›úÑZ35»@2¢8X(i:¤VobBŸ¸%IX’vÛ§X®ðl‹KKxnÈôÇÇQ1‹…â"ßýñcc:–h¡Î°á²„ðÉ÷å1Æ`Œ!›°¨Št2B"êR­ú´Û>s¥:¥z‹‹6¦0 ª5Ÿ¤#éËtѨ¶Æ -›7Þ&|ßÿÔ–ò\€Í~°»êd³Y´Ö+…ƒÁG ƒ£C*Õ¥bƒùraA_.A&®Â†{âDm ¾²–’h­ñ}¥–6èu]`ô…æêF·‹mÛh­1Æ0_ªÓ=Øb~ÉОoÒÛã‘Îx4ü]Q%º31jA‰¨«ÊeQR’‰(šÕ&Ç>˜Á±t@J‰ZJÿz´ec¦cÿí7neÇh’¤h³!ë²e0Aܶ9R8CÔǵ‚€|&‰c‡d“WJ\`|ÛÝžM&aóìã?ZS„V( ×áàÞ‡c½¡ÉЛÀ²,´ÖD½Û¶mÆ©Îc¡ˆÆ"d»¢lJ°u8‡R´Fƒ!F(c°ÁÒ†å…2ù|/ù|!DÇ;„R­s@ˆKúuˆÕÅq´^±-™Œ5 ¼z ŒA¹Š®TËR±r¹` M[´P€2†f¥Îßüƒññ±N¬Ul-Yw mvزE6›EJÙ©­5;vlÅÿøÂJmeN€Ñfeƒ0 [DBÍr­ÉÁßd``‡½×‰ÁJ‚p}l Â#>™LfMr­5R ®ßJíÝ7hÌ~B»Ò6†Ð€´1l”#äÍFæN–xæÉÄ£|¿M$âR­ÔiL=K¬ä´¥"bÖ†ËËYÉh$Ò)ÂU !H§Ü|ó5¼úê{/Èõáç3x]ŹÕb™â‰Sœœ™cçÎKYZª38ØKø”^~Äég±»¿…Û±•…¿® ,[‰žJÚÂó¼Î°š|FJÁîÝ—S«5˜™™§ðÚ;ÌÏŸ&™L24ÔÃö-}ìÛuigïR¹†ž~šÜh:~%¢ð4—˜S”¬‹Ö ¤ k-üõ9^Šºø:IJ,”RH)‰Åbär9r¹½½½Œ rñÅ™ššbË–-ØUx!æ£ß“ÏÎám¿›–`lúf.­ãùf{ À[¶}ë¦êÈݹ÷Õ• KõG-qm-\K£T€‹ås¢MU·hJ—MaG#ìŸxŽC<'‘HÉdÈår¤Sûh¾ÿ(c±'pGî  ‡¯q¿Óú<ð@Çéõ?›oþ¥Bt !3!e!3GnÈ:V~9$ô”8}Iܺ)iÑçšVÚ£é8º‰60´hÑdûÀAnøöõˆ‘;i^¤U8HùÃCá‰åž?ìzxæ®óü¯ºø;¿K£0ºß=Ðk1:d5¶Ý6ú§}7Þ¶+!×@¼Ò.”rÜû‹Ù»þoŸ¥'ïÛïÏU÷_{Ë-»Î†(}øºþ°4ü[yá_L·=v¤Z8¿é•§þrHžÀù:Φ½Ì˜Ýr®û{êKw`U¿ùþX|¸¯ºÏí·ìzûpKîU¼59ÿWð«;Æâ¹œz¾¶éÞÒ\Ù9<99ýÈW p>}é5p!ý©GÐ[›š0IEND®B`‚djview4-4.10.5/desktopfiles/prebuilt-hi64-djview4.png000066400000000000000000000131171264256014000223320ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsììu85tEXtSoftwarewww.inkscape.org›î<ÌIDATxœíšyŒ]×}ß?¿sîòö™y³¯äPEQ$¥P #ÉZ¬%*£lű'iÿiÓµÐÂEÒi`$@‹È)šh¤…ÑuÔTJ­Å¶"×ÔFk_)Râ6Üf8û¼õ.çœþñæ8ä gh9u,ô78óî{÷¾{¿ÏùžßùÝó®8çØÈºoþ—y`U`væ‡ØØð‹?&¸þÆ_û³]qü•gü¹œ¥ZbÏbµÐ&mÁ%J\*X£Nph8çN"r ˜pÎÒZ¿ýØcMý¿n3vY=·|õK/ÍüÅÖ4æþ”Ÿùgñ©O} A)…ˆ¬jíÏ.Ü—¦)§Nbbb‚“'O211áŽ=ö²1é7'''ÿø•W^I|ðÁZë X‘I`jiiéü³Ï>›þDü̾þý¯-¿ëõþ”¡/ÜÉÃ?ŒÖúc_ôÌ™3|ó›ßäÕg_2åÐ4oüÂ]™ ;«u¥„!Iâ8&I*•Š;}úôü©S§Þ´Öþ8ÇñKO?ýtíc;ÂeôìXÝ5–~¹:—f<å?=þd³ÙÇ5WìðáÃL4ßç¶ëïÃᘩ̰µ¸uÍc“$áôéÓœø¥ÿjã„v‘yëídû IòþH÷=x€r¹Ìɳ)uêÄÄëëû>ãã㌷܃¡4M?ÿá‡~þ·ßæý¾Á¿ºç¡¸´dç¶.éwë^Þžù¥ÿêìzç]"{‡LJÝw oùÑ"ÜÀ*• qT߀µÌóˆïû›vÀZÇâb•ÅÅ ¾ïã “©šÐL¡ž‚q …,tû1¥¸ÆâÜïNcd¤ŽŽÂ•E¾lI’,ûaÑN0" bÖ;~m"{‡Ó„šÃ[6?þ«Õ:33 xžÆe:xù¼pfÉí9D+´¥„Zê ¶­÷ý€±r[áÈ‘ r¹«¯#6V+@;Á"\½CÆ0›·›ÿ³³‹,,TðóE^›ò8¾$è@ÐY…§@iY~¹‰"Šb¬K0YEU<>¨du‘íc˜›äÕW±{÷vŠÅÜÀs‚}Y¬™uº­¹©` ™Í8{vš…… IÐÁãG4Ç‚ŸÓÁ?Tøx>hOð´àið}A)¾!õcÈ&_q¸¢X( Rîíæ•WÞcvváŠXkÑFÂ4æ:a!ØÀùósT«Mf]ß>®°Y « 2d„0#¡àBà+|¥4ECW1Ò@¼­ZÀ‚¼b.Qœ »Ù:Êk¯¦R©o @;8çÐV°ä€K Þñëc&Í B¥ Z÷b ffˆ‚Î:üœ& …ЇL „¾"ãCƇ¬'BO†í92“ê& –Äák…ï)‚œ+Åù°ÄÀ`//¾ø6Qtù:Á9‡1­X­µxË9€+S€ìIR¬¥ñ!”Z{nN’”‰‰)¼BÏœTx9MA øžh!ÔøÒÊÖµŽË™Œ ÀÓ!¥à„8ž¯ð³Š¦R˜¾!òù o¾yä²ÚÁ·ahF)DÖO‚—F'²wؤ,…–-[×—ÿ¹s3„aÀKg.ãø ßß|M+pÏúB*2¡P((< Ä •%Wô–A)Qn}_A(-€aÖca`ûV&&¦˜Ÿ¯¬ëS[þp¡W¤¹~Ðæ³2þs«Z½ÞäüùyjºÄt¤ñ|ÁóÀ÷[úz‚'(,ÊP a ð€C¬1(O,K^œef¶‚¯„ÞÎ V‹•˜z3!”…l{—|Ï‘ZÇùé%òÙ€Îr›Ñ˜ÈÑ»mŒžzŽjµN¡péÔØÐ6ÆŠl~ºë7ÂÁÔŒ ²¢kí „?ùë7ùÆ_¾Ž˜ãgYˆ¡[R“âœ%Næë,VšøºÕƒ¥Œ¦àƒg Ú¦œZàÔäÕZO z„ž&P-õLž_àÔÔ,§¦f©Õð•k ­@ˆCŸr¹Ä‰çÖU@{9Î9‡ï¤¥€ÍB»†R£E„z§O¹\ÆZ»BÕ9Ë@WHÆf“ Êl’ ñÀX‡I ÍØE1ÅŒO! ðÅQÊúx&1­…ùZоÆh‹Õ‚³)Óó‹ød|¡˜™ž]¾ž‰Õôô•yùµ#<÷ö[GzxàŽ=k* U « KáÕ9@dïˆI1 ÊãC$I²jìléËâùгPÊQÌ(²akŠ+OƒÒPoÄàKµ&Õz„‰cbC½y|ÝZÒ9?=‡(ך•brf ´= NsâÔ4ÇOžÇ¦)ž:»©,.ñü5_ÿÿ$Ž?ZçhPJµ€\ÙhM­8<2²ª¨h[1£ñ=zªð}M>—! |üÀ#ãgÐJi©E Èr›«G4,Œt“ ­¡Rk"Ê(105SA†zËhXi.M~&$M ÙÀ£Z­’¦éJ]š[•à¦uî†>c™ SWN~!„®‚Æ÷4‘DÑj"(À˜žiR©$c1j LÕ8_‹Ð<-Œñ4d<4µx(âØ!Ö¡ž¢Og±¸ €¶­°ÎRÈø+~µ}»€çVÔæo††Œ¹A‰0¤ìÀZ»*xçù°•d ,޵ /€f#¦ZµD!f95]Ã÷ Wk´nõüPO‘Z¥I QìÈç,‰iŸ`°§ ½|îv)ZCÉ ¢}nmm_=§0lR#Ÿþ­¾¡Ô”a.Hèíí]E¸}‘…jL%øÊ‘¦†z”PR*•&µ8¡X ѪU+ÅÊí¯^Ùg¶v°Øˆ[3)¢ZzK>…(f‚LÏTp©AC³шÌ%s±|iMƒ—+„.P€ìI ¡YÈd2h­W€Ù¥˜j­A˜3TR¨G ¾Q”àŒ¡¿?C>çQÎpvåö7ãkD¾j9–rä‚y¬I1$he)…0ÐÝ…nEDoGŽŒ’Ô1=Se´¿Œ‰Sâ(¦%äVAX5 ‹ZYÙD),ÂÞ‘ÔÐô,Ã}DQ„ïû—(`©‘R©4Èiƒ§d%Ñi%Ôë óÓ5 (÷v`éîÊÒS è-ç u«wêQ„§ãC8c±¤ˆ¶ô=Jùüª±¿c´L!r¡•ijØÖ'„¾¬òïBˆuÈ&n‡/TÀžÑÔ0¦ôõõ­Ìÿ*à÷ÿÉNÞÿêµ*ý¡a)ÊE…¯QŠÞLJ>P­Y^>7I6Tärš0phíaÄ¡pz»Š4«³¤$d2–nUhUîôÌ@w']ÅõFqŽSGO“Ëy|ã7™sçέLym´ß+ÛJΛÎíë´Ž~BOOÏ%Á\³c;×ìØÎã?W›ÅêÅŽ\ëNÏ/ŸÇ÷`æÔ J 5“X % ôQ"€s+raH J[2¾‡¾€£U.ã„F­ÉÑ£§¹õÖ¸öÚkÙµkWë˜5†€ZQÀ&†Àè=¿£‡³Sf3)årÏó.‘{{h¨Lev†Æ|´à*Ë¿›ŽöåèP w [û2 ö}tžåÀÛM‰`HIu Ö.¯åÔ4€±8ci,,111ÉÎ[WùÓnƘ•BˆtsC ZØ1’š@D˜õc:::Vÿ‹/¶mÛ0gÏN3À&J°í ¼VT,dß2ÈÖ±!z{{ÐZ· ¢5ÐhRŒN1.E/;¥hååi’bã˜>ÿ&ccýtu/ þâ°¢€V|— ÈÞQc„¨;DDÃpÍ‹8çèèȳe˳'Ž“3 Òö}¸s8}áБ þ_pÑV©Øêm))F"­ß`Rƒ5†óg¦yã#<ðÀÏ®ëW;o‰Ê´sÀæÖöŒ$†Šg(ôtE™LfÍÞo·}ûv099KWmÛHH’Ö5D ¢ÚÙÙ®úNû\®2)IûOZ÷Ö9K%Ô–j|÷©)sø¾·¦?°ºÔ––Ô&–ÄDdïhj™ b:;;ÑZ¯8¹íl6äöÛ÷ðîëïÒߘ"ª7W ´T°|×JdíªÍƒö<\ë#EBJBJê³òyb,µfL½ñ·ß9ÈéÓç¹í¶ø›¿yžééù  í€\vIÌèO;¬ƒ™0¡X,ÁJðkY{†Ø±c„©©YÞõuvÜr ª·Uød=‡eYíË¥iŠçym6xø”â# ã{ ¤©%Žb¢fÌë/¾ÍÁƒïð¥/}ß×4Ѫ©ïBÚI@™€tƒiPÝ÷»é­˜ c …Šüדڅïo¿}år‰wž{‘ŽÙ ’¥:Q-&M—ïñU»fëq’ ´^Hȵrª‹ Qj¹¸¼öŒZ‹hÅl³#›%ŸÏ¯ÙûkÕ>x¼ÉÁg_dï×!£[©™.ïá2>*ÓúÝ×9G’¦ æ‚óXc‰RƒI ¤)sg¦yæÉ˜˜˜ä«_ýŠÅ=ö}î¿?•J'Ÿ|‰›nÚIÕÈú¼Ò0¥Û~kEÎ9w}}Ý<úè3\ýÕŒŽö355G£qúäúN~Ûx›æt“$Xû©ÖPˆVËuÀå ìÝâ, ™„l!O’$kXÏ.sÝuãlß>Âoñƒï \î °‡á«Ç‘r'6ôðBã)HR$I±QÌÙ£§ùðÐ Nœ8G6ð•¯|†Ý»·qôè}ô{<ðÀ~ææ*:tç;¯¤ùü×È…ò™ fþ‹'¿ËˆwŽ)¹ã#h…iåòË)€-À1?&—ˆá%½½^ï¯õyxÜ{ï>n½uï¼sŒ·Þ:Ê+?|—0 ÈåB|_ãûÍfD½Þ`a¡NzìÙs¿ø‹÷±k×Ö•ó^uÕ0W]5 @gg·Þ:F¹#Kó¥C¡3GgÏu˜ùÖêpÇüQ’¦e—‹xÙÝŠ‡ByŠtƒ:Àë¶tžbÚÈdº.éýËI=r¹ ·Ü²‹[nÙE³199ÏÒR—_~±±ŠÅ¥RžÎ΃ƒÝ«–³×»^¹#@Þü]J[·Ó{Íõ˜ùc«ö÷ÌÇÄŽ½’ð†i­Áe+A¯ÇÙ.QŠiÝĤ)“““8pkíÊ’x;¨µžÕZ“Ïç)•J‹EJ¥Ò%T„aÀ–-ýˆ³³Üu׫`­ôÅà‰±¯ü&åÅð·aýþ5ê›?Ž1·«Ž¼>L*‰§}ý'DN)õRªåê-¶ÈùCóœ:<Ía9HCšÊ’(‡¨VÀµ¶e2:;;c||œ­[·R,[KÕ-²´Ÿº\ð&ªÏOPq0ù=ÔÀ}x]ÛÖ jãØ²#Ùóöð=ëö>€ŒÝÿõ‘=ξv‹Ð;¤…¢§(iEÉS<Zh(C]Rê¤ÔI¨·¶mBÕFÔlLÍÄÔlLÃ¥°°þþ~¶mk9Ü××G½^§R©´~Ãó<‚ Õ×|>OWW]]­a)"4ÏâìÿšÝ{ …í÷ÂÀ}X¿ŸtþfþØòëqÒùc¤óÇ9³0ÆfvØ}å ÿ®ß~oMˆsŽ­?÷{ ‘;¹‘!´H¹ ¤§¨T±¨EŠË`ŠZÑá)о¢ÃW-h˯B‰¡fcªiD-¨™ˆjQI#ã4¢š6©»´¥0O¯!ˆöv6›]Qbûúà†,Å«7†ðÁÜg¬÷-ãô—ïýw—BØðqy€í>¢Ê‚”éF¤,\ô*ÒÍò~O¤\ò¥§¨U¾FÓ°Žê–غ7uøý7”t¶7z|EQ >MjI“JÜ`)jPIšT—[%mÒ %ÖhG.âÓÝoqëÏú”vl áøüPµ–dŸ0Vù3__ aS~TÛõП eÊ %ÞýÖ?šÝýÅÿš> n¯ƒa#ZÜp—'£Ý>ÅnOèö…Êz4tk( xÖR#íQéqn¹]Ó± Gg‡ªÕ¸áüþGþNü(¶ë¡?+€vÎ ƒÁ­l;çF:5£]šÞ…ÏL²¿ÿrÇŠŽkîÛ‘éÁj%jAø‡ÿþPk†üû`3¶ãsäáÜ ¸á;;^»û³/þÛ»ï ²A˜;ÎûSƒÕÅeŸÿƒCö§ÀÅö?¾zíþÀ7OÝuw¶³kçÆÞi.ÖƒÇS«¿ü‰ðßÿŵûCß<õé{³å ij'xîØv“nÿÄøo¿víþ00OÝ_¶³|íÚ’Ùc<ÿµÂÍ1Û¿ØûñÏþ{d¿òLJÖê§ž®/̾÷½VŘLáumCwmCŠ[xáÕˆJñVæÊÄ33 ×}¢üãÿòþÁZC?ðí'ë 3@Â(ßÿß/‘tÝDv×/P­ÖíÌÌÂÜ'j\hÿùWwîÏæ©Ï>˜ë,_sOü¯“è®Ýt]ÿçÎÍò oo6ãíŸXÿñ+;÷gBûbG¦°˜¹Ù]uÏ?Õï¼s49rääÙz½ùsþç¿}ä ྼóæÐ··ÿŸè ‡K¥ü­KK×­5O|ë[¿ÁOi!ôã´O\¼Rûÿ~Òü¤íÿq„7µIÙaIEND®B`‚djview4-4.10.5/djview4.spec000066400000000000000000000021501264256014000154030ustar00rootroot00000000000000%define release 1 %define version 4.10 Summary: DjVu viewer Name: djview4 Version: %{version} Release: %{release} License: GPL Group: Applications/Publishing Source: djview-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-root URL: http://djvu.sourceforge.net # BuildRequires: qt4-devel >= 4.2 # BuildRequires: qt4-designer >= 4.2 # BuildRequires: libjpeg-devel # BuildRequires: libtiff-devel # BuildRequires: glibc-devel # BuildRequires: gcc-c++ # BuildRequires: djvulibre >= 3.5.19 # BuildRequires: xdg-utils # Requires xdg-utils %description DjView4 is a viewer and browser plugin for DjVu documents, based on the DjVuLibre-3.5 library and the Qt4 toolkit. %prep %setup -q %build %configure make %install rm -rf %{buildroot} make DESTDIR=%{buildroot} install %clean rm -rf %{buildroot} %files %defattr(-, root, root) %doc README* COPYRIGHT COPYING NEWS %{_bindir} %{_datadir} %{_mandir} %changelog * Thu Jan 22 2015 Leon Bottou 4.9-2 - no longer rely on xdg portland tools for appfiles and icons * Sat Jan 27 2007 Leon Bottou 4.0-1 - initial release. djview4-4.10.5/mac/000077500000000000000000000000001264256014000137155ustar00rootroot00000000000000djview4-4.10.5/mac/Makefile.am000066400000000000000000000002061264256014000157470ustar00rootroot00000000000000 SUBDIRS = qlgenerator_src mdimporter_src EXTRA_DIST = skel ReadMe.rtf README EXTRA_DIST += make_djview_bundle.sh make_djview_dmg.sh djview4-4.10.5/mac/README000066400000000000000000000023061264256014000145760ustar00rootroot00000000000000 This directory contains mac specific tools. * Directory "mdimporter_src" contains the source code of the DjVu spotlight plugin contributed by Jeff Sickel years ago. The resulting binary module must be inserted into the template bundle "skel/Library/Spotlight/DjVu.mdimporter". * Directory "qlgenerator_src" contains the source code of the DjVu quicklook plugin contributed by Jeff Sickel years ago. The resulting binary module must be inserted into the template bundle "skel/Library/QuickLook/DjVu.qlgenerator". This code depends on the presence of the "ddjvu" executable in the DjView application bundle. * Shell script "make_djview_bundle.sh" creates a djview application bundle by taking the bundle template "skel", inserting the executable compiled in directory "src", adding the spotlight and quicklook plugins, adding a copy of the djvulibre command line tools and supporting files, and copying all the required Qt and Homebrew libraries. The final step patches all these executables and libraries in order to let them find each other without relying on anything not found in the bundle. * Shell script "make_djview_dmg.sh" creates a disk image suitable for binary distribution. djview4-4.10.5/mac/ReadMe.rtf000066400000000000000000000032301264256014000155650ustar00rootroot00000000000000{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210 {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Monaco;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww10800\viewh8400\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural \f0\fs24 \cf0 \ \ \fs72 \ul DjVuLibre-3.5.27+DjView-4.10\ \ulnone \ Prerequisites\ \fs24 \ \fs28 This version of DjView contains 64 bit Intel executables (x86_64) and has been tested on MacOS X 10.9 "Mavericks". Users of older versions of MacOS X are encouraged to use the previous binary release (3.5.22+4.5) which is available on SourceForge and contains universal 32 bit executables. \ \ \ \fs72 Installation\ \fs24 \ \fs28 To install DjView, simply copy the DjView application bundle into the Application folder.\ \ \ \fs72 Extras\ \fs28 \ Besides the DjView application, the application bundle contains a complete set of DjVuLibre command line utilities, a Spotlight plugin, and a Quicklook plugin. In principle, the two plugins are automatically detected by the Finder when you copy the application bundle into the Application folder. To access the command line utilities and their documentation, you must set the shell variable PATH and MANPATH appropriately. This can be achieved by invoking a convenient shell script hidden inside the application bundle:\ \ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural \f1 \cf0 $ eval `/Applications/DjView.app/Contents/setpath.sh`\ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural \f0 \cf0 \ \ \fs24 \ }djview4-4.10.5/mac/make_djview_bundle.sh000077500000000000000000000107511264256014000200760ustar00rootroot00000000000000#!/bin/bash # util run() { echo 2>&1 "+ $@" "$@" status=$? if test $status -ne 0 ; then echo "[Exit with status $status]" exit $status fi } # test BREWDIR BREWDIR=${BREWDIR-/usr/local} if test -d "$BREWDIR/Cellar/djvulibre" ; then BREWDIR=$(cd "$BREWDIR" ; pwd) # remove trailing slash else echo 2>&1 "Please define BREWDIR to the Homebrew base." exit 10 fi # test QTDIR QTDIR=${QTDIR-/usr/local} if test -x "$QTDIR/bin/qmake" ; then QTDIR=$(cd "$QTDIR" ; pwd) # remove trailing slash else echo 2>&1 "Please define QTDIR to the Qt base dir." exit 10 fi # change to this directory and clear DjView.app run cd $(dirname $0) || exit test -d DjView.app && run rm -rf DjView.app # copy qmake created bundle run cp -r ../src/djview.app DjView.app || exit bundle=DjView.app/Contents # copy skeleton dirs ( cd skel ; find . -type d ) | while read d ; do run mkdir -p "$bundle/$d" || exit done ( cd skel ; find . -type f ) | while read d ; do run cp "skel/$d" "$bundle/$d" || exit done # copy djvulibre dir brewlibdir="$BREWDIR/lib" brewliblink=$(readlink "$brewlibdir/libdjvulibre.dylib") djvulibrelibdir=$(cd "$brewlibdir" ; cd $(dirname "$brewliblink") ; pwd) djvulibre=$(dirname "$djvulibrelibdir") djvuname=$(dirname "$djvulibre") djvuname=$(basename "$djvuname") if test "$djvuname" != "djvulibre" ; then echo 2>&1 "Something wrong in the Homebrew links (exiting)" exit 10 fi ( cd $djvulibre ; find bin include lib share -type d ) | while read d ; do run mkdir -p "$bundle/$d" || exit done ( cd $djvulibre ; find bin include lib share -type f ) | while read d ; do run cp "$djvulibre/$d" "$bundle/$d" || exit done ( cd $djvulibre ; find bin include lib share -type l ) | while read d ; do target=$(readlink "$djvulibre/$d") run ln -s "$target" "$bundle/$d" || exit done # merge MacOS and bin directories run mv $bundle/bin/* $bundle/MacOS || exit run rmdir $bundle/bin || exit run ln -s ./MacOS $bundle/bin || exit # copy needed homebrew libraries for lib in $(otool -L $bundle/MacOS/ddjvu | awk '/^\t/{print $1}') ; do case "$lib" in $BREWDIR/*) libname=$(basename "$lib") test -r "./$bundle/lib/$libname" || \ run cp "$lib" "./$bundle/lib/$libname" || exit ;; esac done for lib in $(otool -L $bundle/MacOS/djview | awk '/^\t/{print $1}') ; do case "$lib" in $BREWDIR/*) libname=$(basename "$lib") test -r "./$bundle/lib/$libname" || \ run cp "$lib" "./$bundle/lib/$libname" || exit ;; $QTDIR/*) libname=$(basename "$lib") test -r "./$bundle/lib/$libname" || \ run cp "$lib" "./$bundle/lib/$libname" || exit ;; esac done # copy needed qt plugins ( cd "$QTDIR" ; \ ls -1 plugins/{platforms,imageformats,printsupport}/*.dylib | \ grep -v _debug.dylib ) | \ while read plugin ; do run mkdir -p $bundle/$(dirname "$plugin") || exit run cp "$QTDIR/$plugin" $bundle/"$plugin" || exit done # copy translations languages=$(ls -1 ../src/*.qm | sed -e 's/^[^_]*_//' -e 's/\.qm$//') run rm $bundle/Resources/empty.lproj run mkdir -p $bundle/Resources/en.lproj || exit for lang in $languages ; do run mkdir -p $bundle/Resources/$lang.lproj || exit run cp ../src/djview_$lang.qm $bundle/Resources/$lang.lproj/djview_$lang.qm || exit run cp "$QTDIR/translations/qt_$lang.qm" $bundle/Resources/$lang.lproj/ || exit if test -r "$QTDIR/translations/qtbase_$lang.qm" ; then run cp "$QTDIR"/translations/qt[a-z]*_$lang.qm $bundle/Resources/$lang.lproj/ || exit fi done # copy mac tools mdir=$bundle/Library/Spotlight/DjVu.mdimporter/Contents/MacOS run mkdir -p $mdir || exit run cp mdimporter_src/.libs/mdimporter.so $mdir/DjVu || exit qdir=$bundle/Library/QuickLook/DjVu.qlgenerator/Contents/MacOS run mkdir -p $qdir || exit run cp qlgenerator_src/.libs/qlgenerator.so $qdir/DjVu || exit # util to thread the libraries fixlib() { for n ; do bn=`basename $n` for l in `otool -L $n | awk '/^\t/ {print $1}'` ; do bl=`basename $l` r=`dirname $n` d='..' while ! test -d "$r/$d/lib" ; do d="$d/.."; done; if test -r "$r/$d/lib/$bl" ; then if test "$bn" = "$bl" ; then run install_name_tool -id "@loader_path/$d/lib/$bn" "$n" || exit else run install_name_tool -change "$l" "@loader_path/$d/lib/$bl" "$n" || exit fi fi done done } # thread libraries run chmod -R u+w DjView.app fixlib $bundle/bin/* fixlib $bundle/lib/* fixlib $bundle/plugins/*/* fixlib $mdir/DjVu fixlib $qdir/DjVu djview4-4.10.5/mac/make_djview_dmg.sh000077500000000000000000000012741264256014000173740ustar00rootroot00000000000000#!/bin/bash dmgname="DjVuLibre-3.5.27+DjView-4.10.2-intel64" cd $(dirname $0) if ! test -d DjView.app ; then echo 2>&1 "Run 'make_djview_bundle.sh' first". exit 10 fi run() { echo 2>&1 "+ $@" "$@" status=$? if test $status -ne 0 ; then echo "[Exit with status $status]" exit $status fi } dmg=dmg$$ test -d $dmg && run rm -rf $dmg trap "rm -rf $dmg 2>/dev/null" 0 run mkdir $dmg || exit run cp -r DjView.app $dmg || exit run cp ReadMe.rtf $dmg || exit book=DjView.app/Contents/share/doc/djvu/djvulibre-book-en.djvu run ln -s $book $dmg/Manual.djvu || exit run hdiutil create -ov -srcfolder $dmg -volname "$dmgname" "$dmgname".dmg || exit run rm -rf $dmg djview4-4.10.5/mac/mdimporter_src/000077500000000000000000000000001264256014000167465ustar00rootroot00000000000000djview4-4.10.5/mac/mdimporter_src/GetMetadataForFile.m000066400000000000000000000147051264256014000225620ustar00rootroot00000000000000// // GetMetadataForFile.m // DjVu // // Created by Jeff Sickel on 9/6/06. // Copyright (c) 2006 Corpus Callosum Corporation. All rights reserved. // #include #include #import #include #include #include #include "libdjvu/miniexp.h" #include "libdjvu/ddjvuapi.h" ddjvu_context_t *ctx; ddjvu_document_t *doc; #pragma mark - void handle(int wait) { const ddjvu_message_t *msg; if (!ctx) return; if (wait) msg = ddjvu_message_wait(ctx); while ((msg = ddjvu_message_peek(ctx))) { switch(msg->m_any.tag) { case DDJVU_ERROR: NSLog(@"%s", msg->m_error.message); if (msg->m_error.filename) NSLog(@"'%s:%d'", msg->m_error.filename, msg->m_error.lineno); return; break; // never gets here default: break; } ddjvu_message_pop(ctx); } } #pragma mark - void mdprint(NSMutableString *str, miniexp_t r) { if (miniexp_consp(r)) { while (miniexp_consp(r)) { mdprint(str, miniexp_car(r)); r = miniexp_cdr(r); } } else if (miniexp_stringp(r)) { [str appendFormat:@" %s", miniexp_to_str(r)]; } } void mdfprint(FILE *str, miniexp_t r) { if (miniexp_consp(r)) { while (miniexp_consp(r)) { mdfprint(str, miniexp_car(r)); r = miniexp_cdr(r); } } else if (miniexp_stringp(r)) { fprintf(str, " %s", miniexp_to_str(r)); } } #pragma mark - /* ----------------------------------------------------------------------------- Get metadata attributes from file This function's job is to extract useful information your file format supports and return it as a dictionary ----------------------------------------------------------------------------- */ Boolean GetMetadataForFile(void* thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile) { Boolean result = NO; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSProcessInfo *pinfo = nil; NSString *path = (NSString *)pathToFile; NSMutableDictionary *dictionary = (NSMutableDictionary *)attributes; int npages; miniexp_t expr; pinfo = [NSProcessInfo processInfo]; if (! (ctx = ddjvu_context_create([[pinfo processName] cStringUsingEncoding:NSASCIIStringEncoding]))) { NSLog(@"Cannot create djvu conext for '%@'.", path); goto pop; } if (! (doc = ddjvu_document_create_by_filename(ctx, [path fileSystemRepresentation], TRUE))) { NSLog(@"Cannot open djvu document '%@'.", path); goto pop; } while (! ddjvu_document_decoding_done(doc)) handle(TRUE); /* Pull any available metadata from the file at the specified path */ /* Return the attribute keys and attribute values in the dict */ /* Return TRUE if successful, FALSE if there was no data provided */ npages = ddjvu_document_get_pagenum(doc); if (npages) { int i; ddjvu_status_t r; ddjvu_pageinfo_t info; double f = 1.0; NSMutableString *buf = [NSMutableString string]; for (i=0; i= DDJVU_JOB_FAILED) goto pop; f = 72.0 / (double)info.dpi; #define DjAddIntKey(n,k) \ [dictionary setObject:[NSNumber numberWithInt:n] forKey:(NSString *)k] DjAddIntKey(npages, kMDItemNumberOfPages); DjAddIntKey(info.height, kMDItemPixelHeight); DjAddIntKey(info.width, kMDItemPixelWidth); DjAddIntKey((int)(f * info.height), kMDItemPageHeight); DjAddIntKey((int)(f * info.width), kMDItemPageWidth); [dictionary setObject:[NSString stringWithFormat:@"%d", info.version] forKey:(NSString *)kMDItemVersion]; /** Image orientation: 0: no rotation 1: 90 degrees counter-clockwise 2: 180 degrees 3: 270 degrees counter-clockwise trying to map to kMDItemOrientation: Values are 0 is "Landscape" or 1 is "Portrait" */ DjAddIntKey(!(info.rotation), kMDItemOrientation); [dictionary setObject:@"DjVu File" forKey:(NSString *)kMDItemKind]; // implement in next release --- // kMDItemDescription // kMDItemCodecs ?? result = YES; } pop: if (doc) ddjvu_document_release(doc); if (ctx) ddjvu_context_release(ctx); [pool release]; return result; } djview4-4.10.5/mac/mdimporter_src/Makefile.am000066400000000000000000000005541264256014000210060ustar00rootroot00000000000000 mactoolsdir = ${libdir}/djview/mactools mactools_LTLIBRARIES = mdimporter.la mdimporter_la_SOURCES = main.c GetMetadataForFile.m mdimporter_la_CFLAGS = ${DDJVUAPI_CFLAGS} mdimporter_la_LIBADD = ${DDJVUAPI_LIBS} mdimporter_la_LDFLAGS = -module -avoid-version \ -framework System -framework CoreFoundation \ -framework CoreServices -framework Foundation djview4-4.10.5/mac/mdimporter_src/main.c000066400000000000000000000203511264256014000200370ustar00rootroot00000000000000// // main.c // DjVu // // Created by Jeff Sickel on 9/6/06. // Copyright (c) 2006 Corpus Callosum Corporation. All rights reserved. // //============================================================================== // // DO NO MODIFY THE CONTENT OF THIS FILE // // This file contains the generic CFPlug-in code necessary for your importer // To complete your importer implement the function in GetMetadataForFile.c // //============================================================================== #include #include #include // ----------------------------------------------------------------------------- // constants // ----------------------------------------------------------------------------- #define PLUGIN_ID "200A2D97-B602-4FAB-84DA-18DE40383D7C" // // Below is the generic glue code for all plug-ins. // // You should not have to modify this code aside from changing // names if you decide to change the names defined in the Info.plist // // ----------------------------------------------------------------------------- // typedefs // ----------------------------------------------------------------------------- // The import function to be implemented in GetMetadataForFile.c Boolean GetMetadataForFile(void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile); // The layout for an instance of MetaDataImporterPlugIn typedef struct __MetadataImporterPluginType { MDImporterInterfaceStruct *conduitInterface; CFUUIDRef factoryID; UInt32 refCount; } MetadataImporterPluginType; // ----------------------------------------------------------------------------- // prototypes // ----------------------------------------------------------------------------- // Forward declaration for the IUnknown implementation. // MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID); void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance); HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); ULONG MetadataImporterPluginAddRef(void *thisInstance); ULONG MetadataImporterPluginRelease(void *thisInstance); // ----------------------------------------------------------------------------- // testInterfaceFtbl definition // ----------------------------------------------------------------------------- // The TestInterface function table. // static MDImporterInterfaceStruct testInterfaceFtbl = { NULL, MetadataImporterQueryInterface, MetadataImporterPluginAddRef, MetadataImporterPluginRelease, GetMetadataForFile }; // ----------------------------------------------------------------------------- // AllocMetadataImporterPluginType // ----------------------------------------------------------------------------- // Utility function that allocates a new instance. // You can do some initial setup for the importer here if you wish // like allocating globals etc... // MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID) { MetadataImporterPluginType *theNewInstance; theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType)); memset(theNewInstance,0,sizeof(MetadataImporterPluginType)); /* Point to the function table */ theNewInstance->conduitInterface = &testInterfaceFtbl; /* Retain and keep an open instance refcount for each factory. */ theNewInstance->factoryID = CFRetain(inFactoryID); CFPlugInAddInstanceForFactory(inFactoryID); /* This function returns the IUnknown interface so set the refCount to one. */ theNewInstance->refCount = 1; return theNewInstance; } // ----------------------------------------------------------------------------- // DeallocDjVuMDImporterPluginType // ----------------------------------------------------------------------------- // Utility function that deallocates the instance when // the refCount goes to zero. // In the current implementation importer interfaces are never deallocated // but implement this as this might change in the future // void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance) { CFUUIDRef theFactoryID; theFactoryID = thisInstance->factoryID; free(thisInstance); if (theFactoryID){ CFPlugInRemoveInstanceForFactory(theFactoryID); CFRelease(theFactoryID); } } // ----------------------------------------------------------------------------- // MetadataImporterQueryInterface // ----------------------------------------------------------------------------- // Implementation of the IUnknown QueryInterface function. // HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) { CFUUIDRef interfaceID; interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); if (CFEqual(interfaceID,kMDImporterInterfaceID)){ /* If the Right interface was requested, bump the ref count, * set the ppv parameter equal to the instance, and * return good status. */ ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance); *ppv = thisInstance; CFRelease(interfaceID); return S_OK; }else{ if (CFEqual(interfaceID,IUnknownUUID)){ /* If the IUnknown interface was requested, same as above. */ ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance); *ppv = thisInstance; CFRelease(interfaceID); return S_OK; }else{ /* Requested interface unknown, bail with error. */ *ppv = NULL; CFRelease(interfaceID); return E_NOINTERFACE; } } } // ----------------------------------------------------------------------------- // MetadataImporterPluginAddRef // ----------------------------------------------------------------------------- // Implementation of reference counting for this type. Whenever an interface // is requested, bump the refCount for the instance. NOTE: returning the // refcount is a convention but is not required so don't rely on it. // ULONG MetadataImporterPluginAddRef(void *thisInstance) { ((MetadataImporterPluginType *)thisInstance )->refCount += 1; return ((MetadataImporterPluginType*) thisInstance)->refCount; } // ----------------------------------------------------------------------------- // SampleCMPluginRelease // ----------------------------------------------------------------------------- // When an interface is released, decrement the refCount. // If the refCount goes to zero, deallocate the instance. // ULONG MetadataImporterPluginRelease(void *thisInstance) { ((MetadataImporterPluginType*)thisInstance)->refCount -= 1; if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){ DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance ); return 0; }else{ return ((MetadataImporterPluginType*) thisInstance )->refCount; } } // ----------------------------------------------------------------------------- // DjVuMDImporterPluginFactory // ----------------------------------------------------------------------------- // Implementation of the factory function for this type. // void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) { MetadataImporterPluginType *result; CFUUIDRef uuid; /* If correct type is being requested, allocate an * instance of TestType and return the IUnknown interface. */ if (CFEqual(typeID,kMDImporterTypeID)){ uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); result = AllocMetadataImporterPluginType(uuid); CFRelease(uuid); return result; } /* If the requested type is incorrect, return NULL. */ return NULL; } djview4-4.10.5/mac/qlgenerator_src/000077500000000000000000000000001264256014000171075ustar00rootroot00000000000000djview4-4.10.5/mac/qlgenerator_src/GeneratePreviewForURL.m000066400000000000000000000162161264256014000234210ustar00rootroot00000000000000#include #include #include #import #include "ddjvuRef.h" /* ----------------------------------------------------------------------------- Generate a preview for file This function's job is to create preview for designated file ----------------------------------------------------------------------------- */ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) { CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview); char *ddjvu = ddjvuPath(bundle); if (ddjvu != NULL) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"]; CFUUIDRef uuid = NULL; CFStringRef uuidString; BOOL debug = FALSE; NSString *tmpPath = nil; if (domain && [domain objectForKey:@"previewpages"]) if ([[domain objectForKey:@"previewpages"] intValue] == 0) goto poppool; if (domain && [domain objectForKey:@"debug"]) { debug = [[domain objectForKey:@"debug"] boolValue]; } uuid = CFUUIDCreate(kCFAllocatorDefault); if (uuid) { uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid); if (uuidString) { tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat:@"djvuql-%@", uuidString]]; CFRelease(uuidString); } CFRelease(uuid); } if (tmpPath) { const char *cmd = NULL; CFStringRef cmdRef; int page = 0; int pages = 1; int maxpages = 5; int width = 612; // default 8.5x11 in points int height = 792; CGSize size; MDItemRef mditem = NULL; NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); NSString *dest = nil; NSFileManager *fmgr = [NSFileManager defaultManager]; [fmgr createDirectoryAtPath:tmpPath attributes:nil]; mditem = MDItemCreate(kCFAllocatorDefault, (CFStringRef)source); if (mditem) { CFTypeRef ref = NULL; ref = MDItemCopyAttribute(mditem, kMDItemNumberOfPages); if (ref) { CFNumberGetValue(ref, kCFNumberIntType, &pages); CFRelease(ref); } ref = MDItemCopyAttribute(mditem, kMDItemPageWidth); if (ref) { CFNumberGetValue(ref, kCFNumberIntType, &width); CFRelease(ref); } ref = MDItemCopyAttribute(mditem, kMDItemPageHeight); if (ref) { CFNumberGetValue(ref, kCFNumberIntType, &height); CFRelease(ref); } CFRelease(mditem); } if (domain && [domain objectForKey:@"previewpages"]) maxpages = [[domain objectForKey:@"previewpages"] intValue]; if (debug) { NSLog(@"metadata: pages=%d, width=%d, height=%d", pages, width, height); NSLog(@"maxpages=%d", maxpages); } CGRect rect = CGRectMake(0, 0, width, height); CGContextRef c; c = QLPreviewRequestCreatePDFContext(preview, &rect, NULL, NULL); page = 0; do { page++; dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%04d.tiff", page]]; size = CGSizeMake(width, height); cmdRef = CFStringCreateWithFormat(NULL, NULL, CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), ddjvu, page, width, height, [source fileSystemRepresentation], [dest fileSystemRepresentation]); cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding()); if (cmd != NULL) { if (debug) NSLog(@"%s", cmd); if ((system(cmd) == 0) && ([fmgr fileExistsAtPath:dest])) { NSURL *durl = [NSURL fileURLWithPath:dest]; CGImageSourceRef sourceRef; sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL); if(sourceRef) { CGImageRef imageRef = NULL; imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL); if (imageRef) { CGFloat offset = height * (page-1); CGRectOffset(rect, 0.0, offset); CGPDFContextBeginPage(c, NULL); CGContextSaveGState(c); CGContextDrawImage(c, rect, imageRef); if (page == maxpages && maxpages < pages) { CGAffineTransform m; CFURLRef more = CFBundleCopyResourceURL(bundle, CFSTR("more_pages"), CFSTR("pdf"), NULL); CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL(more); CGPDFPageRef pdf = CGPDFDocumentGetPage(doc, 1); CGFloat offset = height * page; CGRectOffset(rect, 0.0, offset); CGContextSaveGState(c); m = CGPDFPageGetDrawingTransform(pdf, kCGPDFMediaBox, rect, 0, true); CGContextConcatCTM(c, m); CGContextDrawPDFPage(c, pdf); CGContextRestoreGState(c); CFRelease(doc); } CGContextRestoreGState(c); CGPDFContextEndPage(c); CFRelease(imageRef); } CFRelease(sourceRef); } } } CFRelease(cmdRef); } while (page < pages && page < maxpages); CGPDFContextClose(c); QLPreviewRequestFlushContext(preview, c); CFRelease(c); [fmgr removeFileAtPath:tmpPath handler:nil]; [source release]; } poppool: [pool release]; } return noErr; } void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview) { // implement only if supported } djview4-4.10.5/mac/qlgenerator_src/GenerateThumbnailForURL.m000066400000000000000000000111171264256014000237160ustar00rootroot00000000000000#include #include #include #import #include #include "ddjvuRef.h" /* ----------------------------------------------------------------------------- Generate a thumbnail for file This function's job is to create thumbnail for designated file as fast as possible ----------------------------------------------------------------------------- */ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) { char *ddjvu = ddjvuPath(QLThumbnailRequestGetGeneratorBundle(thumbnail)); if (ddjvu != NULL) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"]; CFUUIDRef uuid; CFStringRef uuidString; NSString *tmpPath = nil; BOOL debug = FALSE; if (domain && [domain objectForKey:@"debug"]) { debug = [[domain objectForKey:@"debug"] boolValue]; } if (domain && [domain objectForKey:@"thumbnail"] && ([[domain objectForKey:@"thumbnail"] boolValue] == FALSE)) { if (debug) NSLog(@"skip thumbnail for %@", url); CFStringRef ext = CFURLCopyPathExtension(url); if (ext) { NSImage *img = [[NSWorkspace sharedWorkspace] iconForFileType:(NSString*)ext]; if (img) { NSData *data = [img TIFFRepresentation]; QLThumbnailRequestSetImageWithData(thumbnail, (CFDataRef)data, NULL); } CFRelease(ext); } } else { if (debug) { CFShow(contentTypeUTI); CFShow(options); } uuid = CFUUIDCreate(kCFAllocatorDefault); if (uuid) { uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid); if (uuidString) { tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat:@"djvuql-%@", uuidString]]; CFRelease(uuidString); } CFRelease(uuid); } if (tmpPath) { NSFileManager *fmgr = [NSFileManager defaultManager]; const char *cmd = NULL; CFStringRef cmdRef; int page = 1; NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); NSString *dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%d.tiff", page]]; [fmgr createDirectoryAtPath:tmpPath attributes:nil]; cmdRef = CFStringCreateWithFormat(NULL, NULL, CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), ddjvu, page, (int)maxSize.width, (int)maxSize.height, [source fileSystemRepresentation], [dest fileSystemRepresentation]); cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding()); if (cmd != NULL) { if (debug) NSLog(@"ddjvu: %s", cmd); if (system(cmd) == 0) { NSURL *durl = [NSURL fileURLWithPath:dest]; CGImageRef imageRef = NULL; CGImageSourceRef sourceRef; sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL); if(sourceRef) { imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL); if (imageRef) QLThumbnailRequestSetImage(thumbnail, imageRef, NULL); CFRelease(sourceRef); } } } [fmgr removeFileAtPath:tmpPath handler:nil]; CFRelease(cmdRef); [source release]; } } [pool release]; } return noErr; } void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail) { // implement only if supported } djview4-4.10.5/mac/qlgenerator_src/Makefile.am000066400000000000000000000006331264256014000211450ustar00rootroot00000000000000 mactoolsdir = ${libdir}/djview/mactools mactools_LTLIBRARIES = qlgenerator.la qlgenerator_la_SOURCES = \ GeneratePreviewForURL.m GenerateThumbnailForURL.m \ ddjvuRef.h ddjvuRef.c main.c qlgenerator_la_OBJCFLAGS = -w qlgenerator_la_LDFLAGS = -module -avoid-version \ -framework System -framework CoreFoundation -framework CoreServices \ -framework Foundation -framework Cocoa -framework QuickLook djview4-4.10.5/mac/qlgenerator_src/ddjvuRef.c000066400000000000000000000043611264256014000210300ustar00rootroot00000000000000/* * ddjvuRef.c * QuickLookDjVu * * Created by Jeff Sickel on 11/27/07. * Copyright 2007 Corpus Callosum Corporation. All rights reserved. * */ #include "ddjvuRef.h" #include #include #include /* for MAXPATHLEN */ #include #include static CFURLRef CFURLCopyAppendAndCheck(CFURLRef url, CFStringRef path, Boolean isdir) { struct stat fstat; char buf[MAXPATHLEN]; url = CFURLCreateWithFileSystemPathRelativeToBase(NULL, path, kCFURLPOSIXPathStyle, isdir, url); if (CFURLGetFileSystemRepresentation(url, true, (UInt8 *)buf, MAXPATHLEN)) if (stat(buf, &fstat) >= 0) return url; CFRelease(url); return 0; } static char* ddjvuPathNoCache(CFBundleRef bundle) { CFURLRef ddjvuRef = NULL; CFURLRef djviewRef = NULL; CFURLRef qlRef = NULL; /* Using bundle */ if (!ddjvuRef && bundle && !qlRef) qlRef = CFBundleCopyExecutableURL(bundle); if (!ddjvuRef && qlRef) ddjvuRef = CFURLCopyAppendAndCheck(qlRef, CFSTR("../../../../../bin/ddjvu"), false); if (!ddjvuRef) bundle = CFBundleGetBundleWithIdentifier(CFSTR("org.djvu.DjView")); if (!ddjvuRef && bundle) ddjvuRef = CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("ddjvu")); if (!ddjvuRef && bundle) ddjvuRef = CFBundleCopyResourceURL(bundle, CFSTR("ddjvu"), NULL, NULL); if (!ddjvuRef && !djviewRef && bundle) djviewRef = CFBundleCopyExecutableURL(bundle); if (!ddjvuRef && djviewRef) ddjvuRef = CFURLCopyAppendAndCheck(djviewRef, CFSTR("../bin/ddjvu"), false); if (!ddjvuRef && djviewRef) ddjvuRef = CFURLCopyAppendAndCheck(djviewRef, CFSTR("ddjvu"), false); if (djviewRef) CFRelease(djviewRef); if (qlRef) CFRelease(qlRef); char *ans = NULL; char buf[MAXPATHLEN]; if (CFURLGetFileSystemRepresentation(ddjvuRef, true, (UInt8 *)buf, MAXPATHLEN)) ans = strdup(buf); if (ddjvuRef) CFRelease(ddjvuRef); return ans; } char * ddjvuPath(CFBundleRef bundle) { struct stat fstat; static char *ans = NULL; if (ans == NULL || stat(ans, &fstat) < 0) ans = ddjvuPathNoCache(bundle); return ans; } djview4-4.10.5/mac/qlgenerator_src/ddjvuRef.h000066400000000000000000000003471264256014000210350ustar00rootroot00000000000000/* * ddjvuRef.h * QuickLookDjVu * * Created by Jeff Sickel on 11/27/07. * Copyright 2007 Corpus Callosum Corporation. All rights reserved. * */ #include char *ddjvuPath(CFBundleRef bundle); djview4-4.10.5/mac/qlgenerator_src/main.c000066400000000000000000000223361264256014000202050ustar00rootroot00000000000000//============================================================================== // // DO NO MODIFY THE CONTENT OF THIS FILE // // This file contains the generic CFPlug-in code necessary for your generator // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c // //============================================================================== #include #include #include #include // ----------------------------------------------------------------------------- // constants // ----------------------------------------------------------------------------- // Don't modify this line #define PLUGIN_ID "C493E7CF-241D-40DF-91CD-04BC3F6A7F06" // // Below is the generic glue code for all plug-ins. // // You should not have to modify this code aside from changing // names if you decide to change the names defined in the Info.plist // // ----------------------------------------------------------------------------- // typedefs // ----------------------------------------------------------------------------- // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); // The preview generation function to be implemented in GeneratePreviewForURL.c OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); // The layout for an instance of QuickLookGeneratorPlugIn typedef struct __QuickLookGeneratorPluginType { void *conduitInterface; CFUUIDRef factoryID; UInt32 refCount; } QuickLookGeneratorPluginType; // ----------------------------------------------------------------------------- // prototypes // ----------------------------------------------------------------------------- // Forward declaration for the IUnknown implementation. // QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); ULONG QuickLookGeneratorPluginRelease(void *thisInstance); // ----------------------------------------------------------------------------- // myInterfaceFtbl definition // ----------------------------------------------------------------------------- // The QLGeneratorInterfaceStruct function table. // static QLGeneratorInterfaceStruct myInterfaceFtbl = { NULL, QuickLookGeneratorQueryInterface, QuickLookGeneratorPluginAddRef, QuickLookGeneratorPluginRelease, NULL, NULL, NULL, NULL }; // ----------------------------------------------------------------------------- // AllocQuickLookGeneratorPluginType // ----------------------------------------------------------------------------- // Utility function that allocates a new instance. // You can do some initial setup for the generator here if you wish // like allocating globals etc... // QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) { QuickLookGeneratorPluginType *theNewInstance; theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); /* Retain and keep an open instance refcount for each factory. */ theNewInstance->factoryID = CFRetain(inFactoryID); CFPlugInAddInstanceForFactory(inFactoryID); /* This function returns the IUnknown interface so set the refCount to one. */ theNewInstance->refCount = 1; return theNewInstance; } // ----------------------------------------------------------------------------- // DeallocQuickLookGeneratorPluginType // ----------------------------------------------------------------------------- // Utility function that deallocates the instance when // the refCount goes to zero. // In the current implementation generator interfaces are never deallocated // but implement this as this might change in the future // void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) { CFUUIDRef theFactoryID; theFactoryID = thisInstance->factoryID; /* Free the conduitInterface table up */ free(thisInstance->conduitInterface); /* Free the instance structure */ free(thisInstance); if (theFactoryID){ CFPlugInRemoveInstanceForFactory(theFactoryID); CFRelease(theFactoryID); } } // ----------------------------------------------------------------------------- // QuickLookGeneratorQueryInterface // ----------------------------------------------------------------------------- // Implementation of the IUnknown QueryInterface function. // HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) { CFUUIDRef interfaceID; interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ /* If the Right interface was requested, bump the ref count, * set the ppv parameter equal to the instance, and * return good status. */ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); *ppv = thisInstance; CFRelease(interfaceID); return S_OK; }else{ /* Requested interface unknown, bail with error. */ *ppv = NULL; CFRelease(interfaceID); return E_NOINTERFACE; } } // ----------------------------------------------------------------------------- // QuickLookGeneratorPluginAddRef // ----------------------------------------------------------------------------- // Implementation of reference counting for this type. Whenever an interface // is requested, bump the refCount for the instance. NOTE: returning the // refcount is a convention but is not required so don't rely on it. // ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) { ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; } // ----------------------------------------------------------------------------- // QuickLookGeneratorPluginRelease // ----------------------------------------------------------------------------- // When an interface is released, decrement the refCount. // If the refCount goes to zero, deallocate the instance. // ULONG QuickLookGeneratorPluginRelease(void *thisInstance) { ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); return 0; }else{ return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; } } // ----------------------------------------------------------------------------- // QuickLookGeneratorPluginFactory // ----------------------------------------------------------------------------- void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) { QuickLookGeneratorPluginType *result; CFUUIDRef uuid; /* If correct type is being requested, allocate an * instance of kQLGeneratorTypeID and return the IUnknown interface. */ if (CFEqual(typeID,kQLGeneratorTypeID)){ uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); result = AllocQuickLookGeneratorPluginType(uuid); CFRelease(uuid); return result; } /* If the requested type is incorrect, return NULL. */ return NULL; } djview4-4.10.5/mac/skel/000077500000000000000000000000001264256014000146535ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/000077500000000000000000000000001264256014000162575ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/000077500000000000000000000000001264256014000201605ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/000077500000000000000000000000001264256014000233525ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/000077500000000000000000000000001264256014000251475ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Info.plist000066400000000000000000000032071264256014000271210ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeRole QLGenerator LSItemContentTypes org.djvu.DjView org.djvuzone.djvulibre.djvu com.lizardtech.djvu CFBundleExecutable djvu CFBundleGetInfoString 1.1, Copyright 2007, 2009 Corpus Callosum Corporation CFBundleIdentifier org.djvu.qlgenerator CFBundleInfoDictionaryVersion 6.0 CFBundleName djvu CFBundleShortVersionString 1.1 CFBundleVersion 1.1 CFPlugInDynamicRegisterFunction CFPlugInDynamicRegistration NO CFPlugInFactories C493E7CF-241D-40DF-91CD-04BC3F6A7F06 QuickLookGeneratorPluginFactory CFPlugInTypes 5E2D9680-5022-40FA-B806-43349622E5B9 C493E7CF-241D-40DF-91CD-04BC3F6A7F06 CFPlugInUnloadFunction QLNeedsToBeRunInMainThread QLSupportsConcurrentRequests QLThumbnailMinimumSize 17 djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Resources/000077500000000000000000000000001264256014000271215ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Resources/English.lproj/000077500000000000000000000000001264256014000316375ustar00rootroot00000000000000InfoPlist.strings000066400000000000000000000006741264256014000351110ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Resources/English.lprojþÿ/* Localized versions of Info.plist keys */ CFBundleGetInfoString = "version 1.1, Copyright (c) 2007, 2009 Corpus Callosum Corporation"; NSHumanReadableCopyright = "Copyright (c) 2007, 2009 Corpus Callosum Corporation"; djview4-4.10.5/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Resources/more_pages.pdf000066400000000000000000000061421264256014000317400ustar00rootroot00000000000000%PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xVKr\7 Üó¸ÀPÀïZ‹TeçÒ"xyc¥ÊÑÂ×ws¾H㔥ÍL6ÁFƒßé }§„̓F¦ÿ¦¿èÊôƒ˜þ¤§çw¦ç|~y¦§?ðåë;ørcb±37SÓÚÂñF­ÄQFƯ“JéôFC£jÅBM1§¡e#¥ÇÒ¥–·H8hý˜mùø”`ìm,Žºå¨9óPËP†œƒôÇο×; ‡Âç3ô‚bÞ v¼SŠRÒü£÷cNfá$•Ø3µSæ4 #¢‘s¡¦XkVq„Tbœ€X—Èœ¥à€Ü{Ô‘3Ý$J•"ÄÈ Â6’%öœ•®qRb®­ììlˆ3À÷¸à<±ßÊNñÜzÙ qž—¸×»vJ §v„pVfÊî¶¿r± dS'bHä–j0- ÛU™8€üRKŒ’­«i©‡%KÀÝ´4¶]KÍS—«9‡% cÅ~žÝdS-Cµ £îVŠ ÕO%ñRNžeãžc j5U‡: R(¨Ðȇ ˆË‚‚ÖÈ#·X vÍ)?²Hô¼¤Ùd§Ä.ÐŒB¬‘}h©]ÐÅh0Ï©‡N:§ÞÅz\>IÜhzÞé—ur7ñHã9Kfù?YMs ¹Õ\NøÁj¬¦´Æ8¶.~#ôuÂû ïVwÄíÀÃÌ4æðæXjÕ‹µ`°H,Û~°¼(æßÕlpšÍU²ì³þ'ânçqFó OnÖ² ld.ì°-›¯Á¡ð™^3TǸxÍ~Üø@ÂôX×àTì—›í5¦*¦35å\æÉozs0£¨¦çŽAuQøû 2¹$Mjk$=ôU¨£C èÄ‘å´@o4n‘\¡Þ…¬Ö Äâ`£åÒ&=|Æûã‘ñJFÉ¥7¤ƒñ†ZŠ\¹NÛ±H<€bësfY~Gœƒ¬¸ÍôðôaÔ(­Ï;41¦~ÂÓkΗÝ}>K›£=ƒ1-m ˆBÓøDßÊó¡†U€,ðä¹¾ÁÙíš”2Æpj 97€¹ª°Pdë÷ N‹ z¥/?Óï]D endstream endobj 5 0 obj 1016 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 349 94] >> endobj 6 0 obj << /ProcSet [ /PDF ] /ColorSpace << /Cs1 7 0 R >> /ExtGState << /Gs1 8 0 R /Gs2 9 0 R /Gs3 10 0 R /Gs4 11 0 R >> >> endobj 8 0 obj << /Type /ExtGState /CA 0.7500000 >> endobj 9 0 obj << /Type /ExtGState /ca 0.7500000 >> endobj 10 0 obj << /Type /ExtGState /CA 1 >> endobj 11 0 obj << /Type /ExtGState /ca 1 >> endobj 12 0 obj << /Length 13 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream x…ROHQþÍ6„ˆA…xˆw •)¬¬ ÚvuY•m[•Ò¢gߺ£³3Ó›Ù5Å“]¢É`¨‰µé²™…}v*Ëìðèñ²bç{aÿ[QÓÀ'a?d‡yÖ­ö®Sà{„=5àήÅñÚŠ^-C÷T#hŒsMÄÓ×9s¤ˆï1Ô˜÷F9¦ 1w–ª7€;aYªf ±]û®ê%î{wÓã;Ñ›9 \ Ir±ÙÐ< X}‹°I<>ÎUàw¨˜À¹‰ÜÍ(÷Õg£RVzWÆOã¹ñÅøelÏ€~¬v×{|ÿéãu×¶><ùzÜ9®½UaVqe ÝÿÇ2„Ù'9¦ÁÓ¡YXkØväšÌL° (Ä>—ú’UÜÕîí¸EÌP>,l%ºKTn)Ôê=ƒJ¬+Øvp’Ä,Z¸Skº9xwØ"zmùMW²ë†þúözûÚòmʨ)(ͳDf”±[£äÝxÛýf‘Ÿ8:¾ç½ŠZÉþIE?…9Z*òUôVPÖÄog~¶~\?¥çõAý< =­ŸÑ¯è£¾ tIÏÂsQ£Ið°i!â Šƒ3ÔNTcâ)ñò´[d‘ý@ýf endstream endobj 13 0 obj 704 endobj 7 0 obj [ /ICCBased 12 0 R ] endobj 3 0 obj << /Type /Pages /MediaBox [0 0 612 792] /Count 1 /Kids [ 2 0 R ] >> endobj 14 0 obj << /Type /Catalog /Pages 3 0 R /Version /1.4 >> endobj 1 0 obj << /Producer (Mac OS X 10.5.1 Quartz PDFContext) /CreationDate (D:20071210185500Z00'00') /ModDate (D:20071210185500Z00'00') >> endobj xref 0 15 0000000000 65535 f 0000002571 00000 n 0000001132 00000 n 0000002424 00000 n 0000000022 00000 n 0000001112 00000 n 0000001235 00000 n 0000002388 00000 n 0000001366 00000 n 0000001418 00000 n 0000001470 00000 n 0000001515 00000 n 0000001560 00000 n 0000002368 00000 n 0000002507 00000 n trailer << /Size 15 /Root 14 0 R /Info 1 0 R /ID [ ] >> startxref 2713 %%EOF djview4-4.10.5/mac/skel/Library/Spotlight/000077500000000000000000000000001264256014000202345ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/000077500000000000000000000000001264256014000232655ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/000077500000000000000000000000001264256014000250625ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Info.plist000066400000000000000000000064161264256014000270410ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeExtensions djvu djv CFBundleTypeName DjVu file CFBundleTypeRole MDImporter LSItemContentTypes org.djvu.DjView org.djvuzone.djvulibre.djvu com.lizardtech.djvu public.djvu CFBundleExecutable DjVu CFBundleGetInfoString 1.3, Copyright Corpus Callosum Corporation 2006 CFBundleIdentifier org.djvuzone.djvulibre.MDImporter.DjVu CFBundleInfoDictionaryVersion 6.0 CFBundleName DjVu Importer for Spotlight CFBundleShortVersionString 1.3 CFBundleVersion 3.5.21 CFPlugInDynamicRegisterFunction CFPlugInDynamicRegistration NO CFPlugInFactories 200A2D97-B602-4FAB-84DA-18DE40383D7C MetadataImporterPluginFactory CFPlugInTypes 8B08C4BF-415B-11D8-B3F9-0003936726FC 200A2D97-B602-4FAB-84DA-18DE40383D7C CFPlugInUnloadFunction UTExportedTypeDeclarations UTTypeConformsTo org.djvuzone.djvulibre.djvu com.lizardtech.djvu public.djvu public.composite-content public.data UTTypeDescription DjVu File UTTypeIdentifier org.djvuzone.djvulibre.djvu UTTypeReferenceURL http://djvulibre.djvuzone.org/ UTTypeTagSpecification com.apple.ostype AT&T public.filename-extension djvu djv UTImportedTypeDeclarations UTTypeConformsTo com.lizardtech.djvu org.djvuzone.djvulibre.djvu public.djvu public.composite-content public.data UTTypeDescription DjVu File UTTypeIdentifier com.lizardtech.djvu UTTypeReferenceURL http://www.lizardtech.com/ UTTypeTagSpecification com.apple.ostype AT&T public.filename-extension djvu djv djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Resources/000077500000000000000000000000001264256014000270345ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Resources/English.lproj/000077500000000000000000000000001264256014000315525ustar00rootroot00000000000000InfoPlist.strings000066400000000000000000000004021264256014000350110ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Resources/English.lprojþÿ/* Localized versions of Info.plist keys */ NSHumanReadableCopyright = "Copyright (c) 2006-2007 Corpus Callosum Corporation."; schema.strings000066400000000000000000000023741264256014000343540ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Resources/English.lprojþÿ /* Localized DisplayNames for your custom metadata attributes */ /* The form is: "myMetadataKey" = "My Metadata Key"; */ /* The name on the left is the name defined in schema.xml */ /* The name on the right is what the user will see */ "com_Foo_YourAttrName" = "Your Localized Attr Name"; /* Localized Description of you custom metadata attributes */ /* The form is: "myMetadataKey.Description" = "stuff"; /* com_Foo_YourAttrName should be definded in the schema.xml file */ /* The value on the right will be displayed by the Finder etc.. */ "com_Foo_YourAttrName.Description" = "Localized description of your attribute";djview4-4.10.5/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Resources/schema.xml000066400000000000000000000055561264256014000310310ustar00rootroot00000000000000 Custom attributes that this metadata importer supports. Below is an example of a multivalued string attribute. Other types are CFNumber, CFDate, CFBoolean and CFData. The keys that this metadata importer handles. kMDItemTextContent kMDItemContentType kMDItemNumberOfPages kMDItemPixelHeight kMDItemPixelWidth kMDItemPageHeight kMDItemPageWidth kMDItemVersion kMDItemOrientation kMDItemKind kMDItemContentType kMDItemNumberOfPages kMDItemPageHeight kMDItemPageWidth kMDItemVersion The keys that this metadata importer handles. kMDItemTextContent kMDItemContentType kMDItemNumberOfPages kMDItemPixelHeight kMDItemPixelWidth kMDItemPageHeight kMDItemPageWidth kMDItemVersion kMDItemOrientation kMDItemKind kMDItemContentType kMDItemNumberOfPages kMDItemPageHeight kMDItemPageWidth kMDItemVersion The keys that this metadata importer handles. kMDItemTextContent kMDItemContentType kMDItemNumberOfPages kMDItemPixelHeight kMDItemPixelWidth kMDItemPageHeight kMDItemPageWidth kMDItemVersion kMDItemOrientation kMDItemKind kMDItemContentType kMDItemNumberOfPages kMDItemPageHeight kMDItemPageWidth kMDItemVersion djview4-4.10.5/mac/skel/Resources/000077500000000000000000000000001264256014000166255ustar00rootroot00000000000000djview4-4.10.5/mac/skel/Resources/qt.conf000066400000000000000000000000571264256014000201220ustar00rootroot00000000000000[Paths] Translations = Resources/translations djview4-4.10.5/mac/skel/setpath.sh000077500000000000000000000023071264256014000166640ustar00rootroot00000000000000#!/bin/bash # Step 1 -- locate the directory containing this script progname="`basename $0`" if [ "$progname" != "$0" ] then # programname contains directory components progdir="`dirname $0`" else # must search along path tmpvar="$PATH" while [ -n "$tmpvar" ] do IFS=':' read progdir tmpvar < *\(.*\)'` progname=`basename $tmpvar` tmpvar=`dirname $tmpvar` progdir=`cd $progdir ; cd $tmpvar ; pwd` done if [ ! -x "$progdir/$progname" ] then echo 1>&2 "$progname: command not found" exit 10 fi # Step 2 -- check path and manpath contains() { tmpvar=`eval echo '$'$1` while [ -n "$tmpvar" ] do IFS=':' read dir tmpvar < Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ------------------------------------------------------------------------- djview4-4.10.5/npdjvu/Makefile.am000066400000000000000000000025171264256014000165240ustar00rootroot00000000000000# include data gathered from npdjvu.pro file include $(srcdir)/npdjvu.am $(srcdir)/npdjvu.am: npdjvu.pro $(AWK) -f $(top_srcdir)/config/qmsources.awk < $< > $@ # libnpdjvu # - compile but do not install. all: libnpdjvu libnpdjvu: Makefile.qmake FORCE ${MAKE} -f Makefile.qmake FORCE: .PHONY: FORCE EXTRA_DIST = npdjvu.pro LICENSE.GPL README $(qmake_sources) # invoke qmake qmake_verbose = $(qmake_verbose_@AM_V@) qmake_verbose_ = $(qmake_verbose_@AM_DEFAULT_V@) qmake_verbose_0 = @echo " QMAKE " $@; qmake_allflags = $(QMAKEFLAGS) \ -I.. -I$(srcdir) -I$(top_srcdir)/src \ -DDIR_DATADIR=\\\"$(datadir)\\\" Makefile.qmake: ${srcdir}/npdjvu.pro Makefile @cmp -s $< npdjvu.pro || cp $< npdjvu.pro $(qmake_verbose)$(QMAKE) $(QMAKEARG)\ QMAKE_UIC=$(UIC) \ QMAKE_MOC=$(MOC) \ QMAKE_RCC=$(RCC) \ QMAKE_LFLAGS+='$(LDFLAGS)' \ QMAKE_CFLAGS+='$(CFLAGS) $(qmake_allflags)' \ QMAKE_CXXFLAGS+='$(CXXFLAGS) $(qmake_allflags)' \ LIBS+='$(QMAKELIBS)' \ VPATH='$(srcdir) $(top_srcdir)/src' -o $@0 npdjvu.pro $(AWK) -f $(top_srcdir)/config/qmsilent.awk < $@0 > $@ && ${RM} $@0 # cleaning mostlyclean-local: mostlyclean-qmake mostlyclean-qmake: -test "${srcdir}" == "." || ${RM} djview.pro -test -f Makefile.qmake && ${MAKE} -f Makefile.qmake clean -$(RM) Makefile.qmake .PHONY: mostlyclean-qmake MOSTLYCLEANFILES = libnpdjvu.so djview4-4.10.5/npdjvu/README000066400000000000000000000017111264256014000153430ustar00rootroot00000000000000This directory contains an experimental portable plugin dll partially based on the Qt solution qtbrowserplugin. You need to compile with --enable-npdjvu to compile this. Warning: This plugin does not work with konqueror or Qt based browsers because of symbol conflicts between the Qt library used by the browser and the Qt library used by the plugin. Static compilation would fix that at the expense of considerable bloat. The mac version does not work because the Qt solution file is based on the deprecated Carbon interface, whereas modern Qt versions are based on Coca. --------------------------------------------------------- The following files are slightly modified variants of the qt browserplugin solution files: qtbrowserplugin.h qtbrowserplugin_p.h qtbrowserplugin_mac.cpp (does not work) qtbrowserplugin_x11.cpp qtbrowserplugin_win.cpp qtbrowserplugin.def qtnpapi.h qtnpapi.cpp These are the main files: npdjvu.h npdjvu.cpp djview4-4.10.5/npdjvu/npdjvu.am000066400000000000000000000035321264256014000163130ustar00rootroot00000000000000qmake_sources= qmake_ts= qmake_qm= qmake_sources += qtnpapi.h qmake_sources += npdjvu.h qmake_sources += qtbrowserplugin.h qmake_sources += qtbrowserplugin_p.h qmake_sources += qtnpapi.cpp qmake_sources += npdjvu.cpp qmake_sources += qtbrowserplugin_x11.cpp qmake_sources += qtbrowserplugin_win.cpp qmake_sources += npdjvu.rc qmake_sources += qtbrowserplugin.def qmake_sources += qtbrowserplugin_mac.cpp qmake_sources += npdjvu.r qmake_sources += npdjvu.plist qmake_sources += ../src/qdjvu.h qmake_sources += ../src/qdjvunet.h qmake_sources += ../src/qdjvuwidget.h qmake_sources += ../src/qdjvu.cpp qmake_sources += ../src/qdjvunet.cpp qmake_sources += ../src/qdjvuwidget.cpp qmake_sources += ../src/qdjvuwidget.qrc qmake_sources += ../src/qdjviewprefs.h qmake_sources += ../src/qdjviewsidebar.h qmake_sources += ../src/qdjviewdialogs.h qmake_sources += ../src/qdjviewexporters.h qmake_sources += ../src/qdjview.h qmake_sources += ../src/djview.h qmake_sources += ../src/qdjviewprefs.cpp qmake_sources += ../src/qdjviewsidebar.cpp qmake_sources += ../src/qdjviewdialogs.cpp qmake_sources += ../src/qdjviewexporters.cpp qmake_sources += ../src/qdjview.cpp qmake_sources += ../src/djview.cpp qmake_sources += ../src/qdjview.qrc qmake_sources += ../src/qdjviewauthdialog.ui qmake_sources += ../src/qdjviewerrordialog.ui qmake_sources += ../src/qdjviewinfodialog.ui qmake_sources += ../src/qdjviewmetadialog.ui qmake_sources += ../src/qdjviewsavedialog.ui qmake_sources += ../src/qdjviewprintdialog.ui qmake_sources += ../src/qdjviewexportdialog.ui qmake_sources += ../src/qdjviewexportps1.ui qmake_sources += ../src/qdjviewexportps2.ui qmake_sources += ../src/qdjviewexportps3.ui qmake_sources += ../src/qdjviewexporttiff.ui qmake_sources += ../src/qdjviewexportprn.ui qmake_sources += ../src/qdjviewprefsdialog.ui qmake_sources += ../src/tiff2pdf.h qmake_sources += ../src/tiff2pdf.c djview4-4.10.5/npdjvu/npdjvu.cpp000066400000000000000000000624021264256014000165010ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2009- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #include "config.h" #include #include #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_WS_X11 # if QT_VERSION >= 0x50000 # define Q_WS_X11_QT5 1 # include # else # define Q_WS_X11_QT4 1 # include # endif #endif // Djview includes #include "qdjvu.h" #include "qdjvuwidget.h" #include "qdjview.h" // Npdjvu includes #include "npdjvu.h" #include "qtbrowserplugin.h" #include "qtbrowserplugin_p.h" /* ------------------------------------------------------------- */ class QtNPForwarder: public QObject { Q_OBJECT public: QtNPForwarder(QtNPInstance *instance, QObject *parent = 0); public slots: void showStatus(QString message); void getUrl(QUrl url, QString target); void onChange(); private: QtNPInstance *instance; }; struct QtNPStream { QUrl url; QtNPInstance *instance; int streamid; bool started; bool checked; bool closed; QtNPStream(int streamid, QUrl url, QtNPInstance *instance); ~QtNPStream(); }; class QtNPDocument : public QDjVuDocument { Q_OBJECT public: QtNPDocument(QtNPInstance *instance); virtual void newstream(int streamid, QString name, QUrl url); private: QtNPInstance *instance; }; /* ------------------------------------------------------------- */ /* Setup application */ static QPointer theApp; static QPointer djvuContext; #ifdef Q_WS_X11_QT4 static bool x11EventFilter(void *message, long *) { // We define a low level handler because we need to make // the window active before calling the QX11EmbedWidget event filter. XEvent *event = reinterpret_cast(message); if (event->type == ButtonPress) { QWidget *w = QWidget::find(event->xbutton.window); if (w && qobject_cast(w->window())) theApp->setActiveWindow(w->window()); } return false; } #endif static void addDirectory(QStringList &dirs, QString path) { QString dirname = QDir::cleanPath(path); if (! dirs.contains(dirname)) dirs << dirname; } static void setupApplication(QtNPInstance *instance) { // quick if (theApp) { qtns_initialize(instance); if (! djvuContext) djvuContext = new QDjVuContext; return; } // globals QApplication::setOrganizationName(DJVIEW_ORG); QApplication::setOrganizationDomain(DJVIEW_DOMAIN); QApplication::setApplicationName(DJVIEW_APP); // mac #ifdef Q_WS_MAC extern void qt_mac_set_native_menubar(bool); qt_mac_set_native_menubar(false); #endif // application qtns_initialize(instance); if (! djvuContext) djvuContext = new QDjVuContext; theApp = (QApplication*)QCoreApplication::instance(); #ifdef Q_WS_X11_QT4 theApp->setEventFilter(x11EventFilter); #endif #ifdef LC_NUMERIC // This is needed in the pdf export code in order to make // sure numbers are represented properly. But is it really // good to change the global state of the browser? ::setlocale(LC_NUMERIC, "C"); #endif // translators QTranslator *qtTrans = new QTranslator(theApp); QTranslator *djviewTrans = new QTranslator(theApp); // - determine preferred languages QStringList langs; QString varLanguage = ::getenv("LANGUAGE"); if (varLanguage.size()) langs += varLanguage.toLower().split(":", QString::SkipEmptyParts); #ifdef LC_MESSAGES QString varLcMessages = ::setlocale(LC_MESSAGES, 0); if (varLcMessages.size()) langs += varLcMessages.toLower(); #else # ifdef LC_ALL QString varLcMessages = ::setlocale(LC_ALL, 0); if (varLcMessages.size()) langs += varLcMessages.toLower(); # endif #endif #ifdef Q_WS_MAC langs += QSettings(".", "globalPreferences") .value("AppleLanguages").toStringList(); #endif QString qtLocale = QLocale::system().name(); if (qtLocale.size()) langs += qtLocale.toLower(); // - determine potential directories QStringList dirs; QDir dir = QApplication::applicationDirPath(); QString dirPath = dir.canonicalPath(); addDirectory(dirs, dirPath); #ifdef DIR_DATADIR QString datadir = DIR_DATADIR; addDirectory(dirs, datadir + "/djvu/djview4"); addDirectory(dirs, datadir + "/djview4"); #endif #ifdef Q_WS_MAC addDirectory(dirs, dirPath + "/Resources/$LANG.lproj"); addDirectory(dirs, dirPath + "/../Resources/$LANG.lproj"); addDirectory(dirs, dirPath + "/../../Resources/$LANG.lproj"); #endif addDirectory(dirs, dirPath + "/share/djvu/djview4"); addDirectory(dirs, dirPath + "/share/djview4"); addDirectory(dirs, dirPath + "/../share/djvu/djview4"); addDirectory(dirs, dirPath + "/../share/djview4"); addDirectory(dirs, dirPath + "/../../share/djvu/djview4"); addDirectory(dirs, dirPath + "/../../share/djview4"); addDirectory(dirs, "/usr/share/djvu/djview4"); addDirectory(dirs, "/usr/share/djview4"); addDirectory(dirs, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); // - load translators bool qtTransValid = false; bool djviewTransValid = false; foreach (QString lang, langs) { foreach (QString dir, dirs) { dir = dir.replace(QRegExp("\\$LANG(?!\\w)"),lang); QDir qdir(dir); if (! qtTransValid && qdir.exists()) qtTransValid = qtTrans->load("qt_" + lang, dir, "_.-"); if (! djviewTransValid && qdir.exists()) djviewTransValid= djviewTrans->load("djview_" + lang, dir, "_.-"); } if (lang == "en" || lang.startsWith("en_") || lang == "c") break; } // - install tranlators if (qtTransValid) theApp->installTranslator(qtTrans); if (djviewTransValid) theApp->installTranslator(djviewTrans); } void NPP_Shutdown() { delete djvuContext; djvuContext = 0; } /* ------------------------------------------------------------- */ /* Forwarder */ QtNPForwarder::QtNPForwarder(QtNPInstance *instance, QObject *parent) : QObject(parent), instance(instance) { } void QtNPForwarder::showStatus(QString message) { message.replace(QRegExp("\\s"), " "); QByteArray utf8 = message.toUtf8(); NPN_Status(instance->npp, utf8.constData()); } void QtNPForwarder::getUrl(QUrl url, QString target) { if (instance) { QByteArray bUrl = url.toEncoded(); QByteArray bTarget = target.toUtf8(); NPN_GetURL(instance->npp, bUrl.constData(), bTarget.isEmpty() ? 0 : bTarget.constData()); } } void QtNPForwarder::onChange() { if (instance && instance->npobject && instance->onchange.type == NPVariant::String) { NPVariant res; NPString *code = &instance->onchange.value.stringValue; NPN_Evaluate(instance->npp, instance->npobject, code, &res); NPN_ReleaseVariantValue(&res); } } /* ------------------------------------------------------------- */ /* Stream */ QtNPStream::QtNPStream(int streamid, QUrl url, QtNPInstance *instance) : url(url), instance(instance), streamid(streamid), started(false), checked(false), closed(false) { instance->streams.insert(this); } QtNPStream::~QtNPStream() { if (instance && instance->streams.contains(this)) if (instance->document && started && !closed) ddjvu_stream_close(*instance->document, streamid, true); closed = true; started = checked = false; instance->streams.remove(this); } /* ------------------------------------------------------------- */ /* Document */ QtNPDocument::QtNPDocument(QtNPInstance *instance) : QDjVuDocument(true), instance(instance) { QUrl docurl = QDjView::removeDjVuCgiArguments(instance->url); setUrl(djvuContext, docurl); } void QtNPDocument::newstream(int streamid, QString, QUrl url) { if (streamid > 0) { new QtNPStream(streamid, url, instance); QString message = tr("Requesting %1.").arg(url.toString()); instance->forwarder->showStatus(message); instance->forwarder->getUrl(url, QString()); } } /* ------------------------------------------------------------- */ /* Open/Close djview */ static QByteArray saveData(QDjVuWidget *widget) { if (! widget) return QByteArray(); QDjVuWidget::Position pos = widget->position(); QBuffer buffer; buffer.open(QIODevice::WriteOnly); QDataStream s(&buffer); s << widget->zoom() << widget->rotation(); s << widget->sideBySide() << widget->continuous(); s << widget->displayMode(); s << pos.pageNo << pos.posView; buffer.close(); return buffer.data(); } static void restoreData(QDjVuWidget *widget, QByteArray data) { if (data.isEmpty()) return; QBuffer buffer(&data); buffer.open(QIODevice::ReadOnly); QDataStream s(&buffer); int zoom, rotation, mode; bool sideBySide, continuous; QDjVuWidget::Position pos; s >> zoom >> rotation >> continuous >> sideBySide; s >> mode >> pos.pageNo >> pos.posView; pos.inPage = false; buffer.close(); if (s.status() != QDataStream::Ok) return; // apply widget->setZoom(zoom); widget->setRotation(rotation); widget->setSideBySide(sideBySide); widget->setContinuous(continuous); widget->setDisplayMode((QDjVuWidget::DisplayMode)mode); widget->setPosition(pos); } static void openInstance(QtNPInstance *instance) { if (! instance->document && instance->url.isValid()) { instance->document = new QtNPDocument(instance); instance->document->ref(); } if (instance->document && instance->djview) if (! instance->djview->getDocument()) { instance->djview->open(instance->document, instance->url); restoreData(instance->djview->getDjVuWidget(), instance->savedData); instance->djview->show(); } } static void closeInstance(QtNPInstance *instance) { if (instance->djview) { instance->savedData = saveData(instance->djview->getDjVuWidget()); instance->djview->close(); delete instance->djview; instance->djview = 0; instance->qt.object = 0; qtns_destroy(instance); } } /* ------------------------------------------------------------- */ /* NPRuntime */ static NPIdentifier npid_getdjvuopt; static NPIdentifier npid_setdjvuopt; static NPIdentifier npid_onchange; static NPIdentifier npid_version; static bool np_hasmethod(NPObject*, NPIdentifier name) { if (name == npid_getdjvuopt || name == npid_setdjvuopt ) return 1; return 0; } static bool np_invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32 argCount, NPVariant *result) { QVariant res; QtNPInstance *instance = (npobj && npobj->_class) ? npobj->_class->qtnp : 0; if (instance && name == npid_getdjvuopt) { // GetDjVuOpt ------------ if (argCount != 1) NPN_SetException(npobj, "Exactly one argument is expected"); else if (args[0].type != NPVariant::String) NPN_SetException(npobj, "First argument should be a string"); else if (instance->djview) { res = instance->djview->getArgument(QVariant(args[0]).toString()); *result = NPVariant::fromQVariant(instance, res); return 1; } return 0; } else if (instance && name == npid_setdjvuopt) { // SetDjVuOpt ------------ if (argCount != 2) NPN_SetException(npobj, "Exactly two arguments were expected"); else if (args[0].type != NPVariant::String) NPN_SetException(npobj, "First argument should be a string"); else { QVariant key = QVariant(args[0]).toString(); QVariant val = QVariant(args[1]).toString(); if (val.canConvert(QVariant::String)) { if (instance->djview) instance->djview->parseArgument(key.toString(), val.toString()); else instance->args += key.toString() + "=" + val.toString(); *result = NPVariant::fromQVariant(instance, res); return 1; } NPN_SetException(npobj, "Arg 2 should be a string or a number"); } return 0; } NPN_SetException(npobj, "Unrecognized method"); return 0; } static bool np_hasproperty(NPObject*, NPIdentifier name) { if (name == npid_onchange || name == npid_version) return 1; return 0; } static bool np_getproperty(NPObject *npobj, NPIdentifier name, NPVariant *result) { QtNPInstance *instance = (npobj && npobj->_class) ? npobj->_class->qtnp : 0; if (instance && name == npid_onchange) { QVariant var = instance->onchange; *result = NPVariant::fromQVariant(instance, var); return 1; } else if (instance && name == npid_version) { *result = NPVariant::fromQVariant(instance, QString("npdjvu+djview4")); return 1; } return 0; } static bool np_setproperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) { QtNPInstance *instance = (npobj && npobj->_class) ? npobj->_class->qtnp : 0; if (instance && name == npid_onchange) { if (value->type == NPVariant::String || value->type == NPVariant::Null ) { NPN_ReleaseVariantValue(&instance->onchange); QVariant var = *value; instance->onchange = NPVariant::fromQVariant(instance, var); return 1; } NPN_SetException(npobj, "String or null expected"); return 0; } return 0; } static void createObject(QtNPInstance *instance) { if (! npid_getdjvuopt) npid_getdjvuopt = NPN_GetStringIdentifier("getdjvuopt"); if (! npid_setdjvuopt) npid_setdjvuopt = NPN_GetStringIdentifier("setdjvuopt"); if (! npid_onchange) npid_onchange = NPN_GetStringIdentifier("onchange"); if (! npid_version) npid_version = NPN_GetStringIdentifier("version"); NPClass *npclass = new NPClass(instance); npclass->hasMethod = np_hasmethod; npclass->invoke = np_invoke; npclass->hasProperty = np_hasproperty; npclass->getProperty = np_getproperty; npclass->setProperty = np_setproperty; instance->npobject = NPN_CreateObject(instance->npp, npclass); } /* ------------------------------------------------------------- */ /* NPP functions */ NPError NPP_New(NPMIMEType mime, NPP npp, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved) { Q_UNUSED(mime) if (! npp) return NPERR_INVALID_INSTANCE_ERROR; QtNPInstance *instance = new QtNPInstance; if (! instance) return NPERR_OUT_OF_MEMORY_ERROR; // initialize npp->pdata = instance; instance->fMode = mode; instance->forwarder = 0; instance->document = 0; instance->djview = 0; instance->npobject = 0; instance->npp = npp; instance->qt.object = 0; #ifdef Q_WS_MAC instance->rootWidget = 0; #endif createObject(instance); if (saved && saved->len) instance->savedData = QByteArray((const char*)saved->buf, saved->len); // arguments for (int i = 0; i < argc; i++) { QString key = QString::fromUtf8(argn[i]); QString val = QString::fromUtf8(argv[i]); QString k = key.toLower(); if (k == "flags") instance->args += val.split(QRegExp("\\s+"), QString::SkipEmptyParts); else instance->args += key + QString("=") + val; } fprintf(stderr,"npdjvu: using the QtBrowserPlugin%s\n", #if defined(Q_WS_X11) "/XEmbed" #elif defined(Q_WS_MAC) "/Mac" #elif defined(Q_WS_Win) "/Windows" #else "" #endif ); return NPERR_NO_ERROR; } NPError NPP_Destroy(NPP npp, NPSavedData** save) { QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; if (! instance) return NPERR_INVALID_INSTANCE_ERROR; closeInstance(instance); delete instance->forwarder; instance->forwarder = 0; if (instance->document) instance->document->deref(); instance->document = 0; if (save && !instance->savedData.isEmpty()) { int len = instance->savedData.size(); void *data = NPN_MemAlloc(len); NPSavedData *saved = (NPSavedData*)NPN_MemAlloc(sizeof(NPSavedData)); if (saved && data) { memcpy(data, instance->savedData.constData(), len); saved->len = len; saved->buf = data; *save = saved; } } instance->npp->pdata = 0; if (instance->onchange.type) NPN_ReleaseVariantValue(&instance->onchange); if (instance->npobject) NPN_ReleaseObject(instance->npobject); delete instance; return NPERR_NO_ERROR; } NPError NPP_SetWindow(NPP npp, NPWindow* window) { QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; if (! instance) return NPERR_INVALID_INSTANCE_ERROR; QRect clipRect; if (window) { clipRect = QRect(window->clipRect.left, window->clipRect.top, window->clipRect.right - window->clipRect.left, window->clipRect.bottom - window->clipRect.top); instance->geometry = QRect(window->x, window->y, window->width, window->height); } // take a shortcut if all that was changed is the geometry if (instance->djview && window && instance->window == (QtNPInstance::Widget)window->window) { qtns_setGeometry(instance, instance->geometry, clipRect); return NPERR_NO_ERROR; } if (instance->djview) closeInstance(instance); if (! window) { instance->window = 0; return NPERR_NO_ERROR; } instance->window = (QtNPInstance::Widget)window->window; setupApplication(instance); if (! instance->forwarder) instance->forwarder = new QtNPForwarder(instance); QDjView::ViewerMode mode = (instance->fMode == NP_FULL) ? QDjView::FULLPAGE_PLUGIN : QDjView::EMBEDDED_PLUGIN; QDjView *djview = new QDjView(*djvuContext, mode); djview->setWindowFlags(djview->windowFlags() & ~Qt::Window); djview->setAttribute(Qt::WA_DeleteOnClose, false); djview->setObjectName("npdjvu"); djview->setAutoFillBackground(true); instance->djview = djview; instance->qt.widget = djview; QObject::connect(djview, SIGNAL(pluginStatusMessage(QString)), instance->forwarder, SLOT(showStatus(QString)) ); QObject::connect(djview, SIGNAL(pluginGetUrl(QUrl,QString)), instance->forwarder, SLOT(getUrl(QUrl,QString)) ); QObject::connect(djview, SIGNAL(pluginOnChange()), instance->forwarder, SLOT(onChange()) ); qtns_embed(instance); QEvent e(QEvent::EmbeddingControl); QApplication::sendEvent(instance->qt.widget, &e); if (!instance->qt.widget->testAttribute(Qt::WA_PaintOnScreen)) instance->qt.widget->setAutoFillBackground(true); instance->qt.widget->raise(); qtns_setGeometry(instance, instance->geometry, clipRect); while (instance->args.size() > 0) djview->parseArgument(instance->args.takeFirst()); openInstance(instance); return NPERR_NO_ERROR; } NPError NPP_NewStream(NPP npp, NPMIMEType mime, NPStream* stream, NPBool seekable, uint16 *stype) { Q_UNUSED(mime) Q_UNUSED(seekable) Q_UNUSED(stype) QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; QUrl url = QUrl::fromEncoded(stream->url); if (instance) { if (! url.isValid() ) { qWarning("npdjvu: invalid url '%s'.", stream->url); return NPERR_GENERIC_ERROR; } // first stream if (! instance->url.isValid()) { instance->url = url; url = QDjView::removeDjVuCgiArguments(url); QtNPStream *s = new QtNPStream(0, url, instance); s->checked = true; } // search streams QtNPStream *npstream = 0; foreach(QtNPStream *s, instance->streams) if (!npstream && !s->started) if (s->url == url) npstream = s; // mark started stream if (npstream) { stream->pdata = npstream; npstream->started = true; if (npstream->streamid == 0) openInstance(instance); } } return NPERR_NO_ERROR; } NPError NPP_DestroyStream(NPP npp, NPStream* stream, NPReason reason) { QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; QtNPStream *npstream = (stream) ? (QtNPStream*)(stream->pdata) : 0; bool okay = (reason == NPRES_DONE); if (instance && npstream && instance->streams.contains(npstream)) { if (instance->document && !npstream->closed) ddjvu_stream_close(*instance->document, npstream->streamid, !okay); npstream->closed = true; if (instance->forwarder) instance->forwarder->showStatus(QString()); delete npstream; } return NPERR_NO_ERROR; } int32 NPP_WriteReady(NPP npp, NPStream* stream) { Q_UNUSED(npp) Q_UNUSED(stream) return 0x7fffffff; } int32 NPP_Write(NPP npp, NPStream* stream, int32 offset, int32 len, void *buffer) { Q_UNUSED(offset) QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; QtNPStream *npstream = (stream) ? (QtNPStream*)(stream->pdata) : 0; const char *cdata = (const char*)buffer; if (instance && npstream && instance->streams.contains(npstream)) { if (!npstream->checked && len > 0) { // -- if the stream is not a djvu file, // this is probably a html error message. // But we need at least 8 bytes to check npstream->checked = true; if (instance->forwarder && len >= 8) { if (strncmp(cdata, "FORM", 4) && strncmp(cdata+4, "FORM", 4)) { instance->forwarder->getUrl(npstream->url, QString("_self")); return len; } } } // pass data QtNPDocument *document = instance->document; if (document) ddjvu_stream_write(*document, npstream->streamid, cdata, len); } return len; } void NPP_StreamAsFile(NPP npp, NPStream* stream, const char* fname) { Q_UNUSED(npp) Q_UNUSED(stream) Q_UNUSED(fname) } void NPP_Print(NPP npp, NPPrint* platformPrint) { QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; if (instance && instance->djview) { instance->djview->print(); if (platformPrint && platformPrint->mode==NP_FULL) platformPrint->print.fullPrint.pluginPrinted=TRUE; } } int16 NPP_HandleEvent(NPP npp, NPEvent* event) { QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; if (instance) return qtns_event(instance, event) ? 1 : 0; return NPERR_INVALID_INSTANCE_ERROR; } void NPP_URLNotify(NPP npp, const char *url, NPReason reason, void *data) { Q_UNUSED(npp) Q_UNUSED(url) Q_UNUSED(reason) Q_UNUSED(data) } NPError NPP_GetValue(NPP npp, NPPVariable variable, void *value) { Q_UNUSED(npp) NPError err = NPERR_GENERIC_ERROR; QtNPInstance *instance = (npp) ? (QtNPInstance*)(npp->pdata) : 0; switch (variable) { case NPPVpluginNameString: *((const char **)value) = "DjView-" DJVIEW_VERSION_STR " (npdjvu)"; err = NPERR_NO_ERROR; break; case NPPVpluginDescriptionString: *((const char **)value) = "This is the " "DjView-" DJVIEW_VERSION_STR " (npdjvu) version of " "the DjVu plugin.
" "See DjVuLibre."; err = NPERR_NO_ERROR; break; case NPPVpluginNeedsXEmbed: *((NPBool*)value) = TRUE; err = NPERR_NO_ERROR; break; case NPPVpluginScriptableNPObject: if (!instance || !instance->npobject) break; NPN_RetainObject(instance->npobject); *((NPObject**)value) = instance->npobject; err = NPERR_NO_ERROR; break; default: break; } return err; } NPError NPP_SetValue(NPP npp, NPPVariable variable, void *value) { Q_UNUSED(npp) Q_UNUSED(variable) Q_UNUSED(value) return NPERR_GENERIC_ERROR; } /* ------------------------------------------------------------- */ #ifdef Q_WS_X11 const char* NP_GetMIMEDescription(void) { return "image/x-djvu:djvu,djv:DjVu File;" "image/x.djvu::DjVu File;" "image/djvu::DjVu File;" "image/x-dejavu::DjVu File (obsolete);" "image/x-iw44::DjVu File (obsolete);" "image/vnd.djvu::DjVu File;" ; } NPError NP_GetValue(void*, NPPVariable aVariable, void *aValue) { return NPP_GetValue(0, aVariable, aValue); } #endif /* ------------------------------------------------------------- */ #include "npdjvu.moc" /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" "NPP" "QtNP\\sw*") End: ------------------------------------------------------------- */ djview4-4.10.5/npdjvu/npdjvu.h000066400000000000000000000046361264256014000161530ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2009- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #include "qtnpapi.h" extern "C" NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); extern "C" NPError NPP_Destroy(NPP instance, NPSavedData** save); extern "C" NPError NPP_SetWindow(NPP instance, NPWindow* window); extern "C" NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); extern "C" NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason); extern "C" int32 NPP_WriteReady(NPP instance, NPStream* stream); extern "C" int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); extern "C" void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname); extern "C" void NPP_Print(NPP instance, NPPrint* platformPrint); extern "C" int16 NPP_HandleEvent(NPP instance, NPEvent* event); extern "C" void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); extern "C" NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value); extern "C" NPError NPP_SetValue(NPP instance, NPPVariable variable, void *value); extern "C" void NPP_Shutdown(); #ifdef Q_WS_X11 extern "C" const char *NP_GetMIMEDescription(void); extern "C" NPError NP_GetValue(void*, NPPVariable aVariable, void *aValue); #endif djview4-4.10.5/npdjvu/npdjvu.plist000066400000000000000000000031531264256014000170500ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable npdjvu CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BRPL CFBundleSignature DJVU CFBundleGetInfoString npdjvu - DjView4 browser plugin CSResourcesFileMapped WebPluginDescription The DjView browser plug-in WebPluginMIMETypes image/x-djvu WebPluginExtensions djvu djv WebPluginTypeDescription DjVu File image/x.djvu WebPluginTypeDescription DjVu File image/djvu WebPluginTypeDescription DjVu File image/x-dejavu WebPluginTypeDescription DjVu File (obsolete) image/x-iw44 WebPluginTypeDescription DjVu File (obsolete) image/vnd.djvu WebPluginTypeDescription DjVu File WebPluginName The DjView4 browser plugin djview4-4.10.5/npdjvu/npdjvu.pro000066400000000000000000000075531264256014000165250ustar00rootroot00000000000000#C- -*- shell-script -*- #C- ------------------------------------------------------------------- #C- DjView4 #C- Copyright (c) 2006 Leon Bottou #C- #C- This software is subject to, and may be distributed under, the #C- GNU General Public License. The license should have #C- accompanied the software or you may obtain a copy of the license #C- from the Free Software Foundation at http:#www.fsf.org . #C- #C- This program is distributed in the hope that it will be useful, #C- but WITHOUT ANY WARRANTY; without even the implied warranty of #C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #C- GNU General Public License for more details. #C- ------------------------------------------------------------------ TEMPLATE = lib TARGET = npdjvu CONFIG += qt thread warn_on QT += network greaterThan(QT_MAJOR_VERSION, 4) { QT += widgets printsupport } # ============ qtbrowserplugin code HEADERS += qtnpapi.h HEADERS += npdjvu.h HEADERS += qtbrowserplugin.h HEADERS += qtbrowserplugin_p.h SOURCES += qtnpapi.cpp SOURCES += npdjvu.cpp # ============ test for X11 win32:contains(DEFINES,__WIN32_X11__) { DEFINES *= WITH_X11 } else:macx:contains(DEFINES,__USE_WS_X11__) { DEFINES *= WITH_X11 } else:!macx:!win32 { DEFINES *= WITH_X11 } contains(DEFINES,WITH_X11) { CONFIG += x11 } greaterThan(QT_MAJOR_VERSION, 4) { contains(DEFINES,WITH_X11) { DEFINES *= Q_WS_X11 DEFINES *= QX11Info=qintptr } else:win32 { DEFINES *= Q_WS_WIN } else:macx { DEFINES *= Q_WS_MAC } } # ============ plugin stuff x11 { CONFIG += dll CONFIG += plugin SOURCES += qtbrowserplugin_x11.cpp } else:win32 { CONFIG += dll SOURCES += qtbrowserplugin_win.cpp RC_FILE = npdjvu.rc DEF_FILE += qtbrowserplugin.def LIBS += -luser32 } else:mac { CONFIG += dll CONFIG += plugin CONFIG += plugin_bundle SOURCES += qtbrowserplugin_mac.cpp REZ_FILES += npdjvu.r RESOURCES.path = Contents/Resources RESOURCES.files = npdjvu.rsrc QMAKE_BUNDLE_DATA += RESOURCES QMAKE_INFO_PLIST = npdjvu.plist } # ============ djview stuff CONFIG += qt thread warn_on QT += network opengl # -- find libraries CONFIG(autoconf) { # for use with autoconf DEFINES += AUTOCONF # Autoconf calls qmake with the following variables # LIBS += ... # QMAKE_CXXFLAGS += ... # QMAKE_CFLAGS += ... # QMAKE_LFLAGS += ... } else { # customize below #LIBS += -ldjvulibre #QMAKE_CXXFLAGS += #QMAKE_CFLAGS += #QMAKE_LFLAGS += #DEFINES += } # -- config CONFIG(release,debug|release) { DEFINES += NDEBUG QT_NO_DEBUG QT_NO_DEBUG_STREAM } # -- djvu HEADERS += ../src/qdjvu.h HEADERS += ../src/qdjvunet.h HEADERS += ../src/qdjvuwidget.h SOURCES += ../src/qdjvu.cpp SOURCES += ../src/qdjvunet.cpp SOURCES += ../src/qdjvuwidget.cpp RESOURCES += ../src/qdjvuwidget.qrc # -- djview HEADERS += ../src/qdjviewprefs.h HEADERS += ../src/qdjviewsidebar.h HEADERS += ../src/qdjviewdialogs.h HEADERS += ../src/qdjviewexporters.h HEADERS += ../src/qdjview.h HEADERS += ../src/djview.h SOURCES += ../src/qdjviewprefs.cpp SOURCES += ../src/qdjviewsidebar.cpp SOURCES += ../src/qdjviewdialogs.cpp SOURCES += ../src/qdjviewexporters.cpp SOURCES += ../src/qdjview.cpp SOURCES += ../src/djview.cpp RESOURCES += ../src/qdjview.qrc FORMS += ../src/qdjviewauthdialog.ui FORMS += ../src/qdjviewerrordialog.ui FORMS += ../src/qdjviewinfodialog.ui FORMS += ../src/qdjviewmetadialog.ui FORMS += ../src/qdjviewsavedialog.ui FORMS += ../src/qdjviewprintdialog.ui FORMS += ../src/qdjviewexportdialog.ui FORMS += ../src/qdjviewexportps1.ui FORMS += ../src/qdjviewexportps2.ui FORMS += ../src/qdjviewexportps3.ui FORMS += ../src/qdjviewexporttiff.ui FORMS += ../src/qdjviewexportprn.ui FORMS += ../src/qdjviewprefsdialog.ui # -- helper files HEADERS += ../src/tiff2pdf.h SOURCES += ../src/tiff2pdf.c djview4-4.10.5/npdjvu/npdjvu.r000066400000000000000000000007061264256014000161570ustar00rootroot00000000000000#define SystemSevenOrLater 1 #include resource 'STR#' (127) {{ "DjVu File", "DjVu File", "DjVu File", "DjVu File (obsolete)", "DjVu File (obsolete)", "DjVu File" }}; resource 'STR#' (128) {{ "image/x-djvu", "djvu,djv", "image/x.djvu", "", "image/djvu", "", "image/x-dejavu", "", "image/x-iw44", "", "image/vnd.djvu", "" }}; resource 'STR#' (126) {{ "The DjView4 browser plugin" }}; djview4-4.10.5/npdjvu/npdjvu.rc000066400000000000000000000022511264256014000163170ustar00rootroot00000000000000 1 ICON DISCARDABLE "../src/images/DjVuApp.ico" 1 VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904e4" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "\0" VALUE "FileDescription", "npdjvu\0" VALUE "FileOpenName", "DjVu File|DjVu File|DjVu File|DjVu File (obsolete)|DjVu File (obsolete)|DjVu File" VALUE "FileExtents", "djvu,djv|||||\0" VALUE "FileVersion", "1, 0, 0, 1\0" VALUE "InternalName", "npdjvu\0" VALUE "LegalCopyright", "\0" VALUE "LegalTrademarks", "\0" VALUE "MIMEType", "image/x-djvu|image/x.djvu|image/djvu|image/x-dejavu|image/x-iw44|image/vnd.djvu\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "DjView4 browser plugin\0" VALUE "ProductVersion", "1, 0, 0, 1\0" VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END djview4-4.10.5/npdjvu/qtbrowserplugin.def000066400000000000000000000001201264256014000204030ustar00rootroot00000000000000EXPORTS NP_GetEntryPoints @1 NP_Initialize @2 NP_Shutdown @3 djview4-4.10.5/npdjvu/qtbrowserplugin.h000066400000000000000000000024351264256014000201070ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2009- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ // Replacement for trolltech's main file #include #include #include #include #include #include "qtnpapi.h" extern "C" bool qtns_event(QtNPInstance*, NPEvent*); extern "C" void qtns_initialize(QtNPInstance* This); extern "C" void qtns_destroy(QtNPInstance* This); extern "C" void qtns_shutdown(void); extern "C" void qtns_embed(QtNPInstance *This); extern "C" void qtns_setGeometry(QtNPInstance *This, const QRect &rect, const QRect &); djview4-4.10.5/npdjvu/qtbrowserplugin_mac.cpp000066400000000000000000000455401264256014000212660ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "qtnpapi.h" #include "qtbrowserplugin.h" #include "qtbrowserplugin_p.h" static bool ownsqapp = false; extern void qt_mac_set_native_menubar(bool b); const UInt32 kWidgetCreatorQt = 'cute'; enum { kWidgetPropertyQWidget = 'QWId' //QWidget * }; class QMacBrowserRoot : public QWidget { Q_OBJECT public: QMacBrowserRoot(HIViewRef root) : QWidget() { // make sure we're not registered with Qt before create WindowRef window = HIViewGetWindow(root); QWidget *oldwindow=0; OSErr err; err = GetWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(oldwindow), 0, &oldwindow); if (err == noErr) RemoveWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget); create((WId)root); // re-register the root window with Qt err = SetWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(oldwindow), &oldwindow); if (err != noErr) { qWarning("Error, couldn't register Window with Qt: (%s:%d:%d)", __FILE__, __LINE__, err); } QPalette pal = palette(); pal.setColor(QPalette::Window,Qt::transparent); setPalette(pal); setAttribute(Qt::WA_WState_Polished); } ~QMacBrowserRoot() { } }; #include "qtbrowserplugin_mac.moc" struct key_sym { int mac_code; int qt_code; const char *desc; }; static key_sym modifier_syms[] = { { shiftKey, Qt::ShiftModifier, "Qt::ShiftModifier" }, { controlKey, Qt::MetaModifier, "Qt::MetaModifier" }, { rightControlKey, Qt::MetaModifier, "Qt::MetaModifier" }, { optionKey, Qt::AltModifier, "Qt::AltModifier" }, { rightOptionKey, Qt::AltModifier, "Qt::AltModifier" }, { cmdKey, Qt::ControlModifier, "Qt::ControlModifier" }, { 0, 0, NULL } }; static Qt::KeyboardModifiers get_modifiers(int key) { Qt::KeyboardModifiers ret = 0; for(int i = 0; modifier_syms[i].desc; i++) { if(key & modifier_syms[i].mac_code) { ret |= Qt::KeyboardModifier(modifier_syms[i].qt_code); } } return ret; } static key_sym key_syms[] = { { kHomeCharCode, Qt::Key_Home, "Qt::Home" }, { kEnterCharCode, Qt::Key_Enter, "Qt::Key_Enter" }, { kEndCharCode, Qt::Key_End, "Qt::Key_End" }, { kBackspaceCharCode, Qt::Key_Backspace, "Qt::Backspace" }, { kTabCharCode, Qt::Key_Tab, "Qt::Tab" }, { kPageUpCharCode, Qt::Key_PageUp, "Qt::PageUp" }, { kPageDownCharCode, Qt::Key_PageDown, "Qt::PageDown" }, { kReturnCharCode, Qt::Key_Return, "Qt::Key_Return" }, //function keys? { kEscapeCharCode, Qt::Key_Escape, "Qt::Key_Escape" }, { kLeftArrowCharCode, Qt::Key_Left, "Qt::Key_Left" }, { kRightArrowCharCode, Qt::Key_Right, "Qt::Key_Right" }, { kUpArrowCharCode, Qt::Key_Up, "Qt::Key_Up" }, { kDownArrowCharCode, Qt::Key_Down, "Qt::Key_Down" }, { kDeleteCharCode, Qt::Key_Delete, "Qt::Key_Delete" } }; static int get_key(int key) { for(int i = 0; key_syms[i].desc; i++) { if(key_syms[i].mac_code == key) { return key_syms[i].qt_code; } } return key; } struct qt_last_mouse_down_struct { unsigned int when; int x, y; } qt_last_mouse_down = { 0, 0, 0 }; //nasty, copied code - static void qt_dispatchEnterLeave(QWidget* enter, QWidget* leave) { #if 0 if(leave) { QEvent e(QEvent::Leave); QApplication::sendEvent(leave, & e); } if(enter) { QEvent e(QEvent::Enter); QApplication::sendEvent(enter, & e); } return; #endif QWidget* w ; if(!enter && !leave) return; QWidgetList leaveList; QWidgetList enterList; bool sameWindow = leave && enter && leave->window() == enter->window(); if(leave && !sameWindow) { w = leave; do { leaveList.append(w); } while(!w->isWindow() && (w = w->parentWidget())); } if(enter && !sameWindow) { w = enter; do { enterList.prepend(w); } while(!w->isWindow() && (w = w->parentWidget())); } if(sameWindow) { int enterDepth = 0; int leaveDepth = 0; w = enter; while(!w->isWindow() && (w = w->parentWidget())) enterDepth++; w = leave; while(!w->isWindow() && (w = w->parentWidget())) leaveDepth++; QWidget* wenter = enter; QWidget* wleave = leave; while(enterDepth > leaveDepth) { wenter = wenter->parentWidget(); enterDepth--; } while(leaveDepth > enterDepth) { wleave = wleave->parentWidget(); leaveDepth--; } while(!wenter->isWindow() && wenter != wleave) { wenter = wenter->parentWidget(); wleave = wleave->parentWidget(); } w = leave; while(w != wleave) { leaveList.append(w); w = w->parentWidget(); } w = enter; while(w != wenter) { enterList.prepend(w); w = w->parentWidget(); } } QEvent leaveEvent(QEvent::Leave); for (int i = 0; i < leaveList.size(); ++i) { w = leaveList.at(i); QApplication::sendEvent(w, &leaveEvent); #if 0 if(w->testAttribute(Qt::WA_Hover)) { Q_ASSERT(instance()); QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos)); QApplication::sendEvent(w, &he); } #endif } QPoint posEnter = QCursor::pos(); QEvent enterEvent(QEvent::Enter); for (int i = 0; i < enterList.size(); ++i) { w = enterList.at(i); QApplication::sendEvent(w, &enterEvent); if(w->testAttribute(Qt::WA_Hover)) { QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1)); QApplication::sendEvent(w, &he); } } } extern "C" bool qtns_event(QtNPInstance *This, NPEvent *event) { static QPointer lastWidget; static QPointer qt_button_down; static Point lastPosition = { 0, 0 }; if(event->what == nullEvent || event->what == adjustCursorEvent) { if(event->what == nullEvent) { qApp->processEvents(); QApplication::sendPostedEvents(); } //watch for mouse moves Point currentPosition; GetMouse(¤tPosition); LocalToGlobal(¤tPosition); if(currentPosition.h != lastPosition.h || currentPosition.v != lastPosition.v) { lastPosition = currentPosition; WindowPtr wp; FindWindow(currentPosition, &wp); QWidget *widget = 0; if(wp == GetWindowFromPort((CGrafPtr)This->window->port)) widget = This->rootWidget->childAt(This->rootWidget->mapFromGlobal(QPoint(event->where.h, event->where.v))); else widget = QApplication::widgetAt(event->where.h, event->where.v); if(widget != lastWidget) { qt_dispatchEnterLeave(widget, lastWidget); lastWidget = widget; } if(widget) { QPoint p(currentPosition.h, currentPosition.v); QPoint plocal(widget->mapFromGlobal(p)); QMouseEvent qme(QEvent::MouseMove, plocal, p, Button() ? Qt::LeftButton : Qt::NoButton, 0, get_modifiers(GetCurrentKeyModifiers())); QApplication::sendEvent(widget, &qme); } } return true; } else if(QWidget *widget = qobject_cast(This->qt.object)) { if(event->what == updateEvt) { widget->repaint(); return true; } else if(event->what == keyUp || event->what == keyDown) { QWidget *widget = 0; if(QWidget::keyboardGrabber()) widget = QWidget::keyboardGrabber(); else if(QApplication::focusWidget()) widget = QApplication::focusWidget(); else //last ditch effort widget = QApplication::widgetAt(event->where.h, event->where.v); if(widget) { #if 0 if(app_do_modal && !qt_try_modal(widget, er)) return 1; #endif int mychar=get_key(event->message & charCodeMask); QEvent::Type etype = event->what == keyUp ? QEvent::KeyRelease : QEvent::KeyPress; QKeyEvent ke(etype, mychar, get_modifiers(event->modifiers), QString(QChar(mychar))); QApplication::sendEvent(widget,&ke); return true; } } else if(event->what == mouseDown || event->what == mouseUp) { QEvent::Type etype = QEvent::None; Qt::KeyboardModifiers keys = get_modifiers(event->modifiers); Qt::MouseButton button = Qt::LeftButton; if(event->what == mouseDown) { if (lastWidget) qt_button_down = lastWidget; //check if this is the second click, there must be a way to make the //mac do this for us, FIXME!! if(qt_last_mouse_down.when && (event->when - qt_last_mouse_down.when <= (uint)QApplication::doubleClickInterval())) { int x = event->where.h, y = event->where.v; if(x >= (qt_last_mouse_down.x-2) && x <= (qt_last_mouse_down.x+4) && y >= (qt_last_mouse_down.y-2) && y <= (qt_last_mouse_down.y+4)) { etype = QEvent::MouseButtonDblClick; qt_last_mouse_down.when = 0; } } if(etype == QEvent::None) { //guess it's just a press etype = QEvent::MouseButtonPress; qt_last_mouse_down.when = event->when; qt_last_mouse_down.x = event->where.h; qt_last_mouse_down.y = event->where.v; } } else { etype = QEvent::MouseButtonRelease; } WindowPtr wp; FindWindow(event->where, &wp); //handle popup's first QWidget *popupwidget = NULL; if(QApplication::activePopupWidget()) { if(wp) { QWidget *clt=QWidget::find((WId)wp); if(clt && clt->windowType() == Qt::Popup) popupwidget = clt; } if(!popupwidget) popupwidget = QApplication::activePopupWidget(); if(QWidget *child = popupwidget->childAt(popupwidget->mapFromGlobal(QPoint(event->where.h, event->where.v)))) popupwidget = child; QPoint p(event->where.h, event->where.v); QPoint plocal(popupwidget->mapFromGlobal(p)); QMouseEvent qme(etype, plocal, p, button, 0, keys); QApplication::sendEvent(popupwidget, &qme); } { QWidget *widget = 0; //figure out which widget to send it to if(event->what == mouseUp && qt_button_down) widget = qt_button_down; else if(QWidget::mouseGrabber()) widget = QWidget::mouseGrabber(); else if(wp == GetWindowFromPort((CGrafPtr)This->window->port)) widget = This->rootWidget->childAt(This->rootWidget->mapFromGlobal(QPoint(event->where.h, event->where.v))); else widget = QApplication::widgetAt(event->where.h, event->where.v); //setup the saved widget qt_button_down = event->what == mouseDown ? widget : 0; //finally send the event to the widget if its not the popup if(widget && widget != popupwidget) { #if 0 if(app_do_modal && !qt_try_modal(widget, er)) return 1; #endif if(event->what == mouseDown) { QWidget* w = widget; while(w->focusProxy()) w = w->focusProxy(); if(w->focusPolicy() & Qt::ClickFocus) w->setFocus(Qt::MouseFocusReason); if(QWidget *tlw = widget->topLevelWidget()) { tlw->raise(); if(tlw->isTopLevel() && tlw->windowType() != Qt::Popup && (tlw->isModal() || tlw->windowType() != Qt::Dialog)) QApplication::setActiveWindow(tlw); } } QPoint p(event->where.h, event->where.v); QPoint plocal(widget->mapFromGlobal( p )); QMouseEvent qme(etype, plocal, p, button, 0, keys); QApplication::sendEvent(widget, &qme); return true; } } } else { //qDebug("%d", event->what); } } return false; } extern "C" void qtns_initialize(QtNPInstance *) { qt_mac_set_native_menubar(false); if(!qApp) { ownsqapp = true; static int argc=0; static char **argv={ 0 }; (void)new QApplication(argc, argv); } } extern "C" void qtns_destroy(QtNPInstance *This) { delete This->rootWidget; This->rootWidget = 0; } extern "C" void qtns_shutdown() { if(!ownsqapp) return; // check if qApp still runs widgets (in other DLLs) QWidgetList widgets = qApp->allWidgets(); int count = widgets.count(); for (int w = 0; w < widgets.count(); ++w) { // ignore all Qt generated widgets QWidget *widget = widgets.at(w); if (widget->windowFlags() & Qt::Desktop) count--; } if (count) // qApp still used return; delete qApp; ownsqapp = false; } extern "C" void qtns_embed(QtNPInstance *This) { Q_ASSERT(qobject_cast(This->qt.object)); WindowPtr windowptr = GetWindowFromPort((CGrafPtr)This->window->port); HIViewRef root = 0; OSErr err; err = GetRootControl(windowptr,&root); if(!root) root = HIViewGetRoot(windowptr); if(!root) { qDebug("No window composition!"); } else { This->rootWidget = new QMacBrowserRoot(root); #if QT_VERSION >= 0x40400 // LYB 2009-3-10 This->qt.widget->setAttribute(Qt::WA_NativeWindow); #endif This->qt.widget->setParent(This->rootWidget); } } extern "C" void qtns_setGeometry(QtNPInstance *This, const QRect &rect, const QRect &clipRect) { Q_ASSERT(qobject_cast(This->qt.object)); WindowPtr windowptr = GetWindowFromPort((CGrafPtr)This->window->port); Rect content_r; GetWindowBounds(windowptr, kWindowContentRgn, &content_r); Rect structure_r; GetWindowBounds(windowptr, kWindowStructureRgn, &structure_r); QRect geom(rect.translated(content_r.left-structure_r.left, content_r.top-structure_r.top)); if(rect != clipRect) { QRegion clipRegion(QRect(clipRect.x()-geom.x(), clipRect.y()-geom.y(), clipRect.width(), clipRect.height()) .translated(content_r.left-structure_r.left, content_r.top-structure_r.top)); if(clipRegion.isEmpty()) clipRegion = QRegion(-1, -1, 1, 1); //eww ### FIXME This->qt.widget->setMask(clipRegion); } else { This->qt.widget->clearMask(); } This->qt.widget->setGeometry(geom); } #ifdef QTBROWSER_USE_CFM static bool qtbrowser_use_cfm = false; struct TVector_rec { ProcPtr fProcPtr; void *fTOC; }; void *CFMFunctionPointerForMachOFunctionPointer(void *inMachProcPtr) { if(!qtbrowser_use_cfm) return inMachProcPtr; TVector_rec *vTVector = (TVector_rec*)malloc(sizeof(TVector_rec)); if(MemError() == noErr && vTVector != 0) { vTVector->fProcPtr = (ProcPtr)inMachProcPtr; vTVector->fTOC = 0; // ignored } return((void *)vTVector); } void DisposeCFMFunctionPointer(void *inCfmProcPtr) { if(!qtbrowser_use_cfm) return; if(inCfmProcPtr) free(inCfmProcPtr); } void* MachOFunctionPointerForCFMFunctionPointer(void* inCfmProcPtr) { if(!qtbrowser_use_cfm) return inCfmProcPtr; static UInt32 gGlueTemplate[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 }; UInt32 *vMachProcPtr = (UInt32*)NewPtr(sizeof(gGlueTemplate)); vMachProcPtr[0] = gGlueTemplate[0] | ((UInt32)inCfmProcPtr >> 16); vMachProcPtr[1] = gGlueTemplate[1] | ((UInt32)inCfmProcPtr & 0xFFFF); vMachProcPtr[2] = gGlueTemplate[2]; vMachProcPtr[3] = gGlueTemplate[3]; vMachProcPtr[4] = gGlueTemplate[4]; vMachProcPtr[5] = gGlueTemplate[5]; MakeDataExecutable(vMachProcPtr, sizeof(gGlueTemplate)); return(vMachProcPtr); } #endif typedef void (*NPP_ShutdownUPP)(void); extern "C" void NPP_MacShutdown() { extern NPError NP_Shutdown(); NP_Shutdown(); } extern "C" int main(NPNetscapeFuncs *npn_funcs, NPPluginFuncs *np_funcs, NPP_ShutdownUPP *shutdown) { #ifdef QTBROWSER_USE_CFM qtbrowser_use_cfm = true; #endif NPError ret; extern NPError NP_Initialize(NPNetscapeFuncs*); if((ret=NP_Initialize(npn_funcs)) != NPERR_NO_ERROR) return ret; extern NPError NP_GetEntryPoints(NPPluginFuncs*); if((ret=NP_GetEntryPoints(np_funcs)) != NPERR_NO_ERROR) return ret; *shutdown = (NPP_ShutdownUPP)MAKE_FUNCTION_POINTER(NPP_MacShutdown); return NPERR_NO_ERROR; } djview4-4.10.5/npdjvu/qtbrowserplugin_p.h000066400000000000000000000053671264256014000204350ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2009- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ /**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #ifdef Q_WS_X11 # include # undef None #endif #include #include #include #include #include #include #include #include class QtNPStream; class QtNPForwarder; class QtNPInstance; class QtNPDocument; class QDjView; struct QtNPInstance { NPP npp; short fMode; #ifdef Q_WS_WIN typedef HWND Widget; #endif #ifdef Q_WS_X11 typedef Window Widget; Display *display; #endif #ifdef Q_WS_MAC typedef NPPort *Widget; QWidget *rootWidget; #endif Widget window; QRect geometry; union { QObject* object; QWidget* widget; } qt; // the following are npdjvu specific QUrl url; QStringList args; QByteArray savedData; QSet streams; QtNPForwarder *forwarder; QtNPDocument *document; QDjView *djview; NPObject *npobject; NPVariant onchange; }; djview4-4.10.5/npdjvu/qtbrowserplugin_win.cpp000066400000000000000000000241451264256014000213210ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include #include "qtbrowserplugin.h" #include "qtbrowserplugin_p.h" #include #include "qtnpapi.h" #if QT_VERSION >= 0x050000 # define QT_WA(unicode, ansi) unicode #endif static HHOOK hhook = 0; static bool ownsqapp = false; static const uint keytbl[256] = { // Keyboard mapping table Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Cancel, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Backspace, Qt::Key_Tab, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Clear, Qt::Key_Return, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Shift, Qt::Key_Control, Qt::Key_Alt, Qt::Key_Pause, Qt::Key_CapsLock, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Escape, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Mode_switch, Qt::Key_Space, Qt::Key_PageUp, Qt::Key_PageDown, Qt::Key_End, Qt::Key_Home, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right, Qt::Key_Down, Qt::Key_Select, Qt::Key_Printer, Qt::Key_Execute, Qt::Key_Print, Qt::Key_Insert, Qt::Key_Delete, Qt::Key_Help, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Meta, Qt::Key_Meta, Qt::Key_Menu, Qt::Key_unknown, Qt::Key_Sleep, Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_Asterisk, Qt::Key_Plus, Qt::Key_Comma, Qt::Key_Minus, Qt::Key_Period, Qt::Key_Slash, Qt::Key_F1, Qt::Key_F2, Qt::Key_F3, Qt::Key_F4, Qt::Key_F5, Qt::Key_F6, Qt::Key_F7, Qt::Key_F8, Qt::Key_F9, Qt::Key_F10, Qt::Key_F11, Qt::Key_F12, Qt::Key_F13, Qt::Key_F14, Qt::Key_F15, Qt::Key_F16, Qt::Key_F17, Qt::Key_F18, Qt::Key_F19, Qt::Key_F20, Qt::Key_F21, Qt::Key_F22, Qt::Key_F23, Qt::Key_F24, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_NumLock, Qt::Key_ScrollLock, Qt::Key_unknown, Qt::Key_Massyo, Qt::Key_Touroku, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Shift, Qt::Key_Shift, Qt::Key_Control, Qt::Key_Control, Qt::Key_Alt, Qt::Key_Alt, Qt::Key_Back, Qt::Key_Forward, Qt::Key_Refresh, Qt::Key_Stop, Qt::Key_Search, Qt::Key_Favorites, Qt::Key_HomePage, Qt::Key_VolumeMute, Qt::Key_VolumeDown, Qt::Key_VolumeUp, Qt::Key_MediaNext, Qt::Key_MediaPrevious, Qt::Key_MediaStop, Qt::Key_MediaPlay, Qt::Key_LaunchMail, Qt::Key_LaunchMedia, Qt::Key_Launch0, Qt::Key_Launch1, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Play, Qt::Key_Zoom, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Clear, 0 }; static int qt_translateKeyCode(int vk) { if (vk >= 0 && vk <= 255) return keytbl[vk]; return Qt::Key_unknown; } LRESULT CALLBACK FilterProc( int nCode, WPARAM wParam, LPARAM lParam ) { if (qApp) qApp->sendPostedEvents(0, -1); if (nCode < 0 || !(wParam & PM_REMOVE)) return CallNextHookEx(hhook, nCode, wParam, lParam); MSG *msg = (MSG*)lParam; bool processed = false; // (some) support for key-sequences via QAction and QShortcut if(msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) { QWidget *focusWidget = QWidget::find(msg->hwnd); if (focusWidget) { int key = msg->wParam; if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9')) key = qt_translateKeyCode(msg->wParam); Qt::KeyboardModifiers modifiers = 0; int modifierKey = 0; if (GetKeyState(VK_SHIFT) < 0) { modifierKey |= Qt::SHIFT; modifiers |= Qt::ShiftModifier; } if (GetKeyState(VK_CONTROL) < 0) { modifierKey |= Qt::CTRL; modifiers |= Qt::ControlModifier; } if (GetKeyState(VK_MENU) < 0) { modifierKey |= Qt::ALT; modifiers |= Qt::AltModifier; } QKeyEvent override(QEvent::ShortcutOverride, key, modifiers); override.ignore(); QApplication::sendEvent(focusWidget, &override); processed = override.isAccepted(); QKeySequence shortcutKey(modifierKey + key); if (!processed) { QList actions = focusWidget->window()->findChildren(); for (int i = 0; i < actions.count() && !processed; ++i) { QAction *action = actions.at(i); if (!action->isEnabled() || action->shortcut() != shortcutKey) continue; QShortcutEvent event(shortcutKey, 0); processed = QApplication::sendEvent(action, &event); } } if (!processed) { QList shortcuts = focusWidget->window()->findChildren(); for (int i = 0; i < shortcuts.count() && !processed; ++i) { QShortcut *shortcut = shortcuts.at(i); if (!shortcut->isEnabled() || shortcut->key() != shortcutKey) continue; QShortcutEvent event(shortcutKey, shortcut->id()); processed = QApplication::sendEvent(shortcut, &event); } } } } return CallNextHookEx(hhook, nCode, wParam, lParam); } extern "C" bool qtns_event(QtNPInstance *, NPEvent *) { return false; } extern "C" void qtns_initialize(QtNPInstance*) { if (!qApp) { ownsqapp = true; static int argc=0; static char **argv={ 0 }; (void)new QApplication(argc, argv); QT_WA({ hhook = SetWindowsHookExW( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() ); }, { hhook = SetWindowsHookExA( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() ); }); } } extern "C" void qtns_destroy(QtNPInstance *) { } extern "C" void qtns_shutdown() { if (!ownsqapp) return; // check if qApp still runs widgets (in other DLLs) QWidgetList widgets = qApp->allWidgets(); int count = widgets.count(); for (int w = 0; w < widgets.count(); ++w) { // ignore all Qt generated widgets QWidget *widget = widgets.at(w); if (widget->windowFlags() & Qt::Desktop) count--; } if (count) // qApp still used return; delete qApp; ownsqapp = false; if ( hhook ) UnhookWindowsHookEx( hhook ); hhook = 0; } extern "C" void qtns_embed(QtNPInstance *This) { Q_ASSERT(qobject_cast(This->qt.object)); LONG oldLong = GetWindowLong(This->window, GWL_STYLE); ::SetWindowLong(This->window, GWL_STYLE, oldLong | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); ::SetWindowLong(This->qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); ::SetParent(This->qt.widget->winId(), This->window); } extern "C" void qtns_setGeometry(QtNPInstance *This, const QRect &rect, const QRect &) { Q_ASSERT(qobject_cast(This->qt.object)); This->qt.widget->setGeometry(QRect(0, 0, rect.width(), rect.height())); } /* extern "C" void qtns_print(QtNPInstance * This, NPPrint *printInfo) { NPWindow* printWindow = &(printInfo->print.embedPrint.window); void* platformPrint = printInfo->print.embedPrint.platformPrint; // #### Nothing yet. } */ djview4-4.10.5/npdjvu/qtbrowserplugin_x11.cpp000066400000000000000000000110471264256014000211320ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include #include #include #include #include #ifdef Q_WS_X11 # if QT_VERSION >= 0x50000 # define Q_WS_X11_QT5 1 # include # define QX11EmbedWidget QWidget # else # define Q_WS_X11_QT4 1 # include # endif #endif #include "qtbrowserplugin.h" #include "qtbrowserplugin_p.h" #include "qtnpapi.h" #include static bool ownsqapp = false; static QMap clients; extern "C" bool qtns_event(QtNPInstance *, NPEvent *) { return false; } extern "C" void qtns_initialize(QtNPInstance* This) { if (!qApp) { ownsqapp = true; static int argc = 0; static char **argv = {0}; // Workaround to avoid re-initilaziation of glib char* envvar = qstrdup("QT_NO_THREADED_GLIB=1"); // Unavoidable memory leak; the variable must survive plugin unloading ::putenv(envvar); (void)new QApplication(argc, argv); } if (!clients.contains(This)) { QX11EmbedWidget* client = new QX11EmbedWidget; QHBoxLayout* layout = new QHBoxLayout(client); layout->setMargin(0); clients.insert(This, client); } } extern "C" void qtns_destroy(QtNPInstance* This) { QMap::iterator it = clients.find(This); if (it == clients.end()) return; delete it.value(); clients.erase(it); } extern "C" void qtns_shutdown() { if (clients.count() > 0) { QMap::iterator it = clients.begin(); while (it != clients.end()) { delete it.value(); ++it; } clients.clear(); } if (!ownsqapp) return; // check if qApp still runs widgets (in other DLLs) QWidgetList widgets = qApp->allWidgets(); int count = widgets.count(); for (int w = 0; w < widgets.count(); ++w) { // ignore all Qt generated widgets QWidget *widget = widgets.at(w); if (widget->windowFlags() & Qt::Desktop) count--; } if (count) // qApp still used return; delete qApp; ownsqapp = false; } extern "C" void qtns_embed(QtNPInstance *This) { Q_ASSERT(qobject_cast(This->qt.object)); QMap::iterator it = clients.find(This); if (it == clients.end()) return; #if Q_WS_X11_QT5 QWidget* client = it.value(); client->setAttribute(Qt::WA_NativeWindow, true); This->qt.widget->setParent(client); client->layout()->addWidget(This->qt.widget); QWindow *dwindow = client->windowHandle(); // memory leak? dwindow->setParent(QWindow::fromWinId(This->window)); // memory leak? #else QX11EmbedWidget* client = it.value(); This->qt.widget->setParent(client); client->layout()->addWidget(This->qt.widget); client->embedInto(This->window); #endif client->show(); } extern "C" void qtns_setGeometry(QtNPInstance *This, const QRect &rect, const QRect &) { Q_ASSERT(qobject_cast(This->qt.object)); QMap::iterator it = clients.find(This); if (it == clients.end()) return; QX11EmbedWidget* client = it.value(); client->setGeometry(QRect(0, 0, rect.width(), rect.height())); } /* extern "C" void qtns_print(QtNPInstance * This, NPPrint *printInfo) { NPWindow* printWindow = &(printInfo->print.embedPrint.window); void* platformPrint = printInfo->print.embedPrint.platformPrint; // #### Nothing yet. } */ djview4-4.10.5/npdjvu/qtnpapi.cpp000066400000000000000000000410231264256014000166430ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2009- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ /**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include #include #include "qtbrowserplugin.h" #include "qtbrowserplugin_p.h" #include "npdjvu.h" #ifndef WINAPI # ifdef Q_WS_WIN # define WINAPI __stdcall # else # define WINAPI # endif #endif #ifdef Q_WS_X11 # ifdef Bool # undef Bool # endif #endif static NPNetscapeFuncs *qNetscapeFuncs = 0; static bool mozilla_has_npruntime = true; // NPN functions, forwarding to function pointers provided by browser void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor) { Q_ASSERT(qNetscapeFuncs); *plugin_major = NP_VERSION_MAJOR; *plugin_minor = NP_VERSION_MINOR; *netscape_major = qNetscapeFuncs->version >> 8; // Major version is in high byte *netscape_minor = qNetscapeFuncs->version & 0xFF; // Minor version is in low byte } #define NPN_Prolog(x) \ Q_ASSERT(qNetscapeFuncs); \ Q_ASSERT(qNetscapeFuncs->x); \ #define NPN_PrologRuntime(x, statement) \ Q_ASSERT(qNetscapeFuncs); \ if (! mozilla_has_npruntime) statement; \ Q_ASSERT(qNetscapeFuncs->x); const char * NPN_UserAgent(NPP instance) { NPN_Prolog(uagent); return FIND_FUNCTION_POINTER(NPN_UserAgentFP, qNetscapeFuncs->uagent)(instance); } void NPN_Status(NPP instance, const char* message) { NPN_Prolog(status); FIND_FUNCTION_POINTER(NPN_StatusFP, qNetscapeFuncs->status)(instance, message); } NPError NPN_GetURL(NPP instance, const char* url, const char* window) { NPN_Prolog(geturl); return FIND_FUNCTION_POINTER(NPN_GetURLFP, qNetscapeFuncs->geturl)(instance, url, window); } NPError NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData) { if ((qNetscapeFuncs->version & 0xFF) < NPVERS_HAS_NOTIFICATION) return NPERR_INCOMPATIBLE_VERSION_ERROR; NPN_Prolog(geturlnotify); return FIND_FUNCTION_POINTER(NPN_GetURLNotifyFP, qNetscapeFuncs->geturlnotify)(instance, url, window, notifyData); } NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) { if ((qNetscapeFuncs->version & 0xFF) < NPVERS_HAS_NOTIFICATION) return NPERR_INCOMPATIBLE_VERSION_ERROR; NPN_Prolog(posturlnotify); return FIND_FUNCTION_POINTER(NPN_PostURLNotifyFP, qNetscapeFuncs->posturlnotify)(instance, url, window, len, buf, file, notifyData); } void* NPN_MemAlloc(uint32 size) { NPN_Prolog(memalloc); return FIND_FUNCTION_POINTER(NPN_MemAllocFP, qNetscapeFuncs->memalloc)(size); } void NPN_MemFree(void* ptr) { NPN_Prolog(memfree); FIND_FUNCTION_POINTER(NPN_MemFreeFP, qNetscapeFuncs->memfree)(ptr); } uint32 NPN_MemFlush(uint32 size) { NPN_Prolog(memflush); return FIND_FUNCTION_POINTER(NPN_MemFlushFP, qNetscapeFuncs->memflush)(size); } NPError NPN_GetValue(NPP instance, NPNVariable variable, void *ret_value) { NPN_Prolog(getvalue); return FIND_FUNCTION_POINTER(NPN_GetValueFP, qNetscapeFuncs->getvalue)(instance, variable, ret_value); } NPError NPN_SetValue(NPP instance, NPPVariable variable, void *ret_value) { NPN_Prolog(setvalue); return FIND_FUNCTION_POINTER(NPN_SetValueFP, qNetscapeFuncs->setvalue)(instance, variable, ret_value); } NPIdentifier NPN_GetStringIdentifier(const char* name) { NPN_PrologRuntime(getstringidentifier, return 0); return FIND_FUNCTION_POINTER(NPN_GetStringIdentifierFP, qNetscapeFuncs->getstringidentifier)(name); } void NPN_GetStringIdentifiers(const char** names, int32 nameCount, NPIdentifier* identifiers) { NPN_PrologRuntime(getstringidentifiers, return); FIND_FUNCTION_POINTER(NPN_GetStringIdentifiersFP, qNetscapeFuncs->getstringidentifiers)(names, nameCount, identifiers); } NPIdentifier NPN_GetIntIdentifier(int32 intid) { NPN_PrologRuntime(getintidentifier, return 0); return FIND_FUNCTION_POINTER(NPN_GetIntIdentifierFP, qNetscapeFuncs->getintidentifier)(intid); } bool NPN_IdentifierIsString(NPIdentifier identifier) { NPN_PrologRuntime(identifierisstring, return false); return FIND_FUNCTION_POINTER(NPN_IdentifierIsStringFP, qNetscapeFuncs->identifierisstring)(identifier); } char* NPN_UTF8FromIdentifier(NPIdentifier identifier) { NPN_PrologRuntime(utf8fromidentifier, return 0); return FIND_FUNCTION_POINTER(NPN_UTF8FromIdentifierFP, qNetscapeFuncs->utf8fromidentifier)(identifier); } int32 NPN_IntFromIdentifier(NPIdentifier identifier) { NPN_PrologRuntime(intfromidentifier, return 0); return FIND_FUNCTION_POINTER(NPN_IntFromIdentifierFP, qNetscapeFuncs->intfromidentifier)(identifier); } NPObject* NPN_CreateObject(NPP npp, NPClass *aClass) { NPN_PrologRuntime(createobject, return 0); return FIND_FUNCTION_POINTER(NPN_CreateObjectFP, qNetscapeFuncs->createobject)(npp, aClass); } NPObject* NPN_RetainObject(NPObject *obj) { NPN_PrologRuntime(retainobject, return obj); return FIND_FUNCTION_POINTER(NPN_RetainObjectFP, qNetscapeFuncs->retainobject)(obj); } void NPN_ReleaseObject(NPObject *obj) { NPN_PrologRuntime(releaseobject, return); FIND_FUNCTION_POINTER(NPN_ReleaseObjectFP, qNetscapeFuncs->releaseobject)(obj); } bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, int32 argCount, NPVariant *result) { NPN_PrologRuntime(invoke, return false); return FIND_FUNCTION_POINTER(NPN_InvokeFP, qNetscapeFuncs->invoke)(npp, obj, methodName, args, argCount, result); } bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, int32 argCount, NPVariant *result) { NPN_PrologRuntime(invokedefault, return false); return FIND_FUNCTION_POINTER(NPN_InvokeDefaultFP, qNetscapeFuncs->invokedefault)(npp, obj, args, argCount, result); } bool NPN_Evaluate(NPP npp, NPObject *obj, NPString *script, NPVariant *result) { NPN_PrologRuntime(evaluate, return false); return FIND_FUNCTION_POINTER(NPN_EvaluateFP, qNetscapeFuncs->evaluate)(npp, obj, script, result); } bool NPN_GetProperty(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result) { NPN_PrologRuntime(getproperty, return false); return FIND_FUNCTION_POINTER(NPN_GetPropertyFP, qNetscapeFuncs->getproperty)(npp, obj, propertyName, result); } bool NPN_SetProperty(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value) { NPN_PrologRuntime(setproperty, return false); return FIND_FUNCTION_POINTER(NPN_SetPropertyFP, qNetscapeFuncs->setproperty)(npp, obj, propertyName, value); } bool NPN_RemoveProperty(NPP npp, NPObject *obj, NPIdentifier propertyName) { NPN_PrologRuntime(removeproperty, return false); return FIND_FUNCTION_POINTER(NPN_RemovePropertyFP, qNetscapeFuncs->removeproperty)(npp, obj, propertyName); } bool NPN_HasProperty(NPP npp, NPObject *obj, NPIdentifier propertyName) { NPN_PrologRuntime(hasproperty, return false); return FIND_FUNCTION_POINTER(NPN_HasPropertyFP, qNetscapeFuncs->hasproperty)(npp, obj, propertyName); } bool NPN_HasMethod(NPP npp, NPObject *obj, NPIdentifier methodName) { NPN_PrologRuntime(hasmethod, return false); return FIND_FUNCTION_POINTER(NPN_HasMethodFP, qNetscapeFuncs->hasmethod)(npp, obj, methodName); } void NPN_ReleaseVariantValue(NPVariant *variant) { NPN_PrologRuntime(releasevariantvalue, return); FIND_FUNCTION_POINTER(NPN_ReleaseVariantValueFP, qNetscapeFuncs->releasevariantvalue)(variant); } void NPN_SetException(NPObject *obj, const char *message) { qDebug("NPN_SetException: %s", message); NPN_PrologRuntime(setexception, return); FIND_FUNCTION_POINTER(NPN_SetExceptionFP, qNetscapeFuncs->setexception)(obj, message); } // Type conversions NPString NPString::fromQString(const QString &qstr) { NPString npstring; const QByteArray qutf8 = qstr.toUtf8(); npstring.utf8length = qutf8.length(); npstring.utf8characters = (char*)NPN_MemAlloc(npstring.utf8length); memcpy((char*)npstring.utf8characters, qutf8.constData(), npstring.utf8length); return npstring; } NPString::operator QString() const { return QString::fromUtf8(utf8characters, utf8length); } NPVariant NPVariant::fromQVariant(QtNPInstance*, const QVariant &qvariant) { NPVariant npvar; npvar.type = Null; QVariant qvar(qvariant); switch(qvariant.type()) { case QVariant::Bool: npvar.value.boolValue = qvar.toBool(); npvar.type = Boolean; break; case QVariant::Int: npvar.value.intValue = qvar.toInt(); npvar.type = Int32; break; case QVariant::Double: npvar.value.doubleValue = qvar.toDouble(); npvar.type = Double; break; default: // including QVariant::String if (!qvar.convert(QVariant::String)) break; npvar.type = String; npvar.value.stringValue = NPString::fromQString(qvar.toString()); break; } return npvar; } NPVariant::operator QVariant() const { switch(type) { case Void: case Null: return QVariant(); case Boolean: return value.boolValue; case Int32: return value.intValue; case Double: return value.doubleValue; case String: return QString(value.stringValue); default: break; } return QVariant(); } static void NPClass_Invalidate(NPObject *npobj) { if (npobj) delete npobj->_class; npobj->_class = 0; } static bool NPClass_HasMethod(NPObject*, NPIdentifier) { return false; } static bool NPClass_Invoke(NPObject*, NPIdentifier, const NPVariant*, uint32, NPVariant*) { return false; } static bool NPClass_InvokeDefault(NPObject*, const NPVariant*, uint32, NPVariant*) { return false; } static bool NPClass_HasProperty(NPObject*, NPIdentifier) { return false; } static bool NPClass_GetProperty(NPObject*, NPIdentifier, NPVariant*) { return false; } static bool NPClass_SetProperty(NPObject*, NPIdentifier, const NPVariant*) { return false; } static bool NPClass_RemoveProperty(NPObject *npobj, NPIdentifier name) { NPVariant var; return NPClass_SetProperty(npobj, name, &var); } NPClass::NPClass(QtNPInstance *This) { structVersion = NP_CLASS_STRUCT_VERSION; allocate = 0; deallocate = 0; invalidate = NPClass_Invalidate; hasMethod = NPClass_HasMethod; invoke = NPClass_Invoke; invokeDefault = NPClass_InvokeDefault; hasProperty = NPClass_HasProperty; getProperty = NPClass_GetProperty; setProperty = NPClass_SetProperty; removeProperty = NPClass_RemoveProperty; qtnp = This; delete_qtnp = false; } NPClass::~NPClass() { if (delete_qtnp) delete qtnp; } // Fills in functiontable used by browser to call entry points in plugin. extern "C" NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs) { if(!pFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; if(!pFuncs->size) pFuncs->size = sizeof(NPPluginFuncs); else if (pFuncs->size < sizeof(NPPluginFuncs)) return NPERR_INVALID_FUNCTABLE_ERROR; pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; pFuncs->newp = MAKE_FUNCTION_POINTER(NPP_New); pFuncs->destroy = MAKE_FUNCTION_POINTER(NPP_Destroy); pFuncs->setwindow = MAKE_FUNCTION_POINTER(NPP_SetWindow); pFuncs->newstream = MAKE_FUNCTION_POINTER(NPP_NewStream); pFuncs->destroystream = MAKE_FUNCTION_POINTER(NPP_DestroyStream); pFuncs->asfile = MAKE_FUNCTION_POINTER(NPP_StreamAsFile); pFuncs->writeready = MAKE_FUNCTION_POINTER(NPP_WriteReady); pFuncs->write = MAKE_FUNCTION_POINTER(NPP_Write); pFuncs->print = MAKE_FUNCTION_POINTER(NPP_Print); pFuncs->event = MAKE_FUNCTION_POINTER(NPP_HandleEvent); pFuncs->urlnotify = MAKE_FUNCTION_POINTER(NPP_URLNotify); pFuncs->javaClass = 0; pFuncs->getvalue = MAKE_FUNCTION_POINTER(NPP_GetValue); pFuncs->setvalue = MAKE_FUNCTION_POINTER(NPP_SetValue); return NPERR_NO_ERROR; } #ifndef Q_WS_X11 extern "C" NPError WINAPI NP_Initialize(NPNetscapeFuncs* pFuncs) { if(!pFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; qNetscapeFuncs = pFuncs; int navMajorVers = qNetscapeFuncs->version >> 8; int navMinorVers = qNetscapeFuncs->version & 0xff; // if the plugin's major version is lower than the Navigator's, // then they are incompatible, and should return an error if(navMajorVers > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; // checks if browser supports npruntime mozilla_has_npruntime = true; if (navMajorVers == 0 && navMinorVers < 14) mozilla_has_npruntime = false; if (qNetscapeFuncs->size < (long)&(((NPNetscapeFuncs*)0)->setexception)) mozilla_has_npruntime = false; return NPERR_NO_ERROR; } #else extern "C" NPError WINAPI NP_Initialize(NPNetscapeFuncs* nFuncs, NPPluginFuncs* pFuncs) { if(!nFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; qNetscapeFuncs = nFuncs; int navMajorVers = qNetscapeFuncs->version >> 8; int navMinorVers = qNetscapeFuncs->version & 0xff; // if the plugin's major version is lower than the Navigator's, // then they are incompatible, and should return an error if(navMajorVers > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; // checks if browser supports npruntime mozilla_has_npruntime = true; if (navMajorVers == 0 && navMinorVers < 14) mozilla_has_npruntime = false; if (qNetscapeFuncs->size < (long)&(((NPNetscapeFuncs*)0)->setexception)) mozilla_has_npruntime = false; // check if the Browser supports the XEmbed protocol int supportsXEmbed = 0; NPError err = NPN_GetValue(0, NPNVSupportsXEmbedBool, (void *)&supportsXEmbed); if (err != NPERR_NO_ERROR ||!supportsXEmbed) return NPERR_INCOMPATIBLE_VERSION_ERROR; return NP_GetEntryPoints(pFuncs); } #endif extern "C" NPError WINAPI NP_Shutdown() { NPP_Shutdown(); qtns_shutdown(); qNetscapeFuncs = 0; return NPERR_NO_ERROR; } djview4-4.10.5/npdjvu/qtnpapi.h000066400000000000000000000477561264256014000163330ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. ** ** This file is part of a Qt Solutions component. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** Trolltech sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ // see http://www.mozilla.org/projects/plugins/ for details regarding the structs and API prototypes #ifndef QTNPAPI_H #define QTNPAPI_H // Plugin API version #define NP_VERSION_MAJOR 0 #define NP_VERSION_MINOR 17 // basic types typedef unsigned short uint16; typedef short int16; typedef unsigned int uint32; typedef int int32; typedef unsigned char NPBool; typedef int16 NPError; typedef int16 NPReason; typedef char* NPMIMEType; typedef void *NPRegion; typedef void *NPIdentifier; // Java stuff typedef void* jref; typedef void* JRIGlobalRef; typedef void* JRIEnv; // ### not quite correct, but we don't use it anyway // NP-types struct NPP_t { void* pdata; // plug-in private data void* ndata; // browser private data }; typedef NPP_t* NPP; struct NPRect { uint16 top; uint16 left; uint16 bottom; uint16 right; }; #ifdef Q_WS_WIN struct NPEvent { uint16 event; uint32 wParam; uint32 lParam; }; #elif defined(Q_WS_X11) # include typedef XEvent NPEvent; #elif defined (Q_WS_MAC) typedef struct EventRecord NPEvent; #endif // Variable names for NPP_GetValue enum NPPVariable { NPPVpluginNameString = 1, NPPVpluginDescriptionString, NPPVpluginWindowBool, NPPVpluginTransparentBool, NPPVjavaClass, NPPVpluginWindowSize, NPPVpluginTimerInterval, NPPVpluginScriptableInstance = 10, NPPVpluginScriptableIID = 11, // Introduced in Mozilla 0.9.9 NPPVjavascriptPushCallerBool = 12, // Introduced in Mozilla 1.0 NPPVpluginKeepLibraryInMemory = 13, NPPVpluginNeedsXEmbed = 14, // Introduced in Firefox 1.0 NPPVpluginScriptableNPObject = 15, NPPVformValue = 16 } ; // Variable names for NPN_GetValue enum NPNVariable { NPNVxDisplay = 1, NPNVxtAppContext, NPNVnetscapeWindow, NPNVjavascriptEnabledBool, NPNVasdEnabledBool, NPNVisOfflineBool, // Introduced in Mozilla 0.9.4 NPNVserviceManager = 10, NPNVDOMElement = 11, // Introduced in Mozilla 1.2 NPNVDOMWindow = 12, NPNVToolkit = 13, NPNVSupportsXEmbedBool = 14, NPNVWindowNPObject = 15, NPNVPluginElementNPObject = 16 }; enum NPWindowType { NPWindowTypeWindow = 1, // Windowed plug-in. The window field holds a platform-specific handle to a window. NPWindowTypeDrawable // Windows: HDC; Mac OS: pointer to NP_Port structure. }; struct NPWindow { // Platform-specific handle to a native window element in the browser's window hierarchy // XEmbed: "In the NPP_SetWindow call, the window parameter will be the XID of the hosting // XEmbed window. As an implementation note, this is really the XID of a GtkSocket window." void* window; // The x and y coordinates for the top left corner of the plug-in relative to the page // (and thus relative to the origin of the drawable) uint32 x, y; // The height and width of the plug-in area. Should not be modified by the plug-in. uint32 width, height; // Used by MAC only (Clipping rectangle in port coordinates) NPRect clipRect; #ifdef Q_WS_X11 // Contains information about the plug-in's Unix window environment // points to an NPSetWindowCallbackStruct void* ws_info; // probably obsolete with XEmbed #endif // The type field indicates the NPWindow type of the target area NPWindowType type; }; struct NPPort { void *port; int32 portx; int32 porty; }; struct NPFullPrint { NPBool pluginPrinted; // true if plugin handled fullscreen printing NPBool printOne; // true if plugin should print one copy to default printer void* platformPrint; // Platform-specific printing info }; struct NPEmbedPrint { NPWindow window; void* platformPrint; // Platform-specific printing info }; struct NPPrint { uint16 mode; // NP_FULL or NP_EMBED union { NPFullPrint fullPrint; NPEmbedPrint embedPrint; } print; }; struct NPSavedData { int32 len; void* buf; }; struct NPStream { void* pdata; void* ndata; const char* url; uint32 end; uint32 lastmodified; void* notifyData; }; struct NPByteRange { int32 offset; // negative offset means from the end uint32 length; NPByteRange* next; }; // Values for mode passed to NPP_New: #define NP_EMBED 1 #define NP_FULL 2 // Values for stream type passed to NPP_NewStream: #define NP_NORMAL 1 #define NP_SEEK 2 #define NP_ASFILE 3 #define NP_ASFILEONLY 4 #define NP_MAXREADY (((unsigned)(~0)<<1)>>1) // Values of type NPError: #define NPERR_NO_ERROR 0 #define NPERR_GENERIC_ERROR 1 #define NPERR_INVALID_INSTANCE_ERROR 2 #define NPERR_INVALID_FUNCTABLE_ERROR 3 #define NPERR_MODULE_LOAD_FAILED_ERROR 4 #define NPERR_OUT_OF_MEMORY_ERROR 5 #define NPERR_INVALID_PLUGIN_ERROR 6 #define NPERR_INVALID_PLUGIN_DIR_ERROR 7 #define NPERR_INCOMPATIBLE_VERSION_ERROR 8 #define NPERR_INVALID_PARAM 9 #define NPERR_INVALID_URL 10 #define NPERR_FILE_NOT_FOUND 11 #define NPERR_NO_DATA 12 #define NPERR_STREAM_NOT_SEEKABLE 13 // Values of type NPReason: #define NPRES_DONE 0 #define NPRES_NETWORK_ERR 1 #define NPRES_USER_BREAK 2 // Version feature information #define NPVERS_HAS_STREAMOUTPUT 8 #define NPVERS_HAS_NOTIFICATION 9 #define NPVERS_HAS_LIVECONNECT 9 #define NPVERS_WIN16_HAS_LIVECONNECT 10 // Mac specifics #ifdef Q_WS_MAC # define getFocusEvent (osEvt + 16) # define loseFocusEvent (osEvt + 17) # define adjustCursorEvent (osEvt + 18) # if defined(__ppc__) || defined(__powerpc__) // LYB 2009-03-10 # define QTBROWSER_USE_CFM # endif #endif #ifdef QTBROWSER_USE_CFM extern void *CFMFunctionPointerForMachOFunctionPointer(void*); extern void DisposeCFMFunctionPointer(void *); extern void* MachOFunctionPointerForCFMFunctionPointer(void*); # define FUNCTION_POINTER(t) void* # define MAKE_FUNCTION_POINTER(f) CFMFunctionPointerForMachOFunctionPointer((void*)f) # define DESTROY_FUNCTION_POINTER(n) DisposeCFMFunctionPointer(n) # define FIND_FUNCTION_POINTER(t, n) (*(t)MachOFunctionPointerForCFMFunctionPointer(n)) #else # define FUNCTION_POINTER(t) t # define MAKE_FUNCTION_POINTER(f) f # define DESTROY_FUNCTION_POINTER(n) # define FIND_FUNCTION_POINTER(t, n) (*n) #endif // Plugin function prototypes typedef NPError (*NPP_NewFP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); typedef NPError (*NPP_DestroyFP)(NPP instance, NPSavedData** save); typedef NPError (*NPP_SetWindowFP)(NPP instance, NPWindow* window); typedef NPError (*NPP_NewStreamFP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); typedef NPError (*NPP_DestroyStreamFP)(NPP instance, NPStream* stream, NPReason reason); typedef void (*NPP_StreamAsFileFP)(NPP instance, NPStream* stream, const char* fname); typedef int32 (*NPP_WriteReadyFP)(NPP instance, NPStream* stream); typedef int32 (*NPP_WriteFP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); typedef void (*NPP_PrintFP)(NPP instance, NPPrint* platformPrint); typedef int16 (*NPP_HandleEventFP)(NPP instance, NPEvent* event); typedef void (*NPP_URLNotifyFP)(NPP instance, const char* url, NPReason reason, void* notifyData); typedef NPError (*NPP_GetValueFP)(NPP instance, NPPVariable variable, void *value); typedef NPError (*NPP_SetValueFP)(NPP instance, NPPVariable variable, void *value); // table of functions implemented by the plugin struct NPPluginFuncs { uint16 size; uint16 version; FUNCTION_POINTER(NPP_NewFP) newp; FUNCTION_POINTER(NPP_DestroyFP) destroy; FUNCTION_POINTER(NPP_SetWindowFP) setwindow; FUNCTION_POINTER(NPP_NewStreamFP) newstream; FUNCTION_POINTER(NPP_DestroyStreamFP) destroystream; FUNCTION_POINTER(NPP_StreamAsFileFP) asfile; FUNCTION_POINTER(NPP_WriteReadyFP) writeready; FUNCTION_POINTER(NPP_WriteFP) write; FUNCTION_POINTER(NPP_PrintFP) print; FUNCTION_POINTER(NPP_HandleEventFP) event; FUNCTION_POINTER(NPP_URLNotifyFP) urlnotify; JRIGlobalRef javaClass; FUNCTION_POINTER(NPP_GetValueFP) getvalue; FUNCTION_POINTER(NPP_SetValueFP) setvalue; } ; // forward declarations struct NPObject; struct NPClass; struct NPVariant; struct NPString; struct QtNPInstance; // NPObject is the type used to express objects exposed by either // the plugin or by the browser. Implementation specific (i.e. plugin // specific, or browser specific) members can come after the struct. // In our case, the plugin specific member (aka QObject) lives in NPClass. struct NPObject { NPClass *_class; uint32 refCount; }; // NPClass is what virtual function tables would look like if // there was no C++... typedef NPObject *(*NPAllocateFP)(NPP npp, NPClass *aClass); typedef void (*NPDeallocateFP)(NPObject *npobj); typedef void (*NPInvalidateFP)(NPObject *npobj); typedef bool (*NPHasMethodFP)(NPObject *npobj, NPIdentifier name); typedef bool (*NPInvokeFP)(NPObject *npobj, NPIdentifier name,const NPVariant *args, uint32 argCount,NPVariant *result); typedef bool (*NPInvokeDefaultFP)(NPObject *npobj,const NPVariant *args,uint32 argCount,NPVariant *result); typedef bool (*NPHasPropertyFP)(NPObject *npobj, NPIdentifier name); typedef bool (*NPGetPropertyFP)(NPObject *npobj, NPIdentifier name, NPVariant *result); typedef bool (*NPSetPropertyFP)(NPObject *npobj, NPIdentifier name, const NPVariant *value); typedef bool (*NPRemovePropertyFP)(NPObject *npobj, NPIdentifier name); #define NP_CLASS_STRUCT_VERSION 1 struct NPClass { NPClass(QtNPInstance *qtnp); ~NPClass(); // NP API uint32 structVersion; NPAllocateFP allocate; NPDeallocateFP deallocate; NPInvalidateFP invalidate; NPHasMethodFP hasMethod; NPInvokeFP invoke; NPInvokeDefaultFP invokeDefault; NPHasPropertyFP hasProperty; NPGetPropertyFP getProperty; NPSetPropertyFP setProperty; NPRemovePropertyFP removeProperty; // User data lives here QtNPInstance *qtnp; bool delete_qtnp; }; struct NPString { const char *utf8characters; uint32 utf8length; // Qt specific conversion routines // (no c'tor as it would be misleading that there is no d'tor in spite of memory allocation) static NPString fromQString(const QString &qstr); operator QString() const; }; struct NPVariant { enum Type { Void, Null, Boolean, Int32, Double, String, Object }; Type type; union { bool boolValue; uint32 intValue; double doubleValue; NPString stringValue; NPObject *objectValue; } value; NPVariant() : type(Null) {} // Qt specific conversion routines // (no c'tor as the NPP instance is required) static NPVariant fromQVariant(QtNPInstance *This, const QVariant &qvariant); operator QVariant() const; private: }; #ifdef Q_WS_X11 extern "C" { #endif // Browser function prototypes typedef NPError (*NPN_GetURLFP)(NPP instance, const char* url, const char* window); typedef NPError (*NPN_PostURLFP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); typedef NPError (*NPN_RequestReadFP)(NPStream* stream, NPByteRange* rangeList); typedef NPError (*NPN_NewStreamFP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); typedef int32 (*NPN_WriteFP)(NPP instance, NPStream* stream, int32 len, void* buffer); typedef NPError (*NPN_DestroyStreamFP)(NPP instance, NPStream* stream, NPReason reason); typedef void (*NPN_StatusFP)(NPP instance, const char* message); typedef const char* (*NPN_UserAgentFP)(NPP instance); typedef void* (*NPN_MemAllocFP)(uint32 size); typedef void (*NPN_MemFreeFP)(void* ptr); typedef uint32 (*NPN_MemFlushFP)(uint32 size); typedef void (*NPN_ReloadPluginsFP)(NPBool reloadPages); typedef JRIEnv* (*NPN_GetJavaEnvFP)(void); typedef jref (*NPN_GetJavaPeerFP)(NPP instance); typedef NPError (*NPN_GetURLNotifyFP)(NPP instance, const char* url, const char* window, void* notifyData); typedef NPError (*NPN_PostURLNotifyFP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); typedef NPError (*NPN_GetValueFP)(NPP instance, NPNVariable variable, void *ret_value); typedef NPError (*NPN_SetValueFP)(NPP instance, NPPVariable variable, void *ret_value); typedef void (*NPN_InvalidateRectFP)(NPP instance, NPRect *rect); typedef void (*NPN_InvalidateRegionFP)(NPP instance, NPRegion *region); typedef void (*NPN_ForceRedrawFP)(NPP instance); typedef NPIdentifier (*NPN_GetStringIdentifierFP)(const char* name); typedef void (*NPN_GetStringIdentifiersFP)(const char** names, int32 nameCount, NPIdentifier* identifiers); typedef NPIdentifier (*NPN_GetIntIdentifierFP)(int32 intid); typedef bool (*NPN_IdentifierIsStringFP)(NPIdentifier identifier); typedef char* (*NPN_UTF8FromIdentifierFP)(NPIdentifier identifier); typedef int32 (*NPN_IntFromIdentifierFP)(NPIdentifier identifier); typedef NPObject* (*NPN_CreateObjectFP)(NPP npp, NPClass *aClass); typedef NPObject* (*NPN_RetainObjectFP)(NPObject *obj); typedef void (*NPN_ReleaseObjectFP)(NPObject *obj); typedef bool (*NPN_InvokeFP)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, int32 argCount, NPVariant *result); typedef bool (*NPN_InvokeDefaultFP)(NPP npp, NPObject* obj, const NPVariant *args, int32 argCount, NPVariant *result); typedef bool (*NPN_EvaluateFP)(NPP npp, NPObject *obj, NPString *script, NPVariant *result); typedef bool (*NPN_GetPropertyFP)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result); typedef bool (*NPN_SetPropertyFP)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value); typedef bool (*NPN_RemovePropertyFP)(NPP npp, NPObject *obj, NPIdentifier propertyName); typedef bool (*NPN_HasPropertyFP)(NPP npp, NPObject *obj, NPIdentifier propertyName); typedef bool (*NPN_HasMethodFP)(NPP npp, NPObject *obj, NPIdentifier methodName); typedef void (*NPN_ReleaseVariantValueFP)(NPVariant *variant); typedef void (*NPN_SetExceptionFP)(NPObject *obj, const char *message); // function declarations NPError NPN_GetURL(NPP instance, const char* url, const char* window); NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* window, NPStream** stream); int32 NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer); NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPReason reason); void NPN_Status(NPP instance, const char* message); const char* NPN_UserAgent(NPP instance); void* NPN_MemAlloc(uint32 size); void NPN_MemFree(void* ptr); uint32 NPN_MemFlush(uint32 size); void NPN_ReloadPlugins(NPBool reloadPages); JRIEnv* NPN_GetJavaEnv(void); jref NPN_GetJavaPeer(NPP instance); NPError NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData); NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); NPError NPN_GetValue(NPP instance, NPNVariable variable, void *ret_value); NPError NPN_SetValue(NPP instance, NPPVariable variable, void *ret_value); void NPN_InvalidateRect(NPP instance, NPRect *rect); void NPN_InvalidateRegion(NPP instance, NPRegion *region); void NPN_ForceRedraw(NPP instance); NPIdentifier NPN_GetStringIdentifier(const char* name); void NPN_GetStringIdentifiers(const char** names, int32 nameCount, NPIdentifier* identifiers); NPIdentifier NPN_GetIntIdentifier(int32 intid); bool NPN_IdentifierIsString(NPIdentifier identifier); char* NPN_UTF8FromIdentifier(NPIdentifier identifier); int32 NPN_IntFromIdentifier(NPIdentifier identifier); NPObject* NPN_CreateObject(NPP npp, NPClass *aClass); NPObject* NPN_RetainObject(NPObject *obj); void NPN_ReleaseObject(NPObject *obj); bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, int32 argCount, NPVariant *result); bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, int32 argCount, NPVariant *result); bool NPN_Evaluate(NPP npp, NPObject *obj, NPString *script, NPVariant *result); bool NPN_GetProperty(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result); bool NPN_SetProperty(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value); bool NPN_RemoveProperty(NPP npp, NPObject *obj, NPIdentifier propertyName); bool NPN_HasProperty(NPP npp, NPObject *obj, NPIdentifier propertyName); bool NPN_HasMethod(NPP npp, NPObject *obj, NPIdentifier methodName); void NPN_ReleaseVariantValue(NPVariant *variant); void NPN_SetException(NPObject *obj, const char *message); // table of function implemented by the browser struct NPNetscapeFuncs { uint16 size; uint16 version; FUNCTION_POINTER(NPN_GetURLFP) geturl; FUNCTION_POINTER(NPN_PostURLFP) posturl; FUNCTION_POINTER(NPN_RequestReadFP) requestread; FUNCTION_POINTER(NPN_NewStreamFP) newstream; FUNCTION_POINTER(NPN_WriteFP) write; FUNCTION_POINTER(NPN_DestroyStreamFP) destroystream; FUNCTION_POINTER(NPN_StatusFP) status; FUNCTION_POINTER(NPN_UserAgentFP) uagent; FUNCTION_POINTER(NPN_MemAllocFP) memalloc; FUNCTION_POINTER(NPN_MemFreeFP) memfree; FUNCTION_POINTER(NPN_MemFlushFP) memflush; FUNCTION_POINTER(NPN_ReloadPluginsFP) reloadplugins; FUNCTION_POINTER(NPN_GetJavaEnvFP) getJavaEnv; FUNCTION_POINTER(NPN_GetJavaPeerFP) getJavaPeer; FUNCTION_POINTER(NPN_GetURLNotifyFP) geturlnotify; FUNCTION_POINTER(NPN_PostURLNotifyFP) posturlnotify; FUNCTION_POINTER(NPN_GetValueFP) getvalue; FUNCTION_POINTER(NPN_SetValueFP) setvalue; FUNCTION_POINTER(NPN_InvalidateRectFP) invalidaterect; FUNCTION_POINTER(NPN_InvalidateRegionFP) invalidateregion; FUNCTION_POINTER(NPN_ForceRedrawFP) forceredraw; FUNCTION_POINTER(NPN_GetStringIdentifierFP) getstringidentifier; FUNCTION_POINTER(NPN_GetStringIdentifiersFP) getstringidentifiers; FUNCTION_POINTER(NPN_GetIntIdentifierFP) getintidentifier; FUNCTION_POINTER(NPN_IdentifierIsStringFP) identifierisstring; FUNCTION_POINTER(NPN_UTF8FromIdentifierFP) utf8fromidentifier; FUNCTION_POINTER(NPN_IntFromIdentifierFP) intfromidentifier; FUNCTION_POINTER(NPN_CreateObjectFP) createobject; FUNCTION_POINTER(NPN_RetainObjectFP) retainobject; FUNCTION_POINTER(NPN_ReleaseObjectFP) releaseobject; FUNCTION_POINTER(NPN_InvokeFP) invoke; FUNCTION_POINTER(NPN_InvokeDefaultFP) invokedefault; FUNCTION_POINTER(NPN_EvaluateFP) evaluate; FUNCTION_POINTER(NPN_GetPropertyFP) getproperty; FUNCTION_POINTER(NPN_SetPropertyFP) setproperty; FUNCTION_POINTER(NPN_RemovePropertyFP) removeproperty; FUNCTION_POINTER(NPN_HasPropertyFP) hasproperty; FUNCTION_POINTER(NPN_HasMethodFP) hasmethod; FUNCTION_POINTER(NPN_ReleaseVariantValueFP) releasevariantvalue; FUNCTION_POINTER(NPN_SetExceptionFP) setexception; }; #ifdef Q_WS_X11 } #endif #endif djview4-4.10.5/nsdejavu/000077500000000000000000000000001264256014000147745ustar00rootroot00000000000000djview4-4.10.5/nsdejavu/.gitignore000066400000000000000000000001261264256014000167630ustar00rootroot00000000000000/nsdejavu.1 /nsdejavu.la /nsdejavu.lo /nsdejavu.x /nsdejavu_la-nsdejavu.lo /test.djvu djview4-4.10.5/nsdejavu/COPYING000066400000000000000000000005271264256014000160330ustar00rootroot00000000000000 Program nsdejavu.so is distributed under the GNU Public License version 2 only because it depends on the Mozilla Plugin SDK files which are distributed under the Mozilla Public License version 1.1 and allow redistribution either under the GNU General Public License version 2, or under the GNU Library General Public License version 2.1. djview4-4.10.5/nsdejavu/Makefile.am000066400000000000000000000024161264256014000170330ustar00rootroot00000000000000 # plugin pluginsdir = ${libdir}/mozilla/plugins plugins_LTLIBRARIES = nsdejavu.la nsdejavu_la_SOURCES = nsdejavu.c nsdejavu_la_LDFLAGS = -module -rpath ${pluginsdir} -avoid-version nsdejavu_la_CPPFLAGS = -DDIR_BINDIR=\"$(bindir)\" -I${srcdir} -I${srcdir}/npsdk nsdejavu_la_CFLAGS = $(OPTS) $(NSDEJAVU_CFLAGS) nsdejavu_la_LIBADD = $(NSDEJAVU_LIBS) EXTRA_DIST = npsdk README COPYING # man page man1_MANS = nsdejavu.1 EXTRA_DIST += nsdejavu.1.in sed_process = eval "nsdejavu=`cat nsdejavu.x`" && $(SED) \ -e "s,PLUGINSDIR,${pluginsdir}," \ -e "s,NSDEJAVUSO,$${nsdejavu}," \ < $< > $@ || (rm $@; exit 1) man_verbose = $(man_verbose_@AM_V@) man_verbose_ = $(man_verbose_@AM_DEFAULT_V@) man_verbose_0 = @echo " MAN " $@; nsdejavu.x: nsdejavu.la @eval `grep '^dlname=' nsdejavu.la` && \ echo $${dlname} | sed -e 's/\([-.][0-9][0-9]*\)*//g' > $@ -@if test -z "`cat nsdejavu.x`" ; then \ echo "-----------------------------------------------";\ echo "*** Libtool cannot build the plugin 'nsdejavu'.";\ echo "*** Did you configure with '--disable-shared'? ";\ echo "-----------------------------------------------";\ fi nsdejavu.1: nsdejavu.1.in nsdejavu.x Makefile $(AM_V_at)rm -f $@ $(man_verbose)$(sed_process) MOSTLYCLEANFILES = nsdejavu.1 nsdejavu.x djview4-4.10.5/nsdejavu/README000066400000000000000000000007071264256014000156600ustar00rootroot00000000000000 This is the main directory for X11/UNIX DjVu browser plugin. It is not enough to compile this module to obtain a fully functioning plugin. You also need to compile the standalone DjVu viewer 'djview' using the X11 version of Qt4. This does not work on the Mac unless you use a X11-based browser. The stock Safari and all downloadable builds of popular browsers for OS X are Cocoa-based. TODO: Write a Cocoa-based browser plugin (see directory npdjvu.)djview4-4.10.5/nsdejavu/npsdk/000077500000000000000000000000001264256014000161135ustar00rootroot00000000000000djview4-4.10.5/nsdejavu/npsdk/COPYING000066400000000000000000000073171264256014000171560ustar00rootroot00000000000000 This directory contains files copied from the mozilla plugin sdk from http://lxr.mozilla.org/seamonkey/source/modules/plugin/base/public: npapi.h, nptypes.h, npupp.h, npruntime.h and files copied from the mozilla nspr library prtypes.h, protypes.h, prcpucfg.h These files contain the following copyright notice: | Version: MPL 1.1/GPL 2.0/LGPL 2.1 | | The contents of this file are subject to the Mozilla Public License Version | 1.1 (the "License"); you may not use this file except in compliance with | the License. You may obtain a copy of the License at | http://www.mozilla.org/MPL/ | | Software distributed under the License is distributed on an "AS IS" basis, | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | for the specific language governing rights and limitations under the | License. | | The Original Code is mozilla.org code. | | The Initial Developer of the Original Code is | Netscape Communications Corporation. | Portions created by the Initial Developer are Copyright (C) 1998 | the Initial Developer. All Rights Reserved. | | Contributor(s): | | Alternatively, the contents of this file may be used under the terms of | either the GNU General Public License Version 2 or later (the "GPL"), or | the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | in which case the provisions of the GPL or the LGPL are applicable instead | of those above. If you wish to allow use of your version of this file only | under the terms of either the GPL or the LGPL, and not to allow others to | use your version of this file under the terms of the MPL, indicate your | decision by deleting the provisions above and replace them with the notice | and other provisions required by the GPL or the LGPL. If you do not delete | the provisions above, a recipient may use your version of this file under | the terms of any one of the MPL, the GPL or the LGPL. The file npruntime.h contains a different copyright notice (BSD style) | Copyright © 2004, Apple Computer, Inc. and The Mozilla Foundation. | All rights reserved. | | Redistribution and use in source and binary forms, with or without | modification, are permitted provided that the following conditions are | met: | | 1. Redistributions of source code must retain the above copyright | notice, this list of conditions and the following disclaimer. | 2. Redistributions in binary form must reproduce the above copyright | notice, this list of conditions and the following disclaimer in the | documentation and/or other materials provided with the distribution. | 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla | Foundation ("Mozilla") nor the names of their contributors may be used | to endorse or promote products derived from this software without | specific prior written permission. | | THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR | THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The file jri.h simply contains dummy type definitions in order to isolate the other files from complicated java stuff. It contains a notice that places it in the public domain. djview4-4.10.5/nsdejavu/npsdk/jri.h000066400000000000000000000002411264256014000170450ustar00rootroot00000000000000/* Authored by Leon Bottou in 2007. This files is public domain. */ typedef void* JRIEnv; typedef void* JRIRef; typedef void* JRIGlobalRef; typedef void* jref; djview4-4.10.5/nsdejavu/npsdk/npapi.h000066400000000000000000000527361264256014000174100ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* npapi.h Revision 3.45 (cvs $Revision$) * Netscape client plug-in API spec */ #ifndef _NPAPI_H_ #define _NPAPI_H_ #ifdef __OS2__ #pragma pack(1) #endif #include "prtypes.h" /* Copied from xp_core.h */ /* removed #ifdef for hpux defined in /usr/include/model.h */ #ifndef _INT16 #define _INT16 #endif #ifndef _INT32 #define _INT32 #endif #ifndef _UINT16 #define _UINT16 #endif #ifndef _UINT32 #define _UINT32 #endif /* * NO_NSPR_10_SUPPORT disables the inclusion * of obsolete/protypes.h, whose int16, uint16, * int32, and uint32 typedefs conflict with those * in this file. */ #ifndef NO_NSPR_10_SUPPORT #define NO_NSPR_10_SUPPORT #endif #ifdef OJI #include "jri.h" /* Java Runtime Interface */ #endif #if defined (__OS2__ ) || defined (OS2) # ifndef XP_OS2 # define XP_OS2 1 # endif /* XP_OS2 */ #endif /* __OS2__ */ #ifdef _WINDOWS # include # ifndef XP_WIN # define XP_WIN 1 # endif /* XP_WIN */ #endif /* _WINDOWS */ #ifdef __MWERKS__ # define _declspec __declspec # ifdef __INTEL__ # undef NULL # ifndef XP_WIN # define XP_WIN 1 # endif /* XP_WIN */ # endif /* __INTEL__ */ #endif /* __MWERKS__ */ #ifdef XP_MACOSX #include #ifdef __LP64__ #define NP_NO_QUICKDRAW #endif #endif #if defined(XP_UNIX) # include # if defined(MOZ_X11) # include # include # endif #endif /*----------------------------------------------------------------------*/ /* Plugin Version Constants */ /*----------------------------------------------------------------------*/ #define NP_VERSION_MAJOR 0 #define NP_VERSION_MINOR 18 /* The OS/2 version of Netscape uses RC_DATA to define the mime types, file extensions, etc that are required. Use a vertical bar to separate types, end types with \0. FileVersion and ProductVersion are 32bit ints, all other entries are strings the MUST be terminated wwith a \0. AN EXAMPLE: RCDATA NP_INFO_ProductVersion { 1,0,0,1,} RCDATA NP_INFO_MIMEType { "video/x-video|", "video/x-flick\0" } RCDATA NP_INFO_FileExtents { "avi|", "flc\0" } RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|", "MMOS2 Flc/Fli player(*.flc)\0" } RCDATA NP_INFO_FileVersion { 1,0,0,1 } RCDATA NP_INFO_CompanyName { "Netscape Communications\0" } RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0" RCDATA NP_INFO_InternalName { "NPAVI32\0" ) RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0" RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" } RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" } */ /* RC_DATA types for version info - required */ #define NP_INFO_ProductVersion 1 #define NP_INFO_MIMEType 2 #define NP_INFO_FileOpenName 3 #define NP_INFO_FileExtents 4 /* RC_DATA types for version info - used if found */ #define NP_INFO_FileDescription 5 #define NP_INFO_ProductName 6 /* RC_DATA types for version info - optional */ #define NP_INFO_CompanyName 7 #define NP_INFO_FileVersion 8 #define NP_INFO_InternalName 9 #define NP_INFO_LegalCopyright 10 #define NP_INFO_OriginalFilename 11 #ifndef RC_INVOKED /*----------------------------------------------------------------------*/ /* Definition of Basic Types */ /*----------------------------------------------------------------------*/ #ifndef _UINT16 typedef unsigned short uint16; #endif #ifndef _UINT32 # if defined(__alpha) || defined(__amd64__) || defined(__x86_64__) typedef unsigned int uint32; # else /* __alpha */ typedef unsigned long uint32; # endif /* __alpha */ #endif /* * AIX defines these in sys/inttypes.h included from sys/types.h */ #ifndef AIX #ifndef _INT16 typedef short int16; #endif #ifndef _INT32 # if defined(__alpha) || defined(__amd64__) || defined(__x86_64__) typedef int int32; # else /* __alpha */ typedef long int32; # endif /* __alpha */ #endif #endif #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (1) #endif #ifndef NULL #define NULL (0L) #endif #ifdef XP_MACOSX typedef enum { #ifndef NP_NO_QUICKDRAW NPDrawingModelQuickDraw = 0, #endif NPDrawingModelCoreGraphics = 1 } NPDrawingModel; #endif typedef unsigned char NPBool; typedef int16 NPError; typedef int16 NPReason; typedef char* NPMIMEType; /*----------------------------------------------------------------------*/ /* Structures and definitions */ /*----------------------------------------------------------------------*/ /* * NPP is a plug-in's opaque instance handle */ typedef struct _NPP { void* pdata; /* plug-in private data */ void* ndata; /* netscape private data */ } NPP_t; typedef NPP_t* NPP; typedef struct _NPStream { void* pdata; /* plug-in private data */ void* ndata; /* netscape private data */ const char* url; uint32 end; uint32 lastmodified; void* notifyData; const char* headers; /* Response headers from host. * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS. * Used for HTTP only; NULL for non-HTTP. * Available from NPP_NewStream onwards. * Plugin should copy this data before storing it. * Includes HTTP status line and all headers, * preferably verbatim as received from server, * headers formatted as in HTTP ("Header: Value"), * and newlines (\n, NOT \r\n) separating lines. * Terminated by \n\0 (NOT \n\n\0). */ } NPStream; typedef struct _NPByteRange { int32 offset; /* negative offset means from the end */ uint32 length; struct _NPByteRange* next; } NPByteRange; typedef struct _NPSavedData { int32 len; void* buf; } NPSavedData; typedef struct _NPRect { uint16 top; uint16 left; uint16 bottom; uint16 right; } NPRect; typedef struct _NPSize { int32 width; int32 height; } NPSize; #ifdef XP_UNIX /* * Unix specific structures and definitions */ /* * Callback Structures. * * These are used to pass additional platform specific information. */ enum { NP_SETWINDOW = 1, NP_PRINT }; typedef struct { int32 type; } NPAnyCallbackStruct; typedef struct { int32 type; #ifdef MOZ_X11 Display* display; Visual* visual; Colormap colormap; unsigned int depth; #endif } NPSetWindowCallbackStruct; typedef struct { int32 type; FILE* fp; } NPPrintCallbackStruct; #endif /* XP_UNIX */ /* * The following masks are applied on certain platforms to NPNV and * NPPV selectors that pass around pointers to COM interfaces. Newer * compilers on some platforms may generate vtables that are not * compatible with older compilers. To prevent older plugins from * not understanding a new browser's ABI, these masks change the * values of those selectors on those platforms. To remain backwards * compatible with differenet versions of the browser, plugins can * use these masks to dynamically determine and use the correct C++ * ABI that the browser is expecting. This does not apply to Windows * as Microsoft's COM ABI will likely not change. */ #define NP_ABI_GCC3_MASK 0x10000000 /* * gcc 3.x generated vtables on UNIX and OSX are incompatible with * previous compilers. */ #if (defined (XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3)) #define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK #else #define _NP_ABI_MIXIN_FOR_GCC3 0 #endif #define NP_ABI_MACHO_MASK 0x01000000 /* * On OSX, the Mach-O executable format is significantly * different than CFM. In addition to having a different * C++ ABI, it also has has different C calling convention. * You must use glue code when calling between CFM and * Mach-O C functions. */ #if (defined(TARGET_RT_MAC_MACHO)) #define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK #else #define _NP_ABI_MIXIN_FOR_MACHO 0 #endif #define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO) /* * List of variable names for which NPP_GetValue shall be implemented */ typedef enum { NPPVpluginNameString = 1, NPPVpluginDescriptionString, NPPVpluginWindowBool, NPPVpluginTransparentBool, NPPVjavaClass, /* Not implemented in Mozilla 1.0 */ NPPVpluginWindowSize, NPPVpluginTimerInterval, NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), NPPVpluginScriptableIID = 11, /* Introduced in Mozilla 0.9.9 */ NPPVjavascriptPushCallerBool = 12, /* Introduced in Mozilla 1.0 */ NPPVpluginKeepLibraryInMemory = 13, NPPVpluginNeedsXEmbed = 14, /* Get the NPObject for scripting the plugin. Introduced in Firefox * 1.0 (NPAPI minor version 14). */ NPPVpluginScriptableNPObject = 15, /* Get the plugin value (as \0-terminated UTF-8 string data) for * form submission if the plugin is part of a form. Use * NPN_MemAlloc() to allocate memory for the string data. Introduced * in Mozilla 1.8b2 (NPAPI minor version 15). */ NPPVformValue = 16 } NPPVariable; /* * List of variable names for which NPN_GetValue is implemented by Mozilla */ typedef enum { NPNVxDisplay = 1, NPNVxtAppContext, NPNVnetscapeWindow, NPNVjavascriptEnabledBool, NPNVasdEnabledBool, NPNVisOfflineBool, /* 10 and over are available on Mozilla builds starting with 0.9.4 */ NPNVserviceManager = (10 | NP_ABI_MASK), NPNVDOMElement = (11 | NP_ABI_MASK), /* available in Mozilla 1.2 */ NPNVDOMWindow = (12 | NP_ABI_MASK), NPNVToolkit = (13 | NP_ABI_MASK), NPNVSupportsXEmbedBool = 14, /* Get the NPObject wrapper for the browser window. */ NPNVWindowNPObject = 15, /* Get the NPObject wrapper for the plugins DOM element. */ NPNVPluginElementNPObject = 16 #ifdef XP_MACOSX /* Used for negotiating drawing models */ , NPNVpluginDrawingModel = 1000 #ifndef NP_NO_QUICKDRAW , NPNVsupportsQuickDrawBool = 2000 #endif , NPNVsupportsCoreGraphicsBool = 2001 #endif } NPNVariable; /* * The type of Tookkit the widgets use */ typedef enum { NPNVGtk12 = 1, NPNVGtk2 } NPNToolkitType; /* * The type of a NPWindow - it specifies the type of the data structure * returned in the window field. */ typedef enum { NPWindowTypeWindow = 1, NPWindowTypeDrawable } NPWindowType; typedef struct _NPWindow { void* window; /* Platform specific window handle */ /* OS/2: x - Position of bottom left corner */ /* OS/2: y - relative to visible netscape window */ int32 x; /* Position of top left corner relative */ int32 y; /* to a netscape page. */ uint32 width; /* Maximum window size */ uint32 height; NPRect clipRect; /* Clipping rectangle in port coordinates */ /* Used by MAC only. */ #if defined(XP_UNIX) && !defined(XP_MACOSX) void * ws_info; /* Platform-dependent additonal data */ #endif /* XP_UNIX */ NPWindowType type; /* Is this a window or a drawable? */ } NPWindow; typedef struct _NPFullPrint { NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */ NPBool printOne; /* TRUE if plugin should print one copy to default printer */ void* platformPrint; /* Platform-specific printing info */ } NPFullPrint; typedef struct _NPEmbedPrint { NPWindow window; void* platformPrint; /* Platform-specific printing info */ } NPEmbedPrint; typedef struct _NPPrint { uint16 mode; /* NP_FULL or NP_EMBED */ union { NPFullPrint fullPrint; /* if mode is NP_FULL */ NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ } print; } NPPrint; #ifdef XP_MACOSX typedef EventRecord NPEvent; #elif defined(XP_WIN) typedef struct _NPEvent { uint16 event; uint32 wParam; uint32 lParam; } NPEvent; #elif defined(XP_OS2) typedef struct _NPEvent { uint32 event; uint32 wParam; uint32 lParam; } NPEvent; #elif defined (XP_UNIX) && defined(MOZ_X11) typedef XEvent NPEvent; #else typedef void* NPEvent; #endif /* XP_MACOSX */ #ifdef XP_MACOSX typedef void* NPRegion; #ifndef NP_NO_QUICKDRAW typedef RgnHandle NPQDRegion; #endif typedef CGPathRef NPCGRegion; #elif defined(XP_WIN) typedef HRGN NPRegion; #elif defined(XP_UNIX) && defined(MOZ_X11) typedef Region NPRegion; #else typedef void *NPRegion; #endif /* XP_MACOSX */ #ifdef XP_MACOSX /* * Mac-specific structures and definitions. */ typedef struct NP_Port { CGrafPtr port; /* Grafport */ int32 portx; /* position inside the topmost window */ int32 porty; } NP_Port; typedef struct NP_CGContext { CGContextRef context; WindowRef window; } NP_CGContext; /* * Non-standard event types that can be passed to HandleEvent */ enum NPEventType { NPEventType_GetFocusEvent = (osEvt + 16), NPEventType_LoseFocusEvent, NPEventType_AdjustCursorEvent, NPEventType_MenuCommandEvent, NPEventType_ClippingChangedEvent, NPEventType_ScrollingBeginsEvent = 1000, NPEventType_ScrollingEndsEvent }; #ifdef OBSOLETE #define getFocusEvent (osEvt + 16) #define loseFocusEvent (osEvt + 17) #define adjustCursorEvent (osEvt + 18) #endif #endif /* XP_MACOSX */ /* * Values for mode passed to NPP_New: */ #define NP_EMBED 1 #define NP_FULL 2 /* * Values for stream type passed to NPP_NewStream: */ #define NP_NORMAL 1 #define NP_SEEK 2 #define NP_ASFILE 3 #define NP_ASFILEONLY 4 #define NP_MAXREADY (((unsigned)(~0)<<1)>>1) /*----------------------------------------------------------------------*/ /* Error and Reason Code definitions */ /*----------------------------------------------------------------------*/ /* * Values of type NPError: */ #define NPERR_BASE 0 #define NPERR_NO_ERROR (NPERR_BASE + 0) #define NPERR_GENERIC_ERROR (NPERR_BASE + 1) #define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) #define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) #define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) #define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) #define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) #define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) #define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) #define NPERR_INVALID_PARAM (NPERR_BASE + 9) #define NPERR_INVALID_URL (NPERR_BASE + 10) #define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) #define NPERR_NO_DATA (NPERR_BASE + 12) #define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) /* * Values of type NPReason: */ #define NPRES_BASE 0 #define NPRES_DONE (NPRES_BASE + 0) #define NPRES_NETWORK_ERR (NPRES_BASE + 1) #define NPRES_USER_BREAK (NPRES_BASE + 2) /* * Don't use these obsolete error codes any more. */ #define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR #define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR #define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK /* * Version feature information */ #define NPVERS_HAS_STREAMOUTPUT 8 #define NPVERS_HAS_NOTIFICATION 9 #define NPVERS_HAS_LIVECONNECT 9 #define NPVERS_WIN16_HAS_LIVECONNECT 9 #define NPVERS_68K_HAS_LIVECONNECT 11 #define NPVERS_HAS_WINDOWLESS 11 #define NPVERS_HAS_XPCONNECT_SCRIPTING 13 #define NPVERS_HAS_NPRUNTIME_SCRIPTING 14 #define NPVERS_HAS_FORM_VALUES 15 #define NPVERS_HAS_POPUPS_ENABLED_STATE 16 #define NPVERS_HAS_RESPONSE_HEADERS 17 #define NPVERS_HAS_NPOBJECT_ENUM 18 /*----------------------------------------------------------------------*/ /* Function Prototypes */ /*----------------------------------------------------------------------*/ #if defined(_WINDOWS) && !defined(WIN32) #define NP_LOADDS _loadds #else #if defined(__OS2__) #define NP_LOADDS _System #else #define NP_LOADDS #endif #endif #ifdef __cplusplus extern "C" { #endif /* * NPP_* functions are provided by the plugin and called by the navigator. */ #ifdef XP_UNIX char* NPP_GetMIMEDescription(void); #endif /* XP_UNIX */ NPError NP_LOADDS NPP_Initialize(void); void NP_LOADDS NPP_Shutdown(void); NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason); int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname); void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); int16 NP_LOADDS NPP_HandleEvent(NPP instance, void* event); void NP_LOADDS NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); #ifdef OJI jref NP_LOADDS NPP_GetJavaClass(void); #endif NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value); NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value); /* * NPN_* functions are provided by the navigator and called by the plugin. */ void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor); NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url, const char* target, void* notifyData); NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url, const char* target); NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData); NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file); NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream); int32 NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer); NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream, NPReason reason); void NP_LOADDS NPN_Status(NPP instance, const char* message); const char* NP_LOADDS NPN_UserAgent(NPP instance); void* NP_LOADDS NPN_MemAlloc(uint32 size); void NP_LOADDS NPN_MemFree(void* ptr); uint32 NP_LOADDS NPN_MemFlush(uint32 size); void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages); #ifdef OJI JRIEnv* NP_LOADDS NPN_GetJavaEnv(void); jref NP_LOADDS NPN_GetJavaPeer(NPP instance); #endif NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable, void *value); NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable, void *value); void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect); void NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion); void NP_LOADDS NPN_ForceRedraw(NPP instance); void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled); void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance); #ifdef __cplusplus } /* end extern "C" */ #endif #endif /* RC_INVOKED */ #ifdef __OS2__ #pragma pack() #endif #endif /* _NPAPI_H_ */ djview4-4.10.5/nsdejavu/npsdk/npruntime.h000066400000000000000000000406601264256014000203130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Copyright © 2004, Apple Computer, Inc. and The Mozilla Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla * Foundation ("Mozilla") nor the names of their contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Revision 1 (March 4, 2004): * Initial proposal. * * Revision 2 (March 10, 2004): * All calls into script were made asynchronous. Results are * provided via the NPScriptResultFunctionPtr callback. * * Revision 3 (March 10, 2004): * Corrected comments to not refer to class retain/release FunctionPtrs. * * Revision 4 (March 11, 2004): * Added additional convenience NPN_SetExceptionWithUTF8(). * Changed NPHasPropertyFunctionPtr and NPHasMethodFunctionPtr to take NPClass * pointers instead of NPObject pointers. * Added NPIsValidIdentifier(). * * Revision 5 (March 17, 2004): * Added context parameter to result callbacks from ScriptObject functions. * * Revision 6 (March 29, 2004): * Renamed functions implemented by user agent to NPN_*. Removed _ from * type names. * Renamed "JavaScript" types to "Script". * * Revision 7 (April 21, 2004): * NPIdentifier becomes a void*, was int32_t * Remove NP_IsValidIdentifier, renamed NP_IdentifierFromUTF8 to NP_GetIdentifier * Added NPVariant and modified functions to use this new type. * * Revision 8 (July 9, 2004): * Updated to joint Apple-Mozilla license. * */ #ifndef _NP_RUNTIME_H_ #define _NP_RUNTIME_H_ #ifdef __cplusplus extern "C" { #endif #include "nptypes.h" /* This API is used to facilitate binding code written in C to script objects. The API in this header does not assume the presence of a user agent. That is, it can be used to bind C code to scripting environments outside of the context of a user agent. However, the normal use of the this API is in the context of a scripting environment running in a browser or other user agent. In particular it is used to support the extended Netscape script-ability API for plugins (NP-SAP). NP-SAP is an extension of the Netscape plugin API. As such we have adopted the use of the "NP" prefix for this API. The following NP{N|P}Variables were added to the Netscape plugin API (in npapi.h): NPNVWindowNPObject NPNVPluginElementNPObject NPPVpluginScriptableNPObject These variables are exposed through NPN_GetValue() and NPP_GetValue() (respectively) and are used to establish the initial binding between the user agent and native code. The DOM objects in the user agent can be examined and manipulated using the NPN_ functions that operate on NPObjects described in this header. To the extent possible the assumptions about the scripting language used by the scripting environment have been minimized. */ #define NP_BEGIN_MACRO do { #define NP_END_MACRO } while (0) /* Objects (non-primitive data) passed between 'C' and script is always wrapped in an NPObject. The 'interface' of an NPObject is described by an NPClass. */ typedef struct NPObject NPObject; typedef struct NPClass NPClass; typedef char NPUTF8; typedef struct _NPString { const NPUTF8 *utf8characters; uint32_t utf8length; } NPString; typedef enum { NPVariantType_Void, NPVariantType_Null, NPVariantType_Bool, NPVariantType_Int32, NPVariantType_Double, NPVariantType_String, NPVariantType_Object } NPVariantType; typedef struct _NPVariant { NPVariantType type; union { bool boolValue; uint32_t intValue; double doubleValue; NPString stringValue; NPObject *objectValue; } value; } NPVariant; /* NPN_ReleaseVariantValue is called on all 'out' parameters references. Specifically it is to be called on variants that own their value, as is the case with all non-const NPVariant* arguments after a successful call to any methods (except this one) in this API. After calling NPN_ReleaseVariantValue, the type of the variant will be NPVariantType_Void. */ void NPN_ReleaseVariantValue(NPVariant *variant); #define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void) #define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null) #define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool) #define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32) #define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double) #define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String) #define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object) #define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue) #define NPVARIANT_TO_INT32(_v) ((_v).value.intValue) #define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue) #define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue) #define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue) #define VOID_TO_NPVARIANT(_v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Void; \ (_v).value.objectValue = NULL; \ NP_END_MACRO #define NULL_TO_NPVARIANT(_v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Null; \ (_v).value.objectValue = NULL; \ NP_END_MACRO #define BOOLEAN_TO_NPVARIANT(_val, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Bool; \ (_v).value.boolValue = !!(_val); \ NP_END_MACRO #define INT32_TO_NPVARIANT(_val, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Int32; \ (_v).value.intValue = _val; \ NP_END_MACRO #define DOUBLE_TO_NPVARIANT(_val, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Double; \ (_v).value.doubleValue = _val; \ NP_END_MACRO #define STRINGZ_TO_NPVARIANT(_val, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_String; \ NPString str = { _val, strlen(_val) }; \ (_v).value.stringValue = str; \ NP_END_MACRO #define STRINGN_TO_NPVARIANT(_val, _len, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_String; \ NPString str = { _val, _len }; \ (_v).value.stringValue = str; \ NP_END_MACRO #define OBJECT_TO_NPVARIANT(_val, _v) \ NP_BEGIN_MACRO \ (_v).type = NPVariantType_Object; \ (_v).value.objectValue = _val; \ NP_END_MACRO /* Type mappings (JavaScript types have been used for illustration purposes): JavaScript to C (NPVariant with type:) undefined NPVariantType_Void null NPVariantType_Null Boolean NPVariantType_Bool Number NPVariantType_Double or NPVariantType_Int32 String NPVariantType_String Object NPVariantType_Object C (NPVariant with type:) to JavaScript NPVariantType_Void undefined NPVariantType_Null null NPVariantType_Bool Boolean NPVariantType_Int32 Number NPVariantType_Double Number NPVariantType_String String NPVariantType_Object Object */ typedef void *NPIdentifier; /* NPObjects have methods and properties. Methods and properties are identified with NPIdentifiers. These identifiers may be reflected in script. NPIdentifiers can be either strings or integers, IOW, methods and properties can be identified by either strings or integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be compared using ==. In case of any errors, the requested NPIdentifier(s) will be NULL. */ NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name); void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers); NPIdentifier NPN_GetIntIdentifier(int32_t intid); bool NPN_IdentifierIsString(NPIdentifier identifier); /* The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed. */ NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier); /* Get the integer represented by identifier. If identifier is not an integer identifier, the behaviour is undefined. */ int32_t NPN_IntFromIdentifier(NPIdentifier identifier); /* NPObject behavior is implemented using the following set of callback functions. The NPVariant *result argument of these functions (where applicable) should be released using NPN_ReleaseVariantValue(). */ typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass); typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj); typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj); typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name); typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result); typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result); typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, NPVariant *result); typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, const NPVariant *value); typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value, uint32_t *count); /* NPObjects returned by create, retain, invoke, and getProperty pass a reference count to the caller. That is, the callee adds a reference count which passes to the caller. It is the caller's responsibility to release the returned object. NPInvokeFunctionPtr function may return 0 to indicate a void result. NPInvalidateFunctionPtr is called by the scripting environment when the native code is shutdown. Any attempt to message a NPObject instance after the invalidate callback has been called will result in undefined behavior, even if the native code is still retaining those NPObject instances. (The runtime will typically return immediately, with 0 or NULL, from an attempt to dispatch to a NPObject, but this behavior should not be depended upon.) The NPEnumerationFunctionPtr function may pass an array of NPIdentifiers back to the caller. The callee allocs the memory of the array using NPN_MemAlloc(), and it's the caller's responsibility to release it using NPN_MemFree(). */ struct NPClass { uint32_t structVersion; NPAllocateFunctionPtr allocate; NPDeallocateFunctionPtr deallocate; NPInvalidateFunctionPtr invalidate; NPHasMethodFunctionPtr hasMethod; NPInvokeFunctionPtr invoke; NPInvokeDefaultFunctionPtr invokeDefault; NPHasPropertyFunctionPtr hasProperty; NPGetPropertyFunctionPtr getProperty; NPSetPropertyFunctionPtr setProperty; NPRemovePropertyFunctionPtr removeProperty; NPEnumerationFunctionPtr enumerate; }; #define NP_CLASS_STRUCT_VERSION 2 #define NP_CLASS_STRUCT_VERSION_ENUM 2 #define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \ ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM) struct NPObject { NPClass *_class; uint32_t referenceCount; /* * Additional space may be allocated here by types of NPObjects */ }; /* If the class has an allocate function, NPN_CreateObject invokes that function, otherwise a NPObject is allocated and returned. This method will initialize the referenceCount member of the NPObject to 1. */ NPObject *NPN_CreateObject(NPP npp, NPClass *aClass); /* Increment the NPObject's reference count. */ NPObject *NPN_RetainObject(NPObject *npobj); /* Decremented the NPObject's reference count. If the reference count goes to zero, the class's destroy function is invoke if specified, otherwise the object is freed directly. */ void NPN_ReleaseObject(NPObject *npobj); /* Functions to access script objects represented by NPObject. Calls to script objects are synchronous. If a function returns a value, it will be supplied via the result NPVariant argument. Successful calls will return true, false will be returned in case of an error. Calls made from plugin code to script must be made from the thread on which the plugin was initialized. */ bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result); bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, NPVariant *result); bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVariant *result); bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value); bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName); bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count); /* NPN_SetException may be called to trigger a script exception upon return from entry points into NPObjects. Typical usage: NPN_SetException (npobj, message); */ void NPN_SetException(NPObject *npobj, const NPUTF8 *message); #ifdef __cplusplus } #endif #endif djview4-4.10.5/nsdejavu/npsdk/nptypes.h000066400000000000000000000065761264256014000200040ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * mozilla.org. * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Johnny Stenback (Original author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * Header file for ensuring that C99 types ([u]int32_t and bool) are * available. */ #if defined(WIN32) || defined(OS2) /* * Win32 and OS/2 don't know C99, so define [u]int_32 here. The bool * is predefined tho, both in C and C++. */ typedef int int32_t; typedef unsigned int uint32_t; #elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX) /* * AIX and SunOS ship a inttypes.h header that defines [u]int32_t, * but not bool for C. */ #include #ifndef __cplusplus typedef int bool; #endif #elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) /* * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and * u_int32_t. */ #include /* * BSD/OS ships no header that defines uint32_t, nor bool (for C) */ #if defined(bsdi) typedef u_int32_t uint32_t; #if !defined(__cplusplus) typedef int bool; #endif #else /* * FreeBSD and OpenBSD define uint32_t and bool. */ #include #include #endif #elif defined(BEOS) #include #else /* * For those that ship a standard C99 stdint.h header file, include * it. Can't do the same for stdbool.h tho, since some systems ship * with a stdbool.h file that doesn't compile! */ #include #ifndef __cplusplus #if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95) #include #else /* * GCC 2.91 can't deal with a typedef for bool, but a #define * works. */ #define bool int #endif #endif #endif djview4-4.10.5/nsdejavu/npsdk/npupp.h000066400000000000000000000603161264256014000174340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * npupp.h $Revision$ * function call mecahnics needed by platform specific glue code. */ #ifndef _NPUPP_H_ #define _NPUPP_H_ #if defined(__OS2__) #pragma pack(1) #endif #ifndef GENERATINGCFM #define GENERATINGCFM 0 #endif #ifndef _NPAPI_H_ #include "npapi.h" #endif #include "npruntime.h" #include "jri.h" /****************************************************************************************** plug-in function table macros for each function in and out of the plugin API we define typedef NPP_FooUPP #define NewNPP_FooProc #define CallNPP_FooProc *******************************************************************************************/ /* NPP_Initialize */ typedef void (* NP_LOADDS NPP_InitializeUPP)(void); #define NewNPP_InitializeProc(FUNC) \ ((NPP_InitializeUPP) (FUNC)) #define CallNPP_InitializeProc(FUNC) \ (*(FUNC))() /* NPP_Shutdown */ typedef void (* NP_LOADDS NPP_ShutdownUPP)(void); #define NewNPP_ShutdownProc(FUNC) \ ((NPP_ShutdownUPP) (FUNC)) #define CallNPP_ShutdownProc(FUNC) \ (*(FUNC))() /* NPP_New */ typedef NPError (* NP_LOADDS NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); #define NewNPP_NewProc(FUNC) \ ((NPP_NewUPP) (FUNC)) #define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) /* NPP_Destroy */ typedef NPError (* NP_LOADDS NPP_DestroyUPP)(NPP instance, NPSavedData** save); #define NewNPP_DestroyProc(FUNC) \ ((NPP_DestroyUPP) (FUNC)) #define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPP_SetWindow */ typedef NPError (* NP_LOADDS NPP_SetWindowUPP)(NPP instance, NPWindow* window); #define NewNPP_SetWindowProc(FUNC) \ ((NPP_SetWindowUPP) (FUNC)) #define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPP_NewStream */ typedef NPError (* NP_LOADDS NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); #define NewNPP_NewStreamProc(FUNC) \ ((NPP_NewStreamUPP) (FUNC)) #define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) /* NPP_DestroyStream */ typedef NPError (* NP_LOADDS NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); #define NewNPP_DestroyStreamProc(FUNC) \ ((NPP_DestroyStreamUPP) (FUNC)) #define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg)) /* NPP_WriteReady */ typedef int32 (* NP_LOADDS NPP_WriteReadyUPP)(NPP instance, NPStream* stream); #define NewNPP_WriteReadyProc(FUNC) \ ((NPP_WriteReadyUPP) (FUNC)) #define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ (*(FUNC))((NPParg), (NPStreamPtr)) /* NPP_Write */ typedef int32 (* NP_LOADDS NPP_WriteUPP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); #define NewNPP_WriteProc(FUNC) \ ((NPP_WriteUPP) (FUNC)) #define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) /* NPP_StreamAsFile */ typedef void (* NP_LOADDS NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname); #define NewNPP_StreamAsFileProc(FUNC) \ ((NPP_StreamAsFileUPP) (FUNC)) #define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPP_Print */ typedef void (* NP_LOADDS NPP_PrintUPP)(NPP instance, NPPrint* platformPrint); #define NewNPP_PrintProc(FUNC) \ ((NPP_PrintUPP) (FUNC)) #define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \ (*(FUNC))((NPParg), (NPPrintArg)) /* NPP_HandleEvent */ typedef int16 (* NP_LOADDS NPP_HandleEventUPP)(NPP instance, void* event); #define NewNPP_HandleEventProc(FUNC) \ ((NPP_HandleEventUPP) (FUNC)) #define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ (*(FUNC))((NPParg), (voidPtr)) /* NPP_URLNotify */ typedef void (* NP_LOADDS NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData); #define NewNPP_URLNotifyProc(FUNC) \ ((NPP_URLNotifyUPP) (FUNC)) #define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /* NPP_GetValue */ typedef NPError (* NP_LOADDS NPP_GetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); #define NewNPP_GetValueProc(FUNC) \ ((NPP_GetValueUPP) (FUNC)) #define CallNPP_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPP_SetValue */ typedef NPError (* NP_LOADDS NPP_SetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); #define NewNPP_SetValueProc(FUNC) \ ((NPP_SetValueUPP) (FUNC)) #define CallNPP_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* * Netscape entry points */ /* NPN_GetValue */ typedef NPError (* NP_LOADDS NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); #define NewNPN_GetValueProc(FUNC) \ ((NPN_GetValueUPP) (FUNC)) #define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_SetValue */ typedef NPError (* NP_LOADDS NPN_SetValueUPP)(NPP instance, NPPVariable variable, void *ret_alue); #define NewNPN_SetValueProc(FUNC) \ ((NPN_SetValueUPP) (FUNC)) #define CallNPN_SetValueProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_GetUrlNotify */ typedef NPError (* NP_LOADDS NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData); #define NewNPN_GetURLNotifyProc(FUNC) \ ((NPN_GetURLNotifyUPP) (FUNC)) #define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /* NPN_PostUrlNotify */ typedef NPError (* NP_LOADDS NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); #define NewNPN_PostURLNotifyProc(FUNC) \ ((NPN_PostURLNotifyUPP) (FUNC)) #define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) /* NPN_GetUrl */ typedef NPError (* NP_LOADDS NPN_GetURLUPP)(NPP instance, const char* url, const char* window); #define NewNPN_GetURLProc(FUNC) \ ((NPN_GetURLUPP) (FUNC)) #define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_PostUrl */ typedef NPError (* NP_LOADDS NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); #define NewNPN_PostURLProc(FUNC) \ ((NPN_PostURLUPP) (FUNC)) #define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) /* NPN_RequestRead */ typedef NPError (* NP_LOADDS NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList); #define NewNPN_RequestReadProc(FUNC) \ ((NPN_RequestReadUPP) (FUNC)) #define CallNPN_RequestReadProc(FUNC, stream, range) \ (*(FUNC))((stream), (range)) /* NPN_NewStream */ typedef NPError (* NP_LOADDS NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); #define NewNPN_NewStreamProc(FUNC) \ ((NPN_NewStreamUPP) (FUNC)) #define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ (*(FUNC))((npp), (type), (window), (stream)) /* NPN_Write */ typedef int32 (* NP_LOADDS NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer); #define NewNPN_WriteProc(FUNC) \ ((NPN_WriteUPP) (FUNC)) #define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ (*(FUNC))((npp), (stream), (len), (buffer)) /* NPN_DestroyStream */ typedef NPError (* NP_LOADDS NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); #define NewNPN_DestroyStreamProc(FUNC) \ ((NPN_DestroyStreamUPP) (FUNC)) #define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ (*(FUNC))((npp), (stream), (reason)) /* NPN_Status */ typedef void (* NP_LOADDS NPN_StatusUPP)(NPP instance, const char* message); #define NewNPN_StatusProc(FUNC) \ ((NPN_StatusUPP) (FUNC)) #define CallNPN_StatusProc(FUNC, npp, msg) \ (*(FUNC))((npp), (msg)) /* NPN_UserAgent */ typedef const char* (* NP_LOADDS NPN_UserAgentUPP)(NPP instance); #define NewNPN_UserAgentProc(FUNC) \ ((NPN_UserAgentUPP) (FUNC)) #define CallNPN_UserAgentProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_MemAlloc */ typedef void* (* NP_LOADDS NPN_MemAllocUPP)(uint32 size); #define NewNPN_MemAllocProc(FUNC) \ ((NPN_MemAllocUPP) (FUNC)) #define CallNPN_MemAllocProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN__MemFree */ typedef void (* NP_LOADDS NPN_MemFreeUPP)(void* ptr); #define NewNPN_MemFreeProc(FUNC) \ ((NPN_MemFreeUPP) (FUNC)) #define CallNPN_MemFreeProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_MemFlush */ typedef uint32 (* NP_LOADDS NPN_MemFlushUPP)(uint32 size); #define NewNPN_MemFlushProc(FUNC) \ ((NPN_MemFlushUPP) (FUNC)) #define CallNPN_MemFlushProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_ReloadPlugins */ typedef void (* NP_LOADDS NPN_ReloadPluginsUPP)(NPBool reloadPages); #define NewNPN_ReloadPluginsProc(FUNC) \ ((NPN_ReloadPluginsUPP) (FUNC)) #define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_GetJavaEnv */ typedef JRIEnv* (* NP_LOADDS NPN_GetJavaEnvUPP)(void); #define NewNPN_GetJavaEnvProc(FUNC) \ ((NPN_GetJavaEnvUPP) (FUNC)) #define CallNPN_GetJavaEnvProc(FUNC) \ (*(FUNC))() /* NPN_GetJavaPeer */ typedef jref (* NP_LOADDS NPN_GetJavaPeerUPP)(NPP instance); #define NewNPN_GetJavaPeerProc(FUNC) \ ((NPN_GetJavaPeerUPP) (FUNC)) #define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_InvalidateRect */ typedef void (* NP_LOADDS NPN_InvalidateRectUPP)(NPP instance, NPRect *rect); #define NewNPN_InvalidateRectProc(FUNC) \ ((NPN_InvalidateRectUPP) (FUNC)) #define CallNPN_InvalidateRectProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPN_InvalidateRegion */ typedef void (* NP_LOADDS NPN_InvalidateRegionUPP)(NPP instance, NPRegion region); #define NewNPN_InvalidateRegionProc(FUNC) \ ((NPN_InvalidateRegionUPP) (FUNC)) #define CallNPN_InvalidateRegionProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPN_ForceRedraw */ typedef void (* NP_LOADDS NPN_ForceRedrawUPP)(NPP instance); #define NewNPN_ForceRedrawProc(FUNC) \ ((NPN_ForceRedrawUPP) (FUNC)) #define CallNPN_ForceRedrawProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_GetStringIdentifier */ typedef NPIdentifier (* NP_LOADDS NPN_GetStringIdentifierUPP)(const NPUTF8* name); #define NewNPN_GetStringIdentifierProc(FUNC) \ ((NPN_GetStringIdentifierUPP) (FUNC)) #define CallNPN_GetStringIdentifierProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_GetStringIdentifiers */ typedef void (* NP_LOADDS NPN_GetStringIdentifiersUPP)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers); #define NewNPN_GetStringIdentifiersProc(FUNC) \ ((NPN_GetStringIdentifiersUPP) (FUNC)) #define CallNPN_GetStringIdentifiersProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_GetIntIdentifier */ typedef NPIdentifier (* NP_LOADDS NPN_GetIntIdentifierUPP)(int32_t intid); #define NewNPN_GetIntIdentifierProc(FUNC) \ ((NPN_GetIntIdentifierUPP) (FUNC)) #define CallNPN_GetIntIdentifierProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_IdentifierIsString */ typedef bool (* NP_LOADDS NPN_IdentifierIsStringUPP)(NPIdentifier identifier); #define NewNPN_IdentifierIsStringProc(FUNC) \ ((NPN_IdentifierIsStringUPP) (FUNC)) #define CallNPN_IdentifierIsStringProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_UTF8FromIdentifier */ typedef NPUTF8* (* NP_LOADDS NPN_UTF8FromIdentifierUPP)(NPIdentifier identifier); #define NewNPN_UTF8FromIdentifierProc(FUNC) \ ((NPN_UTF8FromIdentifierUPP) (FUNC)) #define CallNPN_UTF8FromIdentifierProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_IntFromIdentifier */ typedef int32_t (* NP_LOADDS NPN_IntFromIdentifierUPP)(NPIdentifier identifier); #define NewNPN_IntFromIdentifierProc(FUNC) \ ((NPN_IntFromIdentifierUPP) (FUNC)) #define CallNPN_IntFromIdentifierProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_CreateObject */ typedef NPObject* (* NP_LOADDS NPN_CreateObjectUPP)(NPP npp, NPClass *aClass); #define NewNPN_CreateObjectProc(FUNC) \ ((NPN_CreateObjectUPP) (FUNC)) #define CallNPN_CreateObjectProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPN_RetainObject */ typedef NPObject* (* NP_LOADDS NPN_RetainObjectUPP)(NPObject *obj); #define NewNPN_RetainObjectProc(FUNC) \ ((NPN_RetainObjectUPP) (FUNC)) #define CallNPN_RetainObjectProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_ReleaseObject */ typedef void (* NP_LOADDS NPN_ReleaseObjectUPP)(NPObject *obj); #define NewNPN_ReleaseObjectProc(FUNC) \ ((NPN_ReleaseObjectUPP) (FUNC)) #define CallNPN_ReleaseObjectProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_Invoke */ typedef bool (* NP_LOADDS NPN_InvokeUPP)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); #define NewNPN_InvokeProc(FUNC) \ ((NPN_InvokeUPP) (FUNC)) #define CallNPN_InvokeProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) /* NPN_InvokeDefault */ typedef bool (* NP_LOADDS NPN_InvokeDefaultUPP)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result); #define NewNPN_InvokeDefaultProc(FUNC) \ ((NPN_InvokeDefaultUPP) (FUNC)) #define CallNPN_InvokeDefaultProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) /* NPN_Evaluate */ typedef bool (* NP_LOADDS NPN_EvaluateUPP)(NPP npp, NPObject *obj, NPString *script, NPVariant *result); #define NewNPN_EvaluateProc(FUNC) \ ((NPN_EvaluateUPP) (FUNC)) #define CallNPN_EvaluateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /* NPN_GetProperty */ typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result); #define NewNPN_GetPropertyProc(FUNC) \ ((NPN_GetPropertyUPP) (FUNC)) #define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /* NPN_SetProperty */ typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value); #define NewNPN_SetPropertyProc(FUNC) \ ((NPN_SetPropertyUPP) (FUNC)) #define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /* NPN_RemoveProperty */ typedef bool (* NP_LOADDS NPN_RemovePropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); #define NewNPN_RemovePropertyProc(FUNC) \ ((NPN_RemovePropertyUPP) (FUNC)) #define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_HasProperty */ typedef bool (* NP_LOADDS NPN_HasPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); #define NewNPN_HasPropertyProc(FUNC) \ ((NPN_HasPropertyUPP) (FUNC)) #define CallNPN_HasPropertyProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_HasMethod */ typedef bool (* NP_LOADDS NPN_HasMethodUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName); #define NewNPN_HasMethodProc(FUNC) \ ((NPN_HasMethodUPP) (FUNC)) #define CallNPN_HasMethodProc(FUNC, ARG1, ARG2, ARG3) \ (*(FUNC))((ARG1), (ARG2), (ARG3)) /* NPN_ReleaseVariantValue */ typedef void (* NP_LOADDS NPN_ReleaseVariantValueUPP)(NPVariant *variant); #define NewNPN_ReleaseVariantValueProc(FUNC) \ ((NPN_ReleaseVariantValueUPP) (FUNC)) #define CallNPN_ReleaseVariantValueProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_SetException */ typedef void (* NP_LOADDS NPN_SetExceptionUPP)(NPObject *obj, const NPUTF8 *message); #define NewNPN_SetExceptionProc(FUNC) \ ((NPN_SetExceptionUPP) (FUNC)) #define CallNPN_SetExceptionProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPN_PushPopupsEnabledStateUPP */ typedef bool (* NP_LOADDS NPN_PushPopupsEnabledStateUPP)(NPP npp, NPBool enabled); #define NewNPN_PushPopupsEnabledStateProc(FUNC) \ ((NPN_PushPopupsEnabledStateUPP) (FUNC)) #define CallNPN_PushPopupsEnabledStateProc(FUNC, ARG1, ARG2) \ (*(FUNC))((ARG1), (ARG2)) /* NPN_PopPopupsEnabledState */ typedef bool (* NP_LOADDS NPN_PopPopupsEnabledStateUPP)(NPP npp); #define NewNPN_PopPopupsEnabledStateProc(FUNC) \ ((NPN_PopPopupsEnabledStateUPP) (FUNC)) #define CallNPN_PopPopupsEnabledStateProc(FUNC, ARG1) \ (*(FUNC))((ARG1)) /* NPN_Enumerate */ typedef bool (* NP_LOADDS NPN_EnumerateUPP)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count); #define NewNPN_EnumerateProc(FUNC) \ ((NPN_EnumerateUPP) (FUNC)) #define CallNPN_EnumerateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) /****************************************************************************************** * The actual plugin function table definitions *******************************************************************************************/ typedef struct _NPPluginFuncs { uint16 size; uint16 version; NPP_NewUPP newp; NPP_DestroyUPP destroy; NPP_SetWindowUPP setwindow; NPP_NewStreamUPP newstream; NPP_DestroyStreamUPP destroystream; NPP_StreamAsFileUPP asfile; NPP_WriteReadyUPP writeready; NPP_WriteUPP write; NPP_PrintUPP print; NPP_HandleEventUPP event; NPP_URLNotifyUPP urlnotify; JRIGlobalRef javaClass; NPP_GetValueUPP getvalue; NPP_SetValueUPP setvalue; } NPPluginFuncs; typedef struct _NPNetscapeFuncs { uint16 size; uint16 version; NPN_GetURLUPP geturl; NPN_PostURLUPP posturl; NPN_RequestReadUPP requestread; NPN_NewStreamUPP newstream; NPN_WriteUPP write; NPN_DestroyStreamUPP destroystream; NPN_StatusUPP status; NPN_UserAgentUPP uagent; NPN_MemAllocUPP memalloc; NPN_MemFreeUPP memfree; NPN_MemFlushUPP memflush; NPN_ReloadPluginsUPP reloadplugins; NPN_GetJavaEnvUPP getJavaEnv; NPN_GetJavaPeerUPP getJavaPeer; NPN_GetURLNotifyUPP geturlnotify; NPN_PostURLNotifyUPP posturlnotify; NPN_GetValueUPP getvalue; NPN_SetValueUPP setvalue; NPN_InvalidateRectUPP invalidaterect; NPN_InvalidateRegionUPP invalidateregion; NPN_ForceRedrawUPP forceredraw; NPN_GetStringIdentifierUPP getstringidentifier; NPN_GetStringIdentifiersUPP getstringidentifiers; NPN_GetIntIdentifierUPP getintidentifier; NPN_IdentifierIsStringUPP identifierisstring; NPN_UTF8FromIdentifierUPP utf8fromidentifier; NPN_IntFromIdentifierUPP intfromidentifier; NPN_CreateObjectUPP createobject; NPN_RetainObjectUPP retainobject; NPN_ReleaseObjectUPP releaseobject; NPN_InvokeUPP invoke; NPN_InvokeDefaultUPP invokeDefault; NPN_EvaluateUPP evaluate; NPN_GetPropertyUPP getproperty; NPN_SetPropertyUPP setproperty; NPN_RemovePropertyUPP removeproperty; NPN_HasPropertyUPP hasproperty; NPN_HasMethodUPP hasmethod; NPN_ReleaseVariantValueUPP releasevariantvalue; NPN_SetExceptionUPP setexception; NPN_PushPopupsEnabledStateUPP pushpopupsenabledstate; NPN_PopPopupsEnabledStateUPP poppopupsenabledstate; NPN_EnumerateUPP enumerate; } NPNetscapeFuncs; #ifdef XP_MACOSX /****************************************************************************************** * Mac platform-specific plugin glue stuff *******************************************************************************************/ /* * Main entry point of the plugin. * This routine will be called when the plugin is loaded. The function * tables are passed in and the plugin fills in the NPPluginFuncs table * and NPPShutdownUPP for Netscape's use. */ typedef NPError (* NP_LOADDS NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*); #define NewNPP_MainEntryProc(FUNC) \ ((NPP_MainEntryUPP) (FUNC)) #define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP)) /* * Mac OS X version(s) of NP_GetMIMEDescription(const char *) * These can be called to retreive MIME information from the plugin dynamically * * Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way * to get mime info from the plugin only on OSX and may not be supported * in furture version -- use NP_GetMIMEDescription instead */ enum { kBPSupportedMIMETypesStructVers_1 = 1 }; typedef struct _BPSupportedMIMETypes { SInt32 structVersion; /* struct version */ Handle typeStrings; /* STR# formated handle, allocated by plug-in */ Handle infoStrings; /* STR# formated handle, allocated by plug-in */ } BPSupportedMIMETypes; OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags); /* NP_GetMIMEDescription */ #define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription" typedef const char* (* NP_LOADDS NP_GetMIMEDescriptionUPP)(); #define NewNP_GetMIMEDescEntryProc(FUNC) \ ((NP_GetMIMEDescriptionUPP) (FUNC)) #define CallNP_GetMIMEDescEntryProc(FUNC) \ (*(FUNC))() /* BP_GetSupportedMIMETypes */ typedef OSErr (* NP_LOADDS BP_GetSupportedMIMETypesUPP)(BPSupportedMIMETypes*, UInt32); #define NewBP_GetSupportedMIMETypesEntryProc(FUNC) \ ((BP_GetSupportedMIMETypesUPP) (FUNC)) #define CallBP_GetMIMEDescEntryProc(FUNC, mimeInfo, flags) \ (*(FUNC))((mimeInfo), (flags)) #endif /* XP_MACOSX */ #if defined(_WINDOWS) #define OSCALL WINAPI #else #if defined(__OS2__) #define OSCALL _System #else #define OSCALL #endif #endif #if defined( _WINDOWS ) || defined (__OS2__) #ifdef __cplusplus extern "C" { #endif /* plugin meta member functions */ #if defined(__OS2__) typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */ char *pMimeTypes; char *pFileExtents; char *pFileOpenTemplate; char *pProductName; char *pProductDescription; unsigned long dwProductVersionMS; unsigned long dwProductVersionLS; } NPPluginData; NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData); #endif NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs); NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs); NPError OSCALL NP_Shutdown(); char* NP_GetMIMEDescription(); #ifdef __cplusplus } #endif #endif /* _WINDOWS || __OS2__ */ #if defined(__OS2__) #pragma pack() #endif #ifdef XP_UNIX #ifdef __cplusplus extern "C" { #endif /* plugin meta member functions */ char* NP_GetMIMEDescription(void); NPError NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*); NPError NP_Shutdown(void); NPError NP_GetValue(void *future, NPPVariable aVariable, void *aValue); #ifdef __cplusplus } #endif #endif /* XP_UNIX */ #endif /* _NPUPP_H_ */ djview4-4.10.5/nsdejavu/npsdk/obsolete/000077500000000000000000000000001264256014000177275ustar00rootroot00000000000000djview4-4.10.5/nsdejavu/npsdk/obsolete/protypes.h000066400000000000000000000154011264256014000217660ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * This header typedefs the old 'native' types to the new PRs. * These definitions are scheduled to be eliminated at the earliest * possible time. The NSPR API is implemented and documented using * the new definitions. */ #if !defined(PROTYPES_H) #define PROTYPES_H typedef PRUintn uintn; #ifndef _XP_Core_ typedef PRIntn intn; #endif /* * It is trickier to define uint, int8, uint8, int16, uint16, * int32, uint32, int64, and uint64 because some of these int * types are defined by standard header files on some platforms. * Our strategy here is to include all such standard headers * first, and then define these int types only if they are not * defined by those standard headers. */ /* * BeOS defines all the int types below in its standard header * file SupportDefs.h. */ #ifdef XP_BEOS #include #endif /* * OpenVMS defines all the int types below in its standard * header files ints.h and types.h. */ #ifdef VMS #include #include #endif /* * SVR4 typedef of uint is commonly found on UNIX machines. * * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h) * defines the types int8, int16, int32, and int64. */ #ifdef XP_UNIX #include #endif /* model.h on HP-UX defines int8, int16, and int32. */ #ifdef HPUX #include #endif /* * uint */ #if !defined(XP_BEOS) && !defined(VMS) \ && !defined(XP_UNIX) || defined(NTO) typedef PRUintn uint; #endif /* * uint64 */ #if !defined(XP_BEOS) && !defined(VMS) typedef PRUint64 uint64; #endif /* * uint32 */ #if !defined(XP_BEOS) && !defined(VMS) #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) typedef PRUint32 uint32; #else typedef unsigned long uint32; #endif #endif /* * uint16 */ #if !defined(XP_BEOS) && !defined(VMS) typedef PRUint16 uint16; #endif /* * uint8 */ #if !defined(XP_BEOS) && !defined(VMS) typedef PRUint8 uint8; #endif /* * int64 */ #if !defined(XP_BEOS) && !defined(VMS) \ && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) typedef PRInt64 int64; #endif /* * int32 */ #if !defined(XP_BEOS) && !defined(VMS) \ && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ && !defined(HPUX) #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) typedef PRInt32 int32; #else typedef long int32; #endif #endif /* * int16 */ #if !defined(XP_BEOS) && !defined(VMS) \ && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ && !defined(HPUX) typedef PRInt16 int16; #endif /* * int8 */ #if !defined(XP_BEOS) && !defined(VMS) \ && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ && !defined(HPUX) typedef PRInt8 int8; #endif typedef PRFloat64 float64; typedef PRUptrdiff uptrdiff_t; typedef PRUword uprword_t; typedef PRWord prword_t; /* Re: prbit.h */ #define TEST_BIT PR_TEST_BIT #define SET_BIT PR_SET_BIT #define CLEAR_BIT PR_CLEAR_BIT /* Re: prarena.h->plarena.h */ #define PRArena PLArena #define PRArenaPool PLArenaPool #define PRArenaStats PLArenaStats #define PR_ARENA_ALIGN PL_ARENA_ALIGN #define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL #define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE #define PR_ARENA_GROW PL_ARENA_GROW #define PR_ARENA_MARK PL_ARENA_MARK #define PR_CLEAR_UNUSED PL_CLEAR_UNUSED #define PR_CLEAR_ARENA PL_CLEAR_ARENA #define PR_ARENA_RELEASE PL_ARENA_RELEASE #define PR_COUNT_ARENA PL_COUNT_ARENA #define PR_ARENA_DESTROY PL_ARENA_DESTROY #define PR_InitArenaPool PL_InitArenaPool #define PR_FreeArenaPool PL_FreeArenaPool #define PR_FinishArenaPool PL_FinishArenaPool #define PR_CompactArenaPool PL_CompactArenaPool #define PR_ArenaFinish PL_ArenaFinish #define PR_ArenaAllocate PL_ArenaAllocate #define PR_ArenaGrow PL_ArenaGrow #define PR_ArenaRelease PL_ArenaRelease #define PR_ArenaCountAllocation PL_ArenaCountAllocation #define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth #define PR_ArenaCountGrowth PL_ArenaCountGrowth #define PR_ArenaCountRelease PL_ArenaCountRelease #define PR_ArenaCountRetract PL_ArenaCountRetract /* Re: prhash.h->plhash.h */ #define PRHashEntry PLHashEntry #define PRHashTable PLHashTable #define PRHashNumber PLHashNumber #define PRHashFunction PLHashFunction #define PRHashComparator PLHashComparator #define PRHashEnumerator PLHashEnumerator #define PRHashAllocOps PLHashAllocOps #define PR_NewHashTable PL_NewHashTable #define PR_HashTableDestroy PL_HashTableDestroy #define PR_HashTableRawLookup PL_HashTableRawLookup #define PR_HashTableRawAdd PL_HashTableRawAdd #define PR_HashTableRawRemove PL_HashTableRawRemove #define PR_HashTableAdd PL_HashTableAdd #define PR_HashTableRemove PL_HashTableRemove #define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries #define PR_HashTableLookup PL_HashTableLookup #define PR_HashTableDump PL_HashTableDump #define PR_HashString PL_HashString #define PR_CompareStrings PL_CompareStrings #define PR_CompareValues PL_CompareValues #if defined(XP_MAC) #ifndef TRUE /* Mac standard is lower case true */ #define TRUE 1 #endif #ifndef FALSE /* Mac standard is lower case false */ #define FALSE 0 #endif #endif #endif /* !defined(PROTYPES_H) */ djview4-4.10.5/nsdejavu/npsdk/prcpucfg.h000066400000000000000000000526271264256014000201110ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nspr_cpucfg___ #define nspr_cpucfg___ #ifndef XP_UNIX #define XP_UNIX #endif #ifndef LINUX #define LINUX #endif #define PR_AF_INET6 10 /* same as AF_INET6 */ #ifdef __powerpc64__ #ifdef __LITTLE_ENDIAN__ #undef IS_BIG_ENDIAN #define IS_LITTLE_ENDIAN 1 #else #undef IS_LITTLE_ENDIAN #define IS_BIG_ENDIAN 1 #endif #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 8 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 64 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 6 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 8 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 8 #define PR_BYTES_PER_WORD_LOG2 3 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__powerpc__) #undef IS_LITTLE_ENDIAN #define IS_BIG_ENDIAN 1 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__alpha) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 8 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 64 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 6 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 8 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 8 #define PR_BYTES_PER_WORD_LOG2 3 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__ia64__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 8 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 64 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 6 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 8 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 8 #define PR_BYTES_PER_WORD_LOG2 3 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__x86_64__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 8 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 64 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 6 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 8 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 8 #define PR_BYTES_PER_WORD_LOG2 3 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__mc68000__) #undef IS_LITTLE_ENDIAN #define IS_BIG_ENDIAN 1 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 2 #define PR_ALIGN_OF_LONG 2 #define PR_ALIGN_OF_INT64 2 #define PR_ALIGN_OF_FLOAT 2 #define PR_ALIGN_OF_DOUBLE 2 #define PR_ALIGN_OF_POINTER 2 #define PR_ALIGN_OF_WORD 2 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__sparc__) #undef IS_LITTLE_ENDIAN #define IS_BIG_ENDIAN 1 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__i386__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 4 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__mips__) #ifdef __MIPSEB__ #define IS_BIG_ENDIAN 1 #undef IS_LITTLE_ENDIAN #elif defined(__MIPSEL__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #else #error "Unknown MIPS endianness." #endif #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__arm__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 4 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__aarch64__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 8 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__hppa__) #undef IS_LITTLE_ENDIAN #define IS_BIG_ENDIAN 1 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__s390x__) #define IS_BIG_ENDIAN 1 #undef IS_LITTLE_ENDIAN #define IS_64 #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 8 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 8 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 64 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 64 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 6 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 6 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 8 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_WORD 8 #define PR_BYTES_PER_WORD_LOG2 3 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__s390__) #define IS_BIG_ENDIAN 1 #undef IS_LITTLE_ENDIAN #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 4 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #elif defined(__sh__) #ifdef __LITTLE_ENDIAN__ #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN #else #define IS_BIG_ENDIAN 1 #undef IS_LITTLE_ENDIAN #endif #define PR_BYTES_PER_BYTE 1 #define PR_BYTES_PER_SHORT 2 #define PR_BYTES_PER_INT 4 #define PR_BYTES_PER_INT64 8 #define PR_BYTES_PER_LONG 4 #define PR_BYTES_PER_FLOAT 4 #define PR_BYTES_PER_DOUBLE 8 #define PR_BYTES_PER_WORD 4 #define PR_BYTES_PER_DWORD 8 #define PR_BITS_PER_BYTE 8 #define PR_BITS_PER_SHORT 16 #define PR_BITS_PER_INT 32 #define PR_BITS_PER_INT64 64 #define PR_BITS_PER_LONG 32 #define PR_BITS_PER_FLOAT 32 #define PR_BITS_PER_DOUBLE 64 #define PR_BITS_PER_WORD 32 #define PR_BITS_PER_BYTE_LOG2 3 #define PR_BITS_PER_SHORT_LOG2 4 #define PR_BITS_PER_INT_LOG2 5 #define PR_BITS_PER_INT64_LOG2 6 #define PR_BITS_PER_LONG_LOG2 5 #define PR_BITS_PER_FLOAT_LOG2 5 #define PR_BITS_PER_DOUBLE_LOG2 6 #define PR_BITS_PER_WORD_LOG2 5 #define PR_ALIGN_OF_SHORT 2 #define PR_ALIGN_OF_INT 4 #define PR_ALIGN_OF_LONG 4 #define PR_ALIGN_OF_INT64 8 #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 #else #error "Unknown CPU architecture" #endif #define HAVE_LONG_LONG #if PR_ALIGN_OF_DOUBLE == 8 #define HAVE_ALIGNED_DOUBLES #endif #if PR_ALIGN_OF_INT64 == 8 #define HAVE_ALIGNED_LONGLONGS #endif #ifndef NO_NSPR_10_SUPPORT #define BYTES_PER_BYTE PR_BYTES_PER_BYTE #define BYTES_PER_SHORT PR_BYTES_PER_SHORT #define BYTES_PER_INT PR_BYTES_PER_INT #define BYTES_PER_INT64 PR_BYTES_PER_INT64 #define BYTES_PER_LONG PR_BYTES_PER_LONG #define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT #define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE #define BYTES_PER_WORD PR_BYTES_PER_WORD #define BYTES_PER_DWORD PR_BYTES_PER_DWORD #define BITS_PER_BYTE PR_BITS_PER_BYTE #define BITS_PER_SHORT PR_BITS_PER_SHORT #define BITS_PER_INT PR_BITS_PER_INT #define BITS_PER_INT64 PR_BITS_PER_INT64 #define BITS_PER_LONG PR_BITS_PER_LONG #define BITS_PER_FLOAT PR_BITS_PER_FLOAT #define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE #define BITS_PER_WORD PR_BITS_PER_WORD #define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 #define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 #define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 #define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 #define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 #define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 #define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 #define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 #define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT #define ALIGN_OF_INT PR_ALIGN_OF_INT #define ALIGN_OF_LONG PR_ALIGN_OF_LONG #define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 #define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT #define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE #define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER #define ALIGN_OF_WORD PR_ALIGN_OF_WORD #define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 #define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 #define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 #endif /* NO_NSPR_10_SUPPORT */ #endif /* nspr_cpucfg___ */ djview4-4.10.5/nsdejavu/npsdk/prtypes.h000066400000000000000000000467761264256014000200160ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* ** File: prtypes.h ** Description: Definitions of NSPR's basic types ** ** Prototypes and macros used to make up for deficiencies that we have found ** in ANSI environments. ** ** Since we do not wrap and all the other standard headers, authors ** of portable code will not know in general that they need these definitions. ** Instead of requiring these authors to find the dependent uses in their code ** and take the following steps only in those C files, we take steps once here ** for all C files. **/ #ifndef prtypes_h___ #define prtypes_h___ #ifdef MDCPUCFG #include MDCPUCFG #else #include "prcpucfg.h" #endif #include /*********************************************************************** ** MACROS: PR_EXTERN ** PR_IMPLEMENT ** DESCRIPTION: ** These are only for externally visible routines and globals. For ** internal routines, just use "extern" for type checking and that ** will not export internal cross-file or forward-declared symbols. ** Define a macro for declaring procedures return types. We use this to ** deal with windoze specific type hackery for DLL definitions. Use ** PR_EXTERN when the prototype for the method is declared. Use ** PR_IMPLEMENT for the implementation of the method. ** ** Example: ** in dowhim.h ** PR_EXTERN( void ) DoWhatIMean( void ); ** in dowhim.c ** PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; } ** ** ***********************************************************************/ #if defined(WIN32) #define PR_EXPORT(__type) extern __declspec(dllexport) __type #define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPORT(__type) __declspec(dllimport) __type #define PR_IMPORT_DATA(__type) __declspec(dllimport) __type #define PR_EXTERN(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT(__type) __declspec(dllexport) __type #define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type #define PR_CALLBACK #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x #elif defined(XP_BEOS) #define PR_EXPORT(__type) extern __declspec(dllexport) __type #define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPORT(__type) extern __declspec(dllexport) __type #define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type #define PR_EXTERN(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT(__type) __declspec(dllexport) __type #define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type #define PR_CALLBACK #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x #elif defined(WIN16) #define PR_CALLBACK_DECL __cdecl #if defined(_WINDLL) #define PR_EXPORT(__type) extern __type _cdecl _export _loadds #define PR_IMPORT(__type) extern __type _cdecl _export _loadds #define PR_EXPORT_DATA(__type) extern __type _export #define PR_IMPORT_DATA(__type) extern __type _export #define PR_EXTERN(__type) extern __type _cdecl _export _loadds #define PR_IMPLEMENT(__type) __type _cdecl _export _loadds #define PR_EXTERN_DATA(__type) extern __type _export #define PR_IMPLEMENT_DATA(__type) __type _export #define PR_CALLBACK __cdecl __loadds #define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK #else /* this must be .EXE */ #define PR_EXPORT(__type) extern __type _cdecl _export #define PR_IMPORT(__type) extern __type _cdecl _export #define PR_EXPORT_DATA(__type) extern __type _export #define PR_IMPORT_DATA(__type) extern __type _export #define PR_EXTERN(__type) extern __type _cdecl _export #define PR_IMPLEMENT(__type) __type _cdecl _export #define PR_EXTERN_DATA(__type) extern __type _export #define PR_IMPLEMENT_DATA(__type) __type _export #define PR_CALLBACK __cdecl __loadds #define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK #endif /* _WINDLL */ #elif defined(XP_MAC) #define PR_EXPORT(__type) extern __declspec(export) __type #define PR_EXPORT_DATA(__type) extern __declspec(export) __type #define PR_IMPORT(__type) extern __declspec(export) __type #define PR_IMPORT_DATA(__type) extern __declspec(export) __type #define PR_EXTERN(__type) extern __declspec(export) __type #define PR_IMPLEMENT(__type) __declspec(export) __type #define PR_EXTERN_DATA(__type) extern __declspec(export) __type #define PR_IMPLEMENT_DATA(__type) __declspec(export) __type #define PR_CALLBACK #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x #elif defined(XP_OS2) && defined(__declspec) #define PR_EXPORT(__type) extern __declspec(dllexport) __type #define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPORT(__type) extern __declspec(dllimport) __type #define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type #define PR_EXTERN(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT(__type) __declspec(dllexport) __type #define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type #define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type #define PR_CALLBACK #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x #elif defined(XP_OS2_VACPP) #define PR_EXPORT(__type) extern __type #define PR_EXPORT_DATA(__type) extern __type #define PR_IMPORT(__type) extern __type #define PR_IMPORT_DATA(__type) extern __type #define PR_EXTERN(__type) extern __type #define PR_IMPLEMENT(__type) __type #define PR_EXTERN_DATA(__type) extern __type #define PR_IMPLEMENT_DATA(__type) __type #define PR_CALLBACK _Optlink #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK #else /* Unix */ /* GCC 3.3 and later support the visibility attribute. */ #if (__GNUC__ >= 4) || \ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) #define PR_VISIBILITY_DEFAULT __attribute__((visibility("default"))) #else #define PR_VISIBILITY_DEFAULT #endif #define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type #define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type #define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type #define PR_CALLBACK #define PR_CALLBACK_DECL #define PR_STATIC_CALLBACK(__x) static __x #endif #if defined(_NSPR_BUILD_) #define NSPR_API(__type) PR_EXPORT(__type) #define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type) #else #define NSPR_API(__type) PR_IMPORT(__type) #define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type) #endif /*********************************************************************** ** MACROS: PR_BEGIN_MACRO ** PR_END_MACRO ** DESCRIPTION: ** Macro body brackets so that macros with compound statement definitions ** behave syntactically more like functions when called. ***********************************************************************/ #define PR_BEGIN_MACRO do { #define PR_END_MACRO } while (0) /*********************************************************************** ** MACROS: PR_BEGIN_EXTERN_C ** PR_END_EXTERN_C ** DESCRIPTION: ** Macro shorthands for conditional C++ extern block delimiters. ***********************************************************************/ #ifdef __cplusplus #define PR_BEGIN_EXTERN_C extern "C" { #define PR_END_EXTERN_C } #else #define PR_BEGIN_EXTERN_C #define PR_END_EXTERN_C #endif /*********************************************************************** ** MACROS: PR_BIT ** PR_BITMASK ** DESCRIPTION: ** Bit masking macros. XXX n must be <= 31 to be portable ***********************************************************************/ #define PR_BIT(n) ((PRUint32)1 << (n)) #define PR_BITMASK(n) (PR_BIT(n) - 1) /*********************************************************************** ** MACROS: PR_ROUNDUP ** PR_MIN ** PR_MAX ** PR_ABS ** DESCRIPTION: ** Commonly used macros for operations on compatible types. ***********************************************************************/ #define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) #define PR_MIN(x,y) ((x)<(y)?(x):(y)) #define PR_MAX(x,y) ((x)>(y)?(x):(y)) #define PR_ABS(x) ((x)<0?-(x):(x)) PR_BEGIN_EXTERN_C /************************************************************************ ** TYPES: PRUint8 ** PRInt8 ** DESCRIPTION: ** The int8 types are known to be 8 bits each. There is no type that ** is equivalent to a plain "char". ************************************************************************/ #if PR_BYTES_PER_BYTE == 1 typedef unsigned char PRUint8; /* ** Some cfront-based C++ compilers do not like 'signed char' and ** issue the warning message: ** warning: "signed" not implemented (ignored) ** For these compilers, we have to define PRInt8 as plain 'char'. ** Make sure that plain 'char' is indeed signed under these compilers. */ #if (defined(HPUX) && defined(__cplusplus) \ && !defined(__GNUC__) && __cplusplus < 199707L) \ || (defined(SCO) && defined(__cplusplus) \ && !defined(__GNUC__) && __cplusplus == 1L) typedef char PRInt8; #else typedef signed char PRInt8; #endif #else #error No suitable type for PRInt8/PRUint8 #endif /************************************************************************ * MACROS: PR_INT8_MAX * PR_INT8_MIN * PR_UINT8_MAX * DESCRIPTION: * The maximum and minimum values of a PRInt8 or PRUint8. ************************************************************************/ #define PR_INT8_MAX 127 #define PR_INT8_MIN (-128) #define PR_UINT8_MAX 255U /************************************************************************ ** TYPES: PRUint16 ** PRInt16 ** DESCRIPTION: ** The int16 types are known to be 16 bits each. ************************************************************************/ #if PR_BYTES_PER_SHORT == 2 typedef unsigned short PRUint16; typedef short PRInt16; #else #error No suitable type for PRInt16/PRUint16 #endif /************************************************************************ * MACROS: PR_INT16_MAX * PR_INT16_MIN * PR_UINT16_MAX * DESCRIPTION: * The maximum and minimum values of a PRInt16 or PRUint16. ************************************************************************/ #define PR_INT16_MAX 32767 #define PR_INT16_MIN (-32768) #define PR_UINT16_MAX 65535U /************************************************************************ ** TYPES: PRUint32 ** PRInt32 ** DESCRIPTION: ** The int32 types are known to be 32 bits each. ************************************************************************/ #if PR_BYTES_PER_INT == 4 typedef unsigned int PRUint32; typedef int PRInt32; #define PR_INT32(x) x #define PR_UINT32(x) x ## U #elif PR_BYTES_PER_LONG == 4 typedef unsigned long PRUint32; typedef long PRInt32; #define PR_INT32(x) x ## L #define PR_UINT32(x) x ## UL #else #error No suitable type for PRInt32/PRUint32 #endif /************************************************************************ * MACROS: PR_INT32_MAX * PR_INT32_MIN * PR_UINT32_MAX * DESCRIPTION: * The maximum and minimum values of a PRInt32 or PRUint32. ************************************************************************/ #define PR_INT32_MAX PR_INT32(2147483647) #define PR_INT32_MIN (-PR_INT32_MAX - 1) #define PR_UINT32_MAX PR_UINT32(4294967295) /************************************************************************ ** TYPES: PRUint64 ** PRInt64 ** DESCRIPTION: ** The int64 types are known to be 64 bits each. Care must be used when ** declaring variables of type PRUint64 or PRInt64. Different hardware ** architectures and even different compilers have varying support for ** 64 bit values. The only guaranteed portability requires the use of ** the LL_ macros (see prlong.h). ************************************************************************/ #ifdef HAVE_LONG_LONG #if PR_BYTES_PER_LONG == 8 typedef long PRInt64; typedef unsigned long PRUint64; #elif defined(WIN16) typedef __int64 PRInt64; typedef unsigned __int64 PRUint64; #elif defined(WIN32) && !defined(__GNUC__) typedef __int64 PRInt64; typedef unsigned __int64 PRUint64; #else typedef long long PRInt64; typedef unsigned long long PRUint64; #endif /* PR_BYTES_PER_LONG == 8 */ #else /* !HAVE_LONG_LONG */ typedef struct { #ifdef IS_LITTLE_ENDIAN PRUint32 lo, hi; #else PRUint32 hi, lo; #endif } PRInt64; typedef PRInt64 PRUint64; #endif /* !HAVE_LONG_LONG */ /************************************************************************ ** TYPES: PRUintn ** PRIntn ** DESCRIPTION: ** The PRIntn types are most appropriate for automatic variables. They are ** guaranteed to be at least 16 bits, though various architectures may ** define them to be wider (e.g., 32 or even 64 bits). These types are ** never valid for fields of a structure. ************************************************************************/ #if PR_BYTES_PER_INT >= 2 typedef int PRIntn; typedef unsigned int PRUintn; #else #error 'sizeof(int)' not sufficient for platform use #endif /************************************************************************ ** TYPES: PRFloat64 ** DESCRIPTION: ** NSPR's floating point type is always 64 bits. ************************************************************************/ typedef double PRFloat64; /************************************************************************ ** TYPES: PRSize ** DESCRIPTION: ** A type for representing the size of objects. ************************************************************************/ typedef size_t PRSize; /************************************************************************ ** TYPES: PROffset32, PROffset64 ** DESCRIPTION: ** A type for representing byte offsets from some location. ************************************************************************/ typedef PRInt32 PROffset32; typedef PRInt64 PROffset64; /************************************************************************ ** TYPES: PRPtrDiff ** DESCRIPTION: ** A type for pointer difference. Variables of this type are suitable ** for storing a pointer or pointer subtraction. ************************************************************************/ typedef ptrdiff_t PRPtrdiff; /************************************************************************ ** TYPES: PRUptrdiff ** DESCRIPTION: ** A type for pointer difference. Variables of this type are suitable ** for storing a pointer or pointer sutraction. ************************************************************************/ #ifdef _WIN64 typedef unsigned __int64 PRUptrdiff; #else typedef unsigned long PRUptrdiff; #endif /************************************************************************ ** TYPES: PRBool ** DESCRIPTION: ** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE ** for clarity of target type in assignments and actual arguments. Use ** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans ** just as you would C int-valued conditions. ************************************************************************/ typedef PRIntn PRBool; #define PR_TRUE 1 #define PR_FALSE 0 /************************************************************************ ** TYPES: PRPackedBool ** DESCRIPTION: ** Use PRPackedBool within structs where bitfields are not desirable ** but minimum and consistant overhead matters. ************************************************************************/ typedef PRUint8 PRPackedBool; /* ** Status code used by some routines that have a single point of failure or ** special status return. */ typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; #ifndef __PRUNICHAR__ #define __PRUNICHAR__ #if defined(WIN32) || defined(XP_MAC) typedef wchar_t PRUnichar; #else typedef PRUint16 PRUnichar; #endif #endif /* ** WARNING: The undocumented data types PRWord and PRUword are ** only used in the garbage collection and arena code. Do not ** use PRWord and PRUword in new code. ** ** A PRWord is an integer that is the same size as a void*. ** It implements the notion of a "word" in the Java Virtual ** Machine. (See Sec. 3.4 "Words", The Java Virtual Machine ** Specification, Addison-Wesley, September 1996. ** http://java.sun.com/docs/books/vmspec/index.html.) */ #ifdef _WIN64 typedef __int64 PRWord; typedef unsigned __int64 PRUword; #else typedef long PRWord; typedef unsigned long PRUword; #endif #if defined(NO_NSPR_10_SUPPORT) #else /********* ???????????????? FIX ME ??????????????????????????? *****/ /********************** Some old definitions until pr=>ds transition is done ***/ /********************** Also, we are still using NSPR 1.0. GC ******************/ /* ** Fundamental NSPR macros, used nearly everywhere. */ #define PR_PUBLIC_API PR_IMPLEMENT /* ** Macro body brackets so that macros with compound statement definitions ** behave syntactically more like functions when called. */ #define NSPR_BEGIN_MACRO do { #define NSPR_END_MACRO } while (0) /* ** Macro shorthands for conditional C++ extern block delimiters. */ #ifdef NSPR_BEGIN_EXTERN_C #undef NSPR_BEGIN_EXTERN_C #endif #ifdef NSPR_END_EXTERN_C #undef NSPR_END_EXTERN_C #endif #ifdef __cplusplus #define NSPR_BEGIN_EXTERN_C extern "C" { #define NSPR_END_EXTERN_C } #else #define NSPR_BEGIN_EXTERN_C #define NSPR_END_EXTERN_C #endif #ifdef XP_MAC #include "protypes.h" #else #include "obsolete/protypes.h" #endif /********* ????????????? End Fix me ?????????????????????????????? *****/ #endif /* NO_NSPR_10_SUPPORT */ PR_END_EXTERN_C #endif /* prtypes_h___ */ djview4-4.10.5/nsdejavu/nsdejavu.1.in000066400000000000000000000173131264256014000173070ustar00rootroot00000000000000.\" t .\" -*- nroff -*- .\" .\" Copyright (c) 2001 Leon Bottou, Yann Le Cun, Patrick Haffner, .\" AT&T Corp., and Lizardtech, Inc. .\" .\" This is free documentation; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License as .\" published by the Free Software Foundation; either version 2 of .\" the License, or (at your option) any later version. .\" .\" The GNU General Public License's references to "object code" .\" and "executables" are to be interpreted as the output of any .\" document formatting or typesetting system, including .\" intermediate and printed output. .\" .\" This manual 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 General Public License for more details. .\" .\" You should have received a copy of the GNU General Public .\" License along with this manual. Otherwise check the web site .\" of the Free Software Foundation at http://www.fsf.org. .TH NSDEJAVU 1 "1/4/2007" "DjView-4" "DjView-4" .de SS .SH \\0\\0\\0\\$* .. .SH NAME nsdejavu \- DjVu browser plugin .SH SYNOPSIS .B PLUGINSDIR/NSDEJAVUSO .SH DESCRIPTION The shared library .B NSDEJAVUSO uses the Netscape browser plugin .SM API to display DjVu images in in a number of popular web browsers. Different web browsers provide various level of support for Netscape plugins. Please check section "Browser Compatibility" for instructions on how to enable the DjVu browser plugin. The DjVuLibre browser plugin works by invoking a standalone viewer with the special command line option .BR -netscape . The plugin first searches a program named .BR djview . If this program cannot be found, it searches for .BR djview4 and finally .BR djview3. It is always possible to override this search strategy by setting the environment variable .B NPX_DJVIEW to the full path of the desired executable. .SH MIME TYPES AND EXTENSIONS Typing the .SM URL of a recognized DjVu document in your web browser should automatically invoke the DjVu browser plugin. Each browser uses different methods to determine that a particular .SM URL is in fact a DjVu document. Web server normally provide a .SM MIME type to web browsers. The official .SM MIME type for DjVu documents is .BR image/vnd.djvu . For compatibility with ancient versions of the DjVu viewer, it is common to use instead the experimental .SM MIME type .B image/x-djvu or .BR image/x.djvu . Web servers should be configured to send the proper .SM MIME type for DjVu documents. Most web browsers also recognize files ending with .B .djvu or .B .djv as DjVu files. An easy way to check if an http server is giving an appropriate content-type is to invoke the following command with a .SM URL corresponding to an actual DjVu file on the server. .IP "" 2 .BI "curl -u " URL " | grep Content-Type" .PP The result should be one of the following, preferably the first. .IP "" 2 .B Content-Type: image/vnd.djvu .br .B Content-Type: image/x.djvu .br .B Content-Type: image/x-djvu .PP Any other .SM MIME type indicates a server misconfiguration. .SH CGI-STYLE FLAGS The behavior of the DjVu browser plugin can be specified by augmenting the .SM URL using a syntax similar to that used by the .SM CGI programs. This syntax is described by the following template: .IP "" 3 .BI "http://.../file.djvu?djvuopts&" "keyword=value" "&" "keyword=value" "&" "..." .PP The DjVu browser plugin only recognizes keywords that appear after the word .BR djvuopts . The keywords recognized by each viewer are listed in the corresponding man page. Unrecognized keywords are ignored. The most common keywords are: .TP .BI page= pagename Specify which page is displayed by name or by ordinal number. .TP .BI zoom= zoomfactor Set the zoom factor. Legal values for .I zoomfactor are: .br .TS center,box; lfI l lfB l lfB l lfB l lfB l . number Magnification factor in range 10% to 999%. one2one Select the "one-to-one" mode. width Select the "fit width" mode. page Select the "fit page" mode. stretch Stretch the image to the plugin window size. .TE .SH BROWSER COMPATIBILITY The DjVu browser plugin has been tested with several popular web browsers: Netscape 4 and 6; Gecko based browsers such as Mozilla, Galeon and Firefox; KHTML based browsers such as Konqueror; and Opera. Please read the browser documentation to find out where the plugin library should be installed. .SH EMBEDDING DJVU IMAGES IN HTML PAGES You can integrate DjVu content on an .SM HTML web page with either the .SM or the .SM tag. This method will work even if your web server does not support the DjVu .SM MIME type. The .SM CGI style flags can be directly used as attributes of the embedding tag. The following example shows the W3C standard syntax with the .SM OBJECT tag: .IP "" 3 .B "" .br .B "\0\0\0 " .br .B "\0\0\0 " .br .B "\0\0\0 This browser cannot render djvu data." .br .B "" .PP And this is the customary syntax with the .SM EMBED tag: .IP "" 3 .B "" .PP .SH INTERFACING THE DJVIEW PLUGIN WITH JAVASCRIPT Recent versions of the .B djview4 plugin can be controlled from the JavaScript intepreter of browsers implementing the Mozilla NPRuntime API. To access the plugin object, include the attribute .BI "id=""" pluginname """" into the .B or .B tag and use the JavaScript function .BI "getElementById(""" pluginname """)." .PP The plugin object implements two methods to retrieve and set the value of the options usually recognized as CGI-style flags. It also can evaluate a specified JavaScript expression whenever something changes in the status of the djview interface. .TP .IB "pluginobject" ".setdjvuopt(""" key """," value ")" Set the value of the djvu option .I key to the character string .IR value . This achieves the same effect as specifying option .IR key = value among the CGI-style flags. For instance, values of the key .B page can be page IDs, page titles, page numbers, or page names. .TP .IB "pluginobject" ".getdjvuopt(""" key """)" Return the value of the djvu option .I key as a string. The returned value is always a character string, even when the return is logically a number. Boolean values are returned as strings .B yes or .BR no. Besides the usual CGI-style flags, this function recognizes the additional key .B pages and returns the total number of pages in the DjVu document. An empty string is returned when the key is not recognized. .TP .IB "pluginobject" ".onchange=""" code """;" Ensure that string .I code is evaluated in the context of the plugin object whenever something changes in the djview graphical user interface. For instance, this evaluation happens when progressive refinements are painted, and when the user manipulates the image interactively. .TP .IB "pluginobject" ".version" Return a string describing the plugin version. This property can be used to test whether the djview plugin is scriptable in this browser. .PP Note that the scriptability feature may not be accessible until the djview plugin is fully loaded. Therefore it is advisable to check .IB "pluginobject" ".version" from the JavaScript .B onload before calling any other method. .SH CREDITS This program was written by Andrei Erofeev and was then improved by Bill Riemers and L\('eon Bottou . .SH SEE ALSO .BR djvu (1), .BR ddjvu (1), .BR djview4 (1) djview4-4.10.5/nsdejavu/nsdejavu.c000066400000000000000000002340711264256014000167660ustar00rootroot00000000000000/* //C- ------------------------------------------------------------------- //C- DjVuLibre-3.5 //C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. //C- Copyright (c) 2001 AT&T //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either Version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from //C- Lizardtech Software. Lizardtech Software has authorized us to //C- replace the original DjVu(r) Reference Library notice by the following //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): //C- //C- ------------------------------------------------------------------ //C- | DjVu (r) Reference Library (v. 3.5) //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. //C- | The DjVu Reference Library is protected by U.S. Pat. No. //C- | 6,058,214 and patents pending. //C- | //C- | This software is subject to, and may be distributed under, the //C- | GNU General Public License, either Version 2 of the license, //C- | or (at your option) any later version. The license should have //C- | accompanied the software or you may obtain a copy of the license //C- | from the Free Software Foundation at http://www.fsf.org . //C- | //C- | The computer code originally released by LizardTech under this //C- | license and unmodified by other parties is deemed "the LIZARDTECH //C- | ORIGINAL CODE." Subject to any third party intellectual property //C- | claims, LizardTech grants recipient a worldwide, royalty-free, //C- | non-exclusive license to make, use, sell, or otherwise dispose of //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU //C- | General Public License. This grant only confers the right to //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to //C- | the extent such infringement is reasonably necessary to enable //C- | recipient to make, have made, practice, sell, or otherwise dispose //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to //C- | any greater extent that may be necessary to utilize further //C- | modifications or combinations. //C- | //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. //C- +------------------------------------------------------------------ */ #include "config.h" #ifndef DJVIEW_NAME # define DJVIEW_NAME "djview" #endif #ifndef DJVIEW4_NAME # define DJVIEW4_NAME "djview4" #endif #ifndef DJVIEW3_NAME # define DJVIEW3_NAME "djview3" #endif #ifndef LIBRARY_NAME # if defined(hpux) # define LIBRARY_NAME "nsdejavu.sl" # elif defined(WIN32) || defined(__CYGWIN32__) # define LIBRARY_NAME "nsdejavu.dll" # else # define LIBRARY_NAME "nsdejavu.so" # endif #endif #include #include #include #include #include #include #include #include #include #include #include #if HAVE_UNISTD_H # include #endif #if TIME_WITH_SYS_TIME # include # include #elif HAVE_SYS_TIME_H # include #else # include #endif #if HAVE_SYS_WAIT_H # include #else # include #endif #if !HAVE_WORKING_VFORK # define vfork fork #endif #ifndef MAXPATHLEN # ifdef _MAX_PATH # define MAXPATHLEN _MAX_PATH # else # define MAXPATHLEN 1024 # endif #endif #if ( MAXPATHLEN < 1024 ) # undef MAXPATHLEN # define MAXPATHLEN 1024 #endif #define XP_UNIX 1 #define MOZ_X11 1 #include "npapi.h" #include "npruntime.h" #include "npupp.h" #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif #ifndef offsetof # define offsetof(TYPE,MEMBER) ((size_t)&((TYPE*)0)->MEMBER) #endif #ifndef min # define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef USE_XT # if HAVE_XT # define USE_XT 1 # else # define USE_XT 0 # endif #endif #ifndef USE_GLIB # if HAVE_GLIB # define USE_GLIB 1 # else # define USE_GLIB 0 # endif #endif #if USE_XT # define XTSTRINGDEFINES 1 # include # include # include # include # pragma weak XtAddCallback # pragma weak XtAddEventHandler # pragma weak XtAppAddInput # pragma weak XtRemoveCallback # pragma weak XtRemoveEventHandler # pragma weak XtRemoveInput # pragma weak XtShellStrings # pragma weak XtStrings # pragma weak XtVaGetValues # pragma weak XtWidgetToApplicationContext # pragma weak XtWindowToWidget #endif #if USE_GLIB # include # pragma weak g_io_channel_unix_new # pragma weak g_io_channel_unref # pragma weak g_io_add_watch # pragma weak g_source_remove #endif /* ------------------------------------------------------------ */ /* IO */ typedef struct { int cmd_mode; int cmd_zoom; int imgx; int imgy; } SavedData; #define OK_STRING "OK" #define ERR_STRING "ERR" #define CMD_SHUTDOWN 0 #define CMD_NEW 1 #define CMD_DETACH_WINDOW 2 #define CMD_ATTACH_WINDOW 3 #define CMD_RESIZE 4 #define CMD_DESTROY 5 #define CMD_PRINT 6 #define CMD_NEW_STREAM 7 #define CMD_WRITE 8 #define CMD_DESTROY_STREAM 9 #define CMD_SHOW_STATUS 10 #define CMD_GET_URL 11 #define CMD_GET_URL_NOTIFY 12 #define CMD_URL_NOTIFY 13 #define CMD_HANDSHAKE 14 #define CMD_SET_DJVUOPT 15 #define CMD_GET_DJVUOPT 16 #define CMD_ON_CHANGE 17 #define TYPE_INTEGER 1 #define TYPE_DOUBLE 2 #define TYPE_STRING 3 #define TYPE_POINTER 4 #define TYPE_ARRAY 5 /* All these routines return * - positive value on success * - zero on end-of-file condition * - negative on error */ static int Read(int fd, void * buffer, int length, int refresh_pipe, void (* refresh_cb)(void)) { int size = length; int maxfd = (refresh_pipe>fd) ? refresh_pipe : fd; char *ptr = (char*)buffer; int res; int rc; while(size>0) { fd_set read_fds; struct timeval tv; FD_ZERO(&read_fds); FD_SET(fd, &read_fds); if (refresh_pipe>=0 && refresh_cb) FD_SET(refresh_pipe, &read_fds); tv.tv_sec=5; tv.tv_usec=0; rc = select(maxfd+1, &read_fds, 0, 0, &tv); if (rc>0 && FD_ISSET(fd, &read_fds)) { errno = 0; res = read(fd, ptr, size); if (res<0 && errno==EINTR) continue; if (res<0) return -1; if (res==0) return 0; size -= res; ptr += res; } if (rc<0 && errno!=EINTR) return -1; if (refresh_cb) refresh_cb(); } return length; } static int Write(int fd, const void * buffer, int length) { int size = length; const char *ptr = (const char*)buffer; #if HAVE_SIGACTION sigset_t new_mask, old_mask; struct sigaction new_action, old_action; #else void *oldhandler; #endif int res; #if HAVE_SIGACTION sigemptyset(&new_mask); sigaddset(&new_mask, SIGPIPE); sigprocmask(SIG_BLOCK, &new_mask, &old_mask); #else oldhandler = signal(SIGPIPE, SIG_IGN); #endif while(size>0) { errno = 0; res = write(fd, ptr, size); if (res<0 && errno==EINTR) continue; if (res <= 0) break; size-=res; ptr+=res; } #if HAVE_SIGACTION sigaction(SIGPIPE, 0, &new_action); new_action.sa_handler=SIG_IGN; new_action.sa_flags=SA_NODEFER; sigaction(SIGPIPE, &new_action, &old_action); sigprocmask(SIG_SETMASK, &old_mask, 0); sigaction(SIGPIPE, &old_action, 0); #else signal(SIGPIPE, oldhandler); #endif if (size > 0) return -1; return 0; } static int WriteStringLen(int fd, const char *str, int length) { int type = TYPE_STRING; static char zero = 0; if ( (Write(fd, &type, sizeof(type)) < 0) || (Write(fd, &length, sizeof(length)) < 0) || (Write(fd, str, length) < 0) || (Write(fd, &zero, 1) < 0) ) return -1; return 1; } static int WriteString(int fd, const char *str) { int length; if (! str) str = ""; length = strlen(str); return WriteStringLen(fd, str, length); } static int WriteInteger(int fd, int var) { int type=TYPE_INTEGER; if ( (Write(fd, &type, sizeof(type)) < 0) || (Write(fd, &var, sizeof(var)) < 0) ) return -1; return 1; } static int WritePointer(int fd, const void *ptr) { int type=TYPE_POINTER; if ( (Write(fd, &type, sizeof(type)) < 0) || (Write(fd, &ptr, sizeof(ptr)) < 0) ) return -1; return 1; } static int WriteArray(int fd, int size, const char *array) { int type=TYPE_ARRAY; if ( (Write(fd, &type, sizeof(type)) < 0) || (Write(fd, &size, sizeof(size)) < 0) || (Write(fd, array, size) < 0) ) return -1; return 1; } static int ReadString(int fd, char **pstr, int refresh_pipe, void (* refresh_cb)(void)) { char *ptr; int type, length, status; *pstr = 0; status = Read(fd, &type, sizeof(type), refresh_pipe, refresh_cb); if (status <= 0) return status; if (type != TYPE_STRING) return -1; status = Read(fd, &length, sizeof(length), refresh_pipe, refresh_cb); if (status <= 0) return status; if (length < 0) return -1; if (! (ptr = malloc(length+1))) return -1; status = Read(fd, (char*)ptr, length+1, refresh_pipe, refresh_cb); if (status <= 0) { free(ptr); return status; } *pstr = ptr; return 1; } static int ReadInteger(int fd, int *pvar, int refresh_pipe, void (* refresh_cb)(void)) { int type, status; status = Read(fd, &type, sizeof(type), refresh_pipe, refresh_cb); if (status <= 0) return status; if (type != TYPE_INTEGER) return -1; status = Read(fd, pvar, sizeof(*pvar), refresh_pipe, refresh_cb); return status; } static int ReadPointer(int fd, void **pvar, int refresh_pipe, void (* refresh_cb)(void)) { int type, status; status = Read(fd, &type, sizeof(type), refresh_pipe, refresh_cb); if (status <= 0) return status; if (type != TYPE_POINTER) return -1; status = Read(fd, pvar, sizeof(*pvar), refresh_pipe, refresh_cb); return status; } static int ReadResult(int fd, int refresh_pipe, void (* refresh_cb)(void)) { char *res; int status; status = ReadString(fd, &res, refresh_pipe, refresh_cb); if (status <= 0) return status; status = +1; if (strcmp(res, OK_STRING)) status = -2; free(res); return status; } /* ------------------------------------------------------------ */ /* PATHS */ /* Stuff for easily dealing with string allocation */ struct strpool_data { struct strpool_data *next; char data[1]; }; typedef struct strpool { struct strpool_data *first; } strpool; static void strpool_init(strpool *pool) { pool->first = 0; } static char * strpool_alloc(strpool *pool, int n) { char *b = malloc(sizeof(struct strpool_data)+n); struct strpool_data *d = (struct strpool_data *)b; d->next = pool->first; d->data[n] = 0; pool->first = d; return d->data; } static void strpool_fini(strpool *pool) { struct strpool_data *d; while ((d = pool->first)) { pool->first = d->next; if (d) free(d); } } static const char * strconcat(strpool *pool, ...) { va_list ap; int n = 0; char *d, *r; const char *s; va_start(ap, pool); while ((s = va_arg(ap, const char *))) n += strlen(s); va_end(ap); r = d = strpool_alloc(pool, n); va_start(ap, pool); while ((s = va_arg(ap, const char *))) while (*s) *d++ = *s++; *d = 0; return r; } /* Stuff to test and manipulate filenames */ static int is_file(const char *filename) { struct stat buf; if (stat(filename,&buf) >= 0) if (! (buf.st_mode & S_IFDIR)) return TRUE; return FALSE; } static int is_executable(const char *filename) { if (!is_file(filename)) return FALSE; if (access(filename, X_OK)<0) return FALSE; return TRUE; } static const char * dirname(strpool *pool, const char *fname) { int n; char *ret; const char *s = fname + strlen(fname); while (s>fname && s[-1]=='/') s--; while (s>fname && s[-1]!='/') s--; while (s>fname && s[-1]=='/') s--; if (s == fname) return ( (s[0] == '/') ? "/" : "." ); n = s - fname; ret = strpool_alloc(pool, n); strncpy(ret, fname, n); return ret; } static const char * pathclean(strpool *pool, const char *n) { char *ret = strpool_alloc(pool, strlen(n)); char *d = ret; int slash = FALSE; if (n[0] == '/') *d++ = '/'; while (*n) { if (n[0] == '/') { while (n[0] == '/') n += 1; continue; } if (n[0]=='.' && (n[1]=='/' || !n[1])) { n += 1; continue; } if (n[0]=='.' && n[1]=='.' && (n[2]=='/' || !n[2]) && d>ret && d[-1]!='/') { *d = 0; while (d>ret && d[-1] != '/') d -= 1; if (d[0]=='.' && d[1]=='.' && !d[2]) { d += 2; } else { n += 2; slash = FALSE; continue; } } if (slash) *d++ = '/'; while (n[0] && n[0] != '/') *d++ = *n++; slash = (n[0] == '/'); } if (d == ret) *d++ = '.'; *d = 0; return ret; } static const char * follow_symlinks(strpool *pool, const char *fname) { const char *ret = fname; #ifdef S_IFLNK int lnklen; char lnkbuf[MAXPATHLEN+1]; while ((lnklen = readlink(ret, lnkbuf, sizeof(lnkbuf))) > 0) { lnkbuf[lnklen] = 0; if (lnkbuf[0] != '/') ret = strconcat(pool, dirname(pool, ret), "/", lnkbuf, 0); else ret = lnkbuf; ret = pathclean(pool,ret); } #endif return ret; } static const char * pathelem(strpool *pool, const char **pathptr) { if (*pathptr) { const char *s = strchr(*pathptr,':'); if (s) { int n = s - *pathptr; char *ret = strpool_alloc(pool, n); strncpy(ret, *pathptr, n); *pathptr += n+1; return ret; } s = *pathptr; *pathptr = 0; return s; } return 0; } static const char *stdpath = "/usr/lib/mozilla/plugins:" "/usr/local/lib/netscape/plugins:" "/usr/local/netscape/plugins:" "/usr/lib/netscape/plugins:" "/opt/netscape/plugins"; static const char * get_plugin_path(strpool *pool) { const char *env; const char *dir; /* MOZ_PLUGIN_PATH */ if ((env = getenv("MOZ_PLUGIN_PATH"))) { while ((dir = pathelem(pool, &env))) { const char *lib = strconcat(pool, dir, "/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; } } /* NPX_PLUGIN_PATH */ if ((env = getenv("NPX_PLUGIN_PATH"))) { while ((dir = pathelem(pool, &env))) { const char *lib = strconcat(pool, dir, "/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; } } /* $HOME/.{mozilla,netscape}/plugins */ if ((env = getenv("HOME"))) { const char *lib; lib = strconcat(pool, env, "/.mozilla/plugins/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; lib = strconcat(pool, env, "/.netscape/plugins/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; } /* MOZILLA_HOME */ if ((env = getenv("MOZILLA_HOME"))) { const char *lib = strconcat(pool, env, "/plugins/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; } /* OTHER */ env = stdpath; while ((dir = pathelem(pool, &env))) { const char *lib = strconcat(pool, dir, "/", LIBRARY_NAME, 0); if (is_file(lib)) return lib; } return 0; } static const char * GetPluginPath(void) { static char path[MAXPATHLEN+1]; if (! path[0]) { const char *p; strpool apool; strpool_init(&apool); if ((p = get_plugin_path(&apool))) strncpy(path, p, MAXPATHLEN); path[MAXPATHLEN] = 0; strpool_fini(&apool); } return path; } static const char * get_viewer_path(strpool *pool) { int i; const char *env = 0; const char *envs = 0; static const char *djview[] = { DJVIEW_NAME, DJVIEW4_NAME, DJVIEW3_NAME, 0 }; /* Environment variable NPX_DJVIEW overrides everything */ if ((env = getenv("NPX_DJVIEW"))) if (is_executable(env)) return env; /* Locate plugin path */ if ((env = GetPluginPath())) envs = follow_symlinks(pool, env); /* Try the following names */ for (i=0; djview[i]; i++) { const char *dir; const char *test; if (envs) { /* Try relative to plugin path */ dir = dirname(pool, envs); test = strconcat(pool, dir, "/../../../bin/", djview[i], 0); if (is_executable(test)) return test; test = strconcat(pool, dir, "/../../bin/", djview[i], 0); if (is_executable(test)) return test; dir = dirname(pool, env); test = strconcat(pool, dir, "/../DjVu/", djview[i],0); if (is_executable(test)) return test; dir = dirname(pool, envs); test = strconcat(pool, dir, "/../DjVu/", djview[i],0); if (is_executable(test)) return test; } /* Try ${bindir} */ #if defined(DIR_BINDIR) test = strconcat(pool,DIR_BINDIR,"/",djview[i],0); if (is_executable(test)) return test; #endif /* Try in the shell path */ if ((env = getenv("PATH"))) while ((dir = pathelem(pool, &env))) { test = strconcat(pool, dir, "/", djview[i], 0); if (is_executable(test)) return test; } } /* Deep trouble */ return 0; } static const char * GetViewerPath(void) { static char path[MAXPATHLEN+1]; if (! path[0]) { const char *p; strpool apool; strpool_init(&apool); if ((p = get_viewer_path(&apool))) strncpy(path, p, MAXPATHLEN); path[MAXPATHLEN] = 0; strpool_fini(&apool); } return path; } static const char * get_library_path(strpool *pool) { const char *env = 0; if ((env = (const char*)GetPluginPath())) { env = dirname(pool, env); env = strconcat(pool, env, "/../DjVu", 0); env = pathclean(pool, env); return env; } return 0; } static const char * GetLibraryPath(void) { /* This is no longer needed since djview no longer uses the provided path. This is kept to allow interoperability between nsdejavu.so and previous version of djview. LYB. */ static char path[MAXPATHLEN+1]; if (! path[0]) { const char *p; strpool apool; strpool_init(&apool); if ((p = get_library_path(&apool))) strncpy(path, p, MAXPATHLEN); path[MAXPATHLEN] = 0; strpool_fini(&apool); } return path; } /* ------------------------------------------------------------ */ /* MAP */ struct map_entry_s { struct map_entry_s *next; void *key; void *val; }; typedef struct { int nelems; int nbuckets; struct map_entry_s **buckets; } Map; static int hash(void *v, int nbuckets) { return (((long)v ^ ((long)v>>7)) % nbuckets); } static void map_purge(Map *m) { int i; struct map_entry_s *p; if (m->buckets) { for (i=0; inbuckets; i++) while ((p = m->buckets[i])) { m->buckets[i] = p->next; free(p); } free(m->buckets); } m->buckets = 0; m->nbuckets = 0; m->nelems = 0; } static void map_reorganize(Map *m) { int new_nbuckets = 17; struct map_entry_s **new_buckets = 0; struct map_entry_s *p; int i; if (m->nbuckets > new_nbuckets) new_nbuckets = m->nbuckets * 2 - 1; new_buckets = malloc(new_nbuckets * sizeof(struct map_entry*)); if (!new_buckets) return; memset(new_buckets, 0, new_nbuckets * sizeof(struct map_entry*)); for (i=0; inbuckets; i++) while ((p = m->buckets[i])) { int h = hash(p->key, new_nbuckets); m->buckets[i] = p->next; p->next = new_buckets[h]; new_buckets[h] = p; } if (m->nbuckets) free(m->buckets); m->buckets = new_buckets; m->nbuckets = new_nbuckets; } static void* map_lookup(Map *m, void *key) { int h; struct map_entry_s *q; if (m->nbuckets) { h = hash(key, m->nbuckets); for (q=m->buckets[h]; q; q=q->next) if (q->key == key) return q->val; } return NULL; } static int map_remove(Map *m , void *key) { int h; struct map_entry_s **pq; if (m->nbuckets) { h = hash(key, m->nbuckets); for (pq=&(m->buckets[h]); *pq; pq=&((*pq)->next)) if ((*pq)->key == key) { struct map_entry_s *q = *pq; (*pq) = q->next; free(q); return 1; } } return 0; } static int map_insert(Map *m, void *key, void *val) { int h; struct map_entry_s *q; if (m->nelems * 3 >= m->nbuckets * 2) map_reorganize(m); if (! m->nbuckets) return -1; if (! val) return map_remove(m, key); h = hash(key, m->nbuckets); for (q=m->buckets[h]; q; q=q->next) if (q->key == key) { q->val = val; return 1; } if (! (q = malloc(sizeof(struct map_entry_s)))) return -1; q->next = m->buckets[h]; q->key = key; q->val = val; m->buckets[h] = q; return 1; } /* ------------------------------------------------------------ */ /* INSTANCE */ typedef struct { Window window; NPP np_instance; int full_mode; int xembed_mode; NPNToolkitType toolkit; #if USE_XT Window client; Widget widget; #endif NPObject *npobject; NPVariant onchange; } Instance; static Instance * instance_new(NPP np_instance, int full_mode) { Instance *this = malloc(sizeof(Instance)); if (this) { memset(this, 0, sizeof(Instance)); this->np_instance = np_instance; this->full_mode = full_mode; this->xembed_mode = 0; this->npobject = 0; VOID_TO_NPVARIANT(this->onchange); } return this; } static void instance_free(Instance *this) { if (this) { NPN_ReleaseVariantValue(&this->onchange); memset(this, 0, sizeof(Instance)); free(this); } } /* ------------------------------------------------------------ */ /* DELAYED REQUESTS */ typedef struct { struct DelayedRequest_s *first; struct DelayedRequest_s *last; } DelayedRequestList; typedef struct DelayedRequest_s { struct DelayedRequest_s *next; int req_num; void *id; char *status; char *url; char *target; } DelayedRequest; static DelayedRequest * delayedrequest_append(DelayedRequestList *dlist) { DelayedRequest *ptr = malloc(sizeof(DelayedRequest)); if (ptr) { memset(ptr, 0, sizeof(DelayedRequest)); if (!dlist->first) dlist->first = ptr; if (dlist->last) dlist->last->next = ptr; dlist->last = ptr; } return ptr; } static DelayedRequest * delayedrequest_pop(DelayedRequestList *dlist) { DelayedRequest *ptr = dlist->first; if (ptr) { dlist->first = ptr->next; if (dlist->last == ptr) dlist->last = 0; ptr->next = 0; } return ptr; } static void delayedrequest_free(DelayedRequest *ptr) { if (ptr->status) free(ptr->status); if (ptr->url) free(ptr->url); if (ptr->target) free(ptr->target); free(ptr); } static void delayedrequest_purge(DelayedRequestList *dlist) { DelayedRequest *reqp; while ((reqp = delayedrequest_pop(dlist))) delayedrequest_free(reqp); } /******************************************************************************* ******************************* Preserved Data ******************************** *******************************************************************************/ #define ENV_DJVU_STORAGE_PTR "_DJVU_STORAGE_PTR" /* The plugin can be freely loaded/unloaded by Netscape, * so any static variable is at risk of being destroyed at any time * after NPP_Shutdown() is called. */ /* -- These variables need to be destroyed and reinitialized * when the plugin is reloaded. */ static int delay_pipe[2]; static Map instance, strinstance; static DelayedRequestList delayed_requests; static NPIdentifier npid_getdjvuopt; static NPIdentifier npid_setdjvuopt; static NPIdentifier npid_onchange; static NPIdentifier npid_version; #if USE_XT static XtInputId input_id, delay_id; #endif #if USE_GLIB static gint input_gid, delay_gid; #endif /* -- These variables need to be saved and restored * when the plugin is reloaded. */ static int pipe_read = -1; static int pipe_write = -1; static int rev_pipe = -1; static int scriptable = 0; static int xembedable = 0; static unsigned long white, black; static Colormap colormap; typedef struct { int pipe_read, pipe_write, rev_pipe; int scriptable, xembedable; unsigned long white, black; Colormap colormap; } SavedStatic; static void SaveStatic(void) /* Saves static variables from Group #3 into the Netscape's environment. Next time nsdejavu.so is loaded, we will read their values again. */ { SavedStatic *storage = 0; char *value = getenv(ENV_DJVU_STORAGE_PTR); int pid = -1; if (value) sscanf(value, "%p-%d", &storage, &pid); if (pid != getpid()) storage = 0; if (! storage) { char *buffer = malloc(128); if (buffer) { storage = malloc(sizeof(SavedStatic)); if (storage) { sprintf(buffer, ENV_DJVU_STORAGE_PTR "=%p-%d", (void*)storage, getpid()); putenv(buffer); } } } if (storage) { storage->pipe_read = pipe_read; storage->pipe_write = pipe_write; storage->rev_pipe = rev_pipe; storage->scriptable = scriptable; storage->xembedable = xembedable; storage->white = white; storage->black = black; storage->colormap = colormap; } } static void LoadStatic(void) /* Loads static variables, which have been saved into the environment via SaveStatic() by the previous instance of nsdejavu.so */ { SavedStatic *storage = 0; int pid = -1; char *value = getenv(ENV_DJVU_STORAGE_PTR); if (value) sscanf(value, "%p-%d", &storage, &pid); if (pid != getpid()) storage = 0; if (storage) { pipe_read = storage->pipe_read; pipe_write = storage->pipe_write; rev_pipe = storage->rev_pipe; scriptable = storage->scriptable; xembedable = storage->xembedable; white = storage->white; black = storage->black; colormap = storage->colormap; } } /******************************************************************************* ********************************** Callbacks ********************************** *******************************************************************************/ static int Detach(void *id); static int Resize(void *id); static void CloseConnection(void); static int IsConnectionOK(int); static void ProgramDied(void); static int StartProgram(void); /******* Check macro ********/ #define CHECK(x) if ((x) < 0) \ fprintf(stderr,"unexpected error: %s:%d %s\n", __FILE__,__LINE__,#x); /******* Pipe functions ********/ static void process_delayed_requests(void) { char ch; DelayedRequest *reqp; Instance *inst; CHECK(read(delay_pipe[0], &ch, 1)); while((reqp = delayedrequest_pop(&delayed_requests))) { switch(reqp->req_num) { case CMD_SHOW_STATUS: if ((inst = map_lookup(&instance, reqp->id))) if (inst->window) NPN_Status(inst->np_instance, reqp->status); break; case CMD_GET_URL: if ((inst = map_lookup(&instance, reqp->id))) { const char *target = (reqp->target && reqp->target[0]) ? reqp->target : 0; NPN_GetURL(inst->np_instance, reqp->url, target); } break; case CMD_GET_URL_NOTIFY: if ((inst = map_lookup(&instance, reqp->id))) { const char *target = (reqp->target && reqp->target[0]) ? reqp->target : 0; if (NPN_GetURLNotify(inst->np_instance, reqp->url, target, 0) != NPERR_NO_ERROR ) NPN_GetURL(inst->np_instance, reqp->url, target); } break; case CMD_ON_CHANGE: if ((inst = map_lookup(&instance, reqp->id)) && NPVARIANT_IS_STRING(inst->onchange) ) { NPString *code = &NPVARIANT_TO_STRING(inst->onchange); NPP npp = inst->np_instance; NPVariant res; VOID_TO_NPVARIANT(res); NPN_Evaluate(npp, inst->npobject, code, &res); NPN_ReleaseVariantValue(&res); } break; default: break; } delayedrequest_free(reqp); } } static void process_requests(void) { if (!IsConnectionOK(FALSE)) { problem: ProgramDied(); return; } for(;;) { struct timeval tv; fd_set read_fds; int req_num; if (ReadInteger(rev_pipe,&req_num,0,0) <= 0) goto problem; switch(req_num) { case CMD_SHOW_STATUS: { DelayedRequest *reqp = delayedrequest_append(&delayed_requests); if (!reqp) return; reqp->req_num = req_num; if ( (ReadPointer(rev_pipe,&reqp->id,0,0) <= 0) || (ReadString(rev_pipe,&reqp->status,0,0) <= 0) ) goto problem; CHECK(write(delay_pipe[1], "1", 1)); } break; case CMD_GET_URL: case CMD_GET_URL_NOTIFY: { DelayedRequest *reqp = delayedrequest_append(&delayed_requests); if (!reqp) return; reqp->req_num = req_num; if ( (ReadPointer(rev_pipe,&reqp->id,0,0) <= 0) || (ReadString(rev_pipe,&reqp->url,0,0) <= 0) || (ReadString(rev_pipe,&reqp->target,0,0) <= 0) ) goto problem; CHECK(write(delay_pipe[1], "1", 1)); } break; case CMD_ON_CHANGE: { DelayedRequest *reqp = delayedrequest_append(&delayed_requests); if (!reqp) return; reqp->req_num = req_num; if ( (ReadPointer(rev_pipe,&reqp->id,0,0) <= 0) ) goto problem; CHECK(write(delay_pipe[1], "1", 1)); } default: break; } /* Process as many requests as possible before returning control back to Netscape. This pipe tends to overflow, so we don't want data to stay there too long. */ FD_ZERO(&read_fds); FD_SET(rev_pipe, &read_fds); tv.tv_sec=0; tv.tv_usec=0; if (select(rev_pipe+1, &read_fds, 0, 0, &tv) != 1) break; if (!FD_ISSET(rev_pipe, &read_fds)) break; } } static void check_requests(void) { if (rev_pipe) { fd_set read_fds; struct timeval tv; int rc; FD_ZERO(&read_fds); FD_SET(rev_pipe, &read_fds); tv.tv_sec = 0; tv.tv_usec = 0; rc = select(rev_pipe+1, &read_fds, 0, 0, &tv); if (rc>0) process_requests(); } } /******* Xt Callbacks ********/ #if USE_XT static XtInputId xt_add_input_fd(XtAppContext app, int fd, XtInputCallbackProc proc) { return XtAppAddInput(app, fd, (XtPointer) XtInputReadMask, proc, 0); } static void Delay_cb(XtPointer ptr, int * fd, XtInputId *xid) { process_delayed_requests(); } static void Input_cb(XtPointer ptr, int * fd, XtInputId *xid) { process_requests(); } static void Destroy_cb(Widget w, XtPointer cl_data, XtPointer ptr) { Detach((void*)cl_data); } static void Resize_hnd(Widget w, XtPointer cl_data, XEvent * event, Boolean * cont) { /* This function is necessary because Netscape sometimes doesn't resize the drawing area. */ *cont = True; if (event->type == ConfigureNotify) /* There can be a GravityNotify too */ { Instance *inst; void *id = (void*)cl_data; if ((inst = map_lookup(&instance, id))) if (Resize(id) <= 0) ProgramDied(); } } static const long event_mask = (KeyPressMask|KeyReleaseMask|SubstructureNotifyMask); static void Simulate_focus(Display *dpy, Window client, int yes) { XEvent ev; memset(&ev, 0, sizeof(ev)); ev.xfocus.display = dpy; ev.xfocus.type = (yes ? FocusIn : FocusOut); ev.xfocus.window = client; ev.xfocus.mode = NotifyNormal; ev.xfocus.detail = NotifyPointer; XSendEvent(dpy, client, False, NoEventMask, &ev); } static void Event_hnd(Widget w, XtPointer cl_data, XEvent * event, Boolean * cont) { Instance *inst; void *id = (void*)cl_data; *cont = True; if ((inst = map_lookup(&instance, id))) { Widget wid = inst->widget; Display *dpy = XtDisplay(wid); Window win = XtWindow(wid); XEvent ev = *event; switch(event->type) { case KeyPress: if ((ev.xkey.window = inst->client)) XSendEvent(dpy, inst->client, False, KeyPressMask, &ev ); break; case KeyRelease: if ((ev.xkey.window = inst->client)) XSendEvent(dpy, inst->client, False, KeyReleaseMask, &ev ); break; case DestroyNotify: if (ev.xdestroywindow.window == inst->client) inst->client = 0; break; case ReparentNotify: if (ev.xreparent.window == inst->client && ev.xreparent.parent != win) inst->client = 0; else if (ev.xreparent.parent == win) if ((inst->client = ev.xreparent.window)) Simulate_focus(dpy, inst->client, 1); break; } } } #endif /******* Gtk Callbacks ********/ #if USE_GLIB static gint g_source_add_input_fd(int fd, GIOFunc func) { GIOCondition cond = G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP; GIOChannel *channel = g_io_channel_unix_new(fd); gint result = g_io_add_watch(channel, cond, func, 0); g_io_channel_unref(channel); return result; } static gboolean Delay_gcb(GIOChannel *source, GIOCondition condition, gpointer data) { process_delayed_requests(); return TRUE; } static gboolean Input_gcb(GIOChannel *source, GIOCondition condition, gpointer data) { process_requests(); return TRUE; } #endif /******************************************************************************* ***************************** Copying the colormap ***************************** *******************************************************************************/ /* This is no longer needed since djview no longer uses the provided colormap. This is kept to allow interoperability between nsdejavu.so and previous version of djview. LYB. */ static void CopyColormap(Display *displ, Visual *visual, Screen *screen, Colormap cmap) { unsigned long *pixels = 0; XColor *colors = 0; int n; if (colormap) return; if (cmap == DefaultColormapOfScreen(screen)) { /* This is also what we do should a problem occur */ problem: if (pixels) free(pixels); if (colors) free(colors); colormap = cmap; return; } /* Depends on the visual class */ switch(visual->class) { case StaticGray: case StaticColor: case TrueColor: /* Colormap for which there is nothing to copy */ colormap = XCreateColormap(displ, RootWindowOfScreen(screen), visual, AllocNone); break; case DirectColor: /* Use a simple ramp. QT does not like these anyway. */ colormap = XCreateColormap(displ, RootWindowOfScreen(screen), visual, AllocNone); for (n=0; nmap_entries; n++) { XColor cell; cell.pixel = n; cell.red = cell.green = cell.blue = (n * 0x10000)/visual->map_entries; cell.flags = DoRed | DoGreen | DoBlue; XAllocColor(displ, colormap, &cell); } break; case PseudoColor: case GrayScale: /* The complicated case */ { /* Make sure the colormap is rich enough. This happens to be pretty useless code, btw, as: 1. Netscape allocates the colorcube 2. It allocates it as RW, basically leaving no space in the 8bpp colormap that we could use. But we will give it a try anyway... */ int i,j,k; int again = TRUE; static unsigned short r1[] = { 0x0000, 0x9999, 0xffff }; static unsigned short r2[] = { 0x0000, 0x3333, 0x6666, 0x9999, 0xcccc, 0xffff }; /* Allocate 3x3x3 cube first. It's a good idea to allocate the most distinct colors first (from 3x3x3) and then proceed with other colors from 6x6x6. Should the colormap be nearly full, we will still get a reasonable approximation. */ for(i=0; again && i<3; i++) for(j=0; again && j<3; j++) for(k=0; again && k<3; k++) { XColor cell; cell.red = r1[i]; cell.green = r1[j]; cell.blue = r1[k]; cell.flags = DoRed | DoGreen | DoBlue; if (!XAllocColor(displ, cmap, &cell)) again = FALSE; } /* Proceed with additional colors of 6x6x6 cube. */ for(i=0; again && i<6; i++) for(j=0; again && j<6; j++) for(k=0; again && k<6; k++) { XColor cell; cell.red = r2[i]; cell.green = r2[j]; cell.blue = r2[k]; cell.flags = DoRed | DoGreen | DoBlue; if (!XAllocColor(displ, cmap, &cell)) again = FALSE; } /* Now copy the colormap */ colormap = XCreateColormap(displ, RootWindowOfScreen(screen), visual, AllocNone); pixels = malloc(visual->map_entries * sizeof(unsigned long)); if (!pixels) goto problem; XAllocColorCells(displ, colormap, False, pixels, 0, pixels, visual->map_entries); colors = malloc(visual->map_entries * sizeof(XColor)); if (!colors) goto problem; for (n=0; nmap_entries; n++) { colors[n].pixel = n; colors[n].flags = DoRed | DoGreen | DoBlue; /* This can be dropped */ } XQueryColors(displ, cmap, colors, visual->map_entries); XStoreColors(displ, colormap, colors, visual->map_entries); /* But make the desired ones read-only (so that QT can use them) */ for (n=0; nmap_entries; n++) { /* Free one cell exactly (all others are read/write) */ XColor cell = colors[n]; XFreeColors(displ, colormap, &cell.pixel, 1, 0); if (!XAllocColor(displ, colormap, &cell)) goto problem; if (cell.pixel != colors[n].pixel ) { cell.pixel = colors[n].pixel; XAllocColorCells(displ, colormap, False, 0, 0, &cell.pixel, 1); XStoreColor(displ, colormap, &cell); } } /* Calling XInstallColormap is needed on SGIs to ``finish-up'' the new colormap. This should be ok since it contains the same colors as Netscape's and we can expect that the currently installed colormap is Netscape's. Otherwise the screen may flash. */ XSync(displ, False); XInstallColormap(displ, colormap); /* Cleanup */ if (colors) free(colors); if (pixels) free(pixels); } break; default: goto problem; } } /******************************************************************************* ************************************* Utilities ******************************** *******************************************************************************/ static int IsConnectionOK(int handshake) { if (pipe_read<=0 || pipe_write<=0 || rev_pipe<=0) return FALSE; if (handshake) { if ( (WriteInteger(pipe_write, CMD_HANDSHAKE) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) return FALSE; } return TRUE; } static void ProgramDied(void) { CloseConnection(); /** Do not clear instances here as you used to! Netscape will probably call NPP_Destroy() later, and you will need to unregister handlers (such as Resize_hnd) */ StartProgram(); } static void CloseConnection(void) { /* Close all connections to the viewer */ #if USE_XT if (input_id) XtRemoveInput(input_id); input_id=0; #endif #if USE_GLIB if (input_gid) g_source_remove(input_gid); input_gid=0; #endif if (pipe_read>0) close(pipe_read); pipe_read=-1; if (pipe_write>0) close(pipe_write); pipe_write=-1; if (rev_pipe>0) close(rev_pipe); rev_pipe=-1; /* Update environment */ SaveStatic(); } static int Resize(void *id) { /* Instead of selecting ConfigureEvent in the application I catch resizeCallback here and send the appropriate request to the application */ Instance *inst; if (! (inst = map_lookup(&instance, id))) return 1; if (inst->xembed_mode) return 1; #if USE_XT else if (inst->widget && inst->window) { XWindowAttributes attr; Display *displ = XtDisplay(inst->widget); if (! XGetWindowAttributes(displ, inst->window, &attr)) return 1; if (! IsConnectionOK(TRUE)) return -1; if ( (WriteInteger(pipe_write, CMD_RESIZE) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteInteger(pipe_write, attr.width) <= 0) || (WriteInteger(pipe_write, attr.height) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) return -1; } #endif return 1; } static int Detach(void * id) { Instance *inst; if (! (inst = map_lookup(&instance, id))) return 1; if (inst->window) { #if USE_XT if (inst->widget && !inst->xembed_mode) { XtRemoveCallback(inst->widget, XtNdestroyCallback, Destroy_cb, id); XtRemoveEventHandler(inst->widget, event_mask, False, Event_hnd, id); XtRemoveEventHandler(inst->widget, StructureNotifyMask, False, Resize_hnd, id); inst->widget = 0; inst->client = 0; } #endif inst->window = 0; if (! IsConnectionOK(TRUE)) return -1; if ( (WriteInteger(pipe_write, CMD_DETACH_WINDOW) <= 0) || (WritePointer(pipe_write, id) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) return -1; } return 1; } static int Attach(Display *displ, NPWindow *npw, void *id) { char *displ_str; Instance *inst; Screen *screen; Colormap cmap; Visual *visual; char protocol_str[128]; XWindowAttributes attributes; Window window = (npw) ? (Window)npw->window : 0; int width, height; #if USE_XT XtAppContext app_context = 0; Widget widget = 0; #endif XSync(displ, False); if (!(inst = map_lookup(&instance, id))) return 1; #if USE_XT if (!inst->xembed_mode) { widget = XtWindowToWidget(displ, window); app_context = XtWidgetToApplicationContext(widget); XtAddCallback(widget, XtNdestroyCallback, Destroy_cb, id); XtAddEventHandler(widget, event_mask, False, Event_hnd, id); XtAddEventHandler(widget, StructureNotifyMask, False, Resize_hnd, id); if (! input_id) input_id = xt_add_input_fd(app_context, rev_pipe, Input_cb); if (! delay_id) delay_id = xt_add_input_fd(app_context, delay_pipe[0], Delay_cb); } #endif #if USE_GLIB if (inst->xembed_mode) { if (! input_gid) input_gid = g_source_add_input_fd(rev_pipe, Input_gcb); if (! delay_gid) delay_gid = g_source_add_input_fd(delay_pipe[0], Delay_gcb); } #endif /* Preparing CMD_ATTACH_WINDOW attributes */ displ_str = DisplayString(displ); if (!displ_str) displ_str=getenv("DISPLAY"); if (!displ_str) displ_str=":0"; if (XGetWindowAttributes(displ, window, &attributes)) { width = attributes.width; height = attributes.height; screen = attributes.screen; cmap = attributes.colormap; visual = attributes.visual; if (!colormap) { /* Allocating black and white colors */ XColor white_screen, white_exact; XColor black_screen, black_exact; XAllocNamedColor(displ, cmap, "white", &white_screen, &white_exact); white = white_screen.pixel; XAllocNamedColor(displ, cmap, "black", &black_screen, &black_exact); black = black_screen.pixel; CopyColormap(displ, visual, screen, cmap); } /* Prepare protocol string */ protocol_str[0]=0; if (inst->xembed_mode) { width = (npw) ? npw->width : width; height = (npw) ? npw->height : height; strcpy(protocol_str, "XEMBED"); } #if USE_XT else { /* Old viewers want the background color name instead. */ unsigned long back_color; XColor cell; XtVaGetValues(widget, XtNbackground, &back_color, NULL); cell.flags = DoRed | DoGreen | DoBlue; cell.pixel = back_color; XQueryColor(displ, cmap, &cell); sprintf(protocol_str, "rgb:%X/%X/%X", cell.red, cell.green, cell.blue); } if (widget && !inst->xembed_mode) XtMapWidget(widget); #endif XSync(displ, False); /* Send attach command */ if ( (WriteInteger(pipe_write, CMD_ATTACH_WINDOW) > 0) && (WritePointer(pipe_write, id) > 0) && (WriteString(pipe_write, displ_str) > 0) && (WriteString(pipe_write, protocol_str) > 0) && (WriteInteger(pipe_write, window) > 0) && (WriteInteger(pipe_write, colormap) > 0) && (WriteInteger(pipe_write, XVisualIDFromVisual(visual)) > 0) && (WriteInteger(pipe_write, width) > 0) && (WriteInteger(pipe_write, height) > 0) && (ReadResult(pipe_read, rev_pipe, check_requests) > 0) ) { /* Success */ inst->window = window; #if USE_XT inst->widget = widget; inst->client = 0; #endif return 1; } } /* Failure */ #if USE_XT if (widget) { XtRemoveCallback(widget, XtNdestroyCallback, Destroy_cb, id); XtRemoveEventHandler(widget, event_mask, False, Event_hnd, id); XtRemoveEventHandler(widget, StructureNotifyMask, False, Resize_hnd, id); } inst->widget = 0; inst->client = 0; #endif inst->window = 0; return -1; } static void UnsetVariable(const char *var) { const char *ptr = getenv(var); if (ptr && ptr[0]) { /* Putenv() does not work on RH5.1. But Unsetenv() is available. */ #ifdef __linux__ unsetenv(var); #else char *env = malloc(strlen(var)+2); strcpy(env, var); strcat(env, "="); putenv(env); #endif } } static int StartProgram(void) { const char *path; int fd[2]; int _pipe_read; int _pipe_write; int _rev_pipe; void *sigsave; pid_t pid; char *ptr, *p, *q; struct stat st; int s; if (IsConnectionOK(TRUE)) return 0; path = GetViewerPath(); if (!path || !path[0]) return -1; if (pipe(fd)<0) return -1; pipe_read = fd[0]; _pipe_write = fd[1]; if (pipe(fd)<0) return -1; pipe_write = fd[1]; _pipe_read = fd[0]; if (pipe(fd)<0) return -1; rev_pipe = fd[0]; _rev_pipe = fd[1]; /* We want to wait for this child. */ sigsave = (void*)signal(SIGCHLD,SIG_DFL); pid = vfork(); if (pid < 0) return -1; if (! pid) { /* These three lines look crazy, but the this is the only way I know to orphan a child under all versions of Unix. Otherwise the SIGCHLD may cause Netscape to crash. */ #ifdef NDEBUG setsid(); #endif signal(SIGCHLD,SIG_IGN); if (vfork()) _exit(0); /* Real Child */ close(pipe_read); close(pipe_write); close(rev_pipe); close(3); CHECK(dup(_pipe_read)); close(_pipe_read); close(4); CHECK(dup(_pipe_write)); close(_pipe_write); close(5); CHECK(dup(_rev_pipe)); close(_rev_pipe); /* Duplication above will guarantee, that the new file descriptors will not be closed on exec. Now close all file descriptors which we don't use. For some reasons we will inherit some from Netscape if we don't close them. */ for(s=8;s<1024;s++) close(s); /* This is needed for RedHat's version of Netscape. */ UnsetVariable("LD_PRELOAD"); UnsetVariable("XNLSPATH"); /* This is needed to disable session management in Qt */ UnsetVariable("SESSION_MANAGER"); /* Old autoinstaller fails to set the "executable" flag. */ if (stat(path, &st)>=0) { mode_t mode=st.st_mode; if (mode & S_IRUSR) mode|=S_IXUSR; if (mode & S_IRGRP) mode|=S_IXGRP; if (mode & S_IROTH) mode|=S_IXOTH; chmod(path, mode); } execl(path, path, "-netscape", NULL); fprintf(stderr,"nsdejavu: failed to execute %s\n", path); fflush(stderr); _exit(1); } /* Parent */ close(_pipe_write); close(_pipe_read); close(_rev_pipe); /* Wait for the primary child */ waitpid(pid, &s, 0); signal(SIGCHLD, sigsave); if (ReadString(pipe_read, &ptr, 0, 0) <= 0) { CloseConnection(); return -1; } /* Determine scriptability */ scriptable = 0; xembedable = 0; for (p=ptr; *p; p++) { if (isspace(*p)) continue; for (q=p; *q; q++) if (isspace(*q)) break; s = *q; *q = 0; if (!strcmp(p, "XEMBED")) xembedable = 1; if (!strcmp(p, "SCRIPT")) scriptable = 1; *q = s; p = q; } free(ptr); /* Obtain scriptability atoms */ if (scriptable && !npid_version) { npid_getdjvuopt = NPN_GetStringIdentifier("getdjvuopt"); npid_setdjvuopt = NPN_GetStringIdentifier("setdjvuopt"); npid_onchange = NPN_GetStringIdentifier("onchange"); npid_version = NPN_GetStringIdentifier("version"); } return 1; } /******************************************************************************* ***************************** NPRuntime interface ****************************** *******************************************************************************/ static void npvariantcpy(NPVariant *to, const NPVariant *from) { if (NPVARIANT_IS_OBJECT(*from)) { NPObject *object = NPVARIANT_TO_OBJECT(*from); NPN_RetainObject(object); OBJECT_TO_NPVARIANT(object, *to); return; } if (NPVARIANT_IS_STRING(*from)) { const NPString *s = &NPVARIANT_TO_STRING(*from); char *nstr = NPN_MemAlloc(s->utf8length+1); VOID_TO_NPVARIANT(*to); if (nstr) { memcpy(nstr, s->utf8characters, s->utf8length); nstr[s->utf8length] = 0; STRINGZ_TO_NPVARIANT(nstr, *to); } return; } *to = *from; } typedef struct FatNPObject { NPObject obj; NPP npp; } FatNPObject; static NPObject * np_allocate(NPP npp, NPClass *npclass) { FatNPObject *npobj = malloc(sizeof(FatNPObject)); if (npobj) { memset(npobj, 0, sizeof(FatNPObject)); npobj->obj._class = npclass; npobj->obj.referenceCount = 1; npobj->npp = npp; } return (NPObject*)npobj; } static void np_deallocate(NPObject *npobj) { free(npobj); } static void np_invalidate(NPObject *npobj) { } static bool np_hasmethod(NPObject *npobj, NPIdentifier name) { if (name == npid_getdjvuopt || name == npid_setdjvuopt ) return 1; return 0; } static bool np_invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) { void *id = 0; Instance *inst = 0; if (npobj->_class && npobj->_class->allocate == np_allocate) if ((id = ((FatNPObject*)npobj)->npp->pdata)) inst = map_lookup(&instance, id); if (inst && name == npid_getdjvuopt) { // GetDjVuOpt ------------ if (argCount != 1) NPN_SetException(npobj, "Exactly one argument is expected"); else if (args[0].type != NPVariantType_String) NPN_SetException(npobj, "First argument should be a string"); else { char *res = 0; char *tmp = 0; const char *kname = NPVARIANT_TO_STRING(args[0]).utf8characters; int klen = NPVARIANT_TO_STRING(args[0]).utf8length; if ( (WriteInteger(pipe_write, CMD_GET_DJVUOPT) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteStringLen(pipe_write, kname, klen) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) || (ReadString(pipe_read, &res, 0, 0) <= 0) ) { NPN_SetException(npobj, "Djview program died"); ProgramDied(); return 0; } if (! (tmp = NPN_MemAlloc(strlen(res) + 1))) { NPN_SetException(npobj, "Out of memory"); return 0; } strcpy(tmp, res); STRINGZ_TO_NPVARIANT(tmp, *result); free(res); return 1; } return 0; } else if (inst && name == npid_setdjvuopt) { // SetDjVuOpt ------------ if (argCount != 2) NPN_SetException(npobj, "Exactly two arguments were expected"); else if (args[0].type != NPVariantType_String) NPN_SetException(npobj, "First argument should be a string"); else { const char *kname = NPVARIANT_TO_STRING(args[0]).utf8characters; int klen = NPVARIANT_TO_STRING(args[0]).utf8length; char buffer[32]; const char *arg = buffer; int len = -1; if (NPVARIANT_IS_INT32(args[1])) sprintf(buffer,"%d", NPVARIANT_TO_INT32(args[1])); else if (NPVARIANT_IS_DOUBLE(args[1])) sprintf(buffer,"%e", NPVARIANT_TO_DOUBLE(args[1])); else if (NPVARIANT_IS_STRING(args[1])) { arg = NPVARIANT_TO_STRING(args[1]).utf8characters; len = NPVARIANT_TO_STRING(args[1]).utf8length; } else { NPN_SetException(npobj, "Arg 2 should be a string or a number"); return 0; } if (len < 0) len = strlen(arg); if ( (WriteInteger(pipe_write, CMD_SET_DJVUOPT) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteStringLen(pipe_write, kname, klen) <= 0) || (WriteStringLen(pipe_write, arg, len) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) { NPN_SetException(npobj, "Djview program died"); ProgramDied(); return 0; } VOID_TO_NPVARIANT(*result); return 1; } return 0; } NPN_SetException(npobj, "Unrecognized method"); return 0; } static bool np_invokedefault(NPObject *npobj, const NPVariant *args, uint32 argCount, NPVariant *result) { return 0; } static bool np_hasproperty(NPObject *npobj, NPIdentifier name) { if (name == npid_onchange || name == npid_version) return 1; return 0; } static bool np_getproperty(NPObject *npobj, NPIdentifier name, NPVariant *result) { void *id = 0; Instance *inst = 0; if (npobj->_class && npobj->_class->allocate == np_allocate) if ((id = ((FatNPObject*)npobj)->npp->pdata)) inst = map_lookup(&instance, id); if (inst && name == npid_onchange) { npvariantcpy(result, &inst->onchange); return 1; } else if (inst && name == npid_version) { NPVariant res; STRINGZ_TO_NPVARIANT("nsdejavu+djview4 (x11)", res); npvariantcpy(result, &res); return 1; } return 0; } static bool np_setproperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) { void *id = 0; Instance *inst = 0; if (npobj->_class && npobj->_class->allocate == np_allocate) if ((id = ((FatNPObject*)npobj)->npp->pdata)) inst = map_lookup(&instance, id); if (inst && name == npid_onchange) { int onchange_flag = 0; NPN_ReleaseVariantValue(&inst->onchange); npvariantcpy(&inst->onchange, value); if (NPVARIANT_IS_STRING(*value)) onchange_flag = 1; else if (! NPVARIANT_IS_NULL(*value) && ! NPVARIANT_IS_VOID(*value) ) { NPN_SetException(npobj, "String or null expected"); return 0; } if ( (WriteInteger(pipe_write, CMD_ON_CHANGE) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteInteger(pipe_write, onchange_flag) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) { NPN_SetException(npobj, "Djview program died"); ProgramDied(); return 0; } return 1; } return 0; } static bool np_removeproperty(NPObject *npobj, NPIdentifier name) { NPVariant v; VOID_TO_NPVARIANT(v); return np_setproperty(npobj, name, &v); } static NPClass npclass = { NP_CLASS_STRUCT_VERSION, np_allocate, np_deallocate, np_invalidate, np_hasmethod, np_invoke, np_invokedefault, np_hasproperty, np_getproperty, np_setproperty, np_removeproperty }; /******************************************************************************* ***************************** Netscape plugin interface ************************ *******************************************************************************/ NPError NPP_Initialize(void) { LoadStatic(); if (pipe(delay_pipe) < 0) return NPERR_GENERIC_ERROR; return NPERR_NO_ERROR; } void NPP_Shutdown(void) { #if USE_XT if (input_id) XtRemoveInput(input_id); input_id = 0; if (delay_id) XtRemoveInput(delay_id); delay_id = 0; #endif #if USE_GLIB if (input_gid) g_source_remove(input_gid); input_gid = 0; if (delay_gid) g_source_remove(delay_gid); delay_gid = 0; #endif close(delay_pipe[0]); close(delay_pipe[1]); map_purge(&instance); map_purge(&strinstance); delayedrequest_purge(&delayed_requests); SaveStatic(); if (IsConnectionOK(FALSE)) WriteInteger(pipe_write, CMD_SHUTDOWN); } NPError NPP_New(NPMIMEType mime, NPP np_inst, uint16 np_mode, int16 argc, char* argn[], char* argv[], NPSavedData * saved) { const char *path; Instance *inst = 0; void *id = 0; int i; if (!IsConnectionOK(TRUE)) { CloseConnection(); StartProgram(); } path = GetLibraryPath(); if ( (WriteInteger(pipe_write, CMD_NEW) <= 0) || (WriteInteger(pipe_write, np_mode==NP_FULL) <= 0) || (WriteString(pipe_write, path) <= 0) || (WriteInteger(pipe_write, argc) <= 0) ) { problem: ProgramDied(); map_remove(&instance, id); return NPERR_GENERIC_ERROR; } for(i=0;ibuf && saved->len==sizeof(SavedData)) { SavedData * data = (SavedData *) saved->buf; if ( (WriteInteger(pipe_write, 1) <= 0) || (WriteInteger(pipe_write, data->cmd_mode) <= 0) || (WriteInteger(pipe_write, data->cmd_zoom) <= 0) || (WriteInteger(pipe_write, data->imgx) <= 0) || (WriteInteger(pipe_write, data->imgy) <= 0) ) goto problem; } else if (WriteInteger(pipe_write, 0) <= 0) goto problem; if (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) goto problem; if (ReadPointer(pipe_read, &id, 0, 0) <= 0) goto problem; if ((inst = map_lookup(&instance, id))) /* This can happen because we do not clear the instance array when restarting djview. We just undo it... */ map_remove(&instance, id); np_inst->pdata = id; if (! (inst = instance_new(np_inst, np_mode==NP_FULL))) goto problem; if (map_insert(&instance, id, inst) < 0) goto problem; if (scriptable) inst->npobject = NPN_CreateObject(np_inst, &npclass); #if USE_GLIB if (xembedable) NPN_GetValue(np_inst, NPNVSupportsXEmbedBool, &inst->xembed_mode); #endif if (NPN_GetValue(np_inst, NPNVToolkit, &inst->toolkit) != NPERR_NO_ERROR) inst->toolkit = (NPNToolkitType)(-1); #if USE_XT_IN_PRIORITY if (inst->xembed_mode && inst->toolkit != NPNVGtk2 && XtWindowToWidget) inst->xembed_mode = 0; #endif fprintf(stderr,"nsdejavu: using the %s protocol.\n", (inst->xembed_mode) ? "XEmbed" : "Xt"); #if USE_GLIB if (inst->xembed_mode && g_io_add_watch) return NPERR_NO_ERROR; #endif #if USE_XT if (!inst->xembed_mode && XtWindowToWidget) return NPERR_NO_ERROR; #endif fprintf(stderr,"nsdejavu: browser does not export the %s symbols.\n", (inst->xembed_mode) ? "Glib2" : "Xt" ); return NPERR_INCOMPATIBLE_VERSION_ERROR; } NPError NPP_Destroy(NPP np_inst, NPSavedData ** save) { Instance *inst = 0; void * id = np_inst->pdata; SavedData saved_data; if (! (inst = map_lookup(&instance, id))) return NPERR_INVALID_INSTANCE_ERROR; if (inst->npobject) NPN_ReleaseObject(inst->npobject); inst->npobject = 0; NPP_SetWindow(np_inst, 0); map_remove(&instance, id); np_inst->pdata=0; if (IsConnectionOK(FALSE)) { if ( (WriteInteger(pipe_write, CMD_DESTROY) <= 0) || (WritePointer(pipe_write, id) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) || (ReadInteger(pipe_read, &saved_data.cmd_mode, 0, 0) <= 0) || (ReadInteger(pipe_read, &saved_data.cmd_zoom, 0, 0) <= 0) || (ReadInteger(pipe_read, &saved_data.imgx, 0, 0) <= 0) || (ReadInteger(pipe_read, &saved_data.imgy, 0, 0) <= 0) ) { ProgramDied(); if (inst) instance_free(inst); return NPERR_GENERIC_ERROR; } if (save && !*save && saved_data.cmd_mode>0 && saved_data.cmd_zoom>0) { SavedData *data = (SavedData*) NPN_MemAlloc(sizeof(SavedData)); NPSavedData *saved = (NPSavedData*) NPN_MemAlloc(sizeof(NPSavedData)); if (saved && data) { *data=saved_data; saved->len = sizeof(SavedData); saved->buf = (void*)data; *save = saved; } } } if (inst) instance_free(inst); return NPERR_NO_ERROR; } NPError NPP_SetWindow(NPP np_inst, NPWindow * win_str) { Instance *inst = 0; void * id = np_inst->pdata; Window cur_window, new_window; if (! (inst = map_lookup(&instance, id))) return NPERR_INVALID_INSTANCE_ERROR; cur_window = inst->window; new_window = (win_str) ? (Window) win_str->window : 0; if (cur_window) { if (new_window == cur_window) { Resize(id); return NPERR_NO_ERROR; } if (Detach(id) < 0) { ProgramDied(); return NPERR_GENERIC_ERROR; } } if (new_window) { Display *displ = 0; if (NPN_GetValue(np_inst, NPNVxDisplay, &displ) != NPERR_NO_ERROR) displ = ((NPSetWindowCallbackStruct *)(win_str->ws_info))->display; if (!IsConnectionOK(FALSE)) return NPERR_GENERIC_ERROR; if (Attach(displ, win_str, id) < 0) { ProgramDied(); return NPERR_GENERIC_ERROR; } } return NPERR_NO_ERROR; } void NPP_Print(NPP np_inst, NPPrint* printInfo) { Instance *inst = 0; void * id = np_inst->pdata; if ((inst = map_lookup(&instance, id))) if (inst->window) { if (printInfo && printInfo->mode==NP_FULL) printInfo->print.fullPrint.pluginPrinted=TRUE; if (IsConnectionOK(FALSE)) { int modefull = printInfo && printInfo->mode==NP_FULL; if ( (WriteInteger(pipe_write, CMD_PRINT) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteInteger(pipe_write, modefull) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) { ProgramDied(); return; } } } } NPError NPP_NewStream(NPP np_inst, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype) { Instance *inst = 0; void * id = np_inst->pdata; void * sid = 0; if (! (inst = map_lookup(&instance, id))) return NPERR_INVALID_INSTANCE_ERROR; if ( (WriteInteger(pipe_write, CMD_NEW_STREAM) <= 0) || (WritePointer(pipe_write, id) <= 0) || (WriteString(pipe_write, stream->url) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) || (ReadPointer(pipe_read, &sid, 0, 0) <= 0) ) { ProgramDied(); return NPERR_GENERIC_ERROR; } /* Zero sid means that we do not want this stream */ stream->pdata = sid; if (sid != 0) map_insert(&strinstance, sid, (void*)1); return NPERR_NO_ERROR; } int32 NPP_WriteReady(NPP np_inst, NPStream *np_stream) { return 0x7fffffff; } int32 NPP_Write(NPP np_inst, NPStream *stream, int32 junk, int32 len, void *buffer) { int res = 0; void * sid = stream->pdata; if (sid) { if (! map_lookup(&strinstance, sid)) return res; if ( (WriteInteger(pipe_write, CMD_WRITE) <= 0) || (WritePointer(pipe_write, sid) <= 0) || (WriteArray(pipe_write, len, buffer) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) || (ReadInteger(pipe_read, &res, 0, 0) <= 0) ) { ProgramDied(); return res; } /* ZERO means, that the stream ID sid is meaningless to the viewer. This may happen from time to time. Especially when user hits Reload or when viewer dies and another one is started back (of course, the new instance of the viewer knows nothing about streams or plugins, which were active in the viewer, which just died */ if (res == 0) map_remove(&strinstance, sid); return res; } return len; } NPError NPP_DestroyStream(NPP np_inst, NPStream *stream, NPError reason) { void * sid = stream->pdata; if (! map_lookup(&strinstance, sid)) return NPERR_INVALID_INSTANCE_ERROR; if (!IsConnectionOK(FALSE)) return NPERR_GENERIC_ERROR; map_remove(&strinstance, sid); if ( (WriteInteger(pipe_write, CMD_DESTROY_STREAM) <= 0) || (WritePointer(pipe_write, sid) <= 0) || (WriteInteger(pipe_write, reason==NPRES_DONE) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) { ProgramDied(); return NPERR_GENERIC_ERROR; } return NPERR_NO_ERROR; } /******************************************************************************* ***************************** Stuff, really stuff ****************************** *******************************************************************************/ void NPP_StreamAsFile(NPP np_inst, NPStream *stream, const char* fname) { } int16 NPP_HandleEvent(NPP np_inst, void* event) { return 0; } void NPP_URLNotify(NPP np_inst, const char *url, NPReason reason, void *ptr) { if (IsConnectionOK(FALSE)) { int code; if (reason==NPRES_DONE) code = 0; else if (reason==NPRES_USER_BREAK) code = 1; else code = 2; if ( (WriteInteger(pipe_write, CMD_URL_NOTIFY) <= 0) || (WriteString(pipe_write, url) <= 0) || (WriteInteger(pipe_write, code) <= 0) || (ReadResult(pipe_read, rev_pipe, check_requests) <= 0) ) { ProgramDied(); } } } char * NPP_GetMIMEDescription(void) { return "image/x-djvu:djvu,djv:DjVu File;" "image/x.djvu::DjVu File;" "image/djvu::DjVu File;" "image/x-dejavu::DjVu File (obsolete);" "image/x-iw44::DjVu File (obsolete);" "image/vnd.djvu::DjVu File;" ; } jref NPP_GetJavaClass(void) { return NULL; } NPError NPP_GetValue(NPP np_inst, NPPVariable variable, void *value) { NPError err = NPERR_GENERIC_ERROR; switch (variable) { case NPPVpluginNameString: #if defined(DJVIEW_VERSION_STR) *((char **)value) = "DjView-" DJVIEW_VERSION_STR; #elif defined(DJVULIBRE_VERSION) *((char **)value) = "DjVuLibre-" DJVULIBRE_VERSION; #endif err = NPERR_NO_ERROR; break; case NPPVpluginDescriptionString: *((char **)value) = #if defined(DJVIEW_VERSION_STR) "This is the " "DjView-" DJVIEW_VERSION_STR " version of the DjVu plugin.
" #elif defined(DJVULIBRE_VERSION) "This is the " "DjVuLibre-" DJVULIBRE_VERSION " version of the DjVu plugin.
" #endif "See DjVuLibre."; err = NPERR_NO_ERROR; break; case NPPVpluginNeedsXEmbed: { void * id = np_inst->pdata; Instance *inst = map_lookup(&instance, id); if (! inst ) break; err = NPERR_NO_ERROR; if (! inst->xembed_mode) break; *((NPBool*)value) = TRUE; } break; case NPPVpluginScriptableNPObject: if (scriptable) { void * id = np_inst->pdata; Instance *inst = map_lookup(&instance, id); if (!inst || !inst->npobject) break; err = NPERR_NO_ERROR; NPN_RetainObject(inst->npobject); *((NPObject**)value) = inst->npobject; } break; default: break; } return err; } /****************************************************************************** *************** This replaces npunix.c from the Netscape SDK ****************** ******** Derived from nspluginwrapper licensed under GPL v2 or later ********** *******************************************************************************/ char * NP_GetMIMEDescription(void) { return NPP_GetMIMEDescription(); } NPError NP_GetValue(void *future, NPPVariable variable, void *value) { return NPP_GetValue((NPP)future, variable, value); } NPError NP_Shutdown(void) { NPP_Shutdown(); return NPERR_NO_ERROR; } static NPNetscapeFuncs mozilla_funcs; static int mozilla_has_npruntime = 0; void NPN_Version(int* plugin_major, int* plugin_minor, int* mozilla_major, int* mozilla_minor) { *plugin_major = NP_VERSION_MAJOR; *plugin_minor = NP_VERSION_MINOR; *mozilla_major = mozilla_funcs.version >> 8; *mozilla_minor = mozilla_funcs.version & 0xFF; } NPError NPN_GetValue(NPP instance, NPNVariable variable, void *r_value) { if (mozilla_funcs.getvalue == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_GetValueProc(mozilla_funcs.getvalue, instance, variable, r_value); } NPError NPN_GetURL(NPP instance, const char* url, const char* window) { if (mozilla_funcs.geturl == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_GetURLProc(mozilla_funcs.geturl, instance, url, window); } NPError NPN_GetURLNotify(NPP instance, const char* url, const char* window, void * data) { if (mozilla_funcs.geturlnotify == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_GetURLNotifyProc(mozilla_funcs.geturlnotify, instance, url, window, data); } NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file) { if (mozilla_funcs.posturl == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_PostURLProc(mozilla_funcs.posturl, instance, url, window, len, buf, file); } NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) { if (mozilla_funcs.requestread == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_RequestReadProc(mozilla_funcs.requestread, stream, rangeList); } NPError NPN_NewStream(NPP instance, NPMIMEType type, const char *window, NPStream** stream_ptr) { if (mozilla_funcs.newstream == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_NewStreamProc(mozilla_funcs.newstream, instance, type, window, stream_ptr); } int32 NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer) { if (mozilla_funcs.write == NULL) return -1; return CallNPN_WriteProc(mozilla_funcs.write, instance, stream, len, buffer); } NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) { if (mozilla_funcs.destroystream == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_DestroyStreamProc(mozilla_funcs.destroystream, instance, stream, reason); } void NPN_Status(NPP instance, const char* message) { CallNPN_StatusProc(mozilla_funcs.status, instance, message); } const char* NPN_UserAgent(NPP instance) { return CallNPN_UserAgentProc(mozilla_funcs.uagent, instance); } void* NPN_MemAlloc(uint32 size) { return CallNPN_MemAllocProc(mozilla_funcs.memalloc, size); } void NPN_MemFree(void* ptr) { CallNPN_MemFreeProc(mozilla_funcs.memfree, ptr); } void NPN_ReloadPlugins(NPBool reloadPages) { if (mozilla_funcs.reloadplugins != NULL) CallNPN_ReloadPluginsProc(mozilla_funcs.reloadplugins, reloadPages); } NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) { if (mozilla_funcs.setvalue == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; return CallNPN_GetValueProc(mozilla_funcs.setvalue, instance, variable, value); } void NPN_InvalidateRect(NPP instance, NPRect *invalid) { if (mozilla_funcs.invalidaterect != NULL) CallNPN_InvalidateRectProc(mozilla_funcs.invalidaterect, instance, invalid); } void NPN_InvalidateRegion(NPP instance, NPRegion invalid) { if (mozilla_funcs.invalidateregion != NULL) CallNPN_InvalidateRegionProc(mozilla_funcs.invalidateregion, instance, invalid); } void NPN_ForceRedraw(NPP instance) { if (mozilla_funcs.forceredraw != NULL) CallNPN_ForceRedrawProc(mozilla_funcs.forceredraw, instance); } NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) { if (!mozilla_funcs.getstringidentifier || !mozilla_has_npruntime) return NULL; return CallNPN_GetStringIdentifierProc(mozilla_funcs.getstringidentifier, name); } NPIdentifier NPN_GetIntIdentifier(int32_t intid) { if (!mozilla_funcs.getintidentifier || !mozilla_has_npruntime) return NULL; return CallNPN_GetIntIdentifierProc(mozilla_funcs.getintidentifier, intid); } bool NPN_IdentifierIsString(NPIdentifier identifier) { if (!mozilla_funcs.identifierisstring || !mozilla_has_npruntime) return FALSE; return CallNPN_IdentifierIsStringProc(mozilla_funcs.identifierisstring, identifier); } NPUTF8 * NPN_UTF8FromIdentifier(NPIdentifier identifier) { if (!mozilla_funcs.utf8fromidentifier || !mozilla_has_npruntime) return NULL; return CallNPN_UTF8FromIdentifierProc(mozilla_funcs.utf8fromidentifier, identifier); } int32_t NPN_IntFromIdentifier(NPIdentifier identifier) { if (!mozilla_funcs.intfromidentifier || !mozilla_has_npruntime) return 0; return CallNPN_IntFromIdentifierProc(mozilla_funcs.intfromidentifier, identifier); } NPObject * NPN_CreateObject(NPP npp, NPClass *aClass) { if (!mozilla_funcs.createobject || !mozilla_has_npruntime) return 0; return CallNPN_CreateObjectProc(mozilla_funcs.createobject, npp, aClass); } NPObject * NPN_RetainObject(NPObject *npobj) { if (!mozilla_funcs.retainobject || !mozilla_has_npruntime) return npobj; return CallNPN_RetainObjectProc(mozilla_funcs.retainobject, npobj); } void NPN_ReleaseObject(NPObject *npobj) { if (mozilla_funcs.releaseobject && mozilla_has_npruntime) CallNPN_ReleaseObjectProc(mozilla_funcs.releaseobject, npobj); } void NPN_ReleaseVariantValue(NPVariant *npvariant) { if (mozilla_funcs.releasevariantvalue && mozilla_has_npruntime) CallNPN_ReleaseVariantValueProc(mozilla_funcs.releasevariantvalue, npvariant); } bool NPN_Evaluate(NPP npp, NPObject* obj, NPString *script, NPVariant *result) { if (!mozilla_funcs.createobject || !mozilla_has_npruntime) return 0; return CallNPN_EvaluateProc(mozilla_funcs.evaluate, npp, obj, script, result); } void NPN_SetException(NPObject *npobj, const NPUTF8 *message) { if (mozilla_funcs.setexception && mozilla_has_npruntime) CallNPN_SetExceptionProc(mozilla_funcs.setexception, npobj, message); } NPError NP_Initialize(NPNetscapeFuncs *moz_funcs, NPPluginFuncs *plugin_funcs) { /* basic checks */ if (moz_funcs == NULL || plugin_funcs == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; if ((moz_funcs->version >> 8) != NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; if (moz_funcs->size < (offsetof(NPNetscapeFuncs, forceredraw) + sizeof(NPN_ForceRedrawUPP) )) return NPERR_INVALID_FUNCTABLE_ERROR; if (plugin_funcs->size < sizeof(NPPluginFuncs)) return NPERR_INVALID_FUNCTABLE_ERROR; /* copy mozilla_funcs. */ memcpy(&mozilla_funcs, moz_funcs, min(moz_funcs->size, sizeof(mozilla_funcs))); /* fill plugin_funcs. */ memset(plugin_funcs, 0, sizeof(*plugin_funcs)); plugin_funcs->size = sizeof(NPPluginFuncs); plugin_funcs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; plugin_funcs->newp = NewNPP_NewProc(NPP_New); plugin_funcs->destroy = NewNPP_DestroyProc(NPP_Destroy); plugin_funcs->setwindow = NewNPP_SetWindowProc(NPP_SetWindow); plugin_funcs->newstream = NewNPP_NewStreamProc(NPP_NewStream); plugin_funcs->destroystream = NewNPP_DestroyStreamProc(NPP_DestroyStream); plugin_funcs->asfile = NewNPP_StreamAsFileProc(NPP_StreamAsFile); plugin_funcs->writeready = NewNPP_WriteReadyProc(NPP_WriteReady); plugin_funcs->write = NewNPP_WriteProc(NPP_Write); plugin_funcs->print = NewNPP_PrintProc(NPP_Print); plugin_funcs->event = NULL; plugin_funcs->urlnotify = NewNPP_URLNotifyProc(NPP_URLNotify); plugin_funcs->javaClass = NULL; plugin_funcs->getvalue = NewNPP_GetValueProc(NPP_GetValue); plugin_funcs->setvalue = NULL; /* check for npruntime */ mozilla_has_npruntime = 1; if ((moz_funcs->version >> 8) == 0 && (moz_funcs->version & 0xff) < 14) mozilla_has_npruntime = 0; if (moz_funcs->size < (offsetof(NPNetscapeFuncs, setexception) + sizeof(NPN_SetExceptionUPP) )) mozilla_has_npruntime = 0; /* call npp_initialize */ return NPP_Initialize(); } djview4-4.10.5/nsdejavu/test.html000066400000000000000000000052101264256014000166370ustar00rootroot00000000000000 Test of nsdejavu scriptability features


No plugin


Plugin has not yet been detected.


       


Key: 
Value: 


djview4-4.10.5/src/000077500000000000000000000000001264256014000137445ustar00rootroot00000000000000djview4-4.10.5/src/.gitignore000066400000000000000000000001661264256014000157370ustar00rootroot00000000000000/*.moc /*.o /*.pdb /*.qm /*.vcxproj* /Makefile.qmake /debug/ /djview /moc_*.cpp /qm.dir/ /qrc_*.cpp /release/ /ui_*.h djview4-4.10.5/src/Doxyfile000066400000000000000000001430771264256014000154660ustar00rootroot00000000000000# Doxyfile 1.4.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = djview # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 4.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = NO # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is YES. SHOW_DIRECTORIES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the progam writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp # *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = moc_* ui_* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = Q_PROPERTY(x)= \ Q_DISABLE_COPY= \ _WS_X11_ \ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = Q_OBJECT Q_VARIANT # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO djview4-4.10.5/src/Makefile.am000066400000000000000000000036251264256014000160060ustar00rootroot00000000000000 # include data gathered from djview.pro file include $(srcdir)/djview.am $(srcdir)/djview.am: djview.pro $(AWK) -f $(top_srcdir)/config/qmsources.awk < $< > $@ # program djview # - can we do better than pretending djview is a script? bin_SCRIPTS = djview djview: Makefile.qmake FORCE ${MAKE} -f Makefile.qmake FORCE: .PHONY: FORCE EXTRA_DIST = images Doxyfile djview.pro $(qmake_sources) # man page dist_man1_MANS = djview.1 # translations # - Maybe we should do them all at once and avoid listing # the translation files in both djview.pro and Makefile.am translationsdir = $(datadir)/djvu/djview4 translations_DATA = $(qmake_qm) EXTRA_DIST += $(qmake_ts) lrelease_verbose = $(lrelease_verbose_@AM_V@) lrelease_verbose_ = $(lrelease_verbose_@AM_DEFAULT_V@) lrelease_verbose_0 = @echo " LRELEASE" $@; $(qmake_qm): djview SUFFIXES=.ts .qm .ts.qm: $(lrelease_verbose)$(LRELEASE) -silent $< -qm $@ # invoke qmake qmake_verbose = $(qmake_verbose_@AM_V@) qmake_verbose_ = $(qmake_verbose_@AM_DEFAULT_V@) qmake_verbose_0 = @echo " QMAKE " $@; qmake_allflags = $(QMAKEFLAGS) -I.. -I$(srcdir) -DDIR_DATADIR=\\\"$(datadir)\\\" Makefile.qmake: ${srcdir}/djview.pro Makefile @cmp -s $< djview.pro || cp $< djview.pro $(qmake_verbose)$(QMAKE) $(QMAKEARG)\ QMAKE_UIC=$(UIC) \ QMAKE_MOC=$(MOC) \ QMAKE_RCC=$(RCC) \ QMAKE_LFLAGS+='$(LDFLAGS)' \ QMAKE_CFLAGS+='$(CFLAGS) $(qmake_allflags)' \ QMAKE_CXXFLAGS+='$(CXXFLAGS) $(qmake_allflags)' \ QMAKE_CPPFLAGS+='$(CPPFLAGS) $(qmake_allflags)' \ LIBS+='$(QMAKELIBS)' \ VPATH='$(srcdir)' -o $@0 djview.pro $(AWK) -f $(top_srcdir)/config/qmsilent.awk < $@0 > $@ && ${RM} $@0 # cleaning mostlyclean-local: mostlyclean-qmake mostlyclean-qmake: -test "${srcdir}" == "." || ${RM} djview.pro -test -f Makefile.qmake && ${MAKE} -f Makefile.qmake clean -$(RM) Makefile.qmake .PHONY: mostlyclean-qmake mostlyclean-qm MOSTLYCLEANFILES = djview $(qmake_qm) djview4-4.10.5/src/djview.1000066400000000000000000000511561264256014000153260ustar00rootroot00000000000000.\" t .\" .\" Copyright (c) 2007- Leon Bottou .\" .\" This is free documentation; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License as .\" published by the Free Software Foundation; either version 2 of .\" the License, or (at your option) any later version. .\" .\" The GNU General Public License's references to "object code" .\" and "executables" are to be interpreted as the output of any .\" document formatting or typesetting system, including .\" intermediate and printed output. .\" .\" This manual 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 General Public License for more details. .\" .\" You should have received a copy of the GNU General Public .\" License along with this manual. Otherwise check the web site .\" of the Free Software Foundation at http://www.fsf.org. .TH DJVIEW4 1 "10/11/2001" "DjVuLibre" "DjVuLibre" .de SS .SH \\0\\0\\0\\$* .. .SH NAME djview4 \- Standalone DjVu viewer .SH SYNOPSIS .BI "djview4 [" "options" "] [" "argument" "]" .SH DESCRIPTION Standalone viewer for DjVu files. Features include navigating documents, zooming and panning page images, producing and displaying thumbnails, displaying document outlines, searching documents for particular words in the hidden text layer, copying hidden text to the clipboard, saving pages and documents as bundled or indirect multi-page files, and printing page and documents. The viewer can simultaneously display several pages using a side-by-side or a continuous layout. .SH COMMAND LINE ARGUMENT AND OPTIONS This program can run as a standalone program or as a slave process for the DjVu browser plugin .BR nsdejavu . When running as a standalone program, the command line argument .I argument can be: .IP "*" 3 The filename of a valid DjVu document. .IP "*" 3 A local DjVu document .SM URL of the form: .IP "" 5 .BI "file:///" path "/" name.djvu "[?djvuopts&" keyword = value "&...]" .IP "" 3 The square brackets delimit the optional components of the .SM URL. Various options can be specified using a syntax similar to that of .SM CGI arguments. Specifying options in this manner is very useful for a browser plugin because there are no command line arguments. In the case of a standalone viewer, all options can be specified as command line arguments. .IP "*" 3 An remote DjVu document .SM URL of the form: .IP "" 5 .BI http:// host / path "/" name.djvu "[?djvuopts&" keyword = value "&...]" .IP "" 5 .BI https:// host / path "/" name.djvu "[?djvuopts&" keyword = value "&...]" .IP "" 3 Browsing remote DjVu documents with the standalone viewer is less efficient than using the browser plugin. The standalone viewer does not benefit from the browser caching strategies and proxy settings. Proxy settings for the standalone viewer can be set independently with the preferences dialog. .PP An extensive list of options are recognized. Most options can be specified as command line argument starting with the customary dash character .BR "" "(" "-" ")" or using the syntax of .SM CGI arguments in the document .SM URL. Some options however are only meaningful as command line arguments. Other options are only recognized when running the .SM X11 version of the .BR djview4 program. .SH COMMAND LINE OPTIONS The following options are only meaningful when specified on the command line. .TP .B "-help" Display a brief help message. .TP .B "-verbose" Prints informational messages on the console. This option is very useful because it displays messages about the unrecognized constructs in the DjVu annotation and hyperlink layers. .TP .BI "-fullscreen, -fs " Start .B djview4 in full screen mode. Use the key .B ESC to exit the full screen mode. .TP .BI "-slideshow[=" arg "] Start .B djview4 in slide show mode. The optional numerical argument .I arg specifies the number of seconds before turning each page. Use the key .B ESC to exit the slide show mode. .TP .BI "-style=" "stylename" Specify the graphical user interface style. The recognized values for .I stylename depend on the installed version of the Qt toolkit. Common style names include .BR cde , .BR motif , .BR plastique , .BR platinum , and .BR windows . .SH X11 OPTIONS The following command line options are recognized by the .SM X11 version of the .B djview4 program. Unlike most .B djview4 options, X11 options that demand an argument do not use the equal character to introduce their argument. .TP .BI "-display " "displayname" Specify that the .B djview4 windows should appear on the X11 display .IR displayname . .TP .BI "-geometry " W x H + X + Y Specify the initial size and position of the first window using the traditional X11 geometry specification syntax. The numerical arguments .IR W " and " H represent the initial window width and height. The numerical arguments .IR X " and " Y indicate the window position relative to the top left corner of the screen. .TP .BI "-name " "name" Set the application name. .TP .BI "-title " "title" Set the title of the first window. .TP .BI "-fn " "fontname" ", -font " "fontname" Specify the name of the default font used for buttons and menus. The font should be specified using a X logical font description string. .TP .BI "-bg " "color" ", -background " "color" Specify the default background color for graphical user interface elements. The color should be given as a standard X11 color name. .TP .BI "-fg " "color" ", -foreground " "color" Specify the default foreground color for graphical user interface elements. The color should be given as a standard X11 color name. .TP .BI "-btn " "color" Specify the default button color. The color should be given as a standard X11 color name. .TP .BI "-ncols " "count" Limit the number of colors allocated on a 8 bit display. The default color cube contains 216 distinct colors. .TP .B "-cmap" Force the allocation of a private color map on a 8-bit display. This might increase the color quality but cause flashing when the viewer window gets activated. .SH GENERAL OPTIONS The following options can be specified as command line options or can be passed by augmenting the document .SM URL using a syntax similar to that of .SM CGI arguments .IP "" 3 .BI "http://.../file.djvu?djvuopts&" "key=value" "&" "key=value" "&" "..." .PP In order to separate real .SM CGI arguments from these options, the viewer only recognizes keywords that appear after the word .BR djvuopts . The keywords .I key are derived from the option names by removing the initial dashes. .TP .BI "-page=" "pagename" Display a specific document page. The viewer first searches a page whose identifier matches the argument .IR pagename . Otherwise, if .I pagename is a number preceded by character .BR "+" " or " "-" "," the viewer performs a displacement relative to the current page. Otherwise, starting from the current page and wrapping around, it searches for a page whose title matches the argument .IR pagename . Otherwise, if .I pagename is numerical, it is interpreted as an ordinal page number. Otherwise, and finally, the viewer searches a page whose name matches .IR pagename . .TP .BI "-pageno=" "pagenumber" The page searching algorithm for option .B "page" can cause ambiguities when page titles can be interpreted as numbers. The argument of option .B "pageno" is always interpreted as an ordinal page number. This option is less portable than .B "page" because it is not recognized by earlier versions of the djvu plugin. When using this option is necessary, it is advisable to use both the .B "page" and .B "pageno" options. .TP .BI "-zoom=" zoomfactor Specify the initial zoom factor. Unless the toolbar, pop-up menu and keyboard are disabled, the user will be able to change the zoom factor. Legal values for .I zoomfactor are shown in the below: .br .TS center,box; lfI l lfB l lfB l lfB l lfB l . number Magnification factor in range 10% to 999%. one2one Select the "one-to-one" mode. width Select the "fit width" mode. page Select the "fit page" mode. stretch Stretch the image to the plugin window size. .TE .PP .TP .BI "-showposition=" px "," py Specify a point in the current page that should be as close as possible to the center of the window. The horizontal and vertical positions .IB px "," py in the current page are given as fractions in range 0 to 1. For instance, .B 0,0 designates the upper left corner of the page, .B 0.5,0.5 is the center, and .B 1,1 is the lower right corner. .TP .BI "-mode=" modespec Specify the initial display mode. Unless the toolbar and pop-up menu are disabled, the user will be able to change it. Legal values for .I modespec are shown in the below: .br .TS center,box; lfB l lfB l lfB l lfB l lfB l . color Display the color image. bw Display the foreground mask only. fore Display the foreground only. back Display the background only. text Overlay the hidden text over the color image. .TE .PP .TP .BI "-hor_align=" keyword ", -halign=" keyword Specify the horizontal position of the page in the viewer window. (This does not specify what part of the page will be shown, but rather how margins will be laid out around the page in the plugin window.) Argument .I keyword must be .BR left , .BR center , or .BR right . .TP .BI "-ver_align=" keyword ", -valign=" keyword Specify the vertical position of the page in the viewer window. (This does not specify what part of the page will be shown, but rather how margins will be laid out around the page in the plugin window.) Argument .I keyword must be .BR top , .BR center , or .BR bottom . .TP .BI "-cache=(yes|no)" Enable or disable the caching of fully decoded pages of the document. Caching is on by default. Caching of documents whose .SM URL does not contain an extension .BR .djvu " or " .djv is off by default. .TP .BI "-continuous=(yes|no)" Enable or disable the continuous layout of multipage documents. .TP .BI "-sidebyside=(yes|no), -side_by_side=(yes|no)" Enable or disable the side-by-side layout of multipage documents. .TP .BI "-coverpage=(yes|no)" Specify whether the cover page must be displayed alone when multipage documents are shown in side-by-side layout. .TP .BI "-righttoleft=(yes|no)" Specify whether pages should be arranged right-to-left when multipage documents are shown in side-by-side layout. .TP .BI "-layout=" keyword "{," keyword "}" Specify the layout settings using a single list of comma-separated keywords. The following keywords are recognized: .br .TS center,box; lfB l lfB l lfB l lfB l lfB l lfB l . single Disable the side-by-side and continuous modes. double Enable the side-by-side mode. continuous Enable the continuous mode. cover,nocover First page treatment in side-by-side mode. ltor,rtol Layout direction for side-by-side mode. gap,nogap Specify whether there is a gap between pages. .TE .TP .BI "-scrollbars=(yes|no)" Enable or disable the presence of scroll bars when the full image size exceeds the plugin window size. The default is yes. .TP .BI "-frame=(yes|no)" Enable or disable the display of a thin frame and shadow around the DjVu images. Frames are enabled by default. .TP .BI "-background=" color Specify the color of the background border displayed around the document. The color .I color must be given in hexadecimal .SM RRGGBB or .SM #RRGGBB format. .TP .BI "-toolbar=" keyword "{(,|+|-)" keyword "}" Controls the appearance and the contents of the toolbar. The argument of option .B toolbar is composed of a number of keywords separated by characters comma, plus or minus. The appearance of the toolbar is controlled by keywords placed before the first occurrence of a character plus or minus. The following keywords are recognized in this context: .br .TS center,box; lfB l lfB l lfB l lfB l lfB l . no Disable toolbar. always Displays the toolbar. auto Enable toolbar "autohide" mode (not implemented). top Place toolbar along the top edge. bottom Place toolbar along the bottom edge. .TE .IP "" The contents of the toolbar is controlled by keywords placed after the first occurrence of a character plus or minus. Each keyword adds (after a plus) or removes (after a minus) a particular toolbar button or group of buttons. The initial content of the toolbar is determined by the first occurrence of a character plus or minus. When this is a plus, the toolbar is initially empty. When this is a minus, the toolbar initially contains the default selection of buttons. The following keywords are recognized: .br .TS center,box; lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l . modecombo for the display mode selection tool. zoomcombo for the zoom selection tool. zoom for the zoom buttons. select for the selection button. rotate for the image rotation buttons. find for the text search button. new for the new window button. open for the open new document button. save for the save button. print for the print button. layout for the page layout buttons. pagecombo for the page selection tool. firstlast for the first-page and last-page buttons. prevnext for the previous- and next-page buttons. backforw reserved for the back and forward buttons. help for the contextual help button. .TE .PP For the sake of backward compatibility, the keywords .BR fore , .BR fore_button , .BR back , .BR back_button , .BR bw , .BR bw_button , .BR color , and .BR color_button are interpreted like keyword .BR modecombo ; the keyword .BR rescombo is a synonym of .BR zoomcombo ; the keywords .BR pan , .BR zoomsel , and .BR textsel are interpreted like keyword .BR select ; and the keyword .BR doublepage is interpreted like keyword .BR layout . All other keywords are ignored. .PP .TP .BI "-menubar=(yes|no)" Enable or disable the presence of the menu bar located on top of the window. .TP .BI "-statusbar=(yes|no)" Enable or disable the presence of the status bar located at the bottom of the window. .TP .BI "-sidebar=" keyword "{," keyword "}" Control the dockable panels. The argument is a comma separated list of keywords. A first group of keywords selects which panels are affected. Omitting these keywords selects all panels. A second group of keywords then controls the visibility and the position of the selected panels. .br .TS center,box; lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l lfB l . thumbnails specify the thumbnail panel. outline,bookmarks specify the outline panel. search,find specify the search panel. = yes,true show the specified panels (default). no,false hide the specified panels. left dock specified panels on the left side. right dock specified panels on the right side. top dock specified panels on the top side. bottom dock specified panels on the bottom side. .TE .PP .TP .BI "-thumbnails=" keyword "{," keyword "}" Compatibility alias for .BI "-sidebar=" keyword "{," keyword "},thumbnails." .TP .BI "-outline=" keyword "{," keyword "}" Compatibility alias for .BI "-sidebar=" keyword "{," keyword "},outline." .TP .BI "-menu=(yes|no)" Enable or disable the pop-up menu. .TP .BI "-keyboard=(yes|no)" Enable or disable the DjVu plugin keyboard shortcuts. The default is yes (enabled). Note that disabling the keyboard handling does not disable the shortcuts associated with active menus (see options .BR "-menu" " and " "-menubar" ")," visible toolbars and sidebars (see options .BR "-toolbar" " and " "-sidebar" ")." .TP .BI "-mouse=(yes|no)" Enable or disable mouse interaction for panning and selecting. The default is yes (enabled). .TP .BI "-links=(yes|no)" Enable or disable hyper-links in the DjVu image. Hyper-links are enabled by default. .TP .BI "-highlight=" x "," y "," w "," h "[," color "]" Display a highlighted rectangle at the specified coordinates in the current page and with the specified color. Coordinates .IR x ", " y ", " w ", and " h are measured in document image coordinates (not screen coordinates). The origin is set at the bottom left corner of the image. The color .I color must be given in hexadecimal .SM RRGGBB or .SM #RRGGBB format. Multiple highlighted zone can be specified and can be interspersed with multiple .BI "-page=" "pagename" options. .TP .BI "-find=" text Highlight occurrences of the given string .IR text . This option works when the document contains a hidden text layer. It can be used in conjunction with .BR "-sidebar=find" to display the text searching interface. String .I text can be terminated by slash .BR "" "(" "/" ")" followed by letters specifying search options. The following letters are recognized .br .TS center,box; lfB l lfB l lfB l lfB l lfB l lfB l . c Case-sensitive search. C Case-insensitive search (default). w Search hits start on word boundaries (default). W Ignore word boundaries. r Regular expression search. R String search (default). .TE .PP .TP .BI "-rotate=(0|90|180|270)" Rotate the djvu image by the specified angle expressed in degrees counter-clockwise. .TP .BI "-print=(yes|no)" Enable or disable printing the DjVu document. Printing is enabled by default. .TP .BI "-save=(yes|no)" Enable or disable saving the DjVu document. Saving is enabled by default. .TP .BI "-passive" Cause the DjVu image to be displayed in a manner similar to an ordinary web image. The default zoom factor is changed to .BR page . The toolbar, the status bar, the scrollbars, the menus, and the keyboard shortcuts are disabled. .TP .BI "-passivestretch" Cause the DjVu image to be displayed in a manner similar to an ordinary web image. The default zoom factor is changed to .BR stretch . The toolbar, the status bar, the scrollbars, the menus, and the keyboard shortcuts are disabled. .TP .BI "-nomenu, -notoolbar, -noscrollbars" These options were recognized by some versions of the DjVu viewers and are honored for the sake of backward compatibility. A warning message is printed when option .BR -verbose is active. .TP .BI "-logo, -textsel, -search" These options were recognized by some versions of the DjVu viewers but are currently not implemented by .BR djview4 . A warning message is printed when option .BR -verbose is active. .SH USAGE Most features can be accessed using the menus, the toolbar, the side bar or the pop-up menu shown when the right mouse button is depressed over a DjVu image. Detailled help can be accessed by clicking the contextual help icon from the toolbar and then clicking on various section of the djview user interface. The following table lists some useful key combinations recognized when the djvu document is active: .PP .TS center,box; lfB lfB l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l . Key Action = SHIFT+F1 Activate the contextual help. 1,2, and 3 Change zoom to to 100%, 200% and 300%. Up, Down, Left, Right Scroll the image in the given direction. Home Display top left corner of the image. End Display bottom right corner of the image. Control+Home Go to the beginning of the document. Control+End Go to the end of the document. Space, Return Scroll down or go to next page. Backspace Scroll up or go to previous page. Page Down Go to the next page. Page Up Go to the previous page. +, - Zoom in and out. [, ] Rotate image. W Select the "Fit Width" zooming mode. P Select the "Fit Page" zooming mode. CTRL+F, F3 Search the hidden text layer. CTRL+G Go to a specific page by name or by number. .TE .PP Handy effects can be achieved by holding modifier keys. Although these keys are configurable from the preference dialog, the following table lists the default assignments .PP .TS center,box; lfB lfB l l l l l l . Key Action = CTRL+SHIFT Hold these keys to show the magnification lens. CTRL Hold this key to select an area with the mouse. SHIFT Hold this key to display all hyperlinks. .TE .PP .SH ENVIRONMENT Setting environment variable .BR DJVIEW_VERBOSE to a nonzero value is equivalent to calling .BR djview with option .BR -verbose . Setting environment variable .BR DJVIEW_OPENGL to values 0 or 1 overrides the preference settings regarding OpenGL rendering. When the user clicks on a djvu hyperlink pointing to a web page, the program first tries to execute the web browser programs whose names are listed in the colon separated environment variable .BR BROWSER , then tries sensible platform dependent defaults. The user interface language is determined by first trying to find a complete set of translation files for the language specified in the preference dialog, then for the ISO 639 languages specified in the colon separated environment variable .BR LANGUAGE , and finally the language specified by the system locale. If all these searches fail, the user interface language reverts to the english default. .SH CREDITS This program was written by L\('eon Bottou and is distributed under the GNU General Public License. This program includes code derived from program .BR tiff2pdf , written by Ross Finlayson and released under a BSD license. .SH SEE ALSO .BR djvu (1), .BR ddjvu (1), .BR nsdejavu (1), .BR tiff2pdf (1) djview4-4.10.5/src/djview.am000066400000000000000000000033601264256014000155550ustar00rootroot00000000000000qmake_sources= qmake_ts= qmake_qm= qmake_sources += djview.plist qmake_sources += djview.rc qmake_sources += qdjvu.h qmake_sources += qdjvunet.h qmake_sources += qdjvuwidget.h qmake_sources += qdjvu.cpp qmake_sources += qdjvunet.cpp qmake_sources += qdjvuwidget.cpp qmake_sources += qdjvuwidget.qrc qmake_sources += qdjviewprefs.h qmake_sources += qdjviewsidebar.h qmake_sources += qdjviewdialogs.h qmake_sources += qdjviewexporters.h qmake_sources += qdjview.h qmake_sources += djview.h qmake_sources += version.h qmake_sources += qdjviewprefs.cpp qmake_sources += qdjviewsidebar.cpp qmake_sources += qdjviewdialogs.cpp qmake_sources += qdjviewexporters.cpp qmake_sources += qdjview.cpp qmake_sources += djview.cpp qmake_sources += qdjview.qrc qmake_sources += qdjviewerrordialog.ui qmake_sources += qdjviewauthdialog.ui qmake_sources += qdjviewinfodialog.ui qmake_sources += qdjviewmetadialog.ui qmake_sources += qdjviewsavedialog.ui qmake_sources += qdjviewprintdialog.ui qmake_sources += qdjviewexportdialog.ui qmake_sources += qdjviewexportps1.ui qmake_sources += qdjviewexportps2.ui qmake_sources += qdjviewexportps3.ui qmake_sources += qdjviewexporttiff.ui qmake_sources += qdjviewexportprn.ui qmake_sources += qdjviewprefsdialog.ui qmake_sources += qdjviewplugin.h qmake_sources += qdjviewplugin.cpp qmake_sources += tiff2pdf.h qmake_sources += tiff2pdf.c qmake_ts += djview_fr.ts qmake_qm += djview_fr.qm qmake_ts += djview_uk.ts qmake_qm += djview_uk.qm qmake_ts += djview_de.ts qmake_qm += djview_de.qm qmake_ts += djview_cs.ts qmake_qm += djview_cs.qm qmake_ts += djview_ru.ts qmake_qm += djview_ru.qm qmake_ts += djview_es.ts qmake_qm += djview_es.qm qmake_ts += djview_zh_cn.ts qmake_qm += djview_zh_cn.qm qmake_ts += djview_zh_tw.ts qmake_qm += djview_zh_tw.qm djview4-4.10.5/src/djview.cpp000066400000000000000000000330541264256014000157450ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include "qdjvu.h" #include "qdjview.h" #include "qdjvuwidget.h" #include "djview.h" #ifndef NPDJVU # include "qdjviewplugin.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(Q_OS_WIN32) # include #endif #ifdef QT_NO_DEBUG static bool verbose = false; #else static bool verbose = true; #endif static bool appReady = false; static void qt4MessageHandler(QtMsgType type, const char *msg) { switch (type) { case QtFatalMsg: fprintf(stderr,"djview fatal error: %s\n", msg); abort(); case QtCriticalMsg: fprintf(stderr,"djview critical error: %s\n", msg); break; case QtWarningMsg: if (verbose || !appReady) fprintf(stderr,"djview: %s\n", msg); break; default: if (verbose || !appReady) fprintf(stderr,"%s\n", msg); break; } } #if QT_VERSION >= 0x50000 static void qt5MessageHandler(QtMsgType type, const QMessageLogContext&, const QString &msg) { QByteArray bmsg = msg.toLocal8Bit(); qt4MessageHandler(type, bmsg.data()); } #endif static void message(QString string, bool prefix=true) { QByteArray m = string.toLocal8Bit(); if (prefix) fprintf(stderr, "djview: "); fprintf(stderr, "%s\n", (const char*) m); } static void message(QStringList sl) { foreach (QString s, sl) message(s); } QDjViewApplication::QDjViewApplication(int &argc, char **argv) : QApplication(argc, argv), context(argv[0]) { // Message handler #if QT_VERSION >= 0x50000 qInstallMessageHandler(qt5MessageHandler); #else qInstallMsgHandler(qt4MessageHandler); #endif // Locale should not mess with printf // We do this again because old libdjvulibre // did not correctly set LC_NUMERIC. #ifdef LC_ALL ::setlocale(LC_ALL, ""); # ifdef LC_NUMERIC ::setlocale(LC_NUMERIC, "C"); # endif #endif // Parse arguments using OEM code page under windows. #if defined(Q_OS_WIN32) _setmbcp(_MB_CP_OEM); #endif // Mac/Cocoa bug workaround #if defined(Q_OS_DARWIN) && defined(QT_MAC_USE_COCOA) && QT_VERSION<0x40503 extern void qt_mac_set_native_menubar(bool); qt_mac_set_native_menubar(false); #endif // Wire session management signals connect(this, SIGNAL(saveStateRequest(QSessionManager&)), this, SLOT(saveSessionState(QSessionManager&)) ); // Install translators QStringList langs = getTranslationLangs(); QTranslator *djviewTrans = new QTranslator(this); QTranslator *qtTrans = new QTranslator(this); if (loadTranslators(langs, djviewTrans, qtTrans)) { installTranslator(qtTrans); installTranslator(djviewTrans); } else { delete qtTrans; delete djviewTrans; } // Application is ready appReady = true; } QDjView * QDjViewApplication::newWindow() { if (lastWindow && !lastWindow->getDocument()) return lastWindow; QDjView *main = new QDjView(context); main->setAttribute(Qt::WA_DeleteOnClose); lastWindow = main; return main; } static void addDirectory(QStringList &dirs, QString path) { QString dirname = QDir::cleanPath(path); if (! dirs.contains(dirname)) dirs << dirname; } QStringList QDjViewApplication::getTranslationDirs() { if (translationDirs.isEmpty()) { QStringList dirs; QDir dir = applicationDirPath(); QString dirPath = dir.canonicalPath(); addDirectory(dirs, dirPath); #ifdef DIR_DATADIR QString datadir = DIR_DATADIR; addDirectory(dirs, datadir + "/djvu/djview4"); addDirectory(dirs, datadir + "/djview4"); #endif #ifdef Q_OS_DARWIN addDirectory(dirs, dirPath + "/Resources/$LANG.lproj"); addDirectory(dirs, dirPath + "/../Resources/$LANG.lproj"); addDirectory(dirs, dirPath + "/../../Resources/$LANG.lproj"); #endif addDirectory(dirs, dirPath + "/share/djvu/djview4"); addDirectory(dirs, dirPath + "/share/djview4"); addDirectory(dirs, dirPath + "/../share/djvu/djview4"); addDirectory(dirs, dirPath + "/../share/djview4"); addDirectory(dirs, dirPath + "/../../share/djvu/djview4"); addDirectory(dirs, dirPath + "/../../share/djview4"); addDirectory(dirs, "/usr/share/djvu/djview4"); addDirectory(dirs, "/usr/share/djview4"); addDirectory(dirs, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); translationDirs = dirs; } return translationDirs; } static void addLang(QStringList &langs, QString s) { if (s.size() > 0) { s = s.replace(QChar('-'), QChar('_')); if (! langs.contains(s)) langs << s; #ifdef Q_OS_DARWIN if (s == "zh_Hans" && ! langs.contains("zh_CN")) langs << "zh_CN"; if (s == "zh_Hant" && ! langs.contains("zh_TW")) langs << "zh_TW"; #endif } } QStringList QDjViewApplication::getTranslationLangs() { if (translationLangs.isEmpty()) { QStringList langs; addLang(langs, QSettings().value("language").toString()); QString varLanguage = QString::fromLocal8Bit(::getenv("LANGUAGE")); foreach(QString lang, varLanguage.split(":", QString::SkipEmptyParts)) addLang(langs, lang); #ifdef LC_MESSAGES addLang(langs, QString::fromLocal8Bit(::setlocale(LC_MESSAGES, 0))); #endif addLang(langs, QString::fromLocal8Bit(::getenv("LANG"))); #ifdef Q_OS_DARWIN QSettings g(".", "globalPreferences"); foreach (QString lang, g.value("AppleLanguages").toStringList()) addLang(langs, lang); #endif addLang(langs, QLocale::system().name()); translationLangs = langs; } return translationLangs; } static bool loadOneTranslator(QTranslator *trans, QString name, QString lang, QStringList dirs) { QString llang = lang.toLower(); foreach (QString dir, dirs) { dir = dir.replace(QRegExp("\\$LANG(?!\\w)"), lang); QDir qdir(dir); if (qdir.exists()) { if (trans->load(name + "_" + lang, dir, "_.-")) return true; if (lang != llang && trans->load(name + "_" + llang, dir, "_.-")) return true; } } return false; } bool QDjViewApplication::loadTranslators(QStringList langs, QTranslator *dTrans, QTranslator *qTrans) { QStringList dirs = getTranslationDirs(); foreach (QString lang, langs) { bool okay = true; if (okay && dTrans && !loadOneTranslator(dTrans, "djview", lang, dirs)) okay = false; if (okay && qTrans && !loadOneTranslator(qTrans, "qt", lang, dirs)) okay = false; if (okay || lang.startsWith("en_") || lang == "en") return okay; } return false; } bool QDjViewApplication::event(QEvent *ev) { if (ev->type() == QEvent::FileOpen) { QString name = static_cast(ev)->file(); QDjView *main = newWindow(); if (main->open(name)) { main->show(); } else { message(tr("cannot open '%1'.").arg(name)); delete main; } return true; } else if (ev->type() == QEvent::Close) { closeAllWindows(); } return QApplication::event(ev); } void QDjViewApplication::saveSessionState(QSessionManager &sm) { int n = 0; QSettings s; foreach(QWidget *w, topLevelWidgets()) { QDjView *djview = qobject_cast(w); if (djview && !djview->objectName().isEmpty() && djview->getViewerMode() == QDjView::STANDALONE ) { if (++n == 1) { QStringList discard = QStringList(applicationFilePath()); discard << QLatin1String("-discard") << sessionId(); sm.setDiscardCommand(discard); QStringList restart = QStringList(applicationFilePath()); restart << QLatin1String("-session"); restart << sessionId() + "_" + sessionKey(); sm.setRestartCommand(restart); QString id = QLatin1String("session_") + sessionId(); s.sync(); s.remove(id); s.beginGroup(id); } s.beginGroup(QString::number(n)); djview->saveSession(&s); s.endGroup(); } } if (n > 0) { s.setValue("windows", n); s.endGroup(); s.sync(); } } #ifndef NPDJVU static void usage() { QString msg = QDjViewApplication::tr ("Usage: djview [options] [filename-or-url]\n" "Common options include:\n" "-help~~~Prints this message.\n" "-verbose~~~Prints all warning messages.\n" "-display ~~~Select the X11 display .\n" "-geometry ~~~Select the initial window geometry.\n" "-font ~~~Select the X11 name of the main font.\n" "-style ~~~Select the QT user interface style.\n" "-fullscreen, -fs~~~Start djview in full screen mode.\n" "-page=~~~Jump to page .\n" "-zoom=~~~Set zoom factor.\n" "-continuous=~~~Set continuous layout.\n" "-sidebyside=~~~Set side-by-side layout.\n" ); // align tabs QStringList opts = msg.split("\n"); int tab = 0; foreach (QString s, opts) tab = qMax(tab, s.indexOf("~~~")); foreach (QString s, opts) { int pos = s.indexOf("~~~"); if (pos >= 0) s = QString(" %1 %2").arg(s.left(pos), -tab).arg(s.mid(pos+3)); message(s, false); } exit(10); } int main(int argc, char *argv[]) { // Application data QApplication::setOrganizationName(DJVIEW_ORG); QApplication::setOrganizationDomain(DJVIEW_DOMAIN); QApplication::setApplicationName(DJVIEW_APP); // Message handler #if QT_VERSION >= 0x50000 qInstallMessageHandler(qt5MessageHandler); #else qInstallMsgHandler(qt4MessageHandler); #endif // Set verbose flag as early as possible #ifdef Q_OS_UNIX const char *s = ::getenv("DJVIEW_VERBOSE"); if (s && strcmp(s,"0")) verbose = true; #endif for (int i=1; i 0) { for (int n=1; n<=windows; n++) { QDjView *w = new QDjView(*app.djvuContext()); w->setAttribute(Qt::WA_DeleteOnClose); s.beginGroup(QString::number(n)); w->restoreSession(&s); s.endGroup(); w->show(); } return app.exec(); } } // Process command line QStringList args; QDjView *main = app.newWindow(); while (argc > 1 && argv[1][0] == '-') { QString arg = QString::fromLocal8Bit(argv[1]).replace(QRegExp("^-+"),""); QString key = arg.section(QChar('='),0,1); if (arg == "help") usage(); else if (arg == "verbose") verbose = true; else if (arg == "quiet") verbose = false; else if (arg == "fix") message(QApplication::tr("Option '-fix' is deprecated.")); else args += arg; argc --; argv ++; } if (argc > 2) usage(); // Open file if (argc > 1) { QString name = QString::fromLocal8Bit(argv[1]); bool okay = true; if (name.contains(QRegExp("^[a-zA-Z]{3,8}:/"))) okay = main->open(QUrl(name)); else okay = main->open(name); if (! okay) { message(QDjView::tr("cannot open '%1'.").arg(argv[1])); exit(10); } } // Process options and go foreach(QString arg, args) message(main->parseArgument(arg)); main->show(); return app.exec(); } #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/djview.h000066400000000000000000000035471264256014000154160ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef DJVIEW_H #define DJVIEW_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include "qdjvu.h" class QDjView; class QTranslator; class QDjViewApplication : public QApplication { Q_OBJECT QDjVuContext context; QPointer lastWindow; QStringList translationLangs; QStringList translationDirs; public: QDjViewApplication(int &argc, char **argv); QDjVuContext *djvuContext() { return &context; } QDjView *newWindow(); bool loadTranslators(QStringList langs, QTranslator *dt, QTranslator *qt); protected: bool event(QEvent *ev); protected slots: void saveSessionState(QSessionManager &sm); private: QStringList getTranslationLangs(); QStringList getTranslationDirs(); }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/djview.plist000066400000000000000000000055141264256014000163160ustar00rootroot00000000000000 CFBundleIconFile @ICON@ CFBundlePackageType APPL CFBundleName DjView CFBundleGetInfoString DjView - viewer for DjVu files CFBundleSignature DJVU CFBundleExecutable @EXECUTABLE@ CFBundleIdentifier org.djvu.DjView CFBundleInfoDictionaryVersion 6.0 CFBundleShortVersionString @SHORT_VERSION@ CFBundleVersion @SHORT_VERSION@ CFBundleDocumentTypes CFBundleTypeExtensions djvu djv CFBundleTypeMIMETypes image/vnd.djvu image/x-dejavu image/djvu image/x.djvu image/x-djvu image/x-iw44 CFBundleTypeIconFile DjVu.icns CFBundleTypeName DjVu File CFBundleTypeRole Viewer LSIsAppleDefaultForType LSItemContentTypes com.lizardtech.djvu UTExportedTypeDeclarations UTTypeConformsTo org.djvuzone.djvulibre.djvu com.lizardtech.djvu public.djvu public.composite-content public.content public.data UTTypeDescription DjVu File UTTypeIdentifier com.lizardtech.djvu UTTypeIconFile DjVu.icns UTTypeTagSpecification public.filename-extension djv djvu public.mime-type image/vnd.djvu image/x-dejavu image/djvu image/x.djvu image/x-djvu image/x-iw44 djview4-4.10.5/src/djview.pro000066400000000000000000000070721264256014000157640ustar00rootroot00000000000000#C- -*- shell-script -*- #C- ------------------------------------------------------------------- #C- DjView4 #C- Copyright (c) 2006 Leon Bottou #C- #C- This software is subject to, and may be distributed under, the #C- GNU General Public License. The license should have #C- accompanied the software or you may obtain a copy of the license #C- from the Free Software Foundation at http:#www.fsf.org . #C- #C- This program is distributed in the hope that it will be useful, #C- but WITHOUT ANY WARRANTY; without even the implied warranty of #C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #C- GNU General Public License for more details. #C- ------------------------------------------------------------------ TEMPLATE = app TARGET = djview CONFIG += qt thread warn_on QT += network opengl # -- QT5 modules greaterThan(QT_MAJOR_VERSION, 4) { QT += widgets printsupport } # -- find libraries CONFIG(autoconf) { # for use with autoconf DEFINES += AUTOCONF # Autoconf calls qmake with the following variables # LIBS += ... # QMAKE_CXXFLAGS += ... # QMAKE_CFLAGS += ... # QMAKE_LFLAGS += ... } else { # customize below INCLUDEPATH += /usr/include LIBS += -L/usr/local/lib -ldjvulibre -ljpeg #QMAKE_CXXFLAGS += #QMAKE_CFLAGS += #QMAKE_LFLAGS += #DEFINES += } # -- no debug in release mode CONFIG(release,debug|release) { DEFINES += NDEBUG QT_NO_DEBUG QT_NO_DEBUG_STREAM } # -- mac stuff macx { ICON = images/DjVuApp.icns VERSION = $$PACKAGE_VERSION RESOURCES.path = Contents/Resources RESOURCES.files = images/DjVu.icns QMAKE_BUNDLE_DATA += RESOURCES QMAKE_INFO_PLIST = djview.plist QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 } # --- windows stuff win32 { RC_FILE = djview.rc } # --- djviewplugin logic greaterThan(QT_MAJOR_VERSION, 4) { DEFINES *= WITH_DJVIEWPLUGIN } else:macx:contains(DEFINES,__USE_WS_X11__) { DEFINES *= WITH_DJVIEWPLUGIN } else:win32:contains(DEFINES,_WIN32_X11_) { DEFINES *= WITH_DJVIEWPLUGIN } else:!macx:!win32 { DEFINES *= WITH_DJVIEWPLUGIN } contains(DEFINES,WITH_DJVIEWPLUGIN) { greaterThan(QT_MAJOR_VERSION, 4) { } else { DEFINES *= WITH_X11 CONFIG += x11 } } # -- djvu files HEADERS += qdjvu.h HEADERS += qdjvunet.h HEADERS += qdjvuwidget.h SOURCES += qdjvu.cpp SOURCES += qdjvunet.cpp SOURCES += qdjvuwidget.cpp RESOURCES += qdjvuwidget.qrc # -- djview files HEADERS += qdjviewprefs.h HEADERS += qdjviewsidebar.h HEADERS += qdjviewdialogs.h HEADERS += qdjviewexporters.h HEADERS += qdjview.h HEADERS += djview.h HEADERS += version.h SOURCES += qdjviewprefs.cpp SOURCES += qdjviewsidebar.cpp SOURCES += qdjviewdialogs.cpp SOURCES += qdjviewexporters.cpp SOURCES += qdjview.cpp SOURCES += djview.cpp RESOURCES += qdjview.qrc FORMS += qdjviewerrordialog.ui FORMS += qdjviewauthdialog.ui FORMS += qdjviewinfodialog.ui FORMS += qdjviewmetadialog.ui FORMS += qdjviewsavedialog.ui FORMS += qdjviewprintdialog.ui FORMS += qdjviewexportdialog.ui FORMS += qdjviewexportps1.ui FORMS += qdjviewexportps2.ui FORMS += qdjviewexportps3.ui FORMS += qdjviewexporttiff.ui FORMS += qdjviewexportprn.ui FORMS += qdjviewprefsdialog.ui contains(DEFINES,WITH_DJVIEWPLUGIN) { HEADERS += qdjviewplugin.h SOURCES += qdjviewplugin.cpp } # -- helper files HEADERS += tiff2pdf.h SOURCES += tiff2pdf.c # -- transations TRANSLATIONS += djview_fr.ts TRANSLATIONS += djview_uk.ts TRANSLATIONS += djview_de.ts TRANSLATIONS += djview_cs.ts TRANSLATIONS += djview_ru.ts TRANSLATIONS += djview_es.ts TRANSLATIONS += djview_zh_cn.ts TRANSLATIONS += djview_zh_tw.ts djview4-4.10.5/src/djview.rc000066400000000000000000000014221264256014000155610ustar00rootroot00000000000000 #include #include "version.h" IDI_ICON1 ICON DISCARDABLE "images/DjVuApp.ico" IDI_ICON2 ICON DISCARDABLE "images/DjVu.ico" VS_VERSION_INFO VERSIONINFO FILEVERSION RC_VERSION PRODUCTVERSION RC_VERSION BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", DJVIEW_ORG VALUE "FileDescription", DJVIEW_APP VALUE "ProductName", DJVIEW_APP VALUE "FileVersion", RC_VERSION_STR VALUE "ProductVersion", RC_VERSION_STR VALUE "InternalName", DJVIEW_APP VALUE "OriginalFilename", "djview.exe" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END djview4-4.10.5/src/djview_cs.ts000066400000000000000000004640521264256014000163040ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language ÄŒesky QApplication Option '-fix' is deprecated. PÅ™epínaÄ â€ž-fix“ není doporuÄeno používat. QDjView cannot open '%1'. „%1“ nelze otevřít. FitWidth zoomCombo Na šířku FitPage zoomCombo Celá stránka Stretch zoomCombo Roztáhnout 1:1 zoomCombo 1:1 300% zoomCombo 300 % 200% zoomCombo 200 % 150% zoomCombo 150 % 100% zoomCombo 100 % 75% zoomCombo 75 % 50% zoomCombo 50 % Color modeCombo BarevnÄ› Stencil modeCombo Kresbu Foreground modeCombo PopÅ™edí Background modeCombo Pozadí &New File| &Nové okno Ctrl+N File|New Ctrl+N Create a new DjView window. Vytvoří nové okno s DjView. &Open File| &Otevřít Ctrl+O File|Open Ctrl+O Open a DjVu document. OtevÅ™e dokument DjVu. &Close File| &Zavřít Ctrl+W File|Close Ctrl+W Close this window. ZavÅ™e toto okno. &Quit File| U&konÄit Ctrl+Q File|Quit Ctrl+Q Close all windows and quit the application. ZavÅ™e vÅ¡echna okna a ukonÄí aplikaci. Save &as... File| Uložit &jako… Ctrl+S File|SaveAs Ctrl+S Save the DjVu document. Uloží dokument DjVu. &Export as... File| &Exportovat jako… Ctrl+E File|ExportAs Ctrl+E Export DjVu page or document to other formats. Exportuje stránku DjVu nebo celý dokument do jiného formátu. &Print... File| &Tisknout… Ctrl+P File|Print Ctrl+P Print the DjVu document. Vytiskne dokument DjVu. &Find... Edit| Na&jít… Ctrl+F Edit|Find Ctrl+F Find text in the document. Hledá text v dokumentu. Find &Next Edit| Najít &další F3 Edit|Find Next F3 Find next occurence of search text in the document. Hledá v dokumentu další výskyt hledaného textu. Find &Previous Edit| Najít &pÅ™edchozí Shift+F3 Edit|Find Previous Shift+F3 Find previous occurence of search text in the document. Hledá v dokumentu pÅ™edchozí výskyt hledaného textu. &Select Edit| &Vybrat F2 Edit|Select F2 Select a rectangle in the document. Vyberte v dokumentu obdélníkovou oblast. Zoom &In Zoom| &PÅ™iblížit Increase the magnification. Zvýší zvÄ›tÅ¡ení. Zoom &Out Zoom| &Oddálit Decrease the magnification. Sníží zvÄ›tÅ¡ení. Fit &Width Zoom| Na šíř&ku Set magnification to fit page width. Nastaví takové zvÄ›tÅ¡ení, aby se stránka veÅ¡la na šířku okna. Fit &Page Zoom| &Celá stránka Set magnification to fit page. Nastaví takové zvÄ›tÅ¡ení, aby se stránka veÅ¡la do okna. One &to one Zoom| ZvÄ›tÅ¡ení &1:1 Set full resolution magnification. Nastaví plné zvÄ›tÅ¡ení. &300% Zoom| &300 % Magnify 300% ZvÄ›tÅ¡ení 300 % &200% Zoom| &200% Magnify 20% ZvÄ›tÅ¡ení 20 % Magnify 150% ZvÄ›tÅ¡ení 150 % &100% Zoom| &100 % Magnify 100% ZvÄ›tÅ¡ení 100 % &75% Zoom| &75 % Magnify 75% ZvÄ›tÅ¡ení 75 % &50% Zoom| &50 % Magnify 50% ZvÄ›tÅ¡ení 50 % &First Page Go| P&rvní stránka Jump to first document page. Nalistuje první stránku v dokumentu. &Next Page Go| &Následující stránka Jump to next document page. Nalistuje následující stránku v dokumentu. &Previous Page Go| &PÅ™edchozí stránka Jump to previous document page. Nalistuje pÅ™edchozí stránku v dokumentu. &Last Page Go| Pos&lední stránka Jump to last document page. Nalistuje poslední stránku v dokumentu. &Backward Go| &ZpÄ›t Backward in history. ZpÄ›t v historii. &Forward Go| &DopÅ™edu Forward in history. DopÅ™edu v historii. Rotate &Left Rotate| OtoÄit do&leva Rotate page image counter-clockwise. OtoÄí stránku proti smÄ›ru hodinových ruÄiÄek. Rotate &Right Rotate| OtoÄit do&prava Rotate page image clockwise. OtoÄí stránku ve smÄ›ru hodinových ruÄiÄek. Rotate &0° Rotate| OtoÄení &0 ° Set natural page orientation. Nastaví pÅ™irozený smÄ›r stránky. Rotate &90° Rotate| OtoÄení &90 ° Turn page on its left side. Stránku otoÄí na svoji levou stranu. Rotate &180° Rotate| OtoÄení &180 ° Turn page upside-down. OtoÄí stránku vzhůru nohama. Rotate &270° Rotate| OtoÄení &270 ° Turn page on its right side. Stránku otoÄí na svoji pravou stranu. &Information... Edit| &Informace… Ctrl+I Edit|Information Ctrl+I Show information about the document encoding and structure. Zobrazí informace o kódování dokumentu a jeho struktuÅ™e. &Metadata... Edit| &Metadata… Ctrl+M Edit|Metadata Ctrl+M Show the document and page meta data. Zobrazí metadata o stránce a celém dokumentu. &About DjView... &O DjView… Show information about this program. Zobrazí informace o tomto programu. &Color Display| &BarevnÄ› Display everything. Zobrazí vÅ¡e. &Stencil Display| &Kresbu Only display the document bitonal stencil. Zobrazí pouze dvoubarevnou kresbu dokumentu. &Foreground Display| &PopÅ™edí Only display the foreground layer. Zobrazí pouze vrstvu popÅ™edí. &Background Display| Po&zadí Only display the background layer. Zobrazí pouze vrstvu pozadí. I&nvert Luminance View| PÅ™evrátit &jas Invert image luminance while preserving hue. PÅ™evrátí jas obrazu pÅ™i zachování odstínu. Prefere&nces... Settings| Nasta&vení… Show the preferences dialog. Zobrazí dialog s nastavením. F9 Settings|Show sidebar F9 Show/hide the side bar. Zobrazí/skryje postranní panel. F10 Settings|Show toolbar F10 Show/hide the standard tool bar. Zobrazí/skryje standardní liÅ¡tu nástrojů. Show/hide the status bar. Zobrazí/skryje stavový řádek. F11 View|FullScreen F11 Toggle full screen mode. PÅ™epne celoobrazovkový režim. &Slide Show View| P&rezentace Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. PÅ™epne režim prezentace. &Continuous Layout| &Navazující stránky F4 Layout|Continuous F4 Toggle continuous layout mode. PÅ™epne souvislý režim zobrazení. Side &by Side Layout| &Po dvou stránkách F5 Layout|SideBySide F5 Toggle side-by-side layout mode. PÅ™epne režim zobrazení po dvou stránkách. &File File| &Soubor &Edit Edit| Ú&pravy &View View| &Zobrazení &Zoom View|Zoom Z&vÄ›tÅ¡ení &Rotate View|Rotate &OtoÄení &Display View|Display &Zobrazení &Go Go| PÅ™e&jít &Settings Settings| Nasta&vení &Help Help| &NápovÄ›da Control Left Mouse Button Ovládat levým tlaÄítkem myÅ¡i Right Mouse Button Pravé tlaÄítko myÅ¡i <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html<b>Obdélníkový výbÄ›r.</b><br/>Jakmile vyberete obdélníkovou oblast, vyskoÄí nabídka umožňující zkopírování odpovídajícího textu nebo obrázku. Místo tohoto nástroje můžete podržet %1 a použít levé tlaÄítko myÅ¡i.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>ZvÄ›tÅ¡ení.</b><br/>Vybere míru zvÄ›tÅ¡ení pÅ™i prohlížení dokumentu. Hodnota 100 % zobrazí dokument pro 100DPI obrazovku. Hodnoty <tt>Celá stránka</tt> a <tt>Na šířku</tt> zajistí, že celá stránka nebo celá šířka stránky se vmÄ›stná do okna.</html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>OtáÄení stránek.</b><br/>Vyberte pro zobrazení stránek v orientaci na výšku nebo na šířku. Taktéž je můžete otoÄit vzhůru nohama.</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Režim zobrazení.</b><br/>Obrázku DjVu se skládají z vrstvy s pozadím a popÅ™edím za pomoc kresby textu. Režim zobrazení urÄuje, které vrstvy mají být zobrazeny.</html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Informace o dokumentu a stránkách</b><br/>Zobrazí interaktivní okno s informacemi o kódování dokumentu nebo urÄité stránky.</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Metadata o dokumentu a stránkách.</b><br/>Zobrazí interaktivní okno s metadaty o dokumentu nebo urÄité stránce.</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Navazující pohled.</b><br/>VÅ¡echny stránky dokumentu budou svisle seÅ™azeny uvnitÅ™ jediné velké rolovatelné oblasti (jako leporelo).</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Pohled po dvou stránkách.</bn><br/>UvnitÅ™ rolovatelné oblasti budou zobrazeny vždy dvÄ› sousedící stránky vedle sebe (jako otevÅ™ená kniha).</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Informace o stránce.</b><br/>Zobrazí informace o stránce umístÄ›né pod kurzorem: poÅ™adové Äíslo stránky, rozmÄ›ry stránky v pixelech a rozliÅ¡ení stránky v bodech na palec.</html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Informace o kurzoru.</b><br/>Zobrazí pozici ukazatele myÅ¡i v souÅ™adném systému stránky.</html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>Oblast pro zobrazování dokumentu.</bn><br/>Toto je hlavní zobrazovací plocha pro dokumenty DjVu.<ul><li>Å ipky, PgUp, PgDn pro pohyb v dokumentu.</li><li>Mezerník a backspace pro Ätení v dokumentu.</li><li>Klávesy <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> pro zvÄ›tÅ¡ování a otáÄení dokumentu.</li><li>Levé tlaÄítko myÅ¡i pro zvýraznÄ›ní a výbÄ›r odkazů.</li><li>%3 pro zobrazení kontextové nabídky.</li><li>%1 levé tlaÄítko myÅ¡i pro výbÄ›r textu a obrázků.</li><li>%2 pro zobrazení lupy.</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>Plocha pro zobrazování dokumentu.</b><br/>Toto je hlavní plocha pro zobrazování dokumentů DjVu. AvÅ¡ak abyste nÄ›co vidÄ›li, musíte nejprve nÄ›jaký dokument DjVu otevřít.</html> Option '%1' requires boolean argument. PÅ™epínaÄ â€ž%1“ vyžaduje pravdivostní argument. Illegal value '%2' for option '%1'. Neplatná hodnota „%2“ pro pÅ™epínaÄ â€ž%1“. Toolbar option '%1' is not implemented. PÅ™epínaÄ liÅ¡ty nástrojů „%1“ není implementován. Toolbar option '%1' is not recognized. PÅ™epínaÄ liÅ¡ty nástrojů „%1“ není znám. Option '%1' requires a standalone viewer. PÅ™epínaÄ â€ž%1“ vyžaduje samostatný prohlížeÄ. Deprecated option '%1' Zastaralý pÅ™epínaÄ â€ž%1“ Option '%1' is not implemented. PÅ™epínaÄ â€ž%1“ není implementován. Option '%1' is not recognized. PÅ™epínaÄ â€ž%1“ není znám. DjView DjView Cannot open file '%1'. Soubor „%1“ nelze otevřít. Opening DjVu file Otevírám soubor DjVu Cannot open URL '%1'. URL „%1“ nelze otevřít. Opening DjVu document Otevírám dokument DjVu Certificate validation error - DjView dialog caption Chyba ověřování certifikátu – DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Chcete pÅ™esto pokraÄovat? </html> Cannot find page numbered: %1 Nelze najít stránku Äíslo: %1 Cannot find page named: %1 Nelze najít stránku pojmenovanou: %1 Unrecognized sidebar options '%1'. Nerozpoznané volby postranního panelu „%1“. <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html>Tento soubor byl dodán s omezením tisku. Chcete jej pÅ™esto vytisknout?</html> <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html>Tento soubor byl dodán s omezením ukládání. Chcete jej pÅ™esto uložit?</html> Print - DjView dialog caption Tisk – DjView &150% Zoom| &150 % &Full Screen View| &Celá obrazovka Save - DjView dialog caption Uložení – DjView Export - DjView dialog caption Export – DjView Text files save filter Textové soubory All files save filter VÅ¡echny soubory Save Text - DjView dialog caption Uložit text – DjView Error - DjView dialog caption Chyba – DjView Cannot write file '%1'. %2. Soubor „%1“ nelze zapsat. %2. Save Image - DjView dialog caption Uložit obrázek – DjView Cannot determine file format. Filename '%1' has no suffix. Formát souboru nelze urÄit. Soubor „%1“ nemá žádnou příponu. Image format %1 not supported. Formát souboru %1 není podporován. Cannot decode page %1. Stránku %1 nelze dekódovat. Cannot decode document. Dokument nelze dekódovat. Decoding DjVu document Dekóduji dokument DjVu x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3×%4+%1+%2 Go: %n pages forward. PÅ™ejít: %n stranu vpÅ™ed. PÅ™ejít: %n strany vpÅ™ed. PÅ™ejít: %n stran vpÅ™ed. Go: %n pages backward. PÅ™ejít: %n stranu zpÄ›t. PÅ™ejít: %n strany zpÄ›t. PÅ™ejít: %n stran zpÄ›t. Go: page %1. PÅ™ejít: na stranu %1. Go: %1 Link: %1 PÅ™ejít: %1 (in other window.) (v dalším oknÄ›.) Cannot resolve link '%1' Odkaz „%1“ nelze vyhodnotit Cannot spawn a browser for url '%1' Pro URL „%1“ nelze vyvolat prohlížeÄ Copy text (%1) Zkopírovat text (%1) Save text as... Uložit text jako… Copy image (%1x%2 pixels) Zkopírovat obrázek (%1×%2 pixelů) Save image as... Uložit obrázek jako… Zoom to rectangle ZvÄ›tÅ¡it na obdélník About DjView O DjView DjVu files Soubory DjVu Enter the URL of a DjVu document: Zadejte URL  dokumentu DjVu: Information - DjView dialog caption Informace – DjView Metadata - DjView dialog caption Metadata – DjView Open &Location... File| Otevřít z &adresy… Open a remote DjVu document. OtevÅ™e vzdálený dokument DjVu. Ctrl+F3 Edit|Find Next Ctrl+F3 Ctrl+F2 Edit|Select Ctrl+F2 Show &Sidebar Settings| Zobrazit &postranní panel Ctrl+F9 Settings|Show sidebar Ctrl+F9 Show &Toolbar Settings| Zobrazit liÅ¡tu &nástrojů Ctrl+F10 Settings|Show toolbar Ctrl+F10 Show Stat&usbar Settings| Zobrazit &stavový řádek Ctrl+F11 View|FullScreen Ctrl+F11 Ctrl+F4 Layout|Continuous Ctrl+F4 Ctrl+F5 Layout|SideBySide Ctrl+F5 Open &Recent Otevřít &nedávné <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>Navigace po dokumentu.</b><br/>Tento výbÄ›r stránky vám dovolí pÅ™ejít na libovolnou stránku podle jejího jména a lze jej kdykoliv vyvolat stiskem Ctrl+G. TlaÄítka navigace směřují na stránku první, pÅ™edcházející, následující nebo poslední.</html> Thumbnails Náhledy Outline Osnova Find Najít %1 files (*.%2);; save image filter %1 souborů (*.%2);; P%1/%2 %3x%4 %5dpi S%1/%2 %3×%4 %5 DPI <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>ProhlížeÄ dokumentů DjVu<br/><a href=%3>%3</a><br/>Copyright © 2006 – Léon Bottou.</p><p align=justify><small>Tento program je svobodné programové vybavení. Můžete jej šířit nebo upravovat podle pravidel Obecné veÅ™ejné licence GNU (GNU GPL) vydané nadací Free Software Foundation. Tento program je šířen <i>bez jakékoliv záruky</i>. Pro podrobnosti nahlédnÄ›te do Obecné veÅ™ejné licence GNU (GNU General Public License)</small></p></html> Open - DjView dialog caption OtevÅ™ení – DjView Open Location - DjView dialog caption OtevÅ™ení z adresy – DjView &Clear History &Smazat historii %n characters %n znak %n znaky %n znaků Go: 1 page forward. PÅ™ejít: 1 stranu vpÅ™ed. Go: 1 page backward. PÅ™ejít: 1 stranu zpÄ›t. Copy &URL Edit| Kopírovat &URL Save an URL for the current page into the clipboard. Uloží do schránky URL souÄasné stránky. Copy &Outline Edit| Kopírovat &osnovu Copy &Annotations Edit| Kopírovat po&známky Copy text into the clipboard. Uloží text do schránky. Save text into a file. Uloží text do souboru. Copy image into the clipboard. Uloží obrázek do schránky. Save image into a file. Uloží obrázek do souboru. Zoom the selection to fit the window. ZvÄ›tší vybranou oblast tak, aby vyplnila okno. Copy URL Kopírovat URL Save into the clipboard an URL that highlights the selection. Uloží do schránky URL, které se nachází ve výbÄ›ru. Copy Maparea Kopírovat maparea Save into the clipboard a maparea annotation expression for program djvused. Uloží do schránky maparea výraz pro program djvused. Ctrl+C Edit|CopyURL Ctrl+C Save the djvused code for the outline into the clipboard. Uloží do schránky djvused kód s osnovou. Save the djvused code for the page annotations into the clipboard. Uloží do schránky dvjused kód s poznámkami na této stránce. Co&ver Page Layout| PÅ™e&bal Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. PÅ™i zobrazení pod dvou stránkách zobrazí pÅ™ebal samostatnÄ›. &Right to Left Layout| Zp&rava doleva Ctrl+Shift+F6 Layout|RightToLeft Ctrl+Shift+F6 Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. PÅ™i zobrazení po dvou stránkách zobrazuje zprava doleva. All files VÅ¡echny soubory &Hidden Text Display| &Skrytý text Overlay a representation of the hidden text layer. Nad dokumentem zobrazí vrstvu skrytého textu. Hidden Text modeCombo Skrytý text QDjViewApplication Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. Použití: djview [pÅ™epínaÄe] [soubor_nebo_URL] Mezi obecné pÅ™epínaÄe patří: -help~~~Vypíše tuto zprávu. -verbose~~~Vypisuje vÅ¡echny varovné hlášky. -display <xdpy>~~~Vybere X11 displej <xdpy>. -geometry <geometrie>~~~Vybere poÄáteÄní geometrii okna. -font <xlfd>~~~Vybere X11 název hlavního fontu. -style <qtstyl>~~~Vybere styl uživatelského rozhraní Qt. -fullscreen, -fs~~~Spustí djview v celoobrazovkovém režimu. -page=<Äíslo_stránky>~~~Nalistuje stránku <Äíslo_stránky>. -zoom=<zvÄ›tÅ¡ení>~~~Nastaví zvÄ›tÅ¡ení. -continuous={y|n}~~~Nastaví navazující pohled („y“ [ano], „n“ [ne]). -sidebyside={y|n}~~~Nastaví pohled dvou stran („y“ [ano], „n“ [ne]). cannot open '%1'. „%1“ nelze otevřít. QDjViewAuthDialog Password: Heslo: User: Uživatel: Authentication required - DjView Vyžadováno prokázání totožnosti – DjView QDjViewDjVuExporter DjVu Bundled Document Svázaný dokument DjVu DjVu Files (*.djvu *.djv) Soubory DjVu (*.djvu *.djv) DjVu Indirect Document Volný dokument DjVu Question - DjView dialog caption Dotaz – DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html>Tento soubor náleží do neprázdného adresáře. PÅ™i uložení volného dokumentu vznikne v tomto adresáři mnoho souborů. Chcete pokraÄovat a riskovat pÅ™epsání souboru v tomto adresáři?</html> Con&tinue &PokraÄovat &Cancel &ZruÅ¡it Unknown error. Neznámá chyba. System error: %1. Systémová chyba: %1. Save job creation failed! VytvoÅ™ení ukládací úlohy selhalo! QDjViewErrorDialog DjView Error Chyba DjView Error - DjView dialog caption Chyba – DjView &Ok &Ok QDjViewExportDialog <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>Uložení.</b><br/>Můžete uložit celý dokument nebo rozsah stránek do rozliÄných formátů. VýbÄ›r nÄ›kterých formátů způsobí zobrazení dodateÄných dialogových stránek pro nastavením daného formátu.</html> Error - DjView dialog caption Chyba – DjView Overwriting the current file is not allowed! PÅ™epsání aktuálního souboru není dovoleno! Question - DjView dialog caption Dotaz – DjView A file with this name already exists. Do you want to replace it? Soubor tohoto jména již existuje. Chcete jej nahradit? &Replace &Nahradit &Cancel &ZruÅ¡it This operation has failed. Tato operace selhala. This operation has been interrupted. Tato operace byla pÅ™eruÅ¡ena. All files save filter VÅ¡echny soubory Export - DjView dialog caption Export – DjView Dialog Dialog Export Exportovat &Document &Dokument C&urrent page &Aktuální stránku &Pages &Stránky to až Destination Cíl Format: Formát: &Defaults &Výchozí &Ok &Ok Stop Zastavit QDjViewExportPS1 Form Tvar Color Barvy &Color &BarevnÄ› &GrayScale O&dstíny Å¡edi Marks ZnaÄky Print image &frame Tisknout o&rámování Print crop &marks Tisknout oÅ™e&zové znaÄky PostScript PostScript Language Level Úroveň jazyka QDjViewExportPS2 Form Tvar Scaling ZvÄ›tÅ¡ení Scale to &fit the page &Roztáhnout na celou stránku &Zoom &ZvÄ›tÅ¡ení %  % Orientation Orientace Automatic Automatická &Portrait Na &výšku &Landscape Na šíř&ku QDjViewExportPS3 Form Print sheets suitable for folding a booklet. Tisknout listy v poÅ™adí pro pohodlné sestavení brožury. Advanced PokroÄilé nastavení Sheets per booklet: Listů na brožuru: Unlimited NeomezenÄ› at most nejvýše Print Tisknout rectos and versos. liché i sudé. rectos only. jen liché. versos only. jen sudé. Shift rectos and versos by Liché a sudé posunout o points. bodů. Center: StÅ™ed: points bodů plus plus /100 /100 per page. na stránku. QDjViewExportPrn Form Tvar Color Barvy &Color &BarevnÄ› &GrayScale O&dstíny Å¡edi Marks ZnaÄky Print image &frame Tisknout o&rámování Print crop &marks Tisknout oÅ™e&zové znaÄky Scaling ZvÄ›tÅ¡ení Scale to &fit the page &Roztáhnout na celou stránku &Zoom Z&vÄ›tÅ¡ení %  % Orientation Orientace Automatic Automatická &Portrait Na &výšku &Landscape Na šíř&ku QDjViewExportTiff Form Tvar Resolution RozliÅ¡ení Maximum image resolution Nejvyšší rozliÅ¡ení obrázku dpi  DPI Compression Komprese Force &bitonal G4 compression. Vynutit &dvoubarvovou G4 kompresi. Allow &lossy JPEG compression. Povolit ztrátovou &JPEG  kompresi. JPEG &quality &Kvalita JPEGU Allow &deflate compression. Povolit &deflate kompresi. QDjViewFind Case sensitive RozliÅ¡ovat velikost písmen Words only Jen celá slova Find Previous (Shift+F3) Najít pÅ™edchozí (Shift+F3) Find Next (F3) Najít další (F3) Options Možnosti <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>Najít text.</b><br/>Nalezené Å™etÄ›zce se objevují již v průbÄ›hu zadávání hledané fráze. Klávesou Enter se pÅ™esunete na další místo nálezu. Pro pÅ™esun na následující nebo pÅ™edcházející nález použijte tlaÄítka se Å¡ipkou nebo klávesové zkratky <tt>F3</tt> nebo <tt>Shift-F3</tt>. Taktéž můžete dva krát kliknout na jméno stránky. Nabídka <tt>Možnosti</tt> umožňuje omezit hledání na celá slova nebo velikost písmen.</html> Regular expression Regulární výraz Reset search options to default values. Vrátit možnosti hledání na jejich výchozí hodnoty. Specify whether search hits must begin on a word boundary. UrÄuje, zda výsledky hledání musí zaÄínat na hranici slova. Specify whether searches are case sensitive. UrÄuje, zda hledání rozliÅ¡uje velikost písmen. Regular expressions describe complex string matching patterns. Regulární výrazy popisují vzory pro hledání složitých Å™etÄ›zců. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Rychlý úvod do regulárních výrazů</b><ul><li>TeÄka <tt>.</tt> odpovídá libovolnému znaku.</li><li>VÄ›tÅ¡ina znaků odpovídá sama sobÄ›.</li><li>VýbÄ›r zvláštních znaků <tt>()[]{}|*+.?!^$\</tt> je nutné uvést zpÄ›tným lomítkem <tt>\</tt>.</li><li><tt>\b</tt> odpovídá hranici slova.</li><li><tt>\w</tt> odpovídá znaku slova.</li><li><tt>\d</tt> odpovídá Äíslici.</li><li><tt>\s</tt> odpovídá bílému znaku.</li><li><tt>\n</tt> odpovídá znaku nový řádek.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> odpovídá znakům z rozsahu <tt><i>a</i></tt>–<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> odpovídá znakům mimo rozsah <tt><i>a</i></tt>–<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> odpovídá buÄ regulárnímu výrazu <tt><i>a</i></tt>, nebo regulárnímu výrazu <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> odpovídá regulárnímu výrazu <tt><i>a</i></tt> opakovanému <tt><i>n</i></tt> až <tt><i>m</i></tt>-krát.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt> a <tt><i>a</i>+</tt> jsou zkratky pro <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt> a <tt><i>a</i>{1,}</tt>.</li><li>Regulární výrazy pÅ™ed <tt>?+*{</tt> lze uzavřít do skupiny pomocí závorek <tt>()</tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 shoda Searching page %1 (waiting for data.) Prohledávám stránku %1 (Äekám na data) Searching page %1. Prohledávám stránku %1. No hits! Nic nenalezeno! <html>Document is not searchable. No page contains information about its textual content.</html> <html>V dokument nelze hledat. Žádná stránka neobsahuje informace o svém textovém obsahu.</html> Page %1 (1 hit) Strana %1 (1 shoda) %n hits %n shoda %n shody %n shod Page %1 (%n hits) Strana %1 (%n shoda) Strana %1 (%n shody) Strana %1 (%n shod) <html>Invalid regular expression.</html> <html>Neplatný regulární výraz.</html> QDjViewImgExporter %1 Image JPG Image Obrázek %1 %1 Files (*.%2) JPG Files Soubory %1 (*.%2) Cannot render page. Stránku nelze vykreslit. Image format %1 not supported. Obrázkový formát %1 není podporován. QDjViewInfoDialog File # ÄŒ. souboru File Name Název souboru File Size Velikost souboru File Type Typ souboru Page # ÄŒ. strany Page Title Název strany <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Informace o dokumentu</b><br/>Tento panel zobrazuje informace o dokumentu a jeho souborech, z kterých se skládá. Na záložce <tt>Soubor</tt> uvidíte informace o souboru vybraném v seznamu podílových souborů. Dvojklikem na podílový soubor zobrazíte odpovídající stránku v hlavním oknÄ›.</html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Informace o souboru a stránce</b><br/>Tento panel zobrazuje strukturu DjVu dat odpovídajících podílovému souboru nebo stránce vybrané v záložce <tt>Dokument</tt>. TlaÄítka s šipkou skoÄí na pÅ™edchozí nebo na následující podílový soubor.</html> Waiting for data... ÄŒekám na data… Page #%1 - « %2 » Strana Ä. %1 – „%2“ Page #%1 Strana Ä. %1 Thumbnails Náhledy Shared annotations Sdílené poznámky Shared data Sdílená data File #%1 - Soubor Ä. %1 – Single DjVu page Jediná stránka DjVu Bundled DjVu document Svázaný dokument DjVu Indirect DjVu document Volný dokument DjVu Obsolete bundled DjVu document Zastaralý svázaný dokument DjVu Obsolete indexed DjVu document Zastaralý volný dokument DjVu n/a není známo Page Strana Thumbnails Náhledy Shared Sdílený Dialog Dialog &Document &Dokument &File &Soubor File: Soubor: &View Page &Zobrazit stránku &Close &Zavřít 1 file 1 soubor %n files %n soubor %n soubory %n souborů 1 page 1 strana %n pages %n strana %n strany %n stran QDjViewMetaDialog Ctrl+C copy Ctrl+C Key KlÃ­Ä Value Hodnota <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Metadata dokumentu</b><br/>Tento panel zobrazuje metadata pokrývající celý dokument, jako je autor, název, odkazy atd. Tyto informace mohou být uloženy do dokumentu pomocí programu <tt>djvused</tt>: použijte příkazy <tt>create-shared-ant</tt> a <tt>set-meta</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Metadata stránky</b><br/>Tento panel zobrazuje metadata vztahující se ke konkrétní stránce. Metadata stránky pÅ™ebíjejí metadata dokumentu. Tyto informace mohou být uloženy do dokumentu pomocí programu <tt>djvused</tt>: pro výbÄ›r stránky použijte příkaz <tt>select</tt> a pro zadání metadat příkaz <tt>set-meta</tt>.</html> Dialog Dialog &Document Metadata Metadata &dokumentu &Page Metadata Metadata &stran Page: Strana: &View Page Zo&brazit stránku &Close &Zavřít QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>Osnova dokumentu.</b><br/>Tento panel zobrazuje osnovu dokumentu jména stránek není-li osnova k dispozici. Dvojklikem na položku se dostanete vybranou stránku.</hml> Outline data is corrupted Osnova je poÅ¡kozena Pages Strany Page %1 Strana %1 Go: page %1. Go: page %1 PÅ™ejít na: stranu %1. Go: %1 Go: %1. PÅ™ejít na: %1 QDjViewPSExporter PostScript PostScript PostScript Files (*.ps *.eps) Postscriptový soubor (*.ps *.eps) Encapsulated PostScript ZapouzdÅ™ený PostScript PostScript tab caption PostScript Position tab caption UmístÄ›ní Booklet tab caption Brožura <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>Nastavení PostScriptu.</b><br/>Volba <tt>BarevnÄ›</tt> umožňuje barevný tisk. Stránky dokumentu mohou být vybaveny orámováním a oÅ™ezovými znaÄkami. Úroveň jazyku 1 je užiteÄná jen s velmi starými tiskárnami. S úrovní 2 funguje vÄ›tÅ¡ina tiskáren. Úroveň 3 urychluje barevný tisk na novÄ›jších tiskárnách.</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>UmístÄ›ní a zvÄ›tÅ¡ení.</b><br/>Volba <tt>Roztáhnout na celou stránku</tt> se pÅ™izpůsobí jakékoliv velikosti papíru, který vaÅ¡e tiskárna používá. Míra zvÄ›tÅ¡ení <tt>100 %</tt> reprodukuje dokument ve své původní velikosti. Orientace <tt>Automatická</tt> vybírá orientaci (na výšku nebo na šířku) každé stránky samostatnÄ›.</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Výroba brožur.</b><br/>Režim brožura tiskne vybrané stránky tak, aby potiÅ¡tÄ›né listy bylo snadno možné uspořádat do jedné nebo více brožur. VÄ›tší množství brožur bude vyrobeno, bude-li pÅ™ekroÄen nastavený limit poÄtu listů na brožuru. Tisknout lze oboustrannÄ› nebo liché a sudé stránky zvlášť.<p>Posunutí lichých a sudých stran je potÅ™eba, neumí-li tiskárna pÅ™i oboustranném tisku dodržet slícování pÅ™edního a zadního potisku listu. StÅ™edové okraje urÄují rozestup mezi levou a pravou stránkou na listu. Tento rozestup se postupnÄ› zvÄ›tÅ¡uje smÄ›rem od vnitÅ™ních ke vnÄ›jším listům brožury.</html> Save job creation failed! VytvoÅ™ení ukládací úlohy selhalo! QDjViewPdfExporter PDF Document Dokument PDF PDF Files (*.pdf) Soubory PDF  (*.pdf) PDF Options tab caption Nastavení PDF <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>Nastavení PDF<b><br/>Tímto nastavením se řídí vlastnosti obrázků vkládaných do exportovaného PDF  souboru. RozliÅ¡ení omezuje nejvyšší rozliÅ¡ení obrázků. Vynucení dvoubarvové G4 komprese zakóduje vÅ¡echny stránky do Äerné a bílé barvy pomocí komprese CCITT  Group 4. Povolením JPEG komprese způsobíte použití ztrátového formátu JPEG pro vÅ¡echny obrázky vyjma dvoubarvových a podvzorkovaných. V opaÄném případÄ› zapnutí deflate komprese způsobí vytvoÅ™ení menších souborů.</html> Error while creating pdf file. Chyba pÅ™i vytvářené PDF  souboru. PDF export was not compiled. Export do PDF nebyl zakompilován. Unable to create output file. Výstupní soubor nelze vytvoÅ™it. System error: %1. Systémová chyba: %1. Unable to reopen temporary file. Pomocný soubor nelze znovu otevřít. Unable to create temporary file. Pomocný soubor nelze vytvoÅ™it. QDjViewPlugin::Document Requesting %1. Požaduji %1. QDjViewPrefsDialog Preferences[*] - DjView Nastavení[*] – DjView <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>Prvotní nastavení rozhraní.</b><br>DjView může běžet jako samostatný prohlížeÄ, jako prohlížeÄ pÅ™es celou obrazovku, jako celostránkový zásuvný modul do webového prohlížeÄe nebo jako zásuvný modul uvnitÅ™ Äásti HTML stránky. Pro každý případ lze zatrhnout pÅ™epínaÄ <tt>Zapamatovat si</tt>, který způsobí automatické uložení konfigurace pÅ™i ukonÄení a naÄtení pÅ™i dalším spuÅ¡tÄ›ní v daném režimu. Jinak lze konfiguraci po novém spuÅ¡tÄ›ní navolit níže.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>ModifikaÄní klávesy.</b><br>UrÄuje, které kombinace modifikátorů způsobí zobrazení lupy, doÄasný režim výbÄ›ru nebo zvýraznÄ›ní odkazů.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Lupa</b><br/>Lupa se objeví, stisknete-li modifikátor urÄený v záložce <tt>Klávesy</tt>. Tento panel nabízí výbÄ›r zvÄ›tÅ¡ení a rozmÄ›rů lupy.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>PokroÄilé.</b><br>Můžete vnutit výchozí jazyk uživatelského rozhraní, vypnout animace stránky nebo zapnout dodateÄné položky v nabídkách, které se hodí pÅ™i vytváření souborů DjVu. Rovněž můžete vypnout omezení na tisk nebo ukládání vyžadované nÄ›kterými webovými stránkami. RuÄní oprava barev může být užiteÄná u starých tiskáren.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>Nastavení síťové proxy.</b><br>Tato nastavení mají vliv, pokud samostatný prohlížeÄ djview pÅ™istupuje k DjVu dokumentu skrze HTTP URL. Zásuvný modul vždy používá nastavení proxy z webového prohlížeÄe.<p><b>Vyrovnávací pamÄ›ti</b><br><i>Pixelová keÅ¡</i> uchovává obrazová data, která se nachází mimo viditelnou oblast. Tato keÅ¡ umožňuje plynulý pohyb po stránce. <i>KeÅ¡ pro dekódované stránky</i> uchovává ÄásteÄnÄ› dekódované stránky. Umožňuje kratší reakÄní dobu pÅ™i listování mezi stránkami nebo pÅ™i návratu na dříve vidÄ›nou stránku. PotÅ™ebujete-li pÅ™ekreslit zmÄ›nÄ›né stránky, můžete místo nového spouÅ¡tÄ›ní DjVu prohlížeÄe vyprázdnit tuto keÅ¡.</html> Standalone Viewer (Full Screen mode) Samostatný prohlížeÄ (celobrazovkový režim) Standalone Viewer (Slideshow mode) Samostatný prohlížeÄ (režim prezentace) Dialog Dialog Gamma Gama Darker Tmavší Lighter SvÄ›tlejší <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>Oprava barev na obrazovce.<br>Pohybujte jezdcem tak dlouho, dokud pole nebudou podobnÄ› Å¡edá.</html> &Interface &Rozhraní Options for Nastavení pro Standalone Viewer Samostatný prohlížeÄ Full Page Plugin Zásuvný modul pÅ™es celou stránku Embedded Plugin VestavÄ›ný zásuvný modul &Remember initial state from last invocation &Zapamatovat si stav z posledního spuÅ¡tÄ›ní Show Zobrazovat &Menu bar &Nabídkový pruh &Tool bar &LiÅ¡tu nástrojů Sc&rollbars &Rolovací jezdce Stat&us bar &Stavový řádek &Side bar &Postranní panel Display Vykreslovat Force inverted luminance Force inverted luminance. Vnutit pÅ™evrácení jasu &Zoom: Z&vÄ›tÅ¡ení: Timer: ÄŒasovaÄ: s  s Display page &frames Zobrazovat o&rámování stránek Display &annotations Zobrazovat &poznámky &Keys &Klávesy Keys Klávesy For displaying hyper&links: Pro zobrazení &odkazů: For &selecting text or images: Pro &výbÄ›r textu nebo obrázku: For displaying the &lens: Pro zobrazení &lupy: Mouse wheel KoleÄko myÅ¡i Mouse wheel scrolls the page Mouse wheel scrolls the page. KoleÄko myÅ¡i posunuje stránkou Mouse wheel changes the zoom factor Mouse wheel changes the zoom factor. KoleÄko myÅ¡i mÄ›ní míru zvÄ›tÅ¡ení &Lens &Lupa Enable magnifying &lens Povolit zvÄ›tÅ¡ování &lupou Lens options Nastavení lupy Lens &size: &Velikost lupy: Magnifying &power: &ZvÄ›tÅ¡ení: x × pixels pixelů Cache Vyrovnávací paměť &Clear &Vyprázdnit &Decoded page cache: KeÅ¡ pro &dekódované stránky: &Pixel cache: &Pixelová keÅ¡: &Network &Síť Use pro&xy to access the network Na síť pÅ™istupovat pÅ™es pro&xy Proxy settings Nastavení proxy Pass&word: &Heslo:  &User: &Uživatel: &Port: &Port: &Host: &Jméno poÄítaÄe: Interface Rozhraní Force language (next time djview runs) Vnutit jazyk (od příštího spuÅ¡tÄ›ní djview) Enable page animations Enable animations Zapnout animace stránky Show hidden text in status bar Zobrazovat skrytý text ve stavovém řádku Render with openGL when available Vykreslovat pomocí OpenGL, je-li dostupné Override saving and printing restrictions PÅ™ebít omezení na ukládání a tisk &Defaults &Výchozí &Apply &Aplikovat &Ok &Ok Cancel ZruÅ¡it <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>Gama oprava obrazovky</b><br>Nejlepšího podání barev se dosáhne posunutím jezdce opravy gamy do pozice, kdy si jsou Å¡edivé Ätverce co nejpodobnÄ›jší.<p><b>RozliÅ¡ení obrazovky</b><br>Tato volba vnutí dané rozliÅ¡ení místo nespolehlivé hodnoty, kterou hlásí operaÄní systém. Nastavení rozliÅ¡ení na 100 DPI je shodné s hodnotami, které používají nástroje pro příkazovou řádku z balíku djvulibre.</html> &Screen &Obrazovka Force screen &resolution Vnutit &rozliÅ¡ení obrazovky dpi  DPI &Advanced &PokroÄilé Miscellaneous Různé Manual printer color correction RuÄní oprava barev tiskárny gamma= gama =  Enable advanced features in menus Zapnout pokroÄilé možnosti v nabídkách MB MB Layout Rozvržení Continuous Navazující stránky Side-by-side Po dvou stránkách Cover Page PÅ™ebal Right-to-Left Zprava doleva QDjViewPrintDialog <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Tisk.</b><br/>Tisknout můžete celý dokument nebo rozsah stran. Tiskárnu a její nastavení vyberete tlaÄítkem <tt>Vybrat</tt>. Mohou se objevit další záložku s dialogy pro nastavení konverze.</html> All files save filter VÅ¡echny soubory Print To File - DjView dialog caption Tisk do souboru – DjView Question - DjView dialog caption Dotaz – DjView A file with this name already exists. Do you want to replace it? Soubor tohoto jména již existuje. Chcete jej nahradit? &Replace &Nahradit &Cancel &ZruÅ¡it This operation has failed. Tato operace selhala. This operation has been interrupted. Tato operace byla pÅ™eruÅ¡ena. Dialog Dialog Print Tisknout &Document &Dokument C&urrent page &Aktuální stránku &Pages &Stránky to až Destination Cíl Print to file Tisknout do souboru Printer name: Jméno tiskárny: Choose Vybrat &Defaults &Výchozí &Ok &Ok Stop Zastavit (invalid printer) (neplatná tiskárna) QDjViewPrnExporter Printer data Tisková data PRN Files (*.prn) Soubory PRN (*.prn) Printing Options tab caption Nastavení tisku <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Nastavení tisku.</b><br>Volba <tt>BarevnÄ›</tt> umožňuje barevný tisk. Stránky dokumentu mohou být vybaveny orámováním. <tt>Roztáhnout na celou stránku</tt> se pÅ™izpůsobí jakékoliv velikosti papíru, který vaÅ¡e tiskárna používá. Míra zvÄ›tÅ¡ení <tt>100 %</tt> reprodukuje dokument ve své původní velikosti. Orientace <tt>Automatická</tt> vybírá orientaci (na výšku nebo na šířku) každé stránky samostatnÄ›.</html> Cannot render page %1. Stránku %1 nelze vykreslit. QDjViewSaveDialog <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>Uložení.</b><br/> Svázaný formát vytvoří jediný soubor. Volný formát vytvoří Å™adu souborů vhodných pro webové prostÅ™edí.</html> Error - DjView dialog caption Chyba – DjView Overwriting the current file is not allowed! PÅ™epsání aktuálního souboru není dovoleno! Question - DjView dialog caption Dotaz – DjView A file with this name already exists. Do you want to replace it? Soubor tohoto jména již existuje.Chcete jej nahradit? &Replace &Nahradit &Cancel &ZruÅ¡it This operation has failed. Tato operace selhala. This operation has been interrupted. Tato operace byla pÅ™eruÅ¡ena. All files save filter VÅ¡echny soubory Save - DjView dialog caption Uložení – DjView Dialog Dialog Save Uložit &Document &Dokument C&urrent page &Aktuální stránku &Pages S&tránky to až Destination Cíl Format: Formát: Bundled DjVu Document Svázaný dokument DjVu Indirect DjVu Document Volný dokument DjVu &Ok &Ok Stop Zastavit QDjViewThumbnails Tiny thumbnail menu Drobné Small thumbnail menu Malé Medium thumbnail menu StÅ™ední Large thumbnail menu Velké Smart thumbnail menu Chytré Control Left Mouse Button Right Mouse Button <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Náhledy dokumentu.</b><br/> Tento panel zobrazuje náhledy na stránky dokumentu. Dvojklikem na náhled pÅ™ejdete na vybranou stránku. %1 použijte pro zmÄ›nu velikosti nebo způsobu obnovování. Chytrý režim obnovy vypoÄítává náhledy jen tÄ›ch stran, jejichž data jsou známa (zobrazena nebo nakeÅ¡ována).</html> QDjViewTiffExporter TIFF Document Dokument TIFF TIFF Files (*.tiff *.tif) Soubory TIFF (*.tiff *.tif) TIFF Options tab caption Nastavení TIFFU <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>Nastavení TIFFU</b><br/>RozliÅ¡ení urÄuje horní limit pro rozliÅ¡ení TIFF obrázků. Vynucení dvoubarvové G4 komprese zakóduje vÅ¡echny stránky do Äerné a bílé barvy pomocí komprese CCITT  Group 4. Povolením JPEG komprese způsobíte použití ztrátového formátu JPEG pro vÅ¡echny obrázky vyjma dvoubarvových a podvzorkovaných. V opaÄném případÄ› zapnutí deflate komprese způsobí vytvoÅ™ení menších (ale ménÄ› pÅ™enositelných) souborů na rozdíl od výchozí komprese packbits.</html> Cannot open output file. Výstupní soubor nelze otevřít. Out of memory. Nedostatek pamÄ›ti. Internal error. VnitÅ™ní chyba. TIFF export has not been compiled. Export do TIFFU nebyl zakompilován. QDjVuNetDocument Requesting '%1' Požaduji „%1“ QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code Na požadavek %2 byl obdržen stats %1. Received <%1> data while retrieving %2. %1 is a mime type Na požadavek %2 byla obdržena data typu %1. %1 while retrieving '%2'. Na požadavek %2 obdrženo %1. Cannot validate the certificate for server %1. Nelze ověřit certifikát serveru %1. Authentication required for %1 (%2). %1 (%2) vyžaduje ověření totožnosti. Authentication required for proxy %1. Proxy %1 vyžaduje ověření totožnosti. djview4-4.10.5/src/djview_de.ts000066400000000000000000004632551264256014000162730ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language Deutsch QApplication Option '-fix' is deprecated. Option '-fix' ist veraltet. QDjView FitWidth zoomCombo An Seitenbreite anpassen FitPage zoomCombo An Seite anpassen Stretch zoomCombo Ausdehnen 1:1 zoomCombo 300% zoomCombo 200% zoomCombo 150% zoomCombo 100% zoomCombo 75% zoomCombo 50% zoomCombo Color modeCombo Farbe Stencil modeCombo Schablone Foreground modeCombo Vordergrund Background modeCombo Hintergrund &New File| &Neu Ctrl+N File|New Create a new DjView window. Erzeugt ein neues DjView Fenster. &Open File| Ö&ffnen Ctrl+O File|Open Open a DjVu document. Öffnet ein DjVu-Dokument. Open &Location... File| &Adresse öffnen... Open a remote DjVu document. Öffnet ein entferntes DjVu Dokument an Adresse. &Close File| &Schließen Ctrl+W File|Close Close this window. Schliesst dieses Fenster. &Quit File| &Beenden Ctrl+Q File|Quit Close all windows and quit the application. Schliesst alle Fenster und beendet die Anwendung. Save &as... File| Speichern &unter... Ctrl+S File|SaveAs Save the DjVu document. Speichert das DjVu Dokument. &Export as... File| &Exportieren als ... Ctrl+E File|ExportAs Export DjVu page or document to other formats. Exportiert DjVu-Seite oder Dokument in andere Formate. &Print... File| &Drucken... Ctrl+P File|Print Print the DjVu document. Druckt das DjVu-Dokument. &Find... Edit| &Suchen... Ctrl+F Edit|Find Find text in the document. Sucht Text in dem Dokument. Find &Next Edit| &Weitersuchen Ctrl+F3 Edit|Find Next F3 Edit|Find Next Find next occurence of search text in the document. Zeigt die nächste Fundstelle des Suchtextes im Dokument. Find &Previous Edit| &Rückwärtssuchen Shift+F3 Edit|Find Previous Find previous occurence of search text in the document. Zeigt die vorherige Fundstelle des Suchtextes im Dokument. &Select Edit| &Auswählen Ctrl+F2 Edit|Select F2 Edit|Select Select a rectangle in the document. Selektiert einen rechteckigen Bereich im Dokument. Zoom &In Zoom| h&ineinzoomen Increase the magnification. Erhöht die Vergrößerung. Zoom &Out Zoom| h&erauszoomen Decrease the magnification. Reduziert die Vergrößerung. Fit &Width Zoom| An Seiten&breite anpassen Set magnification to fit page width. Passt die Vergrößerung an die Seitenbreite an. Fit &Page Zoom| An &Seite anpassen Set magnification to fit page. Passt die Vergrößerung an die Seite an. One &to one Zoom| Eins zu ei&ns Set full resolution magnification. Stellt die maximale Vergrösserung ein. &300% Zoom| Magnify 300% 300%ige Vergrösserung &200% Zoom| Magnify 20% 20%ige Vergrösserung &150% 150% Zoom| &150% Magnify 150% 150%ige Vergrösserung &100% Zoom| Magnify 100% 100%ige Vergrösserung &75% Zoom| Magnify 75% 75%ige Vergrösserung &50% Zoom| Magnify 50% 50%ige Vergrösserung &First Page Go| &Erste Seite Jump to first document page. Springt zur erste Seite im Dokument. &Next Page Go| &Nächste Seite Jump to next document page. Springt zur nächsten Seite im Dokument. &Previous Page Go| V&orherige Seite Jump to previous document page. Springt zur vorherigen Seite im Dokument. &Last Page Go| &Letzte Seite Jump to last document page. Springt zur letzten Seite im Dokument. &Backward Go| &Zurück Backward in history. Zurück in der Historie. &Forward Go| &Vorwärts Forward in history. Vorwärts in der Historie. Rotate &Left Rotate| Drehe nach &links Rotate page image counter-clockwise. Dreht die Abbildung der Seiten gegen den Uhrzeigersinn . Rotate &Right Rotate| Drehe nach &rechts Rotate page image clockwise. Dreht die Abbildung der Seiten im Uhrzeigersinn . Rotate &0° Rotate| Drehe um &0° Set natural page orientation. Keine Drehung. Rotate &90° Rotate| Drehe um &90° Turn page on its left side. Dreht die Abbildung der Seiten auf ihre linke Kante. Rotate &180° Rotate| Drehe um &180° Turn page upside-down. Dreht die Abbildung der Seiten auf die obere Kante. Rotate &270° Rotate| Drehe um &270° Turn page on its right side. Dreht die Abbildung der Seiten auf ihre rechte Kante. &Information... Edit| &Information... Ctrl+I Edit|Information Show information about the document encoding and structure. Zeigt Informationen über die Struktur und die Kodierung des Dokumentes. &Metadata... Edit| &Metadaten... Ctrl+M Edit|Metadata Show the document and page meta data. Zeigt die Metadaten des Dokumentes und der Seite. &About DjView... &Über DjView... Show information about this program. Zeigt Informationen zu diesem Programm an. &Color Display| &Farbe Display everything. Zeige alles. &Stencil Display| &Schablone Only display the document bitonal stencil. Stellt nur die bitonale Schablone/Maske des Dokumentes dar. &Foreground Display| &Vordergrund Only display the foreground layer. Stellt nur die Vordergrundebene des Dokumentes dar. &Background Display| &Hintergrund Only display the background layer. Stellt nur die Hintergrundebene des Dokumentes dar. I&nvert Luminance View| Helligkeit i&nvertieren Invert image luminance while preserving hue. Invertiert die Bildhelligkeit unter Erhaltung der Farbnuancierung. Prefere&nces... Settings| Vorliebe&n... Show the preferences dialog. Zeigt den Dialog mit den Benutzereinstellungen an. Show &Sidebar Settings| Zeige &Seitenleiste Ctrl+F9 Settings|Show sidebar F9 Settings|Show sidebar Show/hide the side bar. Zeige/Verstecke die Seitenleiste. Show &Toolbar Settings| Zeige &Werkzeugleiste Ctrl+F10 Settings|Show toolbar F10 Settings|Show toolbar Show/hide the standard tool bar. Zeige/Verstecke die Werkzeugleiste. Show Stat&usbar Settings| Zeige Stat&usleiste Show/hide the status bar. Zeige/Verstecke die Statusleiste. Ctrl+F11 View|FullScreen F11 View|FullScreen Toggle full screen mode. Schaltet zwischen Vollbild- und Fensterdarstellung um. &Slide Show View| Prä&sentation Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. Wechselt Präsentation und normaler Anzeige. &Continuous Layout| &Kontinuierlich Ctrl+F4 Layout|Continuous F4 Layout|Continuous Toggle continuous layout mode. Schaltet zwischen kontinuierlicher und normaler Darstellung um. Side &by Side Layout| Zwei &Seiten nebeneinander Ctrl+F5 Layout|SideBySide F5 Layout|SideBySide Toggle side-by-side layout mode. Schaltet zwischen ein- und zweiseitiger Darstellung um. &File File| &Datei Open &Recent &Zuletzt benutzte Dokumente &Edit Edit| &Bearbeiten &View View| &Ansicht &Zoom View|Zoom &Maßstab &Rotate View|Rotate D&rehen &Display View|Display &Go Go| &Gehe zu &Settings Settings| &Einstellungen &Help Help| &Hilfe Control Left Mouse Button Steuerung linke Maustaste Right Mouse Button Rechte Maustaste <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>Selektiert einen rechteckigen Bereich.</b><br/>Sobald eine rechteckige Fläche ausgewählt wurde, ermöglicht ein Popup-Menü das Kopieren des entsprechenden Textes oder Bildes. Die Funktionalität dieses Werkzeuges ist auch direkt über die Tastenkombination %1 und die Benutzung der linken Maustaste möglich.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>Maßstab.</b><br/> Zur Auswahl der Vergrößerung der Darstellung des Dokumentes. Zoomstufe 100% stellt das Dokument auf 100 dpi optimal dar. Zoomstufe <tt>An Seitenbreite anpassen</tt> und <tt>An Seitenhöhe anpassen</tt> stellt sicher, daß die Breite bzw. die Höhe mit dem Fenster übereinstimmt. </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>Drehen der Seiten.</b><br/> Bietet die Möglichkeit das Dokument in Hoch- oder Querformat darzustellen. Man kann es auch auf den Kopf stellen.</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Display-Modus.</b><br/> DjVu Bilder bestehen aus einer Hintergrund- und einer Vordergrundebene, die über eine Maske kombiniert werden. Der Display-Modus definiert, welche Ebenen dargestellt werden sollen.</html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Dokument- und Seiteninformationen</b><br> Zeigt Informationen über die Struktur und die Kodierung des Dokumentes oder einer Seite.</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Dokument- und Seitenmetadaten.</b><br> Zeigt einen Dialog zur Darstellung der jeweiligen Metadaten des Dokumentes bzw. der Seite.</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Kontinuierliche Darstellung.</b><br/> Zeigt alle Seiten in einem kontinuierlichem, scrollbaren Fenster an.</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Zwei Seiten nebeneinander.</b><br/> Stellt zwei Seiten nebeneinander dar.</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Seiten Information.</b><br/> Zeigt Informationen über die aktive Seite an: die fortlaufenden Seitennummern, die Seitengröße in Punkten und die Auflösung in Punkte pro Inch. </html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Mauszeiger Information.</b><br/> Zeigt die Position der Maus auf das Koordinatensystem der Seite bezogen an.</html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>Dokumentanzeigegebiet.</b><br/> Dies ist der Hauptdisplaybereich für DjVu-Dokumente. <ul><li>Pfeile und Bild(hoch/runter)tasten um im Dokument zu navigieren.</li><li>Leerzeichen und Rücktaste(BackSpace) um bequem im Dokument zum Lesen.</li><li>Taste <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> zum Zoomen bzw. drehen.</li><li>Linke Maustate zum ziehen der Ebene und zum selektieren von Links.</li><li>%3 zur Anzeige des Kontextmenüs.</li><li>%1 Linke Maustaste zum Selektieren von Text oder Bildern.</li><li>%2 aktiviert das Vergrößerungsglas.</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>Dokumentanzeigegebiet.</b><br/> Dies ist der Hauptdisplaybereich für DjVu-Dokumente. Jedoch muß zuerst noch ein DjVu-Dokument geöffnet werden, um irgendetwas damit anfangen zu können.</html> Option '%1' requires boolean argument. Option '%1' verlangt nach einem boolschen Argument. Illegal value '%2' for option '%1'. Ungültiger Wert '%2' für Option '%1'. Toolbar option '%1' is not implemented. Werkzeugoption '%1' ist nicht implementiert. Toolbar option '%1' is not recognized. Werkzeugoption '%1' ist nicht bekannt. Option '%1' requires a standalone viewer. Option '%1' verlangt ein eigenständiges Anzeigeprogramm. Deprecated option '%1' Abgelehnte Option '%1' Option '%1' is not implemented. Option '%1' ist nicht implementiert. Option '%1' is not recognized. Option '%1' ist nicht bekannt. DjView Cannot open file '%1'. Kann Datei '%1' nicht öffnen. Opening DjVu file Öffne DjVu-Datei Cannot open URL '%1'. Kann die Adresse '%1' nicht öffnen. Opening DjVu document Öffne DjVu-Dokument Certificate validation error - DjView dialog caption Fehler beim Überprüfen des Zertifikates - DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Sind Sie sich des Risikos bewußt und wollen dennoch fortfahren? </html> Cannot find page numbered: %1 Seite mit Seitennummer %1 nicht gefunden Cannot find page named: %1 Seite mit dem Namen '%1' nicht gefunden Unrecognized sidebar options '%1'. Option '%1' nicht bekannt. <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html> Diese Datei enthält Einschränkungen beim Drucken. Wollen Sie dennoch drucken?</html> <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html> Diese Datei enthält Einschränkungen beim Speichern. Wollen Sie dennoch speichern?</html> Print - DjView dialog caption Drucke - DjView &Full Screen View| V&ollbild Save - DjView dialog caption Speichern - DjView Export - DjView dialog caption Export - DjView Text files save filter Textdateien All files save filter alle Dateien Save Text - DjView dialog caption Speichere Text - DjView Error - DjView dialog caption Fehler - DjView Cannot write file '%1'. %2. Kann Datei '%1' nicht schreiben: %2. %1 files (*.%2);; save image filter %1 Dateien (*.%2);; Save Image - DjView dialog caption Speichere Bild - DjView Cannot determine file format. Filename '%1' has no suffix. Kann das Dateiformat nicht feststellen. Dateiname '%1' hat keine Endung. Image format %1 not supported. Bildformat %1 nicht unterstützt. Cannot decode page %1. Kann Seite %1 nicht dekodieren. Cannot decode document. Kann Dokument nicht dekodieren. Decoding DjVu document Dekodiere DjVu-Dokument x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: %n pages forward. Gehe %n Seite vorwärts. Gehe %n Seite vorwärts. Go: %n pages backward. Gehe %n Seite zurück. Gehe %n Seite zurück. Go: page %1. Gehe zu Seite %1. Go: %1 Link: %1 Gehe zu %1 (in other window.) (im anderen Fenster.) Cannot resolve link '%1' Kann den Link '%1' nicht auflösen Cannot spawn a browser for url '%1' Kann keinen Browser für Adresse '%1' starten Copy text (%1) Kopiere Text (%1) Save text as... Speichere Text als... Copy image (%1x%2 pixels) Kopiere Bild (%1x%2 Pixel) Save image as... Speichere Bild als... Zoom to rectangle Zoom das Recheck About DjView Über DjView Open - DjView dialog caption Öffne - DjView DjVu files DjVu Dateien Open Location - DjView dialog caption Öffne Adresse - DjView Enter the URL of a DjVu document: Adresse des DjVu-Dokumentes eingeben: Information - DjView dialog caption Metadata - DjView dialog caption Metadaten - DjView &Clear History &Historie löschen cannot open '%1'. kann '%1' nicht öffnen. %n characters %n Zeichen %n Zeichen Go: 1 page forward. Gehe 1 Seite vorwärts. Go: 1 page backward. Gehe 1 Seite zurück. Copy &URL Edit| Kopiere A&dresse Save an URL for the current page into the clipboard. Lege eine Adresse der aktuellen Seite in die Zwischenablage. Copy &Outline Edit| Kopiere &Inhalt Copy &Annotations Edit| Kopiere An&merkungen <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>Im Dokument navigieren.</b><br/> Mit Hilfe der Seitenauswahl kann man zu jeder Seite des Dokumentes springen. Das Drücken der Navigationsknöpfe springt zur ersten, vorheriegen, nächsten oder letzten Seite. </html> Thumbnails Vorschaubilder Outline Inhalt Find Suchen P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi Copy text into the clipboard. Kopiere Text in die Zwischenablage. Save text into a file. Speichere Text in eine Datei. Save image into a file. Speichere Bild in eine Datei. Zoom the selection to fit the window. Passt die Größe des Fensters an. Copy URL Kopiere Adresse Save into the clipboard an URL that highlights the selection. Lege eine Adresse der aktuellen Selektion in die Zwischenablage. Copy Maparea Kopiere Maparea Save into the clipboard a maparea annotation expression for program djvused. Lege eine 'maparea' Anmerkung für djvused in die Zwischenablage. Ctrl+C Edit|CopyURL Strg+C Save the djvused code for the outline into the clipboard. Lege die Outline als Skript für djvused in der Zwischenablage. Save the djvused code for the page annotations into the clipboard. Lege die Anmerkungen einer Seite als Skript für djvused in der Zwischenablage. Copy image into the clipboard. Kopiere Bild in die Zwischenablage. Co&ver Page Layout| Erste S&eite einzeln Ctrl+F6 Layout|CoverPage Strg+F6 F6 Layout|CoverPage Show the cover page alone in side-by-side mode. Zeigt die erste Seite einzeln wenn 'zwei Seiten nebeneinander' ausgewählt ist. &Right to Left Layout| Rechts nach &Links Ctrl+Shift+F6 Layout|RightToLeft Strg+Shift+F6 Shift+F6 Layout|RightToLeft Show pages right-to-left in side-by-side mode. Zeigt die Seiten von links nach rechts in zweiseitiger Darstellung. <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> All files Alle Dateien &Hidden Text Display| &Verborgener Text Overlay a representation of the hidden text layer. Überlagert die Darstellung der verborgenen Textschicht. Hidden Text modeCombo Verborgener Text QDjViewApplication Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. Anwendung: djview [Optionen] [Dateiname-oder-Url] Optionen sind: -help~~~Zeigt diesen Text an. -verbose~~~Erhöht die Gesprächigkeit des Programms. -display <xdpy>~~~Angabe des X11 Bildschrim <xdpy>.. -geometry <xgeom>~~~Angabe der Größe des Fensters beim Starten. -font <xlfd>~~~Angabe des X11 Namens der Hauptschriftart. -style <qtstyle>~~~Angabe des Qt-Styles für die Fensterdekoration. -fullscreen, -fs~~~Startet djview im Vollbildmodus. -page=<page>~~~Springt zu Seite <page>. -zoom=<zoom>~~~Setzt den Zoomfaktor. -continuous=<yn>~~~Setzt den koninuerlichen Modus. -sidebyside=<yn>~~~Setzt die zwei Seiten Ansicht. cannot open '%1'. kann '%1' nicht öffnen. QDjViewAuthDialog Password: Passwort: User: Benutzer: Authentication required - DjView Authentifizierung erforderlich - DjView QDjViewDjVuExporter DjVu Bundled Document DjVu Bundled-Dokument DjVu Files (*.djvu *.djv) DjVu Dateien (*.djvu *.djv) DjVu Indirect Document DjVu Indirect-Dokument Question - DjView dialog caption Frage - DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> Diese Datei liegt in einem nicht leeren Verzeichnis. Das Speichern eines Indirekt-Dokumentes erzeugt viele Dateien in diesem Verzeichnis. Wollen Sie fortfahren und das Risiko eingehen, dass andere Dateien in diesem Verzeichnis überschrieben werden?</html> Con&tinue &Weiter &Cancel &Abbrechen Unknown error. Unbekannter Fehler. System error: %1. Systemfehler: %1. Save job creation failed! Die Erzeugung des Threads zum Speichern ist gescheitert! QDjViewErrorDialog DjView Error DjView Fehler &Ok &Ok Error - DjView dialog caption Fehler - DjView QDjViewExportDialog Dialog Export &Document &Dokument C&urrent page &Aktuelle Seite &Pages &Seiten to bis Destination Ziel Format: Format: &Defaults &Defaults &Ok &Cancel &Abbrechen Stop Beenden <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>Speichern.</b><br/>Das ganze Dokument oder eine Auswahl an Seiten kann in verschiedenen Formaten gespeichert werden. Die Auswahl bestimmter Formate generiert zusätzliche Dialogseiten im Bedienfeld.</html> Error - DjView dialog caption Fehler - DjView Overwriting the current file is not allowed! Die aktuelle Datei darf nicht überschrieben werden! Question - DjView dialog caption Frage - DjView A file with this name already exists. Do you want to replace it? Eine Datei mit diesem Namen existiert bereits. Soll die Datei überschrieben werden? &Replace &Ersetzen This operation has failed. Diese Operation ist gescheitert. This operation has been interrupted. Diese Operation wurde unterbrochen. All files save filter Alle Dateien Export - DjView dialog caption QDjViewExportPS1 Form Formular Color Farbe &Color &Farbe &GrayScale &Graustufe Marks Marken Print image &frame Drucke Bild&rahmen Print crop &marks Drucke Falt&marken PostScript Language Level QDjViewExportPS2 Form Formular Scaling Skalierung Scale to &fit the page Passe das &Bild an die Seite an &Zoom % Orientation Orientierung Automatic Automatisch &Portrait &Hochformat &Landscape &Querformat QDjViewExportPS3 Form Formular Print sheets suitable for folding a booklet. Drucke die Seiten so, dass sie zu einer Broschüre gefaltet werden können. Advanced Erweitert Sheets per booklet: Seiten pro Broschüre: Unlimited Unbegrenzt at most höchstens Print Drucke rectos and versos. Vorder- und Rückseiten. rectos only. nur Vorderseiten. versos only. nur Rückseiten. Shift rectos and versos by Shifte Vorder- und Rückseiten um points. Punkte. Center: Zentriert: points Punkte plus plus /100 per page. pro Seite. QDjViewExportPrn Form Formular Color Farbe &Color &Farbe &GrayScale &Graustufe Marks Marken Print image &frame Drucke &Bildrahmen Print crop &marks Drucke Falt&marken Scaling Skalierung Scale to &fit the page Passe das &Bild an die Seite an &Zoom &Maßstab % Orientation Orientierung Automatic Automatisch &Portrait &Hochformat &Landscape &Querformat QDjViewExportTiff Form Formular Resolution Auflösung Maximum image resolution Maximale Auflösung des Bildes dpi Compression Komprimierung Force &bitonal G4 compression. Erzwinge &bitonal G4 Komprimierung. Allow &lossy JPEG compression. Erlaube &verlustbehaftete JPEG Komprimierung. JPEG &quality JPEG &Qualität Allow &deflate compression. Erlaube &bereinigte Komprimierung. QDjViewFind Case sensitive Groß- und Kleinschreibung beachten Words only Nur ganze Wörter Find Previous (Shift+F3) Rückwärts suchen (Shift+F3) Find Next (F3) Weitersuchen (F3) Options Optionen <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>Text Suchen.</b><br/> Die Treffer der Suche werden sofort angezeigt. Durch drücken der Retruntaste gelangt man zum nächsten Treffer. Zum Navigieren können ebenfalls die Pfeiltasten, bzw <tt>F3</tt> und <tt>Shift-F3</tt> genutzt werden. Ein Doppelklick auf dem Seitennamen würde auch funktionieren. Mit Hilfe der Optionen können die Suchparameter angepasst werden.</html> Regular expression Regulärer Ausdruck Reset search options to default values. Setzt die Optionen der Suche auf ihre Standardwerte. Specify whether search hits must begin on a word boundary. Lässt Sucherfolge an einer Wortgrenze beginnen. Specify whether searches are case sensitive. Sucht ohne Unterscheidung der Groß-und Kleinschreibung. Regular expressions describe complex string matching patterns. Reguläre Ausdrücke beschreiben komplizierte Textsuchmuster. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Reguläre Ausdrücke Kurz Anleitung</b><ul><li>Der Punkt <tt>.</tt> trifft jedes Zeichen.</li><li>Die meisten Zeichen treffen sich selbst.</li><li>Ein vorausgestellter Backslash <tt>\</tt> ermöglicht die Eingabe<br>der Spezialzeichen <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> trifft die Wortbegrenzung.</li><li><tt>\w</tt> trifft ein Wortzeichen.</li><li><tt>\d</tt> trifft das Zeichen einer Zahl.</li><li><tt>\s</tt> triff ein leeres Zeichen.</li><li><tt>\n</tt> trifft das Zeilenumbruchszeichen.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> trifft Zeichen in einem Bereich <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> trifft Zeichen ausserhalb des Bereichs <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> trifft entweder den regulären Ausdruck <tt><i>a</i></tt> oder regulären Ausdruck <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> trifft wiederholt den <tt><i>a</i></tt> regulären Ausdruck <tt><i>n</i></tt> bis <tt><i>m</i></tt> mal.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt> und <tt><i>a</i>+</tt> sind Kurzschreibweisen für <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt> und <tt><i>a</i>{1,}</tt>.</li><li>Verwende runde Klammern <tt>()</tt> zum Gruppieren von regulären<br> Ausdrücken vor <tt>?+*{</tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 Treffer Page %1 (1 hit) Seite %1 (1 Treffer) Searching page %1 (waiting for data.) Durchsuche Seite %1 (warte auf Daten.) Searching page %1. Durchsuche Seite %1. No hits! Keine Treffer! <html>Document is not searchable. No page contains information about its textual content.</html> <html>Dokument ist nicht durchsuchbar. Keine Seite enthält Informationen über seinen textlichen Inhalt.</html> %n hits %n Treffer %n Treffer Page %1 (%n hits) Seite %1 (%n Treffer) Seite %1 (%n Treffer) <html>Invalid regular expression.</html> <html>Ungültiger regulärer Ausdruck.</html> QDjViewImgExporter %1 Image JPG Image %1 Bild %1 Files (*.%2) JPG Files %1 Dateien (*.%2) Cannot render page. Kann die Seite nicht Rendern. Image format %1 not supported. Das Bildformat %1 ist nicht unterstützt. QDjViewInfoDialog Dialog &Document &Dokument &File &Datei File: Datei: &View Page &Zeige Seite &Close &Schließen File # Datei # File Name Dateiname File Size Dateigröße File Type Dateityp Page # Seite # Page Title Titel der Seite <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Dokument Informationen</b><br>Diese Seite zeigt Informationen über das Dokument und seine abhängigen Dateien. Die Detailinformationen zu der jeweils ausgewählten Datei findet man im <tt>Datei</tt> tab. Durch einen Doppelklick wird die jeweilige Seite im Hauptfenster dargestellt. </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Datei- und Seiteninformation</b><br>Diese Übersicht zeigt die Struktur der DjVu-Daten und der jeweiliges ausgewälten Dateien. Mit den Pfeiltasten kann man zwischen den einzelnen Dateien hin- und herspringen.</html> Waiting for data... Warte auf Daten... Page #%1 - « %2 » Seite #%1 - « %2 » Page #%1 Seite #%1 Thumbnails Vorschaubilder Shared annotations Verteilte Anmerkungen Shared data Verteilte Daten File #%1 - Datei #%1 - Single DjVu page Einzelne DjVu-Seite Bundled DjVu document Bundled DjVu-Dokument Indirect DjVu document Indirect DjVu-Dokument Obsolete bundled DjVu document Veraltetes bundled DjVu-Dokument Obsolete indexed DjVu document Veraltetes indexed DjVu-Dokument n/a n/a Page Seite Thumbnails Vorschaubilder Shared Verteilt 1 file 1 Datei %n files %n Datei %n Dateien 1 page 1 Seite %n pages %n Seite %n Seite QDjViewMetaDialog Dialog Dialog &Document Metadata &Dokumentmetadaten &Page Metadata &Seitenmetadaten Page: Seite: &View Page &Zeige Seite &Close &Schließen Ctrl+C copy Strg+C Key Taste Value Wert <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Dokumentmetadaten</b><br>Diese Ansicht zeigt die Metadaten des Dokumentes. Hierzu zählen author, title, references, etc. Die Informationen können mit Hilfe des Programms <tt>djvused</tt> gespeichert werden: Folgende Kommandos können dazu verwendet werden: <tt>create-shared-ant</tt> und <tt>set-meta</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Seitenmetadaten</b><br>Diese Ansicht zeigt die Metadaten einer einzelnen Seite. Die Seitenmetadaten überschreiben die Dokumentenmetadaten. Die Informationen können mit Hilfe des Programms <tt>djvused</tt> gespeichert werden: Folgende Kommandos können dazu verwendet werden: <tt>select</tt> und <tt>set-meta</tt>.</html> QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>Inhaltsverzeichnis.</b><br/> Hier wird das Inhaltsverzeichnis des Dokumentes angezeigt. Sollte kein Inhaltsverzeichnis verfügbar sein, so werden die Seitennamen angezeigt. Ein Doppelklick springt zur jeweiligen Seite.</html> Outline data is corrupted Das Inhaltsverzeichnis ist defekt Pages Seiten Page %1 Seite %1 Go: page %1. Go: page %1 Gehe zu Seite %1. Go: %1 Go: %1. Gehe zu %1 QDjViewPSExporter PostScript PostScript Files (*.ps *.eps) PostScript Dateien (*.ps *.eps) Encapsulated PostScript PostScript tab caption Position tab caption Booklet tab caption Broschüre <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>PostScript Optionen.</b><br>Die Option <tt>Farbe</tt> schaltet den Farbdruck ein. Die Seiten eines Dokumentes können von einem Rahmen umfasst werden. Zoomfaktor <tt>100%</tt> entspricht der Originalgröße des Dokumentes. Orientatierung <tt>Automatisch</tt> wählt zwischen Hoch- und Querformat für die jeweilige Seite aus. PostScript language level 1 sollte nur benutzt werden, wenn das Alter des Druckers es erfordert. Level 2 funktioniert mit den meisten Druckern. Level 3 druckt farbige Dokumente schneller auf neueren Druckern.</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Positionierung und Skalierung.</b><br>Option <tt>an Papierformat anpassen</tt> paßt Dokument an das vom Drucker genutzte Papierformat an. Zoomfaktor <tt>100%</tt> entspricht der Originalgröße des Dokumentes. Orientatierung <tt>Automatisch</tt> wählt zwischen Hoch- und Querformat für die jeweilige Seite aus.</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Broschüren erzeugen.</b><br>Der Broschürenmodus druckt die Seiten so, dass sie gefaltet werden können. Mehrere Broschüren werden erzeugt, wenn eine maximale Anzahl von Seiten pro Broschüre eingestellt wurde. Man kann mit einem Duplexdrucker arbeiten oder die Vor- und Rückseite getrennt ausdrucken.<p> Das Verschieben der Vorder- und Rückseiten ist sinnvoll für schlecht anpassende Duplex-Drucker. Die 'Zentriert' Angabe bestimmt wieviel Platz zwischen den einzelnen Seiten zum Falten bleibt. Dieser Platz nimmt langsam von innen nach aussen zu.</html> Save job creation failed! Die Erzeugung des Threads zum Speichern ist gescheitert! QDjViewPdfExporter PDF Document PDF-Dokument PDF Files (*.pdf) PDF-Dateien (*.pdf) PDF Options tab caption PDF-Optionen <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>PDF Optionen.</b><br>Diese Optionen kontrollieren die Eigenschaften der in die exportierte PDF-Datein eingebetteten Bilder. Das Auflösungsfeld limtiert ihre maximale Auflösung. Schaltet man bitonal G4 Kompression an, so werden alle Seiten in schwarz/weiß mit Hilfe der CCITT Group 4 Komprimierung kodiert. JPEG Komprimierung verwende verlusthafte JPEG Kodierung für alle nicht bitonal oder unterabgetateten Bilder. Deflate Kompression erzeugt kleinere Dateien. </html> Error while creating pdf file. Fehler während der Erzeugung der PDF-Datei. Unable to create output file. Die Ausgabedatei konnte nicht angelegt werden. System error: %1. Systemfehler: %1. Unable to reopen temporary file. Die temporäre Datei kann nicht wieder geöffnet werden. PDF export was not compiled. Der PDF-Export wurde nicht kompiliert. Unable to create temporary file. Die temporäre Daten kann nicht angelegt werden. QDjViewPlugin::Document Requesting %1. Fordere %1 an. QDjViewPrefsDialog Dialog Dialog Gamma Gamma Darker Dunkler Lighter Heller <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>Farbkorrektur des Bildschirms.<br>Der Schieber muss angepasst werden, bis die grauen Flächen ähnlich aussehen.</html> &Interface &Interface Options for Optionen für Standalone Viewer Eigenständiges Programm Full Page Plugin Ganz Seiten Plugin Embedded Plugin Eingebundenes Plugin &Remember initial state from last invocation &Merke den Status des Programms Show Zeige &Menu bar &Menüleiste &Tool bar &Werkzeugleiste Sc&rollbars Stat&us bar Stat&usleiste &Side bar &Seitenleiste Display Anzeige Force inverted luminance Force inverted luminance. Erzwinge eine Invertierung der Helligkeit &Zoom: &Vergrößerung: s secs s Display page &frames Zeige S&eitenrahmen Display &annotations Zeige &Anmerkungen &Keys &Tasten Keys Tasten For displaying hyper&links: Hyper&links anzuzeigen: For &selecting text or images: Text oder &Bilder auswählen: For displaying the &lens: Die &Lupe anzeigen: Mouse wheel Mausrad Mouse wheel scrolls the page Mouse wheel scrolls the page. Mausrad wechselt zur nächsten Seite Mouse wheel changes the zoom factor Mouse wheel changes the zoom factor. Mausrad ändert den Zoomfaktor &Lens &Lupe Enable magnifying &lens Vergrößerungs&lupe verwenden Lens options Lupenoptionen Lens &size: Lupen&größe: Magnifying &power: Vergrösserung&faktor: x pixels Pixel Cache Zwischenspeicher &Clear &Leeren &Decoded page cache: Speicher zum &dekodieren: &Pixel cache: Speicher der &Bildpunkte: &Network &Netzwerk Use pro&xy to access the network Verwende Pro&xy für den Zugriff zum Netzwerk Proxy settings Proxyeinstellungen Pass&word: Pass&wort: &User: &Benutzer: &Port: &Port: &Host: &Host: Timer: Timer: Interface Interface Force language (next time djview runs) Force language (when djview is restarted.) Spracheinstellung erzwingen (erfordert Neustart von djview) Enable page animations Enable animations Aktiviere Seitenanimation Show hidden text in status bar Zeige versteckten Text in der Statusleiste Render with openGL when available Verwende openGL (falls verfügbar) Override saving and printing restrictions Überschreibe Speicher- und Druckeinschränkungen &Defaults &Standardwerte &Apply &Anwenden &Ok &Ok Cancel Abbrechen Preferences[*] - DjView Vorlieben[*] - DjView <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>Einrichtung der Oberfläche beim Starten.</b><br>DjView kann als eigenständiges Programm, im Vollbildmodus, als Ganzseiten-Browserplugin oder als Plugin eingebunden in einer Html-Seite verwendet werden. Jede Anwendungsart hat ihre eigene Konfiguration. <tt>Merke ...</tt> speichert automatisch beim Beenden des Programms die Einstellungen. Ansonsten besteht die Möglichkeit eine Konfiguration fest vorzugeben.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>Modifizierttasten.</b><br>Hier besteht die Möglichkeit einzustellen, welche Modifiziertasten die jeweilige Aktion auslösen.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Vergrößerungsglas.</b><br>Das Vergrößerungsglas erscheint, wenn man die in <tt>Tasten</tt> definierte Taste drückt. Hier kann die Stärke und die Größe der Linse eingestellt werden.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><p><b>Advanced.</b>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>Erweitert.</b><br>Es ist möglich, die Standardsprache zu überschreiben, Seitenanmationen zu deaktivieren oder zusätzliche Menüs zu aktivieren. Diese sind nützlich beim Bearbeiten von DjVu Dateien. Sie können auch Druck- oder Speichereinschränkungen abstellen. Die manuelle Farbkorrektur kann mit alten Druckern sinnvoll sein.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>Netzwerkproxy Einstellungen.</b><br>Diese Einstellungen finden Verwendung, wenn DjView als 'eigenständiges' Programm verwendet wird und Seiten über Html/Url dargestellt werden sollen. Das Plugin verwendet immer die Proxyeinstellungen des verwendeten Browsers. <p><b>Zwischenspeicher.</b><br>Der <i>Cache der Bildpunkte</i> hält die Daten des Bildes ausserhalb des sichtbaren Bereiches. Durch diesen Speicher wird das Verschieben des Bildes flüssiger. Der <i>Speicher zum Dekodieren</i> enthält partiell dekodierte Seiten. Dadurch werden kürzere Antwortzeiten bei der Navigation durch das Dokument erreicht. Das Leeren dieses Speichers ist sinnvoll, um die Daten der Seite neu zu laden, ohne das Programm neu zu starten.</html> Standalone Viewer (Full Screen mode) Eigenständiges Fenster (Vollbild) Standalone Viewer (Slideshow mode) Eigenständiges Programm (Präsentation) <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>Gammakorrektur des Bildschirms.</b><br>Die beste Farbwiedergabe wird durch Anpassen des Gammaschiebers erreicht. Das graue Rechteck sollte dabei möglichst einheitlich erscheinen.<p><b>Bildschirmauflösung.</b><br>Diese Option erzwingt die eingestelle Auflösung, anstelle der unzuverlässigen, die das Betriebssystem unter Umständen mitteilt. 100 dpi ist die Auflösung die die djvulibre-Kommandozeilen-Programme verwenden.</html> &Screen Bild&schirm Force screen &resolution E&rzwinge Bildschirmauflösung dpi dpi &Advanced &Erweitert Miscellaneous Verschiedenes Manual printer color correction Manuelle Farbkorrektur des Druckers gamma= gamma= Enable advanced features in menus Erweiterte Funktionen in Menüs freischalten MB MB Layout Anordnung Continuous Kontinuierlich Side-by-side Zwei Seiten nebeneinander Cover Page Erste Seite einzeln Right-to-Left Rechts nach Links QDjViewPrintDialog Dialog Dialog Print Drucke &Document &Dokument C&urrent page &Aktuelle Seite &Pages &Seiten to bis Destination Ziel Print to file Drucke in Datei Printer name: Druckername: Choose Auswahl &Defaults &Standardwerte &Ok &Ok &Cancel &Abbrechen Stop Beenden <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Drucken.</b><br/>Das Drucken des ganzen Dokumentes oder eine Auswahl von Seiten ist möglich. Durch Drücken des <tt>Auswahl</tt>Buttons kann der Drucker ausgeählt werden.</html> All files save filter Alle Dateien Print To File - DjView dialog caption Drucke in Datei - DjView Question - DjView dialog caption Frage - DjView A file with this name already exists. Do you want to replace it? Eine Datei mit diesem Namen existiert bereits. Soll die Datei überschrieben werden? &Replace &Ersetzen This operation has failed. Diese Operation ist gescheitert. This operation has been interrupted. Diese Operation ist gescheitert. (invalid printer) (ungültiger Drucker) QDjViewPrnExporter Printer data Druckerdaten PRN Files (*.prn) PRN Dateien (*.prn) Printing Options tab caption Druckeinstellungen <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Druckeinstellungen.</b><br>Die Option <tt>Farbe</tt> schaltet den Farbdruck ein. Die Seiten eines Dokumentes können von einem Rahmen umfasst werden. Zoomfaktor <tt>100%</tt> entspricht der Originalgröße des Dokumentes. Orientatierung <tt>Automatisch</tt> wählt zwischen Hoch- und Querformat für die jeweilige Seite aus.</html> Cannot render page %1. Kann Seite %1 nicht darstellen. QDjViewSaveDialog Dialog Save Speichern &Document &Dokument C&urrent page &Aktuelle Seite &Pages &Seiten to bis Destination Ziel Format: Format: Bundled DjVu Document Bundled DjVu-Dokument Indirect DjVu Document Indirect DjVu-Dokument &Ok &Ok &Cancel &Abbrechen Stop Beenden <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>Speichern.</b><br/> Das ganze Dokument oder eine Auswahl an Seiten kann gespeichert werden. Das gebündelte Format generiert eine einzige Datei. Das indirekte Format generiert mehrere Dateien und eignet sich für die Online-Positionierung des Dokumentes.</html> Error - DjView dialog caption Fehler - DjView Overwriting the current file is not allowed! Die aktuelle Datei darf nicht überschrieben werden! Question - DjView dialog caption Frage - DjView A file with this name already exists. Do you want to replace it? Eine Datei mit diesem Namen existiert bereits. Soll die Datei überschrieben werden? &Replace &Ersetzen This operation has failed. Diese Operation ist gescheitert. This operation has been interrupted. Diese Operation wurde unterbrochen. All files save filter Alle Dateien Save - DjView dialog caption Speichern - DjView QDjViewThumbnails Tiny thumbnail menu Mini Small thumbnail menu Klein Medium thumbnail menu Mittel Large thumbnail menu Groß Smart thumbnail menu Elegant Control Left Mouse Button Steuerung linke Maustaste Right Mouse Button Rechte Maustaste <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Vorschaubilder.</b><br/> Hier werden die Vorschaubilder der Seiten des Dokumentes gezeigt. Ein Doppelklick springt zu der jeweiligen Seite. %1 ermöglicht die Einstellung der Größe, bzw. des Aktualisierungsmodus. Der 'Elegant' Modus erzeugt die Vorschaubilder nur, wenn die Daten der Seite vorhanden sind (angezeigt oder im Zwischenspeicher.)</html> QDjViewTiffExporter TIFF Document TIFF Dokument TIFF Files (*.tiff *.tif) TIFF Dateien (*.tiff *.tif) TIFF Options tab caption TIFF Optionen <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>TIFF Optionen.</b><br>Das Auflösungsfeld limtiert ihre maximale Auflösung. Schaltet man bitonal G4 Kompression an, so werden alle Seiten in schwarz/weiß mit Hilfe der CCITT Group 4 Komprimierung kodiert. JPEG Komprimierung verwendet verlusthafte JPEG Kodierung für alle nicht bitonal oder unterabgetateten Bilder. Deflate Kompression erzeugt kleinere Dateien. </html> Cannot open output file. Kann die Ausgabedatei nicht öffnen. Out of memory. Zuwenig Speicher. Internal error. Interner Fehler. TIFF export has not been compiled. Der TIFF-Export wurde nicht kompiliert. QDjVuNetDocument Requesting '%1' Fordere %1 an QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code Habe den http-status %1 erhalten bei der Anforderung von %2. Received <%1> data while retrieving %2. %1 is a mime type Habe %1 Daten von %2 erhalten. %1 while retrieving '%2'. %1 der Anfrage von '%2'. Cannot validate the certificate for server %1. Kann das Zertifikat von %1 nicht überprüfen. Authentication required for %1 (%2). Authentifizierung benötigt für %1 (%2). Authentication required for proxy %1. Authentifizierung benötigt für Proxy %1. djview4-4.10.5/src/djview_es.ts000066400000000000000000004617741264256014000163160ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language Español QApplication Option '-fix' is deprecated. Opción '-fix' en desuso. QDjView cannot open '%1'. No se puede abrir %1''. FitWidth zoomCombo Ajustar ancho FitPage zoomCombo Ajustar página Stretch zoomCombo Ajustar a la ventana 1:1 zoomCombo 1:1 300% zoomCombo 300% 200% zoomCombo 200% 150% zoomCombo 150% 100% zoomCombo 100% 75% zoomCombo 75% 50% zoomCombo 50% Color modeCombo Color Stencil modeCombo Esténcil Foreground modeCombo Frente Background modeCombo Fondo Hidden Text modeCombo Texto Oculto &New File| &Nuevo Ctrl+N File|New Ctrl+N Create a new DjView window. Crear nueva ventana Djview. &Open File| &Abrir Ctrl+O File|Open Ctrl+O Open a DjVu document. Abrir documento DjVu. Open &Location... File| Abrir &URL... Open a remote DjVu document. Abrir documento DjVu remoto. &Close File| &Cerrar Ctrl+W File|Close Ctrl+W Close this window. Cerrar esta ventana. &Quit File| &Salir Ctrl+Q File|Quit Ctrl+Q Close all windows and quit the application. Cerrar todas las ventanas y la aplicación. Save &as... File| Guardar &como... Ctrl+S File|SaveAs Ctrl+S Save the DjVu document. Guardar documento DjVu. &Export as... File| &Exportar como... Ctrl+E File|ExportAs Ctrl+E Export DjVu page or document to other formats. Exportar página DjVu o documento a otros formatos. &Print... File| &Imprimir... Ctrl+P File|Print Ctrl+P Print the DjVu document. Imprimir documento DjVu. &Find... Edit| &Buscar... Ctrl+F Edit|Find Ctrl+F Find text in the document. Buscar texto en el documento. Find &Next Edit| Buscar &Siguiente Ctrl+F3 Edit|Find Next Ctrl+F3 F3 Edit|Find Next F3 Find next occurence of search text in the document. Buscar siguiente ocurrencia de texto en la búsqueda del documento. Find &Previous Edit| Buscar &Anterior Shift+F3 Edit|Find Previous Shift+F3 Find previous occurence of search text in the document. Buscar anterior ocurrencia de texto en la búsqueda del documento. &Select Edit| &Seleccionar Ctrl+F2 Edit|Select Ctrl+F2 F2 Edit|Select F2 Select a rectangle in the document. Seleccionar un rectángulo en el documento. Zoom &In Zoom| &Ampliar Increase the magnification. Incrementar la ampliación. Zoom &Out Zoom| &Reducir Decrease the magnification. Disminuir la ampliación. Fit &Width Zoom| Ajustar &Ancho Set magnification to fit page width. Ajustar la ampliación al ancho de página. Fit &Page Zoom| Ajustar &Página Set magnification to fit page. Ajustar la ampliación a la página. One &to one Zoom| Uno &a uno Set full resolution magnification. Muestra la página con resolución nativa. &300% Zoom| &300% Magnify 300% Ampliar 300% &200% Zoom| &200% Magnify 20% Ampliar 200% &150% 150% Zoom| &150% Magnify 150% Ampliar 150% &100% Zoom| &100% Magnify 100% Ampliar 100% &75% Zoom| &75% Magnify 75% Ampliar 75% &50% Zoom| &50% Magnify 50% Ampliar 50% &First Page Go| &Página inicial Jump to first document page. Ir a primera página del documento. &Next Page Go| &Página siguiente Jump to next document page. Ir a la siguiente página del documento. &Previous Page Go| &Página anterior Jump to previous document page. Ir a la anterior página del documento. &Last Page Go| &Última página Jump to last document page. Ir a la última página del documento. &Backward Go| &Hacia atras Backward in history. Hacia atrás en historial. &Forward Go| &Hacia adelante Forward in history. Hacia adelante en historial. Rotate &Left Rotate| Girar a la &izquierda Rotate page image counter-clockwise. Girar página en sentido antihorario. Rotate &Right Rotate| Girar a la &derecha Rotate page image clockwise. Girar página en sentido horario. Rotate &0° Rotate| Rotar &0° Set natural page orientation. Ajustar orientación natural. Rotate &90° Rotate| Rotar &90° Turn page on its left side. Girar páagina sobre su lado izquuierdo. Rotate &180° Rotate| Rotar &180° Turn page upside-down. Girar página al revés. Rotate &270° Rotate| Rotar &270° Turn page on its right side. Girar página sobre su lado derecho. &Information... Edit| &Información... Ctrl+I Edit|Information Ctrl+I Show information about the document encoding and structure. Mostrar información acerca de la codificación del documeto y estructura. &Metadata... Edit| &Metadato... Ctrl+M Edit|Metadata Ctrl+M Show the document and page meta data. Mostrar el documento y pagina de metadatos. &About DjView... &Acerca de DjView... Show information about this program. Mostrar información acerca de este programa. &Color Display| &Color Display everything. Visualizar todo. &Stencil Display| &Esténcil Only display the document bitonal stencil. Solamente visualizar el documento esténcil bitonal. &Foreground Display| &Primer plano Only display the foreground layer. Solamente visualizar la capa de primer plano. &Background Display| &Fondo Only display the background layer. Solamente visualizar la capa del fondo. &Hidden Text Display| &Texto oculto Overlay a representation of the hidden text layer. Superponer una representación de capa de texto oculto. I&nvert Luminance View| I&nvertir iluminación Invert image luminance while preserving hue. Inviertir luminancia de imagen, preservando tonalidad. Prefere&nces... Settings| Prefe&rencias... Show the preferences dialog. Mostrar diálogo de preferencias. Show &Sidebar Settings| Mostrar &Barra lateral Ctrl+F9 Settings|Show sidebar Ctrl+F9 F9 Settings|Show sidebar F9 Show/hide the side bar. Mostrar/Ocultar la barra lateral. Show &Toolbar Settings| Mostrar &Barra de herramientas Ctrl+F10 Settings|Show toolbar Ctrl+F10 F10 Settings|Show toolbar F10 Show/hide the standard tool bar. Mostrar/Ocultar barra de herramientas estándar. Show Stat&usbar Settings| Mostrar Barra de est&ado Show/hide the status bar. Mostrar/Ocultar barra de estado. &Full Screen View| P&antalla completa Ctrl+F11 View|FullScreen Ctrl+F11 F11 View|FullScreen F11 Toggle full screen mode. Selección modo pantalla completa. &Slide Show View| &Mostrar Diapositiva Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. Selección modo diapositiva. &Continuous Layout| Desplazamiento &Continuo Ctrl+F4 Layout|Continuous Ctrl+F4 F4 Layout|Continuous F4 Toggle continuous layout mode. Selección modo páginas continuas. Side &by Side Layout| Doble &página Ctrl+F5 Layout|SideBySide Ctrl+F5 F5 Layout|SideBySide F5 Toggle side-by-side layout mode. Selección modo doble página. Co&ver Page Layout| Por&tada Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. Mostrar la portada en modo doble página. &Right to Left Layout| &Derecha a Izquierda Ctrl+Shift+F6 Layout|RightToLeft Ctrl+Shift+F6 Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. Mostrar páginas de derecha a izquierda en modo doble página. Copy &URL Edit| Copiar &URL Save an URL for the current page into the clipboard. Guardar una URL para la página actual en el portapaeles. Ctrl+C Edit|CopyURL Ctrl+C Copy &Outline Edit| Copiar &Esquema Save the djvused code for the outline into the clipboard. Guardar código djvused para el esquema en el portapapeles. Copy &Annotations Edit| Copiar &Anotaciones Save the djvused code for the page annotations into the clipboard. Guardar código djvused para las anotaciones de pagina en el portapapeles. &File File| &Archivo Open &Recent Abrir &Reciente &Edit Edit| &Editar &View View| &Ver &Zoom View|Zoom &Ampliar &Rotate View|Rotate &Rotar &Display View|Display &Visualizar &Go Go| &Ir &Settings Settings| &Ajustes &Help Help| &Ayuda Control Left Mouse Button Control botón izquierdo del Ratón Right Mouse Button Botón Derecho del Ratón <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>Ampliando.</b><br/> Elegir un nivel de ampliación para ver el documento. Un nivel de ampliación del 100% visualiza el documento para una pantalla de 100 dpi. Niveles de ampliación <tt>Ajustar Página</tt> y <tt>Ajustar Ancho</tt> aseguran la página completa o el ancho de página ajustado a la ventana. </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Modo visualización.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. El Modo visualización especifica que capas deben ser visualizadas.</html> <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>Navegando en el documento.</b><br/> El selector de página permite saltar a cualquier página por su nombre y puede ser activado pulsando Ctrl+G. Los botones de navegación saltan a la primera página, la página anterior, la página siguiente, o la última página. </html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Información del documento y página.</b><br> Visulaiza un diálogo para ver la información de codificación pertinente al documento o hacia una página especifica.</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Metadatos del documento y página.</b><br> Visualiza una ventana para ver los metadatos pertinentes del documento o hacia una pagina especifica.</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Desplazamiento continuo.</b><br/> Visualiza todas las páginas del documento en un arreglo vertical como un documento desplazable en el área de visualización.</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Desplazamiento doble página.</b><br/> Visualiza un par de páginas a doble página como un documento desplazable en el área de visualización.</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Información de página.</b><br/> Visualiza información acerca de la página localizada bajo el cursor: el número de secuencia de página, el tamaño de página en pixeles y la resolución de la página en puntos por pulgada. </html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Información del cursor.</b><br/> Visualiza la posición del puntero del ratón expresando las coordenadas en la página. </html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>Ãrea de vista del documento.</b><br/> Esta es la principal área de visualización del documento DjVu. <ul><li>Teclas de flechas y de página para navegar en el documento.</li><li>Espacio and Espacio/hacia-atras para leer el documento.</li><li>Teclas <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> para ampliar o rotar el documento.</li><li>Botón izquierdo del ratón for paneo y selección de enlaces.</li><li>%3 para visualizar el menú contextual.</li><li>%1 Botón izquierdo del ratón para seleccionar texto o imágenes.</li><li>%2 para mostrar la ampliación de la lupa.</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>Ãrea de vista del documento.</b><br/> Esta es la principal área de visualizacion para un documento DjVu. Antes que nada, primero debe abrir un documento DjVu para ver cualquier cosa.</html> Option '%1' requires boolean argument. Opción '%1' requiere argumento booleano. Illegal value '%2' for option '%1'. Valor ilegal '%2' para opción '%1'. Toolbar option '%1' is not implemented. Opción '%1' de la barra de herramientas no implemetado. Toolbar option '%1' is not recognized. Opción '%1' de la barra de herramientas es desconocida. Option '%1' requires a standalone viewer. Opción '%1' requiere visor independiente. Deprecated option '%1' Opción '%1' obsoleta Option '%1' is not implemented. Opción '%1' no implemetado. Option '%1' is not recognized. Opción '%1' es desconocida. DjView DjView Thumbnails Miniaturas Outline Esquema Find Buscar Cannot open file '%1'. Imposible abrir archivo '%1'. Opening DjVu file Abriendo archivo DjVu Cannot open URL '%1'. Imposible abrir URL '%1'. Opening DjVu document Abriendo documento DjVu Certificate validation error - DjView dialog caption Error en el certificado de validación - DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Usted quiere continuar de cualquier modo? </html> Cannot find page numbered: %1 Imposible hallar página enumerada: %1 Cannot find page named: %1 Imposible hallar página nombrada: %1 Unrecognized sidebar options '%1'. Opción '%1' desconocida en el panel lateral. Print - DjView dialog caption Imprimir - DjView <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> Este archivo fue preparado con restricciones de impresión. Usted quiere imprimirlo de todos modos?</html> Save - DjView dialog caption Guardar - DjView <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> Este archivo fue preparado con restricciones de guardado. Usted quiere guardarlo de todos modos?</html> Export - DjView dialog caption Exportar DjView Text files save filter Archivos de texto All files save filter Todos los archivos Save Text - DjView dialog caption Guardar texto - DjView Error - DjView dialog caption Error - DjView Cannot write file '%1'. %2. Imposible escribir archivo '%1'. %2. %1 files (*.%2);; save image filter Archivos %1 (*.%2);; Save Image - DjView dialog caption Guardar Imagen - DjView Cannot determine file format. Filename '%1' has no suffix. Imposible determinar formato de archivo. Nombre de archgivo '%1' no tiene sufijo. Image format %1 not supported. Formato de imagen no soportado en %1. Cannot decode page %1. Imposible decodificar la página %1. Cannot decode document. Imposible decodificar documento. Decoding DjVu document Decodificando documento Djvu P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: 1 page forward. Ir a: 1 página hacia adelante. Go: %n pages forward. Ir a: %n página hacia adelante. Ir a: %n páginas hacia adelante. Go: 1 page backward. Ir a: 1 página hacia atras. Go: %n pages backward. Ir a: %n página hacia atras. Ir a: %n páginas hacia atras. Go: page %1. Ir a: página %1. Go: %1 Ir a: %1 (in other window.) (en otra ventana) Cannot resolve link '%1' Imposible resolver enlace '%1' Cannot spawn a browser for url '%1' Imposible abrir el navegador para la URL '%1' %n characters %n carácter %n caracteres Copy text (%1) Copiar texto (%1) Save text as... Guardar texto como... Copy text into the clipboard. Copiar texto al portapapeles. Save text into a file. Guardar texto dentro del archivo. Copy image (%1x%2 pixels) Copiar imagen (%1x%2 pixeles) Save image as... Guardar imagen como... Copy image into the clipboard. Copiar imagen al portapapeles. Save image into a file. Guardar imagen dentro del archivo. Zoom to rectangle Ampliar este rectángolo Zoom the selection to fit the window. Ampliar la selección para ajustar la ventana. Copy URL Copiar URL Save into the clipboard an URL that highlights the selection. Guardar URL en el portapaeles que resalta la selección. Copy Maparea Copiar Mapa de Imágenes Save into the clipboard a maparea annotation expression for program djvused. Guarddar en el portapapeles una expresión de la anotación de Mapa de Imágenes para el programa djvused. <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>Visor para documentos DjVu<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>Este programa es software libre. Usted puede redistribuirlo o modificarlo bajo los términos de la GNU General Public License publicada por la Free Software Foundation. Este programa es distribuido <i>sin garantía alguna</i>. Ver la GNU General Public License para mayor información.</small></p></html> About DjView Acerca de DjView DjVu files Archivos DjVu All files Todos los archivos Open - DjView dialog caption Abrir - DjView Open Location - DjView dialog caption Abrir URL - DjView Enter the URL of a DjVu document: Ingresar URL de un documento DjVu: Information - DjView dialog caption Información - DjView Metadata - DjView dialog caption Metadatos - DjView &Clear History &Limpiar historial QDjViewApplication cannot open '%1'. No se puede abrir '%1'. Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. Uso: djview [opciones] [archivo-o-url] Opciones comunes incluyen: -help~~~Muestra este mensaje. -verbose~~~Muestra todos los mensajes de advertencia. -display <xdpy>~~~Seleccionar la visualización X11 <xdpy>. -geometry <xgeom>~~~Seleccionar geometría de la ventana inicial. -font <xlfd>~~~Seleccionar nombre de la fuente X11 principal. -style <qtstyle>~~~Seleccionar estilo de la interfaz de usuario Qt. -fullscreen, -fs~~~Iniciar djview en modo pantalla completa. -page=<page>~~~Ir a página <page>. -zoom=<zoom>~~~Ajustar ampliación en un factor <zoom>. -continuous=<yn>~~~Ajustar desplazamiento continuo. -sidebyside=<yn>~~~Ajustar vista de dos páginas. QDjViewAuthDialog Password: Contraseña: User: Usuario: Authentication required - DjView Autenticación requerida - DjView QDjViewDjVuExporter DjVu Bundled Document Documeto DjVu Grapado DjVu Files (*.djvu *.djv) Archivos DjVu (*.djvu *.djv) DjVu Indirect Document Documento DjVu Indirecto Question - DjView dialog caption Pregunta - DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> Este archivo está en un directorio ocupado. Guardar un documento indirecto creara muchos archivos en este directorio. Usted quiere continuar con el riesgo de sobreescribir los archivos de este directorio?</html> Con&tinue Con&tinuar &Cancel &Cancelar Unknown error. Error desconocido. System error: %1. Error de sistema: %1. Save job creation failed! Imposible guardar el trabajo creado! QDjViewErrorDialog DjView Error Error DjView &Ok &Ok Error - DjView dialog caption Error - DjView QDjViewExportDialog Dialog Diálogo Export Exportar &Document &Documento C&urrent page Página a&ctual &Pages &Páginas to a Destination Destino Format: Formato: &Defaults Valores por &Defecto &Ok &Ok &Cancel &Cancelar Stop Detener <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>Guardando.</b><br/> Usted puede guardar el documento entero o un rango de páginas en una variedad de formatos. Seleccionando ciertos formatos creara diálogos adicionales para especificar opciones del formato.</html> Error - DjView dialog caption Error - DjView Overwriting the current file is not allowed! Sobrescritura del archivo actual no está permitido! Question - DjView dialog caption Pregunta - DjView A file with this name already exists. Do you want to replace it? Un archivo con este nombre ya existe. Usted quiere reemplazarlo? &Replace &Reemplazar This operation has failed. Esta operación fallo. This operation has been interrupted. Esta operación fue interrupida. All files save filter Todos los archivos Export - DjView dialog caption Exportar - DjView QDjViewExportPS1 Form Forma Color Color &Color &Color &GrayScale &Escala de grises Marks Marcas Print image &frame Imprimir imagen con &marco Print crop &marks Imprimir marcas de &corte PostScript PostScript Language Level Nivel de Language QDjViewExportPS2 Form Forma Scaling Escalado Scale to &fit the page Escalar para &ajustar imagen &Zoom &Zoom % % Orientation Orientación Automatic Automatica &Portrait &Retrato &Landscape &Paisaje QDjViewExportPS3 Form Forma Print sheets suitable for folding a booklet. Imprime hojas apropiadas para plegar un folleto. Advanced Avanzado Sheets per booklet: Hojas por folleto: Unlimited Ilimitado at most a lo sumo Print Imprimir rectos and versos. delantera y trasera. rectos only. dealtera solamente. versos only. trasera solamente. Shift rectos and versos by Cambiar delantera y trasera por points. puntos. Center: Centro: points puntos plus plus /100 /100 per page. por paginá. QDjViewExportPrn Form Forma Color Color &Color &Color &GrayScale &Escala de grises Marks Marcas Print image &frame Imprimir imagen con &marco Print crop &marks Impimir marcas de &corte Scaling Escalado Scale to &fit the page Escalar para &ajustar imagen &Zoom &Ampliar % % Orientation Orientación Automatic Automatica &Portrait &Retrato &Landscape &Paisaje QDjViewExportTiff Form Forma Resolution Resolución Maximum image resolution Resolución máxima de imagen dpi dpi Compression Compresión Force &bitonal G4 compression. Forzar compresión &bitonal G4. Allow &lossy JPEG compression. Permitir compresión por &pérdida JPEG. JPEG &quality JPEG &calidad Allow &deflate compression. Permitir compresión &deflate. QDjViewFind Case sensitive Distinguir mayúsculas y minúsculas Words only Palabras completas Regular expression Expresión regular Find Previous (Shift+F3) Buscar anterior (Shift+F3) Find Next (F3) Buscar siguiente (F3) Reset search options to default values. Reiniciar opciones de busqueda a valores por defecto. Options Opciones <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>Búsqueda de texto.</b><br/> Búsqueda de coincidencias aparece progresivamente tan pronto se escriba una cadena. Pulsando enter salta a la siguiente coincidencia. Para ir a la anterior o siguiente coincidencia, usted también puede usar los botones con flechas o los atajos <tt>F3</tt> o <tt>Shift-F3</tt>. Usted puede también usar doble click en una página. Use el menú de <tt>Opciones</tt> para buscar palabras completas o especificar distinción entre mayúsculas y minúsculas.</html> Specify whether search hits must begin on a word boundary. Especificar si las coincidencias deben comenzar en un límite de palabra. Specify whether searches are case sensitive. Especificar si la búsqueda debe distinguir entre mayúsculas y minúsculas. Regular expressions describe complex string matching patterns. Expresiones regulares describen complejas cadenas de patrones de coincidencias. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Guía rápida de expresiones regulares</b><ul><li>El punto <tt>.</tt> coincide con cualquier carácteres.</li><li>La mayoría de caracteres coincide consigo mismos.</li><li>Anteponer un backslash <tt>\</tt> coincidará con un carácter especial <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> coincide con un límite de palabra.</li><li><tt>\w</tt> coincide con un carácter de palabra.</li><li><tt>\d</tt> coincide con un carácter de dígito.</li><li><tt>\s</tt> coincide con un carácter en blanco.</li><li><tt>\n</tt> coincide con un carácter de nueva línea.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> coincide con un rango de caracteres <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> coincide con caracteres fuera del rango <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> coincide con cualquier expresión regular <tt><i>a</i></tt> o expresión regular <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> coincide con expresión regular <tt><i>a</i></tt> repetida <tt><i>n</i></tt> a <tt><i>m</i></tt> veces.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, y <tt><i>a</i>+</tt> son abreviaciones para <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, y <tt><i>a</i>{1,}</tt>.</li><li>Use paréntesis <tt>()</tt> para agrupar expresiones regular antes de <tt>?+*{</tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 coincidencia %n hits %n coincidencia %n coincidencias Page %1 (1 hit) Página %1 (1 coincidencia) Page %1 (%n hits) Página %1 (%n coincidencia) Página %1 (%n coincidencias) Searching page %1 (waiting for data.) Buscando en página %1 (esperando datos) Searching page %1. Buscando en página %1. No hits! No hay coincidencias! <html>Document is not searchable. No page contains information about its textual content.</html> <html>Documento sin texto para buscar. La página no contiene información sobre su contenido textual.</html> <html>Invalid regular expression.</html> <html>Expresión regular invalida.</html> QDjViewImgExporter %1 Image JPG Image %1 imagen %1 Files (*.%2) JPG Files %1 Archivos (*.%2) Cannot render page. Imposible renderizar la página. Image format %1 not supported. Formato de imagen %1 no soportado. QDjViewInfoDialog Dialog &Document &Documento &File &Archivo File: Archivo: &View Page &Ver Página &Close &Cerrar File # Archivo # File Name Nombre de archivo File Size Tamaño de archivo File Type Tipo de archivo Page # Página # Page Title Titulo Página <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Información del documento</b><br>Este panel muestra información acerca del documento y sus componentes. Seleccionar un componente mostrara información detallada en la pestaña <tt>Archivo</tt>. Doble click en un componente mostrara la correspondiente página en la ventana principal. </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Información de Archivo y página</b><br>Este panel muestra la estructura de datos DjVu correspondientes al componente o la página seleccionada en la pestaña <tt>Documento</tt>. Los botones de flecha permiten saltar al anterior o siguiente componente del archivo.</html> Waiting for data... Esperando datos... Page #%1 - « %2 » Página #%1 - « %2 » Page #%1 Página #%1 Thumbnails Miniaturas Shared annotations Compartir anotaciones Shared data Compartir datos File #%1 - Archivo #%1 - Single DjVu page Página DjVu Sencilla Bundled DjVu document Documento DjVu Grapado Indirect DjVu document Documento DjVu Indirecto Obsolete bundled DjVu document Documento DjVu con obsoleto grapado Obsolete indexed DjVu document Documento DjVu con índice obsoleto 1 file 1 archivo %n files %n archivo %n archivos 1 page 1 página %n pages %n página %n páginas n/a n/a Page Página Thumbnails Miniatura Shared Compartido QDjViewMetaDialog Dialog Diálogo &Document Metadata Metadatos del &Documento &Page Metadata Metadatos de la &Página Page: Página: &View Page &Ver Página &Close &Cerrar Ctrl+C copy Ctrl+C Key Clave Value Valor <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Metadatos del Documento</b><br>Este panel muestra metadatos pertenecientes al documento, tales como autor, titulo, referencias, etc. Esta información puede ser guardada dentro del documento con el programa <tt>djvused</tt>: use los comandos <tt>create-shared-ant</tt> ay <tt>set-meta</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Metadatos de la Pagína</b><br>Este panel muestra metadatos pertenecientes a una página especifica. Metadatos especificos de una página anulas los metadatos del documento. Esta información puede ser guardada dentro del documento con el programa <tt>djvused</tt>: use el comando <tt>select</tt> para seleccionar la página y el comando <tt>set-meta</tt> para especificar las entradas del metadato.</html> QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>Esquema del documento.</b><br/> Este panel muestra el esquema del documento, o los nombres de las páginas cuando no está disponible, un doble click en cualquier entrada mostrara la página selecionada.</html> Outline data is corrupted Datos del esquema están corruptos Pages Páginas Page %1 Página %1 Go: page %1. Ir a página: %1. Go: %1 Ir a: %1 QDjViewPSExporter PostScript PostScript PostScript Files (*.ps *.eps) Archivos PostScript (*.ps *.eps) Encapsulated PostScript Encapsulado PostScript PostScript tab caption PostScript Position tab caption Posición Booklet tab caption Folleto <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>Opciones PostScript.</b><br>Opción <tt>Color</tt> permite impresión a color. Páginas del documento pueden decorarse con un marco y marcas de corte. Lenguaje postscript nivel 1 es solamente útil con impresoras obsoletas. Nivel 2 trabaja con varias impresoras. Nivel 3 imprime documentos a color de forma rápida en impresoras recientes.</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Posición y ampliación.</b><br>Opción <tt>Ajuste de escala</tt> acommoda el tamaño del papel al usado por la impresora. Factor zoom <tt>100%</tt> reproduce el tamaño inicial del documento. Orientación <tt>Automatica</tt> elige vertical u horizontal en función de cada página.</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Produciendo folletos.</b><br>El modo folleto imprime páginas seleciondas para plegar uno o varios folletos. Varios folletos podrían producirse cuando el número máximo de hojas por folleto es especificado. Puede usar una impresora dúplex o imprimir partes delantera y trasera separadamente.<p> Cambiar a impresión por partes es útil con impresoras dúplex pobremente alineadas. Las márgenes centrales determinan que tanto espacio queda entre las páginas para doblar las hojas. Este espacio se incrementa lentamente desde el interior de la hoja hacia el exterior.</html> Save job creation failed! Imposible guardar el trabajo creado! QDjViewPdfExporter PDF Document Documento PDF PDF Files (*.pdf) Archivos PDF (*.pdf) PDF Options tab caption Opciones PDF <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>Opciones PDF.</b><br>Estas opciones controlan las caracterísiticas de las imágenes incrustadas en los archivos PDF exportados. La caja de resolución limita su máximo valor. Forzando compresión G4 bitonal, codifica todas las páginas en blanco y negro usando la compresión CCITT Group 4. Permitiendo compresión JPEG se usa pérdida JPEG para todas las imágenes no-bitonal o submuestreadas. De otro lado, permitiendo compresión deflate se producen archivos más compactos. </html> Error while creating pdf file. Error en la creación de archivo pdf. Unable to create output file. Imposible crear archivo de salida. System error: %1. Error de sistema: %1. Unable to reopen temporary file. Imposible reabrir archivo temporal. PDF export was not compiled. Exportación de archivos PDF no fue compilado. Unable to create temporary file. Imposible crear archivo temporal. QDjViewPlugin::Document Requesting %1. Solicitando %1. QDjViewPrefsDialog Dialog Diálogo &Screen &Pantalla Gamma Gamma <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>Corrección de color.<br>Ajustar hasta que los grises sean similares.</html> Darker Oscuro Lighter Claro Display Visualización Force screen &resolution Forzar &resolución de pantalla dpi dpi Force inverted luminance Forzar iluminación invertida &Interface &Interfaz Options for Opciones para Standalone Viewer Visor independiente Full Page Plugin Plugin página completa Embedded Plugin Plugin incrustado &Remember initial state from last invocation &Recordar estado inicial desde la última sesión Show Mostrar &Menu bar &Barra menú &Tool bar &Barra de herramientas Sc&rollbars Barra de &desplazamiento Stat&us bar Barra &estado &Side bar &Barra lateral &Zoom: &Ampliar: Timer: Avanzar cada: s secs s Display page &frames Visualizar &marcos de página Display &annotations Visualizar &anotaciones Layout Desplazamiento Continuous Continuo Side-by-side Doble página Cover Page Portada Right-to-Left Derecha a Izquierda &Keys &Teclas Keys Teclas For displaying hyper&links: Para visualizar hiper&enlaces: For &selecting text or images: Para &seleccionar textos o imágenes: For displaying the &lens: Para visualizar la &lupa: Mouse wheel Rueda del ratón Mouse wheel scrolls the page Desplazar página con la rueda del ratón Mouse wheel changes the zoom factor Ampliación cambia con la rueda del ratón &Lens &Lupa Enable magnifying &lens Permitir ampliación de la &lupa Lens options Opciones de la lupa Lens &size: Tamaño &ampliación: Magnifying &power: &Ampliación: x pixels pixeles &Network &Red Proxy settings Configuración Proxy Use pro&xy to access the network Usar pro&xy para acceder a la red &Host: &Host: &Port: &Puerto: &User: &Usuario: Pass&word: Contra&seña: Cache Cache &Clear &Limpiar MB MB &Decoded page cache: Cache de páginas &decodificadas: &Pixel cache: Cache de &pixeles: &Advanced Opciones &avanzadas Interface Interfaz Force language (next time djview runs) Usar lenguaje (es necesario reiniciar) Enable page animations Permitir animaciones Enable advanced features in menus Permitir funciones avanzadas en los menús Show hidden text in status bar Mostrar texto oculto en la barra de estado Miscellaneous Miscelánea Render with openGL when available Renderizar con openGL cuando sea posible Override saving and printing restrictions Anular restricciones de guardar e impresión Manual printer color correction Corrección manual impresión a color gamma= gamma= &Defaults Por &defecto &Apply &Aplicar &Ok &Ok Cancel Cancelar Preferences[*] - DjView Preferencias[*] - DjView <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>Corrección de gamma.</b><br>El mejor color de presentación se logra ajustando el deslizador y eligiendo la escala de grises lo más uniforme posible.<p><b>Resolución de pantalla.</b><br>Con esta opción se obtiene una resolución particular en lugar de usar la resolución adoptada por el sistema operativo. Forzar una resolución 100 dpi, coincide con el comportamiento de las herramientas de línea de comandos de djvulibre.</html> <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>Configuración de interfaz inicial.</b><br>DjView puede ejecutarse como un visor independiente, o como un visor de pantalla completa, o como un plugin navegador de página completa o como un plugin embebido al interior de una página html. Para cualquier caso, verificar la caja <tt>Recordar</tt> para automáticamente guardar y restaurar la configuración de la interfaz. De otra forma, especificar una configuración inicial.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>Modificar teclas.</b><br>Define qué combinación de teclas modificaran el comportamiento de la lupa de ampliación, permitir temporalmente el modo de selección, o el resaltado de los enlaces.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Ampliación de la lupa.</b><br>La ampliación de la lupa aparece cuando usted pulsa la tecla modificadora especificada en la pestaña <tt>Teclas</tt>. En este panel, usted puede elegir el tamaño de ampliación para la lupa.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>Opciones avanzadas.</b><br>Usted puede cambiar el lenguaje, anular página de animaciones, o permitir entradas adicionales en los menús, útiles para la edición de archivos DjVu. Usted también puede modificar las restricciones para el guardado e impresión habilitados por ciertos sitios web. La corrección manual de color es útil para impresoras antiguas.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>Configuración del proxy de la red.</b><br>La configuración del proxy es usada cuando el visor DjView accede a un documento djvu alrededor de un http url. El plugin djview siempre usa la configuración proxy del navegador.<p><b>Ajustes del cache.</b><br>El <i>cache de pixeles</i> almacena datos de la imagen localizados al exterior del área visible. Este cache hace la panorámica más suave. El <i>cache de página decodificado</i> contiene páginas parcialmente decodificadas. Proporciona una respuesta rápida cuando se navega por un documento multipágina o cuando se retorna hacia una página anterior. Limpiando el cache podría ser útil para reflejar un cambio en la página de datos sin reiniciar el visor DjVu.</html> Standalone Viewer (Full Screen mode) Vista autónoma (modo Pantalla Completa) Standalone Viewer (Slideshow mode) Vista autónoma (modo Diapositiva) QDjViewPrintDialog Dialog Diálogo Print Imprimir &Document &Documento C&urrent page P&ágina actual &Pages &Páginas to a Destination Destino Print to file Imprimir a un archivo Printer name: Nombre impresora: Choose Elegir &Defaults Valores por &Defecto &Ok &Ok &Cancel &Cancelar Stop Detener <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Imprimiendo.</b><br/> Usted puede imprimir el documento entero o un rango de páginas. Use el botón <tt>Elegir</tt> para selecionar impresora y especificar opciones de impresión. Pestañas adicionales de diálogo podrían aparecer para especificar opciones de conversión.</html> (invalid printer) (impresora invalida) All files save filter Todos los archivos Print To File - DjView dialog caption Imprimir a Archivo - DjView Question - DjView dialog caption Pregunta - DjView A file with this name already exists. Do you want to replace it? Un archivo con este nombre ya existe. Usted quiere reemplazarlo? &Replace &Reemplazar This operation has failed. Esta operación fallo. This operation has been interrupted. Esta operación fue interrumpida. QDjViewPrnExporter Printer data Datos impresora PRN Files (*.prn) Archivos PRN (*.prn) Printing Options tab caption Opciones de impresión <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Opciones de impresión.</b><br>Opción <tt>Color</tt> permite impresión a color. Páginas del documento pueden decorarse con un marco. Opción <tt>Ajuste de escala</tt> acommoda el tamaño del papel al usado por la impresora. Factor zoom <tt>100%</tt> reproduce el tamaño inicial del documento. Orientación <tt>Automatica</tt> elige vertical u horizontal en función de cada página.</html> Cannot render page %1. Imposible renderizar la página %1. QDjViewSaveDialog Dialog Diálogo Save Guardar &Document &Documento C&urrent page P&ágina actual &Pages &Páginas to a Destination Destino Format: Formato: Bundled DjVu Document Documento DjVu Grapado Indirect DjVu Document Documento Djvu Indirecto &Ok &Ok &Cancel &Cancelar Stop Detener <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>Guardando.</b><br/> Usted puede guardar el documento entero o un rango de páginas. El formato grapado creara un sencillo archivo. El formato indirecto creara múltiples archivos apropiados para el servicio web.</html> Error - DjView dialog caption Error DjView Overwriting the current file is not allowed! Sobreescritura del archivo actual no está permitido! Question - DjView dialog caption Pregunta - DjView A file with this name already exists. Do you want to replace it? Un archivo con este nombre ya existe. Usted quiere reemplazarlo? &Replace &Reemplazar This operation has failed. Esta operación fallo. This operation has been interrupted. Esta operación fue interrumpida. All files save filter Todos los archivos Save - DjView dialog caption Guardar DjView QDjViewThumbnails Tiny thumbnail menu Diminuto Small thumbnail menu Pequeño Medium thumbnail menu Medio Large thumbnail menu Grande Smart thumbnail menu Inteligente Control Left Mouse Button Control botón izquierdo del Ratón Right Mouse Button Botón derecho del Ratón <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Miniaturas del documento.</b><br/> Este panel visualiza las páginas en miniatura del documento. Con un doble click en una miniatura irá a la página seleccionada. %1 para cambiar tamaño de la miniatura o modo actualización. El modo actualización inteligente solamente calcula miniaturas cuando los datos de la pagina estan presentes (visualizados o en cache).</html> QDjViewTiffExporter TIFF Document Documento TIFF TIFF Files (*.tiff *.tif) Archivos TIFF (*.tif *.tiff) TIFF Options tab caption Opciones TIFF <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>Opciones TIFF.</b><br>La caja de resolución especifica el límite superior de las imágenes TIFF. Forzando compresión bitonal-G4 codifica todas las páginas blanco y negro usando la compresión CCITT Group 4. Compresión JPEG permite usar pérdida JPEG para todas las imágenes no-bitonal o submuestras. De otro lado, la compresión deflate produce archivos más compactos (pero menos portable) que la compresión por defecto packbits.</html> Cannot open output file. Imposible abrir archivo salida. Out of memory. Sin memoria. Internal error. Error interno. TIFF export has not been compiled. Exportación TIFF no logro ser compilada. QDjVuNetDocument Requesting '%1' Solicitando '%1' QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code http recibido con estado %1 mientras recuperaba %2. Received <%1> data while retrieving %2. %1 is a mime type Dato <%1> recibido mientras recuperaba %2. %1 while retrieving '%2'. %1 al recuperar '%2'. Cannot validate the certificate for server %1. No es posible validar el certificado del servidor %1. Authentication required for %1 (%2). Autenticación requerida para %1 (%2). Authentication required for proxy %1. Autenticación requerida para el proxy %1. djview4-4.10.5/src/djview_fr.ts000066400000000000000000004673641264256014000163170ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language Français QApplication Option '-fix' is deprecated. L'option «-fix» n'est plus utilisée. QDjView cannot open '%1'. impossible d'ouvrir «%1». FitWidth zoomCombo Pleine Largeur FitPage zoomCombo Pleine Page Stretch zoomCombo Étirer 1:1 zoomCombo 1:1 300% zoomCombo 300% 200% zoomCombo 200% 150% zoomCombo 150% 100% zoomCombo 100% 75% zoomCombo 75% 50% zoomCombo 50% Color modeCombo Couleur Stencil modeCombo Masque Foreground modeCombo Avant-plan Background modeCombo Arrière-plan &New File| &Nouveau Ctrl+N File|New Ctrl+N Create a new DjView window. Crée une nouvelle fenêtre DjView. &Open File| &Ouvrir Ctrl+O File|Open Ctrl+O Open a DjVu document. Ouvre un document DjVu. &Close File| &Fermer Ctrl+W File|Close Ctrl+W Close this window. Ferme cette fenêtre. &Quit File| &Quitter Ctrl+Q File|Quit Ctrl+Q Close all windows and quit the application. Ferme toutes les fenêtres et quitte l'application. Save &as... File| &Enregistrer sous... Save the DjVu document. Enregistre le document DjVu. &Print... File| &Imprimer... Ctrl+P File|Print Ctrl+P Print the DjVu document. Imprime le document DjVu. &Find... Edit| &Rechercher... Ctrl+F Edit|Find Ctrl+F Find text in the document. Recherche de texte dans le document. Find &Next Edit| Sui&vant F3 Edit|Find Next F3 Find next occurence of search text in the document. Montre l'apparition suivante du texte recherché dans le document. Find &Previous Edit| &Précédent Shift+F3 Edit|Find Previous Shift+F3 Find previous occurence of search text in the document. Montre l'apparition précédente du texte recherché dans le document. &Select Edit| &Sélectionner F2 Edit|Select F2 Select a rectangle in the document. Sélectionne un rectangle dans le document. Zoom &In Zoom| &Agrandir Increase the magnification. Augmente l'agrandissement de l'image. Zoom &Out Zoom| &Réduire Decrease the magnification. Réduit l'agrandissement de l'image. Fit &Width Zoom| Pleine &Largeur Set magnification to fit page width. Affiche les pages dans toute leur largeur. Fit &Page Zoom| Pleine &Page Set magnification to fit page. Affiche toute la page. One &to one Zoom| 1&:1 Set full resolution magnification. Affiche la page avec sa résolution native. &300% Zoom| &300% Magnify 300% Grossissement à 300% &200% Zoom| &200% Magnify 20% Grossissement à 200% &150% 150% Zoom| &150% Magnify 150% Grossissement à 150% &100% Zoom| &100% Magnify 100% Grossissement à 100% &75% Zoom| &75% Magnify 75% Grossissement à 75% &50% Zoom| &50% &First Page Go| P&remière Page Jump to first document page. Va à la première page du document. &Next Page Go| Page &Suivante Jump to next document page. Va à la prochaine page du document. &Previous Page Go| Page &Précédente Jump to previous document page. Va à la page précédente. &Last Page Go| &Dernière Page Jump to last document page. Va à la dernière page. &Backward Go| Retour &Arrière Backward in history. Position précédente dans l'historique des positions visitées. &Forward Go| Retour A&vant Forward in history. Position suivante dans l'historique des positions visitées. Rotate &Left Rotate| Pivoter à &Gauche Rotate page image counter-clockwise. Pivote les pages dans le sens inverse des aiguilles d'une montre. Rotate &Right Rotate| Pivoter à &Droite Rotate page image clockwise. Pivote les pages dans le sens des aiguilles d'une montre. Rotate &0° Rotate| Pivoter &0° Set natural page orientation. Restaure l'orientation normale des pages. Rotate &90° Rotate| Pivoter à &90° Turn page on its left side. Pivote les pages sur leur coté gauche. Rotate &180° Rotate| Pivoter à &180° Turn page upside-down. Pivote les pages à 180 degrés. Rotate &270° Rotate| Pivoter à &270° Turn page on its right side. Pivote les pages sur leur coté droit. &Information... Edit| &Informations... Ctrl+I Edit|Information Ctrl+I &Metadata... Edit| &Méta informations... Ctrl+M Edit|Metadata Ctrl+M Show the document and page meta data. Montre les informations supplémentaires sur le document et ses pages. &About DjView... &À propos de DjView... Show information about this program. Montre les informations à propos de ce programme. &Color Display| &Couleur Display everything. Affiche les images en pleine couleur. &Stencil Display| &Masque Only display the document bitonal stencil. N'affiche que le masque bitonal de chaque image. &Foreground Display| A&vant-plan Only display the foreground layer. N'affiche que l'avant-plan de chaque image. &Background Display| A&rrière-plan Only display the background layer. N'affiche que l'arrière-plan de chaque image. I&nvert Luminance View| Luminance i&nversée Invert image luminance while preserving hue. Inverse la luminance de l'image tout en préservant les teintes. Prefere&nces... Settings| Préfére&nces... Show the preferences dialog. Montre le panneau des préférences. F9 Settings|Show sidebar F9 Show/hide the side bar. Montre ou cache la panneau latéral. F10 Settings|Show toolbar F10 Show/hide the standard tool bar. Montre ou cache la barre d'outils. Show/hide the status bar. Montre ou cache la ligne d'état en bas de la fenêtre. F11 View|FullScreen F11 Toggle full screen mode. Sélectionne le mode plein écran. &Slide Show View| Pré&sentation Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. Sélectionne le mode présentation &Continuous Layout| Pages &Continues F4 Layout|Continuous F4 Toggle continuous layout mode. Sélectionne l'affichage continu des pages. Side &by Side Layout| Pages Cô&te-à-Côte F5 Layout|SideBySide F5 Toggle side-by-side layout mode. Sélectionne l'affichage des pages côte à côte. &File File| &Fichier &Edit Edit| &Édition &View View| &Voir &Zoom View|Zoom &Zoom &Rotate View|Rotate &Rotation &Display View|Display A&ffichage &Go Go| &Aller &Settings Settings| &Options &Help Help| &Aide Control Left Mouse Button Control et bouton gauche de la souris Right Mouse Button Bouton droit de la souris <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>Sélectionner un rectangle.</b><br/> Après avoir sélectionné un rectangle, un menu vous permet de copier le texte ou l'image correspondante. Vous pouvez accéder à la même fonction en maintenant la touche %1 pendant l'utilisation du bouton gauche de la souris.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>Grossissement.</b><br/> Le grossissement 100% affiche les page avec une taille adéquate pour un écran à 100 dpi. Les grossissements «Pleine Page» et «Pleine Largeur» font en sorte que toute la page ou toute sa largeur soit visible dans la fenêtre. </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>Rotation.</b><br/> Pivoter les pages permet de les afficher en mode portait ou paysage. Vous pouvez également afficher les pages à l'envers.</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Mode d'affichage.</b><br/> Les images DjVu sont composées d'une couche d'arrière-plan et d'une couche d'avant-plan dessiné au travers d'une couche de masque. Le mode d'affichage sélectionne quelles couches doivent être affichées.</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Affichage continu.</b><br/> Affiche toutes les pages l'une au dessous de l'autre dans la zone de visualisation du document.</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Affichage côte-à-côte.</b><br/> Affiche les paires de pages côte-à-côte dans la zone de visualisation du document.</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Informations sur la page.</b><br/> Affiche quelques informations sur la page située sous le pointeur: le numéro de page, la taille de la page en pixels, et sa résolution en points par pouce.</html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Position du pointeur.</b><br/> Affiche la position du pointeur, exprimée dans les coordonnées de la page. </html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>Zone de visualisation du document.</b><br/> Ceci est la zone de visualisation principale pour le document DjVu. <ul><li>Flèches et touches de pagination pour naviguer à l'intérieur du document.</li><li>Touches Espace et Retour pour lire le document en séquence.</li><li>Touches <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> pour grossir ou pivoter les images.</li><li>Bouton gauche de la souris pour déplacer l'image et sélectionner des liens.</li><li>%3 pour le menu contextuel.</li><li>%1 et bouton gauche de la souris pour sélectionner texte ou images.</li><li>%2 pour montrer la loupe.</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>Zone de visualisation du document.</b><br/> Ceci est la zone de visualisation principale pour le document DjVu. Mais vous devez d'abord ouvrir un document DjVu pour voir quoi que ce soit.</html> Toolbar option '%1' is not implemented. L'option de barre d'outils «%1» n'est pas supportée. Option '%1' requires a standalone viewer. L'option «%1» est invalide en mode «plugin». Deprecated option '%1' L'option «%1» n'est plus utilisée Option '%1' is not implemented. L'option «%1» n'est pas encore codée. Option '%1' is not recognized. L'option «%1» n'est pas reconnue. DjView DjView Cannot open file '%1'. Impossible d'ouvrir le fichier «%1». Cannot open URL '%1'. Impossible d'ouvrir l'URL «%1». Certificate validation error - DjView dialog caption Erreur de validation du certificat - DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Voulez-vous continuer tout-de-même? </html> Cannot find page numbered: %1 Impossible de trouver la page numérotée «%1» Cannot find page named: %1 Impossible de trouver la page nommée «%1» Unrecognized sidebar options '%1'. L'option de panneau latéral «%1» n'est pas reconnue. <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html>Ce fichier est servi avec une restriction d'impression. Voulez-vous l'imprimer quand même?</html> <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html>Ce fichier est servi avec une restriction de sauvegarde. Voulez vous le sauver quand même?</html> Cannot determine file format. Filename '%1' has no suffix. Impossible de déterminer le format du fichier. Le nom «%1» n'a pas de suffixe. Image format %1 not supported. Le format de fichier image «%1» n'est pas supporté. Cannot write file '%1'. %2. Impossible d'écrire le fichier «%1». %2. &Full Screen View| &Plein Écran Thumbnails Vignettes Outline Chapitres Find Recherche Cannot decode page %1. Impossible de décoder la page «%1». Cannot decode document. Impossible de décoder le document. x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: %n pages forward. Avancer de %n page. Avancer de %n pages. Go: %n pages backward. Reculer de %n page. Reculer de %n pages. Go: page %1. Aller page %1. Go: %1 Link: %1 Aller à %1 Cannot resolve link '%1' Impossible d'interpréter le lien «%1» Cannot spawn a browser for url '%1' Impossible de lancer un navigateur pour l'URL «%1» Copy text (%1) Copier le texte (%1) Save text as... Enregistrer le texte... Copy image (%1x%2 pixels) Copier l'image (%1x%2) Save image as... Enregistrer l'image... Zoom to rectangle Zoomer sur ce rectangle About DjView À propos de DjView DjVu files Fichiers DjVu Magnify 50% Grossissement à 50% Show information about the document encoding and structure. Montre les informations sur l'encodage du document et sa structure. (in other window.) (dans une autre fenêtre.) Option '%1' requires boolean argument. L'option «%1» demande un argument booléen. Illegal value '%2' for option '%1'. L'argument «%2» pour l'option «%1» est invalide. Toolbar option '%1' is not recognized. L'option de barre d'outils «%1» n'est pas reconnue. <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Informations sur le document et la page.</b><br> Affiche un panneau montrant les informations d'encodage qui se rapportent au document ou à une de ses pages.</html> <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>Navigation.</b><br/> Le sélecteur de page vous permet de sélectionner une page par son nom. Pressez Ctrl+G pour l'activer à tout moment. Les icônes de navigation vous permettent d'aller directement à la première page, la page précédente, la page suivante, ou la dernière page. </html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Méta informations sur le document et la page.</b><br> Affiche un panneau montrant les informations supplémentaires qui se rapportent au document ou à une de ses pages.</html> Opening DjVu file Ouverture de fichier DjVu Opening DjVu document Ouverture de document DjVu Print - DjView dialog caption Imprimer - DjView Save - DjView dialog caption Sauver - DjView Text files save filter Fichiers texte All files save filter Tous les fichiers Save Text - DjView dialog caption Sauver le texte - DjView Error - DjView dialog caption Erreur - DjView Save Image - DjView dialog caption Enregistrement de l'image - DjView Decoding DjVu document Décodage de document DjVu P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>Afficheur pour documents DjVu<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>Ce programme est un logiciel libre. Vous pouvez le redistribuer ou le modifier au titre des clauses de la «GNU General Public License», telle que publiée par la Free Software Foundation. Ce programme est distribué <i>sans aucune garantie</i>. Voir la «GNU General Public License» pour plus de détails.</small></p></html> Information - DjView dialog caption Information - DjView Metadata - DjView dialog caption Meta-information - DjView &Export as... File| &Exporter... Export DjVu page or document to other formats. Exporte la page ou le document DjVu sous un autre format. Export - DjView dialog caption Export - DjView Ctrl+S File|SaveAs Ctrl+S Ctrl+E File|ExportAs Ctrl+E Open &Recent Ouvrir un Fichier &Récent &Clear History &Effacer l'historique Open &Location... File| Ouvrir une UR&L... Open a remote DjVu document. Ouvre un document DjVu specifié par son URL. Ctrl+F3 Edit|Find Next Ctrl+F3 Ctrl+F2 Edit|Select Ctrl+F2 Ctrl+F9 Settings|Show sidebar Ctrl+F9 Ctrl+F10 Settings|Show toolbar Ctrl+F10 Ctrl+F11 View|FullScreen Ctrl+F11 Ctrl+F4 Layout|Continuous Ctrl+F4 Ctrl+F5 Layout|SideBySide Ctrl+F5 Open Location - DjView dialog caption Ouverture d'une URL - DjView Enter the URL of a DjVu document: Entrez l'URL d'un document DjVu: Open - DjView dialog caption Ouverture - DjView Show &Sidebar Settings| Panneau &Latéral Show &Toolbar Settings| &Barre d'outils Show Stat&usbar Settings| Ligne d'é&tat %1 files (*.%2);; save image filter Fichiers %1 (*.%2) %n characters %n caractère %n caractères Go: 1 page forward. Avancer de 1 page. Go: 1 page backward. Reculer de 1 page. Copy &URL Edit| Copie l'&URL Save an URL for the current page into the clipboard. Copie une URL qui monte la page courante dans le presse-papier. Copy &Outline Edit| Copie le &Sommaire Copy &Annotations Edit| Copie les &Annotations Copy text into the clipboard. Copie le texte correspondant à la sélection. Save text into a file. Enregistre le texte correspondant à la sélection dans un fichier. Copy image into the clipboard. Copie une image correspondant à la sélection. Save image into a file. Enregistre une image correspondant à la sélection dans un fichier. Zoom the selection to fit the window. Change le grossissement de façon à maximiser la sélection dans la fenêtre. Copy URL Copie l'URL Save into the clipboard an URL that highlights the selection. Copie une URL qui monte la page courante et met en valeur la sélection. Copy Maparea Copie la «Maparea» Save into the clipboard a maparea annotation expression for program djvused. Copie une directive d'annotation «maparea» correspondant à la sélection. Ctrl+C Edit|CopyURL Ctrl+C Save the djvused code for the outline into the clipboard. Copie la représentation «djvused» de la table des matières. Save the djvused code for the page annotations into the clipboard. Copie la representation «djvused» des annotations de la page courante. Co&ver Page Layout| Page de Cou&verture Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. Affiche la première page seule en mode côte-à-côte. &Right to Left Layout| &Droite à Gauche Ctrl+Shift+F6 Layout|RightToLeft Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. Affiche les pages de droite à gauche en mode côte-à-côte. All files Tous les fichiers &Hidden Text Display| &Texte Caché Overlay a representation of the hidden text layer. Affiche le texte caché en sur-impression. Hidden Text modeCombo Texte Caché QDjViewApplication Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. Utilisation: djview [options] [fichier-ou-url] Options fréquentes: -help~~~Affiche ce message. -verbose~~~Affiche tous les messages d'erreur. -display <xdpy>~~~Sélectionne le terminal X windows <xdpy>. -geometry <xgeom>~~~Spécifie la position et la taille de la première fenêtre. -font <xlfd>~~~Sélectionne la police X windows <xlfd>. -style <qtstyle>~~~Sélectionne le style d'interface Qt. -fullscreen, -fs~~~Démarre djview en mode plein écran. -page=<page>~~~Va directement vers la page <page>. -zoom=<zoom>~~~Sélectionne un facteur de zoom. -continuous=<yn>~~~Sélectionne l'affichage continu des pages. -sidebyside=<yn>~~~Sélectionne l'affichage côte-à-côte des pages. cannot open '%1'. impossible d'ouvrir «%1». QDjViewAuthDialog Password: Mot de passe: User: Utilisateur: Authentication required - DjView Identification requise - DjView QDjViewDjVuExporter Question - DjView dialog caption Question - DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> Ce fichier appartient à un répertoire qui n'est pas vide. La sauvegarde d'un document DjVu indirect crée de nombreux fichiers dans ce répertoire. Voulez-vous continuer et prendre le risque de remplacer des fichiers dans ce répertoire?</html> Con&tinue Con&tinuer &Cancel &Annuler Save job creation failed! L'operation d'enregistrement a échoué! Unknown error. Erreur inconnue. System error: %1. Erreur système: %1. DjVu Bundled Document Document DjVu «bundled» DjVu Files (*.djvu *.djv) Fichiers DjVu (*.djvu *.djv) DjVu Indirect Document Document DjVu «indirect» QDjViewErrorDialog DjView Error Erreur DjView &Ok &Ok Error - DjView dialog caption Erreur - DjView QDjViewExportDialog Dialog Dialogue Export Exporter Format: Format: &Document &Document C&urrent page Page &courante &Pages &Pages to à Destination Destination &Defaults &Défaults &Ok &Ok &Cancel &Annuler Stop Stop <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>Enregistrer.</b><br/> Vous pouvez enregistrer le document entier ou un intervalle de pages sous divers formats. Certain formats font apparaître des pages supplémentaires permettant de spécifier les options de conversion.</html> Error - DjView dialog caption Erreur - DjView Overwriting the current file is not allowed! Impossible de remplacer le fichier DjVu courant! Question - DjView dialog caption Question - DjView A file with this name already exists. Do you want to replace it? Ce fichier existe déjà. Voulez-vous le remplacer? &Replace &Remplacer This operation has failed. Cette opération a échoué. This operation has been interrupted. Cette opération a été interrompue. All files save filter Tous les fichiers Export - DjView dialog caption Exporter - DjView QDjViewExportPS1 Form Form Color Couleur &Color &Couleur &GrayScale Niveaux de &gris Marks Marques Print image &frame Imprimer un &cadre Print crop &marks Imprimer des marques de &découpe PostScript PostScript Language Level Niveau PostScript QDjViewExportPS2 Form Form Scaling Agrandissement Scale to &fit the page Agrandir à la &page &Zoom &Zoom % % Orientation Orientation Automatic Automatique &Portrait &Portrait &Landscape P&aysage QDjViewExportPS3 Form Form Print sheets suitable for folding a booklet. Imprimer des feuillets à plier en fascicule. Advanced Options avancées Sheets per booklet: Pages par fascicule: Unlimited non limité at most au plus Print Imprimer rectos and versos. les rectos et versos. rectos only. les rectos seulement. versos only. les versos seulement. Shift rectos and versos by Décaler les versos de points. points. Center: Marge centrale: points points /100 /100 plus plus per page. par page. QDjViewExportPrn Form Form Color Couleur &Color &Couleur &GrayScale Niveaux de &gris Marks Marques Print image &frame Imprimer un &cadre Print crop &marks Imprimer des marques de &découpe Scaling Agrandissement Scale to &fit the page Agrandir à la &page &Zoom &Zoom % % Orientation Orientation Automatic Automatique &Portrait &Portrait &Landscape P&aysage QDjViewExportTiff Form Form Resolution Résolution Maximum image resolution Résolution maximale dpi dpi Compression Compression JPEG &quality &Qualité JPEG Force &bitonal G4 compression. Force la compression &bitonale CCITT G4. Allow &lossy JPEG compression. Autorise la com&pression JPEG. Allow &deflate compression. Autorise la compression «&deflate». QDjViewFind Case sensitive Même casse Words only Mots entiers seulement Find Previous (Shift+F3) Précédent (Maj+F3) Find Next (F3) Suivant (F3) Options Options <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>Recherche de texte.</b><br/> Les occurrences du texte à rechercher apparaissent progressivement pendant sa saisie. La touche «Entrée» montre la prochaine occurrence. Pour aller à l'occurrence précédente ou suivante, utilisez les boutons fléchés ou les touches <tt>F3</tt> et <tt>Maj+F3</tt>. Vous pouvez aussi double cliquer un nom de page. Le menu <tt>Options</tt> permet de chercher des mots entiers ou de spécifier la casse.</html> Regular expression Expression régulière Reset search options to default values. Réinitialise les options de recherche à leur valeurs par défaut. Specify whether search hits must begin on a word boundary. Determine si les occurrences commencent toujours sur une limite de mot. Specify whether searches are case sensitive. Determine si la recherche est sensible à la casse des caractères. Regular expressions describe complex string matching patterns. Les expressions régulières décrivent des recherches compliquées. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Expressions régulières</b><ul><li>Le point <tt>.</tt> représente un caractère arbitraire.</li><li>La plupart des caractères ne représentent qu'eux mêmes.</li><li>Utilisez un <tt>\</tt> avant les caractères spéciaux <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> représente une frontière de mot.</li><li><tt>\w</tt> représente un caractère appartenant à un mot.</li><li><tt>\d</tt> représente un caractère numérique.</li><li><tt>\s</tt> représente un caractère d'espacement.</li><li><tt>\n</tt> représente le marqueur de fin de ligne.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> représente un caractère dans l'intervalle <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> représente un caractère hors de l'intervalle <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> représente soit l'expression <tt><i>a</i></tt>, soit l'expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> représente de <tt><i>n</i></tt> à <tt><i>m</i></tt> répétitions de l'expression <tt><i>a</i></tt>.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, et <tt><i>a</i>+</tt> sont des abbréviations pour <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, et <tt><i>a</i>{1,}</tt>.</li><li>Utilisez les parenthèses <tt>()</tt> pour grouper une expression avant <tt>?+*{</tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 occurrence Page %1 (1 hit) Page %1 (1 occurrence) Searching page %1 (waiting for data.) Page %1 (attente des données.) Searching page %1. Page %1. No hits! Rien! <html>Document is not searchable. No page contains information about its textual content.</html> <html>Recherche de texte impossible. Ce document ne contient pas d'information sur le texte.</html> %n hits %n occurrence %n occurrences Page %1 (%n hits) Page %1 (%n occurence) Page %1 (%n occurences) <html>Invalid regular expression.</html> <html>Expression régulière invalide.</html> QDjViewImgExporter Cannot render page. Impossible de dessiner la page. Image format %1 not supported. Le format de fichier image «%1» n'est pas supporté. %1 Image JPG Image Images %1 %1 Files (*.%2) JPG Files Fichiers %1 (*.%2) QDjViewInfoDialog File # Fichier n° File Name Nom File Size Taille File Type Type Page # Page n° Page Title Titre Waiting for data... Attende des données... Page #%1 - « %2 » Page n° %1 - « %2 » Page #%1 Page n° %1 Thumbnails Vignettes Shared annotations Annotations partagées Shared data Données partagées File #%1 - Fichier n° %1 - Single DjVu page Page DjVu simple Bundled DjVu document Document DjVu «bundled» Indirect DjVu document Document DjVu «indirect» Obsolete bundled DjVu document Document DjVu «bundled» obsolète Obsolete indexed DjVu document Document DjVu «indexed» obsolète n/a n/d Page Page Thumbnails Vignettes Shared Partagé Dialog Dialogue &Document &Document &File &Fichier File: Fichier: &View Page &Voir cette Page &Close &Fermer <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Information sur le document</b><br>Ce panneau montre les informations sur le document et les fichiers qui le composent. Sélectionnez un nom de fichier pour afficher ses informations sous l'index <tt>Fichier</tt>. Double-cliquez un nom de fichier pour montrer la page correspondante </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Informations sur un fichier</b><br>Ce panneau montre la structure des données DjVu correspondant au fichier ou à la page sélectionnée dans l'onglet <tt>Document</tt>. Les flèches vous permettent de naviguer vers le fichier précédent ou suivant.</html> 1 file 1 fichier %n files %n fichier %n fichiers 1 page 1 page %n pages %n page %n pages QDjViewMetaDialog Ctrl+C copy Ctrl+C Key Type Value Valeur <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Méta informations sur le document</b><br>Ce panneau montre les informations supplémentaires sur le document: auteur, titre, références, etc. Ces informations peuvent être ajoutées au document en utilisant les commandes <tt>create-shared-ant</tt> and <tt>set-meta</tt> du programme <tt>djvused</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Méta informations sur le document</b><br>Ce panneau montre les informations supplémentaires sur la page sélectionnée. Ces informations ont priorité sur celles se rapportant au document dans son ensemble. Elles peuvent être ajoutées en utilisant les commandes <tt>select</tt> and <tt>set-meta</tt> du programme <tt>djvused</tt>.</html> Dialog Dialogue &Document Metadata &Document &Page Metadata &Page Page: Page: &View Page &Voir cette Page &Close &Fermer QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>Chapitres.</b><br/> Ce panneau montre la structure en chapitres enregistrée dans le document. Lorsque cette information n'est pas disponible, les noms de pages sont affichés. Double-cliquez une entrée pour voir la page correspondante.</html> Outline data is corrupted La table des matières est illisible Pages Pages Page %1 Page %1 Go: page %1. Go: page %1 Aller page %1. Go: %1 Go: %1. Aller vers %1 QDjViewPSExporter PostScript tab caption PostScript Position tab caption Position Booklet tab caption Fascicule <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Production de fascicules.</b><br>Le mode fascicule permet d'imprimer des feuillets à plier en un ou plusieurs fascicules. Plusieurs fascicules sont nécessaires lorsqu'un nombre maximum de feuillets est spécifié. Vous pouvez utiliser une imprimante recto-verso ou imprimer séparément les rectos et les versos<p> Décaler les versos est utile pour les imprimantes recto-versos mal alignées. La marge centrale peut être modifiée et augmente lors de la progression du feuillet intérieur vers le feuillet extérieur.</html> Save job creation failed! L'operation d'enregistrement a échoué! <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>Options PostScript.</b><br>L'option <tt>Couleur</tt> autorise l'impression en couleur. Les pages imprimées peuvent être décorées avec un cadre ou des marques de découpage. Le niveau PostScript 1 est utile pour les très vieilles imprimantes. Le niveau 2 fonctionne avec la plupart des imprimantes en service. Le niveau 3 imprime les documents en couleur plus rapidement sur des imprimantes récentes.</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Position and aggrandissement.</b><br>L'option <tt>Agrandir à la page</tt> choisit un grossissement adapté a la taille de papier utilisée par votre imprimante. Le facteur de grossissement <tt>100%</tt> reproduit la taille originale du document. L'orientation <tt>Automatique</tt> sélectionne portrait ou paysage en fonction de la taille de chaque page.</html> PostScript PostScript PostScript Files (*.ps *.eps) Fichiers PostScript (*.ps *.eps) Encapsulated PostScript PostScript Encapsulé QDjViewPdfExporter PDF Document Document PDF PDF Files (*.pdf) Fichiers PDF (*.pdf) PDF Options tab caption Options PDF <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>Options PDF.</b><br>Ces options s'appliquent aux images encapsulées dans les fichiers PDF exportés. La boite de résolution spécifie leur résolution maximale. Forcer la compression bitonale G4 encode toutes les pages en noir et blanc avec la compression CCITT Groupe 4. Autoriser la compression JPEG utilise JPEG pour toutes les images en niveaux de gris ou en couleurs. Sinon, autoriser la compression «deflate» produit des fichiers plus compacts.</html> Error while creating pdf file. Erreur pendant la création du fichier PDF. PDF export was not compiled. L'exportation de fichiers PDF n'a pas été compilée. Unable to create output file. Impossible de créer le fichier de sortie. System error: %1. Erreur système: %1. Unable to reopen temporary file. Impossible de réouvrir le fichier temporaire. Unable to create temporary file. Impossible de créer le fichier temporaire. QDjViewPlugin::Document Requesting %1. Chargement de %1. QDjViewPrefsDialog Dialog Dialogue Gamma Gamma Darker Foncé Lighter Clair <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>Correction de couleur pour l'écran.<br>Adjustez le potentionmètre de façon à rendre les niveaux de gris similaires.</html> &Interface &Interface Options for Options pour Standalone Viewer Application Full Page Plugin Plugin Pleine-Page Embedded Plugin Plugin en Ligne &Remember initial state from last invocation Mémo&riser les dernières options utilisées Show Élements &Menu bar Barre de &menu &Tool bar Barre d'ou&tils Sc&rollbars Barres de &défilement Stat&us bar Barre d'ét&at &Side bar Panneau &latéral Display Affichage Force inverted luminance Force inverted luminance. Forcer une inversion de luminance &Zoom: &Zoom: s secs s Display page &frames Ca&dres de pages Display &annotations &Annotations &Keys &Touches Keys Touches For displaying hyper&links: Pour montrer les &liens: For &selecting text or images: Pour &selectionner texte ou images: For displaying the &lens: Pour la &loupe: Mouse wheel Molette Mouse wheel scrolls the page Mouse wheel scrolls the page. La molette de la souris fait défiler l'écran Mouse wheel changes the zoom factor Mouse wheel changes the zoom factor. La molette de la souris change le grossissement &Lens &Loupe Enable magnifying &lens Autorise l'utilisation de la &loupe Lens options Options de la loupe Lens &size: T&aille: Magnifying &power: &Grossissement: x x pixels points Cache Cache &Clear &Effacer &Decoded page cache: Cache de pages &décodées: &Pixel cache: Cache de &pixels: &Network &Réseau Use pro&xy to access the network Utiliser un pro&xy pour accéder au réseau Proxy settings Options du proxy Pass&word: Mot de pa&sse: &User: &Utilisateur: &Port: &Port: &Host: &Hôte: Timer: Tourne-page: Interface Interface Force language (next time djview runs) Force language (when djview is restarted.) Langue utilisée (après le prochain démarrage) Enable page animations Enable animations Autoriser l'animation des pages Show hidden text in status bar Affiche le texte caché dans la barre d'état Render with openGL when available Utiliser openGL losrque c'est possible Override saving and printing restrictions Outrepasse les restrictions d'impression et de sauvegarde &Defaults &Défaults &Apply &Appliquer &Ok &Ok Cancel Annuler Preferences[*] - DjView Préférences[*] - DjView <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>Configuration initiale.</b><br>DjView peut fonctionner comme application normale, comme application plein-écran, comme plugin pleine-page, ou plugin en ligne dans une page web. Dans chaque cas, sélectionnez l'option <tt>Mémoriser...</tt> pour retenir la dernière configuration utilisée dans ce mode. Sinon, spécifiez les détails de la configuration initiale desirée.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>Touches spéciales.</b><br>Definissez quelles combinaisons de touches spéciales seront affectées à la loupe, à la selection de texte et d;images, et à l'affichage temporaire des liens.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Loupe.</b><br>La loupe apparaît lorsque vous maintenez les touches spéciales définies dans l'onglet <tt>Touches</tt>. Ce panneau vous permet d'en spécifier la taille et le grossissement.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><p><b>Advanced.</b>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>Options avancées</b><br>Vous pouvez changer la langue de l'interface, supprimer les animations, ou dévoiler des entrées de menus supplémentaires utiles pour la création de documents DjVu. Vous pouvez également ignorer les restrictions d'impression et de sauvegarde spécifiées par le site web. La correction manuelle des couleurs d'impression peut être utile avec certaines vieilles imprimantes.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>Options du réseau.</b><br>Ce panneau permet de définir un proxy utilisé pour atteindre un document DjVu distant avec le protocole réseau HTTP. Ces options sont ignorées lorsque le programme fonctionne en mode plugin: les accès réseaux utilisent alors les options du navigateur hôte.<p><b>Caches.</b><br>Le <i>cache de pixels</i> contient des portions d'images situées en limite de la zone visible. Il permet des défilements plus fluides. Le <i>cache de page décodées</i> contient des pages partiellement décodées. Il permet de parcourir plus rapidement des documents à pages multiples. Effacer ce cache peut être utile pour prendre en compte un fichier modifié sans redemarrer l'application.</html> Standalone Viewer (Full Screen mode) Application (en mode plein écran) Standalone Viewer (Slideshow mode) Application (en mode présentation) <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>Correction de couleur pour l'écran.</b><br>Le meilleur rendu est obtenu en ajustant le potentiomètre de façon à rendre les niveaux de gris de la mire aussi proches que possible.<p><b>Résolution de l'écran.</b><br>Forcer une résolution particulière est utile quand le système donne une résolution qui ne correspond pas à la réalité. Forcer une résolution de 100dpi rend l'affichage compatible avec les programmes utilitaires de DjVuLibre.</html> &Screen &Écran Force screen &resolution Forcer la &résolution de l'écran dpi dpi &Advanced Options &avancées Miscellaneous Divers Manual printer color correction Correction manuelle de couleur d'impression gamma= gamma= Enable advanced features in menus Montrer les fonctions avancées dans les menus MB MB Layout Layout Continuous Pages en continu Side-by-side Pages Côte à Côte Cover Page Page de Couverture Right-to-Left De Droite à Gauche QDjViewPrintDialog Dialog Dialogue Print Imprimer &Document &Document C&urrent page Page &courante &Pages &Pages to à Destination Destination &Ok &Ok &Cancel &Annuler Stop Stop This operation has failed. Cette opération a échoué. This operation has been interrupted. Cette opération a été interrompue. <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Impression.</b><br/> Vous pouvez imprimer le document entier ou un intervalle de pages. Utilisez le bouton <tt>Choisir</tt> pour selectionner une destination d'impression. Des onglets supplémentaires peuvent apparaître pour spécifier des options de conversion adaptées à l'imprimante.</html> &Defaults &Défaults Print to file Imprimer vers un fichier Printer name: Imprimante: Choose Choisir All files save filter Tous les fichiers Print To File - DjView dialog caption Imprimer vers un fichier - DjView Question - DjView dialog caption Question - DjView A file with this name already exists. Do you want to replace it? Ce fichier existe déjà. Voulez-vous le remplacer? &Replace &Remplacer (invalid printer) (imprimante invalide) QDjViewPrnExporter Printer data Données d'impression PRN Files (*.prn) Fichiers PRN (*.prn) Printing Options tab caption Options d'impression <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Options d'impression.</b><br>L'option <tt>Couleur</tt> autorise l'impression en couleur. Les pages imprimées peuvent être décorées avec un cadre. L'option <tt>Agrandir à la page</tt> choisit un grossissement adapté a la taille de papier utilisée par votre imprimante. Le facteur de grossissement <tt>100%</tt> reproduit la taille originale du document. L'orientation <tt>Automatique</tt> sélectionne portrait ou paysage en fonction de la taille de chaque page.</html> Cannot render page %1. Impossible de dessiner la page «%1». QDjViewSaveDialog &Cancel &Annuler Dialog Dialogue Save Enregistrement &Document &Document C&urrent page Page &courante &Pages &Pages to à Destination Destination Stop Stop Format: Format: &Ok &Ok Error - DjView dialog caption Erreur - DjView Overwriting the current file is not allowed! Impossible de remplacer le fichier DjVu courant! Question - DjView dialog caption Question - DjView A file with this name already exists. Do you want to replace it? Ce fichier existe déjà. Voulez-vous le remplacer? &Replace &Remplacer This operation has failed. Cette opération a échoué. This operation has been interrupted. Cette opération a été interrompue. All files save filter Tous les fichiers Save - DjView dialog caption Enregistrer - DjView <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>Saving.</b><br/> Vous pouvez enregistrer le document entier ou quelques pages. Le format DjVu «bundled» consiste en un fichier unique contenant toutes les pages. Le format DjVu «indirect» consiste en une collection de fichiers appropriés pour un serveur Web.</html> Bundled DjVu Document Document DjVu «bundled» Indirect DjVu Document Document DjVu «indirect» QDjViewThumbnails Tiny thumbnail menu Minuscules Small thumbnail menu Petites Medium thumbnail menu Moyennes Large thumbnail menu Grandes Smart thumbnail menu Calcul Intelligent Control Left Mouse Button Control et bouton gauche de la souris Right Mouse Button Bouton droit de la souris <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Vignettes.</b><br/> Ce panneau montre des vignettes représentant les pages du document. Double cliquer une vignette pour voir une page. %1 pour afficher un menu permettant de changer la taille des vignettes et leur mode de calcul. Le mode de calcul intelligent ne calcule que les vignettes pour lesquelles les données sont disponibles en mémoire.</html> QDjViewTiffExporter TIFF Options tab caption Options TIFF Cannot open output file. Impossible d'ouvrir le fichier destination. Out of memory. Mémoire pleine. TIFF export has not been compiled. L'exportation de fichier TIFF n'est pas compilée. Internal error. Erreur interne. TIFF Document Documents TIFF TIFF Files (*.tiff *.tif) Fichiers TIFF (*.tiff *.tif) <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>Options TIFF.</b><br>La boite de résolution spécifie la résolution maximale de chaque image dans le fichier TIFF. Forcer la compression bitonale G4 encode toutes les pages en noir et blanc avec la compression CCITT Groupe 4. Autoriser la compression JPEG utilise JPEG pour toutes les images en niveaux de gris ou en couleurs. Sinon, autoriser la compression «deflate» produit des fichiers plus compacts (mais moins portables) que la compression par défaut «packbits».</html> QDjVuNetDocument Requesting '%1' Chargement de «%1» QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code La requête %2 a produit le code d'erreur http %1. Received <%1> data while retrieving %2. %1 is a mime type La requête %2 a produit des données de type %1. %1 while retrieving '%2'. %1 pendant le chargement de «%2». Cannot validate the certificate for server %1. Erreur de validation du certificat du serveur %1. Authentication required for %1 (%2). Identification requise pour %1 (%2). Authentication required for proxy %1. Identification requise pour le proxy %1. djview4-4.10.5/src/djview_ru.ts000066400000000000000000005247371264256014000163340ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language РуÑÑкий QApplication Option '-fix' is deprecated. Параметр «-fix» уÑтарел. QDjView 100% zoomCombo 100% &100% Zoom| &100% 1:1 zoomCombo 1:1 150% zoomCombo 150% &150% 150% Zoom| &150% %1 files (*.%2);; save image filter %1 файлы (*.%2);; 200% zoomCombo 200% &200% Zoom| &200% 300% zoomCombo 300% &300% Zoom| &300% &50% Zoom| &50% 50% zoomCombo 50% 75% zoomCombo 75% &75% Zoom| &75% About DjView О DjView &About DjView... &О DjView... All files save filter Ð’Ñе файлы Background modeCombo Фон &Background Display| &Фон &Backward Go| &Ðазад Backward in history. ВернутьÑÑ Ð½Ð°Ð·Ð°Ð´ по иÑтории. Cannot decode document. Ðе удаетÑÑ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ документ. Cannot decode page %1. Ðе удаетÑÑ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñтраницу '%1'. Cannot determine file format. Filename '%1' has no suffix. Ðевозможно определить формат файла. Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° '%1' не имеет ÑуффикÑа. Cannot find page named: %1 Ðе удаетÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ Ñтраницу Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ %1 Cannot find page numbered: %1 Ðе удаетÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ Ñтраницу Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ %1 cannot open '%1'. не удаетÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ '%1'. Cannot open file '%1'. Ðе удаетÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ файл '%1'. Cannot open URL '%1'. Ðе удаетÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ URL '%1'. Cannot resolve link '%1' Ðевозможно разрешить ÑÑылку '%1' Cannot spawn a browser for url '%1' Ðевозможно запуÑтить браузер Ð´Ð»Ñ URL '%1' Cannot write file '%1'. %2. Ðе удаетÑÑ Ð·Ð°Ð¿Ð¸Ñать файл '%1'. %2. &Clear History &ОчиÑтить иÑторию &Close File| &Закрыть Close all windows and quit the application. Закрыть вÑе окна и завершить приложение. Close this window. Закрыть окно. &Color Display| &Цвет Color modeCombo Цвет &Continuous Layout| &Ðепрерывный Control Left Mouse Button Control + Ð»ÐµÐ²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши Copy image (%1x%2 pixels) Скопировать изображение (%1x%2 пикÑелов) Copy text (%1) Скопировать текÑÑ‚ (%1) Create a new DjView window. Открыть новое окно DjView. Ctrl+E File|ExportAs Ctrl+E Ctrl+F Edit|Find Ctrl+F Ctrl+F10 Settings|Show toolbar Ctrl+F10 Ctrl+F11 View|FullScreen Ctrl+F11 Ctrl+F2 Edit|Select Ctrl+F2 Ctrl+F3 Edit|Find Next Ctrl+F3 Ctrl+F4 Layout|Continuous Ctrl+F4 Ctrl+F5 Layout|SideBySide Ctrl+F5 Ctrl+F9 Settings|Show sidebar Ctrl+F9 Ctrl+I Edit|Information Ctrl+I Ctrl+M Edit|Metadata Ctrl+M Ctrl+N File|New Ctrl+N Ctrl+O File|Open Ctrl+O Ctrl+P File|Print Ctrl+P Ctrl+Q File|Quit Ctrl+Q Ctrl+S File|SaveAs Ctrl+S Ctrl+W File|Close Ctrl+W Decoding DjVu document Декодирование документа DjVu Decrease the magnification. Уменьшить маÑштаб. Deprecated option '%1' УÑтаревший параметр «%1» &Display View|Display По&казывать Display everything. Показывать вÑÑ‘. DjView DjView DjVu files Файлы DjVu &Edit Edit| &Правка Enter the URL of a DjVu document: Введите Ð°Ð´Ñ€ÐµÑ URL документа DjVu: Error - DjView dialog caption Ошибка — DjView &Export as... File| &ЭкÑпорт... Export - DjView dialog caption ЭкÑпорт — DjView Export DjVu page or document to other formats. ЭкÑпортировать Ñтраницы или документ DjVu в другие форматы. F10 Settings|Show toolbar F10 F11 View|FullScreen F11 F2 Edit|Select F2 F3 Edit|Find Next F3 F4 Layout|Continuous F4 F5 Layout|SideBySide F5 F9 Settings|Show sidebar F9 &File File| &Файл &Find... Edit| &Ðайти... Find &Next Edit| Ðайти &далее Find next occurence of search text in the document. Ðайти Ñледующее вхождение текÑта в документе. Find &Previous Edit| Ðайти &ранее Find previous occurence of search text in the document. Ðайти предыдущее вхождение текÑта в документе. Find text in the document. Ðайти текÑÑ‚ в документе. &First Page Go| &ÐŸÐµÑ€Ð²Ð°Ñ Ñтраница FitPage zoomCombo Страница целиком Fit &Page Zoom| &Страница целиком FitWidth zoomCombo По ширине Ñтраницы Fit &Width Zoom| По &ширине Ñтраницы Foreground modeCombo Передний план &Foreground Display| &Передний план &Forward Go| &Вперёд Forward in history. Вперёд по иÑтории. &Go Go| Пере&ход Go: page %1. Перейти к Ñтранице %1. &Help Help| &Справка <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Ðепрерывный вид (рулоном).</b><br/> Показывает вÑе Ñтраницы документа в вертикальном раÑположении в прокручиваемой облаÑти проÑмотра документа.</html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ ÐºÑƒÑ€Ñора.</b><br/> Показывает позицию курÑора мыши, выраженную в координатах Ñтраницы. </html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Режим отображениÑ.</b><br/> Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ DjVu ÑоÑтавлÑÑŽÑ‚ÑÑ Ð¸Ð· фона и оÑновного ÑÐ»Ð¾Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ трафарета. Режим Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°ÐµÑ‚ Ñлои, которые должны отображатьÑÑ.</html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ документе и Ñтранице.</b><br> Отображает диалоговое окно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра информации, отноÑÑщейÑÑ Ðº документу или к отдельной Ñтранице.</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Метаданные документа и Ñтраниц.</b><br> Отображает диалоговое окно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра метаданных, отноÑÑщихÑÑ Ðº документу или к отдельной Ñтранице.</html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>ОблаÑть проÑмотра документа.</b><br/> Это — оÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° DjVu. Ðо чтобы что-то увидеть, вы должны Ñначала открыть документ DjVu.</html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>ОблаÑть проÑмотра документа.</b><br/> Это — оÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° DjVu. <ul><li>ИÑпользуйте Ñтрелки и клавиши прокрутки Ñтраниц Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ документу.</li><li>Пробел и BackSpace — чтение документа.</li><li>Клавиши <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> — изменение маÑштаба и поворот документа.</li><li>Ð›ÐµÐ²Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ° мыши — прокрутка и выбор ÑÑылок.</li><li>%3 — отображение контекÑтного меню.</li><li>%1 + Ð»ÐµÐ²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши — выделение текÑта и изображений.</li><li>%2 — показ лупы.</li></ul></html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñтранице.</b><br/> Показывает информацию о Ñтранице, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð¿Ð¾Ð´ курÑором: порÑдковый номер Ñтраницы, размер в пикÑелах и разрешение в точках на дюйм. </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>Поворот Ñтраниц.</b><br/> Выберите показ Ñтраниц в книжной или альбомной ориентации. Ð’Ñ‹ также можете перевернуть их.</html> <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>Выделение прÑмоугольной облаÑти.</b><br/> ПоÑле Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð’Ñ‹ можете Ñкопировать текÑÑ‚ или изображение. ВмеÑто Ñтого инÑтрумента Ð’Ñ‹ также можете иÑпользовать левую кнопку мыши, ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÑƒ %1.</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Показ Ñтраниц парами.</b><br/> Отображает пары Ñтраниц Ñ€Ñдом в прокручиваемой облаÑти проÑмотра документа.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>Изменение маÑштаба.</b><br/> Выберите маÑштаб Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра документа. МаÑштаб 100% подходит Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра документа на Ñкране 100 dpi (100 точек/дюйм). </html> Illegal value '%2' for option '%1'. ÐедопуÑтимое значение '%2' Ð´Ð»Ñ Ð¾Ð¿Ñ†Ð¸Ð¸ '%1'. Image format %1 not supported. Формат Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ %1 не поддерживаетÑÑ. Increase the magnification. Увеличить маÑштаб. &Information... Edit| &ИнформациÑ... Information - DjView dialog caption Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ â€” DjView (in other window.) (в новом окне) Jump to first document page. Перейти к первой Ñтранице документа. Jump to last document page. Перейти к поÑледней Ñтранице документа. Jump to next document page. Перейти к Ñледующей Ñтранице документа. Jump to previous document page. Перейти к предыдущей Ñтранице документа. &Last Page Go| &ПоÑледнÑÑ Ñтраница Go: %1 Link: %1 Перейти к %1 Magnify 100% Увеличение 100% Magnify 150% Увеличение 150% Magnify 20% Увеличение 20% Magnify 300% Увеличение 300% Magnify 50% Увеличение 50% Magnify 75% Увеличение 75% &Metadata... Edit| М&етаданные... Metadata - DjView dialog caption Метаданные - DjView &New File| &Ðовый &Next Page Go| &Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтраница One &to one Zoom| &Один к одному Only display the background layer. Показывать только Ñлой фона. Only display the document bitonal stencil. Показывать только двухцветный шаблон. Only display the foreground layer. Показывать только Ñлой переднего плана. &Open File| &Открыть Open a DjVu document. Открыть документ DjVu. Open a remote DjVu document. Открыть удаленный документ DjVu. Open - DjView dialog caption Открыть - DjView Opening DjVu document Открытие документа DjVu Opening DjVu file Открытие файла DjVu Open &Location... File| Открыть &адреÑ... Open Location - DjView dialog caption Открыть Ð°Ð´Ñ€ÐµÑ â€” DjView Open &Recent Открыть &недавние Option '%1' is not implemented. Параметр «%1» не реализован. Option '%1' is not recognized. Параметр «%1» не раÑпознан. Option '%1' requires a standalone viewer. Параметр «%1» требует режима ÑамоÑтоÑтельного приложениÑ. Option '%1' requires boolean argument. Параметр «%1» требует логичеÑкого аргумента. Prefere&nces... Settings| &ÐаÑтроить DjView... &Previous Page Go| &ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ñтраница &Print... File| &Печать... Print - DjView dialog caption Печать — DjView Print the DjVu document. Печать документа DjVu. &Quit File| &Выход Right Mouse Button правую кнопку мыши &Rotate View|Rotate По&ворот Rotate &0° Rotate| Поворот на &0° Rotate &180° Rotate| Поворот на &180° Rotate &270° Rotate| Поворот на &270° Rotate &90° Rotate| Поворот на &90° Rotate &Left Rotate| Повернуть против &чаÑовой Ñтрелки Rotate page image clockwise. Повернуть Ñтраницу по чаÑовой Ñтрелке. Rotate page image counter-clockwise. Повернуть Ñтраницу против чаÑовой Ñтрелки. Rotate &Right Rotate| Повернуть &по чаÑовой Ñтрелке Save &as... File| Сохранить &как... Save - DjView dialog caption Сохранить — DjView Save image as... Сохранить изображение как... Save Image - DjView dialog caption Сохранение Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ â€” DjView Save text as... Сохранить текÑÑ‚ как... Save Text - DjView dialog caption Сохранение текÑта — DjView Save the DjVu document. Сохранить документ DjVu. &Select Edit| &Выделение Select a rectangle in the document. ПрÑмоугольное выделение в документе. Set full resolution magnification. УÑтановить маÑштаб по разрешению изображениÑ. Set magnification to fit page. УÑтановить маÑштаб по размеру Ñтраниц. Set magnification to fit page width. УÑтановить маÑштаб по ширине Ñтраниц. Set natural page orientation. УÑтановить иÑходную ориентацию Ñтраницы. &Settings Settings| &ÐаÑтройка Shift+F3 Edit|Find Previous Shift+F3 Show/hide the side bar. Показать/Ñкрыть боковую панель. Show/hide the standard tool bar. Показать/Ñкрыть Ñтандартную панель инÑтрументов. Show/hide the status bar. Показать/Ñкрыть Ñтроку ÑоÑтоÑниÑ. Show information about the document encoding and structure. Показать информацию о Ñтруктуре и кодировании документа. Show information about this program. Показать информацию о программе. Show &Sidebar Settings| Показать &боковую панель Show Stat&usbar Settings| Показать Ñтроку &ÑоÑтоÑÐ½Ð¸Ñ Show the document and page meta data. Показать метаданные документа и Ñтраниц. Show the preferences dialog. Показать диалог наÑтройки. Show &Toolbar Settings| Показать &панель инÑтрументов Side &by Side Layout| &Пары Ñтраниц &Stencil Display| &Шаблон Stencil modeCombo Шаблон Stretch zoomCombo РаÑÑ‚Ñнуть Text files save filter ТекÑтовые файлы Toggle continuous layout mode. Показывать Ñтраницы непрерывным полотном. Toggle full screen mode. ПолноÑкранный режим. Toggle side-by-side layout mode. Показывать Ñтраницы парами. Toolbar option '%1' is not implemented. Параметр панели инÑтрументов «%1» не реализован. Toolbar option '%1' is not recognized. Параметр панели инÑтрументов «%1» не раÑпознан. Turn page on its left side. Поворот налево. Turn page on its right side. Поворот направо. Turn page upside-down. Перевернуть Ñтраницу. Unrecognized sidebar options '%1'. Параметр боковой панели «%1» не раÑпознан. &View View| &Вид x=%1 y=%2 x=%1 y=%2 &Zoom View|Zoom &МаÑштаб Zoom &In Zoom| &Увеличить Zoom &Out Zoom| У&меньшить Zoom to rectangle Увеличить по выделению Go: 1 page forward. Перейти на 1 Ñтраницу вперед. Go: %n pages forward. Перейти на %n Ñтраницу вперед. Перейти на %n Ñтраницы вперед. Перейти на %n Ñтраниц вперед. Go: 1 page backward. Перейти на 1 Ñтраницу назад. Go: %n pages backward. Перейти на %n Ñтраницу назад. Перейти на %n Ñтраницы назад. Перейти на %n Ñтраниц назад. %n characters %n Ñимвол %n Ñимвола %n Ñимволов Copy &URL Edit| Скопировать Ð°Ð´Ñ€ÐµÑ &URL Hidden Text modeCombo Скрытый текÑÑ‚ I&nvert Luminance View| Инвертировать &ÑркоÑть Invert image luminance while preserving hue. Инвертировать ÑркоÑть изображениÑ, не менÑÑ Ð¾Ñ‚Ñ‚ÐµÐ½ÐºÐ¾Ð². &Full Screen View| Ðа веÑÑŒ &Ñкран &Slide Show View| &Слайд-шоу Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. Слайд-шоу режим. Save an URL for the current page into the clipboard. Сохранить Ð°Ð´Ñ€ÐµÑ URL текущей Ñтраницы в буфер обмена. Ctrl+C Edit|CopyURL Ctrl+C Copy &Outline Edit| Скопировать ÑпиÑок &глав Save the djvused code for the outline into the clipboard. Сохранить в буфер обмена ÑпиÑок глав, определённый утилитой djvused. Copy &Annotations Edit| Скопировать &Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Save the djvused code for the page annotations into the clipboard. Сохранить в буфер обмена примечаниÑ, извлечённые из документа утилитой djvused. <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ñ Ð¿Ð¾ документу.</b><br/> Ð’Ñ‹ можете перейти к любой Ñтранице по её имени, нажав Ctrl+G. Кнопки навигации позволÑÑŽÑ‚ перейти к первой, предыдущей, Ñледующей или поÑледней Ñтранице. </html> Thumbnails Макеты Ñтраниц Outline Главы Find ПоиÑк Certificate validation error - DjView dialog caption Ðевозможно удоÑтоверить Ñертификат — DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Продолжить выполнение запрошенного дейÑтвиÑ? </html> <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html> Этот файл на данном Ñервере опубликован Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸ÐµÐ¼ на печать. Ðапечатать его неÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° Ñто?</html> <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html> Этот файл на данном Ñервере опубликован Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸ÐµÐ¼ на Ñохранение. Сохранить его неÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° Ñто?</html> P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi %3x%4+%1+%2 %3x%4+%1+%2 Copy text into the clipboard. Сохранить текÑÑ‚ в буфер обмена. Save text into a file. Сохранить текÑÑ‚ в файл. Save image into a file. Сохранить изображение в файл. Zoom the selection to fit the window. Увеличить выделенную облаÑть до размеров окна. Copy URL Скопировать Ð°Ð´Ñ€ÐµÑ URL Save into the clipboard an URL that highlights the selection. Сохранить в буфер обмена URL Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о выделении. Copy Maparea Скопировать maparea Save into the clipboard a maparea annotation expression for program djvused. Сохранить в буфер обмена директиву примечаний maparea, ÑоответÑтвующую выделению, полученную c помощью утилиты djvused. Copy image into the clipboard. Скопировать изображение в буфер обмена. Co&ver Page Layout| &Титульный лиÑÑ‚ Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. Показывать первую Ñтраницу отдельно в режиме пар Ñтраниц. &Right to Left Layout| &Справа налево Ctrl+Shift+F6 Layout|RightToLeft Ctrl+Shift+F6 Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. Показывать Ñтраницы Ñправа налево в режиме пар Ñтраниц. <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>Программа проÑмотра документов DjVu<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>Ð”Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð° - Ñвободное программное обеÑпечение. Ð’Ñ‹ можете раÑпроÑтранÑть и/или модифицировать ее на уÑловиÑÑ… Стандартной ОбщеÑтвенной Лицензии GNU (GNU General Public License), опубликованной Фондом Свободного ПО (Free Software Foundation). Ð”Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ð´Ð°Ð¼Ð¼Ð° раÑпроÑтранÑетÑÑ <i>без каких-либо гарантий</i>. ПодробноÑти Ñмотрите в Стандартной ОбщеÑтвенной Лицензии GNU (GNU General Public License).</small></p></html> All files Ð’Ñе файлы &Hidden Text Display| &Скрытый текÑÑ‚ Overlay a representation of the hidden text layer. Показывать также Ñлой Ñкрытого текÑта. QDjViewApplication cannot open '%1'. не удаетÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ «%1». Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. ИÑпользование: djview [параметры] [Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° или Ð°Ð´Ñ€ÐµÑ URL] ОÑновные параметры: -help~~~Выводит Ñто Ñообщение. -verbose~~~Выводить вÑе предупреждениÑ. -display <xdpy>~~~Выбор диÑÐ¿Ð»ÐµÑ X11. -geometry <xgeom>~~~Выбор иÑходной геометрии окна. -font <xlfd>~~~Выбор имени оÑновного шрифта X11. -style <qtstyle>~~~Выбор ÑÑ‚Ð¸Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкого интерфейÑа Qt. -fullscreen, -fs~~~ЗапуÑтить в полноÑкранном режиме. -page=<page>~~~Перейти к Ñтранице <page>. -zoom=<zoom>~~~Задать маÑштаб. -continuous=<yn>~~~УÑтановить непрерывный проÑмотр. -sidebyside=<yn>~~~Показывать пары Ñтраниц. QDjViewAuthDialog Password: Пароль: User: Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: Authentication required - DjView ТребуетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ â€” DjView QDjViewDjVuExporter &Cancel О&тмена Con&tinue &Продолжить DjVu Bundled Document СвÑзанный документ DjVu (в одном файле) DjVu Files (*.djvu *.djv) Файлы DjVu (*.djvu *.djv) DjVu Indirect Document ÐепрÑмой документ DjVu (Ñтраницы в отдельных файлах) <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> Этот файл находитÑÑ Ð² непуÑтом каталоге. При Ñохранении в непрÑмом формате будет Ñоздано множеÑтво файлов в Ñтом каталоге. Ð’Ñ‹ риÑкуете заменить файлы в данном каталоге. Продолжить?</html> Question - DjView dialog caption Ð’Ð¾Ð¿Ñ€Ð¾Ñ â€” DjView Save job creation failed! Ðе удалоÑÑŒ запуÑтить процеÑÑ ÑохранениÑ! System error: %1. СиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %1. Unknown error. ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. QDjViewErrorDialog DjView Error Ошибка DjView Error - DjView dialog caption Ошибка — DjView &Ok &OK QDjViewExportDialog A file with this name already exists. Do you want to replace it? Файл Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует. Заменить его? All files save filter Ð’Ñе файлы &Cancel О&тмена C&urrent page &Текущую Ñтраницу &Defaults &По умолчанию Destination Результат Dialog Диалог &Document &Документ Error - DjView dialog caption Ошибка — DjView Export ЭкÑпортировать Export - DjView dialog caption ЭкÑпорт — DjView Format: Формат: <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>Сохранение.</b><br/> Ð’Ñ‹ можете Ñохранить веÑÑŒ документ или диапазон Ñтраниц в различных форматах. ПоÑле выбора определённого формата поÑвлÑÑŽÑ‚ÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ вкладки Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ формата.</html> &Ok &OK Overwriting the current file is not allowed! Замена текущего файла не позволÑетÑÑ! &Pages &Страницы от Question - DjView dialog caption Ð’Ð¾Ð¿Ñ€Ð¾Ñ â€” DjView &Replace &Заменить Stop ОÑтановить This operation has been interrupted. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð±Ñ‹Ð»Ð° прервана. This operation has failed. Ðе удалоÑÑŒ выполнить операцию. to до QDjViewExportPS1 &Color &Цветной Color Цвет Form Форма &GrayScale &Оттенки Ñерого Language Level Уровень Ñзыка PostScript Marks Разметка PostScript Cтандарт PostScript Print crop &marks Печатать &разметку Ñтраницы Print image &frame Печатать &рамку Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ QDjViewExportPS2 % % Automatic ÐвтоматичеÑки Form Форма &Landscape &ÐÐ»ÑŒÐ±Ð¾Ð¼Ð½Ð°Ñ Orientation ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ &Portrait &ÐšÐ½Ð¸Ð¶Ð½Ð°Ñ Scale to &fit the page МаÑштабировать по &размеру Ñтраницы Scaling МаÑштабирование &Zoom &МаÑштаб QDjViewExportPS3 /100 /100 Advanced Продвинутые параметры at most не более Center: Центральное поле: Form Форма per page. на Ñтраницу. plus Ð¿Ð»ÑŽÑ points точек points. точек. Print Печатать Print sheets suitable for folding a booklet. Печать лиÑтов Ð´Ð»Ñ ÑоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±ÑƒÐºÐ»ÐµÑ‚Ð°. rectos and versos. чётные и нечётные лиÑты. rectos only. только нечётные лиÑты. Sheets per booklet: Страниц на буклет: Shift rectos and versos by Смещать чётные лиÑты от нечётных лиÑтов на Unlimited Без ограничений versos only. только чётные лиÑты. QDjViewExportPrn % % Automatic ÐвтоматичеÑки Color Цвет &Color &Цвет Form Форма &GrayScale &Оттенки Ñерого &Landscape &ÐÐ»ÑŒÐ±Ð¾Ð¼Ð½Ð°Ñ Marks Разметка Orientation ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ &Portrait &ÐšÐ½Ð¸Ð¶Ð½Ð°Ñ Print crop &marks Печатать &разметку Ñтраницы Print image &frame Печатать &рамку Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Scale to &fit the page МаÑштабировать по &размеру Ñтраницы Scaling МаÑштабирование &Zoom &МаÑштаб QDjViewExportTiff Allow &deflate compression. ПозволÑть Ñжатие &без потерь deflate. Allow &lossy JPEG compression. ПозволÑть Ñжатие JPEG Ñ &потерÑми. Compression Сжатие dpi DPI Force &bitonal G4 compression. ПрименÑть &чёрно-белое Ñжатие G4. Form Форма JPEG &quality &КачеÑтво JPEG Maximum image resolution МакÑимальное разрешение Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Resolution Разрешение QDjViewFind Case sensitive С учётом региÑтра Find Next (F3) Ðайти далее (F3) Find Previous (Shift+F3) Ðайти ранее (Shift+F3) <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>ПоиÑк текÑта.</b><br/> Результаты поиÑка поÑвлÑÑŽÑ‚ÑÑ Ð¿Ð¾Ñтепенно по мере набора. Ðажмите Enter Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° к Ñледующему результату. ИÑпользуйте кнопки Ñо Ñтрелками или <tt>F3</tt> и <tt>Shift+F3</tt> Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° к Ñледующему/предыдущему результату. Ð’Ñ‹ также можете иÑпользовать двойной щелчок мышью на названии Ñтраницы. Ð’ меню <tt>ÐаÑтройка</tt> можно наÑтроить поиÑк только Ñлов и чувÑтвительноÑть к региÑтру.</html> Options ÐаÑтройка Words only Только Ñлова Regular expression РегулÑрное выражение Reset search options to default values. ВернутьÑÑ Ðº параметрам поиÑка по умолчанию. Specify whether search hits must begin on a word boundary. ИÑкать по первым буквам целых Ñлов. Specify whether searches are case sensitive. Требовать точного ÑовпадениÑ, Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð°Ñ Ð·Ð°Ð³Ð»Ð°Ð²Ð½Ñ‹Ðµ и Ñтрочные буквы. Regular expressions describe complex string matching patterns. РегулÑрные Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹ Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° Ñложных шаблонов поиÑка текÑта. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Справка по регулÑрным выражениÑм</b><ul><li>Точка (<tt><b>.</b></tt>) ÑопоÑтавлÑетÑÑ Ñ Ð»ÑŽÐ±Ñ‹Ð¼ Ñимволом.</li><li>БольшинÑтво Ñимволов в регулÑрном выражении ÑопоÑтавлÑетÑÑ Ñ Ñ‚ÐµÐ¼Ð¸ же Ñимволами в текÑте.</li><li>ДобавлÑйте обратный ÑлÑш (<tt><b>\</b></tt>) перед Ñимволами <tt><b>()[]{}|*+.?!^$\</b></tt>, еÑли хотите отменить их Ñпециальное значение.</li><li><tt><b>\b</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†ÐµÐ¹ Ñлова.</li><li><tt><b>\w</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð»ÑŽÐ±Ñ‹Ð¼ Ñимволом, который может входить в Ñлово (буквы, цифры, знак нижнего подчёркиваниÑ).</li><li><tt><b>\d</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ñ†Ð¸Ñ„Ñ€Ð¾Ð¹.</li><li><tt><b>\s</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð¿Ñ€Ð¾Ð±ÐµÐ»ÑŒÐ½Ñ‹Ð¼ Ñимволом.</li><li><tt><b>\n</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ñимволом новой Ñтроки.</li><li><tt><b>[a-b]</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð»ÑŽÐ±Ñ‹Ð¼ Ñимволом в диапазоне от <tt><b>a</b></tt> до <tt><b>b</b></tt>.</li><li><tt><b>[^a-b]</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð»ÑŽÐ±Ñ‹Ð¼ Ñимволом вне диапазона от <tt><b>a</b></tt> до <tt><b>b</b></tt>.</li><li><tt><b>a|b</b></tt> ÑопоÑтавлÑетÑÑ Ñ Ð¾Ð´Ð½Ð¸Ð¼ из регулÑрных выражений <tt><b>a</b></tt> и <tt><b>b</b></tt>.</li><li><tt><b>a{n,m}</b></tt> ÑоответÑтвует регулÑрному выражению <tt><b>a</b></tt>, повторенному от <tt><b>n</b></tt> до <tt><b>m</b></tt> раз.</li><li><tt><b>a?</b></tt>, <tt><b>a*</b></tt>, и <tt><b>a+</b></tt> ÑвлÑÑŽÑ‚ÑÑ ÑокращениÑми Ð´Ð»Ñ <tt><b>a{0,1}</b></tt>, <tt><b>a{0,}</b></tt> и <tt><b>a{1,}</b></tt> ÑоответÑтвенно.</li><li>ИÑпользуйте Ñкобки <tt><b>()</b></tt> Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²ÐºÐ¸ регулÑрного Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ Ñимволами <tt><b>?+*{</b></tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 результат <html>Document is not searchable. No page contains information about its textual content.</html> <html>ПоиÑк в документе невозможен. Ðи одна из Ñтраниц не Ñодержит текÑтовой информации.</html> No hits! Ðет Ñовпадений! Page %1 (1 hit) Page %1 (1 результат) Searching page %1. ПоиÑк на Ñтранице %1. Searching page %1 (waiting for data.) ПоиÑк на Ñтранице %1 (ожидание данных) %n hits %n Ñовпадение %n ÑÐ¾Ð²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ %n Ñовпадений Page %1 (%n hits) Страница %1 (%n результат) Страница %1 (%n результата) Страница %1 (%n результатов) <html>Invalid regular expression.</html> <html>Ошибка в регулÑрном выражении.</html> QDjViewImgExporter %1 Files (*.%2) JPG Files Файлы %1 (*.%2) %1 Image JPG Image Изображение %1 Cannot render page. Ðевозможно преобразовать Ñтраницу. Image format %1 not supported. Формат Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ %1 не поддерживаетÑÑ. QDjViewInfoDialog Bundled DjVu document СвÑзанный документ DjVu (в одном файле) &Close &Закрыть Dialog Диалог &Document &Документ &File &Файл File # â„– файла File: Файл: File #%1 - Файл â„–%1 - File Name Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° File Size Размер файла File Type Тип файла <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ документе</b><br>Эта панель показывает информацию о документе и его файлах-компонентах. Выберите файл Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра подробной информации во вкладке <tt>Файл</tt>. Ð’Ñ‹ можете перейти к Ñтранице двойным щелчком по ÑоответÑтвующей Ñтроке. </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ файле или Ñтранице</b><br>Эта панель показывает Ñтруктуру данных DjVu, ÑоответÑтвующих компонентному файлу или Ñтранице, выбранной во вкладке <tt>Документ</tt>. Кнопки Ñо Ñтрелками позволÑÑŽÑ‚ перейти к предыдущему или Ñледующему компонентному файлу.</html> Indirect DjVu document ÐепрÑмой документ DjVu (Ñтраницы в отдельных файлах) n/a недоÑтупен Obsolete bundled DjVu document УÑтаревший формат ÑвÑзанного документа DjVu Obsolete indexed DjVu document УÑтаревший формат индекÑированного документа DjVu Page Страница Page # â„– Ñтраницы Page #%1 Страница â„–%1 Page #%1 - « %2 » Страница â„–%1 — «%2» Page Title Заголовок Ñтраницы Shared Общий Shared annotations Общие Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Shared data Общие данные Single DjVu page ÐžÐ´Ð¸Ð½Ð¾Ñ‡Ð½Ð°Ñ Ñтраница DjVu Thumbnails Макеты Ñтраниц Thumbnails Макеты Ñтраниц &View Page &ПроÑмотр Ñтраницы Waiting for data... Ожидание данных... 1 file 1 файл %n files %n файл %n файла %n файлов 1 page 1 Ñтраница %n pages %n Ñтраница %n Ñтраницы %n Ñтраниц QDjViewMetaDialog &Close &Закрыть Ctrl+C copy Ctrl+C Dialog Диалог &Document Metadata &Метаданные документа <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Метаданные документа</b><br>Эта панель отображает метаданные, отноÑÑщиеÑÑ Ðº документу, такие как автор, заголовок, ÑÑылки и тому подобное. Эта Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть запиÑана в документ программой <tt>djvused</tt>: иÑпользуйте команды <tt>create-shared-ant</tt> и <tt>set-meta</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Метаданные Ñтраницы</b><br>Эта панель отображает метаданные, отноÑÑщиеÑÑ Ðº отдельной Ñтранице. Метаданные Ñтраницы переопределÑÑŽÑ‚ метаданные документа. Эта Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть запиÑана в документ программой <tt>djvused</tt>: иÑпользуйте команду <tt>select</tt> Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° Ñтраницы и команду <tt>set-meta</tt> Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð¼ÐµÑ‚Ð°Ð´Ð°Ð½Ð½Ñ‹Ñ….</html> Key Ключ Page: Страница: &Page Metadata Метаданные &Ñтраницы Value Значение &View Page &ПроÑмотр Ñтраницы QDjViewOutline Go: page %1. Go: page %1 Перейти к Ñтранице %1. <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>ЭÑкиз документа.</b><br/> Эта панель отображает ÑÑкиз документа или Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñтраниц, еÑли ÑÑкиз недоÑтупен. Двойным щелчком можно перейти к выбранной Ñтранице.</html> Outline data is corrupted Данные ÑÑкиза иÑпорчены Page %1 Страница %1 Go: %1 Go: %1. Перейти к %1 Pages Страницы QDjViewPSExporter Booklet tab caption Буклет Encapsulated PostScript ИнкапÑулированный PostScript <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Положение и маÑштаб.</b><br>Параметр <tt>МаÑштабировать по размеру Ñтраницы</tt> приÑпоÑабливает документ к размерам лиÑтов бумаги, иÑпользуемой вашим принтером. МаÑштаб <tt>100%</tt> воÑпроизводит иÑходный размер документа. Параметр ориентации <tt>ÐвтоматичеÑки</tt> выбирает книжную или альбомную ориентацию по размерам каждой Ñтраницы.</html> <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>Параметры PostScript.</b><br>Параметр <tt>Цветной</tt> включает цветную печать. К Ñтраницам может быть добавлена рамка и разметка. Уровень Ñзыка PostScript 1 (PostScript Level 1) полезен только при работе Ñ Ð¾Ñ‡ÐµÐ½ÑŒ Ñтарыми принтерами. PostScript Level 2 работает Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð½Ñтвом принтеров. PostScript Level 3 работает быÑтрее при цветной печати на Ñовременных принтерах.</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Изготовление буклетов.</b><br>Ð’ режиме буклета печатаютÑÑ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ñтраницы в виде лиÑтов, готовых Ð´Ð»Ñ ÑоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ или неÑкольких буклетов. Ð’Ñ‹ можете либо пользоватьÑÑ Ð´Ð²ÑƒÑ…Ñторонним принтером, либо печатать отдельно чётные и нечётные лиÑты.<p> Смещение чётных лиÑтов от нечётных полезно при печати на плохо Ñовмещённых двухÑторонних принтерах. Центральное поле определÑет размер пуÑтого проÑтранÑтва между Ñтраницами на одном лиÑте. Этот размер медленно увеличиваетÑÑ Ð¾Ñ‚ внутреннего лиÑта к внешнему.</html> Position tab caption ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ PostScript PostScript PostScript tab caption PostScript PostScript Files (*.ps *.eps) Файлы PostScript (*.ps *.eps) Save job creation failed! Ðе удалоÑÑŒ запуÑтить процеÑÑ ÑохранениÑ! QDjViewPdfExporter Error while creating pdf file. Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° PDF. <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>Параметры PDF.</b><br>Эти параметры управлÑÑŽÑ‚ характериÑтиками изображений, вÑтраиваемых в ÑкÑпортируемые файлы PDF. Элемент «Разрешение» задаёт верхнюю границу Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹. При применении чёрно-белого ÑÐ¶Ð°Ñ‚Ð¸Ñ G4 вÑе Ñтраницы кодируютÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ÑÐ¶Ð°Ñ‚Ð¸Ñ CCITT Group 4. Сжатие JPEG будет применÑтьÑÑ ÐºÐ¾ вÑем цветным изображениÑм.</html> PDF Document Документ PDF PDF export was not compiled. ЭкÑпорт в PDF не был выполнен. PDF Files (*.pdf) Файлы PDF (*.pdf) PDF Options tab caption Параметры PDF System error: %1. СиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %1. Unable to create output file. Ðе удалоÑÑŒ Ñоздать выходной файл. Unable to create temporary file. Ðе удалоÑÑŒ Ñоздать временный файл. Unable to reopen temporary file. Ðе удалоÑÑŒ заново открыть временный файл. QDjViewPlugin::Document Requesting %1. ЗапрашиваетÑÑ %1. QDjViewPrefsDialog &Apply &Применить Cache КÑш Cancel Отмена &Clear &ОчиÑтить Darker Темнее Timer: Задержка Ñтраниц: &Decoded page cache: КÑш &декодированных Ñтраниц: Interface Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Show hidden text in status bar Показывать Ñкрытый текÑÑ‚ в Ñтроке ÑоÑтоÑÐ½Ð¸Ñ Render with openGL when available ÐариÑуйте Ñ OpenGL при наличии Override saving and printing restrictions Игнорировать запреты на печать и Ñохранение &Defaults &По умолчанию Dialog Диалог Display Отображение Display &annotations Показывать &Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Display page &frames Показывать &рамки Ñтраниц Embedded Plugin вÑтраиваемого плагина Enable magnifying &lens Включить &лупу For displaying hyper&links: Ð”Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ &гиперÑÑылок: For displaying the &lens: Ð”Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° &лупы: For &selecting text or images: Ð”Ð»Ñ &Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑта и изображений: Full Page Plugin полноÑтраничного плагина Gamma Гамма &Host: &ХоÑÑ‚: <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>ИÑходные параметры интерфейÑа.</b><br>DjView может быть запущен как ÑамоÑтоÑтельное приложение, в полноÑкранном режиме, в виде плагина браузера или плагина, вÑтроенного в Ñтраницу HTML. Ð”Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑÐ»ÑƒÑ‡Ð°Ñ ÑƒÑтановите параметр <tt>Запоминать наÑтройку</tt> Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкого ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð² интерфейÑа. Иначе, определите начальную конфигурацию.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>Клавиши-модификаторы.</b><br>Определите, какие комбинации клавиш-модификаторов будут показывать лупу, временно включать режим Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ подÑвечивать гиперÑÑылки.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><p><b>Advanced.</b>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>Продвинутые.</b><br>Ðа Ñтой вкладке можно переопределить Ñзык интерфейÑа по умолчанию, запретить анимацию Ñтраниц, а также включить дополнительные пункты меню программы. Можно также отключить Ñледование ограничениÑм, уÑтанавливаемым некоторыми веб-Ñайтами. Ð ÑƒÑ‡Ð½Ð°Ñ Ð½Ð°Ñтройка цветовой коррекции может быть полезна при иÑпользовании Ñтарых принтеров.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>Параметры прокÑи.</b><br>Эти параметры прокÑи иÑпользуютÑÑ, когда проÑмотрщик в качеÑтве ÑамоÑтоÑтельного Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ñ‰Ð°ÐµÑ‚ÑÑ Ðº документу DjVu по протоколу HTTP. ЕÑли проÑмотрщик запуÑкаетÑÑ Ðº виде плагина, вÑегда иÑпользуютÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ браузера Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи.<p><b>Параметры кÑшированиÑ.</b><br><i>ПикÑельный кÑш</i> хранит данные Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ð½Ðµ видимой облаÑти. Этот кÑш обеÑпечивает плавную прокрутку. <i>КÑш декодированных Ñтраниц</i> Ñодержит чаÑтично декодированные Ñтраницы. Он обеÑпечивает более короткое Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ÐºÐ»Ð¸ÐºÐ° при повторном проÑмотре Ñтраниц многоÑтраничного документа. ОчиÑтка кÑша может быть полезна Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ñтраницы без перезапуÑка проÑмотрщика.</html> Standalone Viewer (Full Screen mode) автономный проÑмотр (полноÑкранный режим) Standalone Viewer (Slideshow mode) автономный проÑмотр (Ñлайд-шоу режим) <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ.<br>УÑтановите ползунок так, чтобы оттенки Ñерого выглÑдели макÑимально похожими.</html> Force inverted luminance Force inverted luminance. Принудительно инвертировать ÑркоÑть &Interface &Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ s secs c &Keys &Комбинации клавиш Keys Комбинации клавиш Mouse wheel КолеÑо мыши Mouse wheel scrolls the page Mouse wheel scrolls the page. КолеÑо мыши прокручивает Ñтраницу Mouse wheel changes the zoom factor Mouse wheel changes the zoom factor. КолеÑо мыши менÑет маÑштаб &Lens &Лупа Lens options Параметры лупы Lens &size: &Размер: Lighter Светлее Magnifying &power: &Увеличение: &Menu bar &Меню &Network &Сеть &Ok &OK Options for Параметры Ð´Ð»Ñ Pass&word: &Пароль: &Pixel cache: &ПикÑельный кÑш: pixels пикÑелов &Port: Пор&Ñ‚: Preferences[*] - DjView ÐаÑтройка[*] — DjView Proxy settings ÐаÑтройка прокÑи &Remember initial state from last invocation &Запоминать параметры, которые иÑпользовалиÑÑŒ в поÑледний раз Sc&rollbars &ПолоÑÑ‹ прокрутки Show Показывать &Side bar &Ð‘Ð¾ÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ Standalone Viewer автономный проÑмотр Stat&us bar Строка &ÑоÑтоÑÐ½Ð¸Ñ &Tool bar &Панель инÑтрументов Use pro&xy to access the network ИÑпользовать &прокÑи Ð´Ð»Ñ Ð´Ð¾Ñтупа к Ñети &User: &Пользователь: x x &Zoom: &МаÑштаб: <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>Ð­ÐºÑ€Ð°Ð½Ð½Ð°Ñ Ð³Ð°Ð¼Ð¼Ð°-коррекциÑ.</b><br>Ð›ÑƒÑ‡ÑˆÐ°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð° доÑтигаетÑÑ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸ÐµÐ¼ ползунка гамма-коррекции и выбором позиции, при которой Ñерый квадрат кажетÑÑ Ð¼Ð°ÐºÑимально однородным.<p><b>Разрешение Ñкрана.</b><br>Этот параметр менÑет разрешение на выбранное, параметр полезен при неправильном определении Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемой. При выборе Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ 100 DPI поведение Ñовпадает Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸ÐµÐ¼ утилит командной Ñтроки djvulibre.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Лупа.</b><br>Лупа поÑвлÑетÑÑ, когда вы нажимаете комбинацию клавиш, определенную на вкладке <tt>Комбинации клавиш</tt>. Эта панель позволÑет выбрать размер и увеличение лупы.</html> &Screen &Экран Force screen &resolution Переопределить &разрешение Ñкрана dpi DPI &Advanced &Дополнительные MB Мб Miscellaneous Разное Force language (next time djview runs) Force language (when djview is restarted.) ЗафикÑировать Ñзык интерфейÑа (Ñо Ñледующего запуÑка) Manual printer color correction ÐаÑтроить цветовую коррекцию принтера вручную gamma= гамма= Enable page animations Enable animations Включить анимацию Ñтраниц Enable advanced features in menus Добавить в меню дополнительные возможноÑти Layout Вид Continuous Ðепрерывный Side-by-side Пары Ñтраниц Cover Page Титульный лиÑÑ‚ Right-to-Left Справа налево QDjViewPrintDialog A file with this name already exists. Do you want to replace it? Файл Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует. Заменить его? All files save filter Ð’Ñе файлы &Cancel О&тмена Choose Выбрать C&urrent page &Текущую Ñтраницу &Defaults &По умолчанию Destination Результат Dialog Диалог &Document &Документ <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Печать.</b><br/> Ð’Ñ‹ можете напечатать веÑÑŒ документ или диапазон Ñтраниц. ИÑпользуйте кнопку <tt>Выбрать</tt>, чтобы выбрать и наÑтроить принтер. ИÑпользуйте другие вкладки Ð´Ð»Ñ Ð½Ð°Ñтройки Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¾Ð².</html> &Ok &OK &Pages &Страницы от Print Печатать Printer name: Ð˜Ð¼Ñ Ð¿Ñ€Ð¸Ð½Ñ‚ÐµÑ€Ð°: Print to file Печать в файл Print To File - DjView dialog caption Печать в файл — DjView Question - DjView dialog caption Ð’Ð¾Ð¿Ñ€Ð¾Ñ - DjView &Replace &Заменить Stop ОÑтановить This operation has been interrupted. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð±Ñ‹Ð»Ð° прервана. This operation has failed. Ðе удалоÑÑŒ выполнить операцию. to до (invalid printer) (недопуÑтимый принтер) QDjViewPrnExporter Cannot render page %1. Ðевозможно преобразовать Ñтраницу %1. <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Параметры печати.</b><br>Параметр <tt>Цвет</tt> включает цветную печать. К Ñтраницам документа может быть добавлена рамка. Параметр <tt>МаÑштабировать по размеру Ñтраницы</tt> приÑпоÑабливает документ к размерам лиÑтов бумаги, иÑпользуемой вашим принтером. МаÑштаб <tt>100%</tt> воÑпроизводит иÑходный размер документа. Параметр ориентации <tt>ÐвтоматичеÑки</tt> выбирает книжную или альбомную ориентацию по размерам каждой Ñтраницы.</html> Printer data Данные принтера Printing Options tab caption Параметры печати PRN Files (*.prn) Файлы PRN (*.prn) QDjViewSaveDialog A file with this name already exists. Do you want to replace it? Файл Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует.Заменить его? All files save filter Ð’Ñе файлы Bundled DjVu Document СвÑзанный документ DjVu (в одном файле) &Cancel О&тмена C&urrent page &Текущую Ñтраницу Destination Результат Dialog Диалог &Document &Документ Error - DjView dialog caption Ошибка — DjView Format: Формат: <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>Сохранение.</b><br/> Ð’Ñ‹ можете Ñохранить веÑÑŒ документ или диапазон Ñтраниц.</html> Indirect DjVu Document ÐепрÑмой документ DjVu (Ñтраницы в отдельных файлах) &Ok &OK Overwriting the current file is not allowed! Замена текущего файла не позволÑетÑÑ! &Pages &Страницы от Question - DjView dialog caption Ð’Ð¾Ð¿Ñ€Ð¾Ñ â€” DjView &Replace &Заменить Save Сохранить Save - DjView dialog caption Сохранение — DjView Stop ОÑтановить This operation has been interrupted. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð±Ñ‹Ð»Ð° прервана. This operation has failed. Ðе удалоÑÑŒ выполнить операцию. to до QDjViewThumbnails Control Left Mouse Button Control + левую кнопку мыши <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Макеты Ñтраниц документа.</b><br/> Эта панель отображает макеты Ñтраниц документа. Двойной щелчок перемещает к выбранной Ñтранице. ИÑпользуйте %1, чтобы изменить размер макетов или режим обновлениÑ. Ð’ умном режиме Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÐµÑ‚Ñ‹ показываютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ñ‚ÐµÑ… Ñтраниц, которые либо отображаютÑÑ, либо кÑшированы.</html> Large thumbnail menu Большие Medium thumbnail menu Средние Right Mouse Button правую кнопку мыши Small thumbnail menu Маленькие Smart thumbnail menu Умные Tiny thumbnail menu Крошечные QDjViewTiffExporter Cannot open output file. Ðе удалоÑÑŒ открыть выходной файл. <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>Параметры TIFF.</b><br>Элемент «Разрешение» задаёт верхнюю границу Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ TIFF. При применении чёрно-белого ÑÐ¶Ð°Ñ‚Ð¸Ñ G4 вÑе Ñтраницы кодируютÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ÑÐ¶Ð°Ñ‚Ð¸Ñ CCITT Group 4. Сжатие JPEG будет применÑтьÑÑ ÐºÐ¾ вÑем цветным изображениÑм.</html> Internal error. ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Out of memory. ÐедоÑтаточно памÑти. TIFF Document Документ TIFF TIFF export has not been compiled. ЭкÑпорт в TIFF не был выполнен. TIFF Files (*.tiff *.tif) Файлы TIFF (*.tiff *.tif) TIFF Options tab caption Параметры TIFF QDjVuNetDocument Requesting '%1' ЗапрашиваетÑÑ Â«%1» QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code Получен ÑÑ‚Ð°Ñ‚ÑƒÑ HTTP %1 при запроÑе %2. Received <%1> data while retrieving %2. %1 is a mime type Получены данные %1 при запроÑе %2. %1 while retrieving '%2'. %1 при запроÑе «%2». Cannot validate the certificate for server %1. Ðевозможно удоÑтоверить Ñертификат Ñервера %1. Authentication required for %1 (%2). ТребуетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð»Ñ %1 (%2). Authentication required for proxy %1. ТребуетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи-Ñервера %1. djview4-4.10.5/src/djview_uk.ts000066400000000000000000005305461264256014000163200ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language УкраїнÑька QApplication Option '-fix' is deprecated. Параметр '-fix' Ñ” заÑтарілим. QDjView FitWidth zoomCombo Підібрати ширину FitPage zoomCombo Підібрати виÑоту Stretch zoomCombo РозтÑгнути 1:1 zoomCombo 1:1 300% zoomCombo 300% 200% zoomCombo 200% 150% zoomCombo 150% 100% zoomCombo 100% 75% zoomCombo 75% 50% zoomCombo 50% Color modeCombo Колір Stencil modeCombo Шаблон Foreground modeCombo Передній план Background modeCombo Тло &New File| С&творити Ctrl+N File|New Ctrl+N Create a new DjView window. Створити нове вікно DjView. &Open File| &Відкрити Open a DjVu document. Відкрити документ DjVu. Close this window. Закрити це вікно. Close all windows and quit the application. Закрити вÑÑ– вікна та вийти з програми. Save the DjVu document. Зберегти документ DjVu. Print the DjVu document. Друкувати документ DjVu. Find text in the document. Знайти текÑÑ‚ у документі. Find next occurence of search text in the document. Шукати наÑтупне Ð²Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÑту до документа. Find previous occurence of search text in the document. Шукати попереднє Ð²Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÑту до документа. Select a rectangle in the document. Обрати прÑмокутну облаÑть у документі. Increase the magnification. Збільшити облаÑть переглÑду. Decrease the magnification. Зменшити облаÑть переглÑду. Set magnification to fit page width. Ð’Ñтановити маÑштаб так, щоб було видно вÑÑŽ виÑоту Ñторінки. Set magnification to fit page. Ð’Ñтановити маÑштаб так, щоб було видно вÑÑŽ ширину Ñторінки. Set full resolution magnification. Ð’Ñтановити показ у натуральному розмірі. Magnify 300% МаÑштаб у 300% Magnify 20% МаÑштаб у 200% Magnify 150% МаÑштаб у 150% Magnify 100% МаÑштаб у 100% Magnify 75% МаÑштаб у 75% Magnify 50% МаÑштаб у 50% Jump to first document page. Перейти до першої Ñторінки документа. Jump to next document page. Перейти до наÑтупної Ñторінки документа. Jump to previous document page. Перейти до попередньої Ñторінки документа. Jump to last document page. Перейти до оÑтанньої Ñторінки документа. Backward in history. Ðазад за журналом. Forward in history. Вперед за журналом. Rotate page image counter-clockwise. ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ¸ Ñторінки проти годинникової Ñтрілки. Rotate page image clockwise. ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ¸ Ñторінки за годинниковою Ñтрілкою. Set natural page orientation. Зберегти початкову орієнтацію Ñторінки. Turn page on its left side. Повернути Ñторінку на Ñ—Ñ— лівий бік. Turn page upside-down. Перевернути Ñторінку догори низом. Turn page on its right side. Повернути Ñторінку на Ñ—Ñ— правий бік. Show information about the document encoding and structure. Показати інформацію про ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° та його Ñтруктуру. Show the document and page meta data. Показати метадані документа та Ñторінки. &About DjView... &Про DjView... Show information about this program. Показати інформацію про цю програму. Display everything. Показувати вÑе. Only display the document bitonal stencil. Показати тільки двокольоровий шаблон документа. Only display the foreground layer. Показувати лише передній план. Only display the background layer. Показувати лише задній план. Show the preferences dialog. Показати діалог налаштуваннÑ. Show/hide the side bar. Показати або Ñховати бічний пенал. Show/hide the standard tool bar. Показати або Ñховати панель інÑтрументів. Show/hide the status bar. Показати або Ñховати панель Ñтану. &Full Screen View| Ðа веÑÑŒ &екран Toggle full screen mode. Перемикач повноекранного режиму. &Slide Show View| &Показ Ñлайдів Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. Увімкнути або вимкнути режим показу Ñлайлів. Toggle continuous layout mode. Перемикач режиму неперервного переглÑду Ñторінок. Toggle side-by-side layout mode. Перемикач режиму показу Ñторінок поруч. Control Left Mouse Button Контроль правою кнопкою миші Right Mouse Button Права кнопка миші <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>Вибір прÑмокутної облаÑті.</b><br/> Тільки-но обрано прÑмокутну облаÑть, Ñпадне меню надаÑть вам змогу Ñкопіювати відповідний текÑÑ‚ чи картинку. ЗаміÑть викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ інÑтрументу Ви можете натиÑнути %1 та викориÑтати ліву кнопку миші.</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>МаÑштабуваннÑ.</b><br/> Оберіть маÑштаб Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду документа. МаÑштаб у 100% покаже документ у роздільній здатноÑті екрана 100 Ñ‚/д. МаÑштаб <tt>Підібрати під Ñторінку</tt> та <tt>Підібрати ширину</tt> надаÑть змогу бачити на екрані вÑÑŽ Ñторінку або вÑÑŽ ширину Ñторінки. </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>Поворот Ñторінок.</b><br/> Оберіть, щоб переглÑдати Ñторінки у книжковому чи альбомному режимі. Ви також можете перевернути Ñ—Ñ… догори низом.</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>Режим показу.</b><br/> Картинки DjVu ÑкладаютьÑÑ Ð· шару тла та шару переднього плану за допомогою шаблону. Режим показу визначає шари, Ñкі буде показано.</html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ документ та Ñторінку.</b><br> Показує вікно діалогу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду інформації про кодуваннÑ, що ÑтоÑуєтьÑÑ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° або певної Ñторінки.</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>Метадані документа та Ñторінки.</b><br> Показує діалогове вікно Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду метаданих, що ÑтоÑуютьÑÑ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° або певної Ñторінки.</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>Ðеперервний показ.</b><br/> Показує вÑÑ– Ñторінки документа розташованими вертикально вÑередині облаÑті переглÑду, придатної Ð´Ð»Ñ Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ.</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€ÑƒÑ‡.</b><br/> Показує пари Ñторінок поруч одна з одною вÑередині облаÑті переглÑду документа, придатної Ð´Ð»Ñ Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ.</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ Ñторінку.</b><br/> Показує інформацію про Ñторінку розташовану під вказівником: номер Ñторінки, розмір Ñторінки у точках та роздільну здатніÑть Ñторінки у точках на дюйм. </html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ вказівник.</b><br/> Показує позицію вказівника миші виражену у координатах Ñторінки. </html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>ОблаÑть переглÑду документа.</b><br/> Це головна облаÑть показу документа DjVu. <ul><li>Стрілки та клавіші Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñторінки може бути викориÑтано Ð´Ð»Ñ Ð½Ð°Ð²Ñ–Ð³Ð°Ñ†Ñ–Ñ— документом.</li><li>Пробіл та BackSpace - Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°.</li><li>Клавіші <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> - Ð´Ð»Ñ Ð¼Ð°ÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° повороту документа.</li><li>Ліва кнопка миші - Ð´Ð»Ñ Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° вибору поÑилань.</li><li>%3 - Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑтного меню.</li><li>%1 ліва кнопка миші - Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ текÑту або картинок.</li><li>%2 - Ð´Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ збільшувальної лінзи.</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>ОблаÑть переглÑду документа.</b><br/> Це головна облаÑть переглÑду Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° DjVu. Ðле перед цим Вам, звичайно, Ñлід відкрити документ DjVu, щоб щоÑÑŒ побачити.</html> Option '%1' requires boolean argument. Параметр '%1' потребує булівÑького аргументу. Illegal value '%2' for option '%1'. Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ '%2' Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°'%1'. Toolbar option '%1' is not implemented. Параметр панелі інÑтрументів '%1' не може бути заÑтоÑований. Toolbar option '%1' is not recognized. Параметр панелі інÑтрументів '%1' неможливо розпізнати. Option '%1' requires a standalone viewer. Параметр '%1' потребує ÑамодоÑтатнього переглÑдача. Deprecated option '%1' Ðебажаний параметр '%1' Option '%1' is not implemented. Параметр '%1' не може бути заÑтоÑований. Option '%1' is not recognized. Параметр '%1' неможливо розпізнати. DjView DjView Cannot open file '%1'. Ðеможливо відкрити файл '%1'. Opening DjVu file Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ„Ð°Ð¹Ð»Ð° DjVu Cannot open URL '%1'. Ðеможливо відкрити URL '%1'. Opening DjVu document Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° DjVu Certificate validation error - DjView dialog caption Помилка під Ñ‡Ð°Ñ Ñпроби перевірити Ñертифікат — DjView <html> %1 Do you want to continue anyway? </html> <html> %1 Бажаєте продовжити обробку попри це?</html> Cannot find page numbered: %1 Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñторінку з номером: %1 Cannot find page named: %1 Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñторінку з назвою: %1 Unrecognized sidebar options '%1'. Ðерозпізнаний параметри бічної панелі '%1'. <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html> Друк цього файла обмежено під Ñ‡Ð°Ñ ÑтвореннÑ. Бажаєте надрукувати його попри це?</html> <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html> Права на Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файла обмежено. Бажаєте зберегти його попри це?</html> Cannot write file '%1'. %2. Файл '%1' неможливо запиÑати. %2. Cannot determine file format. Filename '%1' has no suffix. Ðеможливо визначити формат файла. Ðазва файла '%1' не має ÑуфікÑу. Image format %1 not supported. Формат картинки %1 не підтримуєтьÑÑ. Cannot decode page %1. Ðеможливо розкодувати Ñторінку %1. Cannot decode document. Ðеможливо розкодувати документ. Decoding DjVu document Ð Ð¾Ð·ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð° DjVu x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: %n pages forward. Перехід на %n Ñторінку вперед. Перехід на %n Ñторінки вперед. Перехід на %n Ñторінок вперед. Go: %n pages backward. Перехід на %n Ñторінку назад. Перехід на %n Ñторінки назад. Перехід на %n Ñторінок назад. Go: page %1. Перехід: Ñторінка %1. Go: %1 Link: %1 Перехід: %1 (in other window.) (у іншому вікні.) Cannot resolve link '%1' Ðеможливо розпізнати поÑÐ¸Ð»Ð°Ð½Ð½Ñ '%1' Cannot spawn a browser for url '%1' Ðеможливо викликати переглÑдач Ð´Ð»Ñ url '%1' Copy text (%1) ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑту (%1) Save text as... Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÑту Ñк... Copy image (%1x%2 pixels) ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ¸ (%1x%2 пікÑелів) Save image as... Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ¸ Ñк... Zoom to rectangle МаÑштабувати до прÑмокутника About DjView Про DjView DjVu files Файли DjVu cannot open '%1'. неможливо відкрити '%1'. &Export as... File| &ЕкÑпортувати Ñк... Export DjVu page or document to other formats. ЕкÑпортувати Ñторінку або документ DjVu у інші формати. Export - DjView dialog caption ЕкÑпорт - DjView Ctrl+E File|ExportAs Ctrl+E Ctrl+O File|Open Ctrl+O &Close File| &Закрити Ctrl+W File|Close Ctrl+W &Quit File| Ви&йти Ctrl+Q File|Quit Ctrl+Q Save &as... File| Зберегти &Ñк... Ctrl+S File|SaveAs Ctrl+S &Print... File| &Друкувати... Ctrl+P File|Print Ctrl+P &Find... Edit| Шук&ати... Ctrl+F Edit|Find Ctrl+F Find &Next Edit| Шукати &наÑтупне F3 Edit|Find Next F3 Find &Previous Edit| Шукати &попереднє Shift+F3 Edit|Find Previous Shift+F3 &Select Edit| &Обрати F2 Edit|Select F2 Zoom &In Zoom| З&більшити Zoom &Out Zoom| З&меншити Fit &Width Zoom| Підібрати за &шириною Fit &Page Zoom| Підібрати за &виÑотою One &to one Zoom| Один до &одного &300% Zoom| &300% &200% Zoom| &200% &150% 150% Zoom| &150% &100% Zoom| &100% &75% Zoom| &75% &50% Zoom| &50% &First Page Go| &Перша Ñторінка &Next Page Go| &ÐаÑтупна Ñторінка &Previous Page Go| &ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñторінка &Last Page Go| &ОÑÑ‚Ð°Ð½Ð½Ñ Ñторінка &Backward Go| &Ðазад &Forward Go| &Вперед Rotate &Left Rotate| Повернути &ліворуч Rotate &Right Rotate| Повернути &праворуч Rotate &0° Rotate| Поворот у &0° Rotate &90° Rotate| Поворот у &90° Rotate &180° Rotate| Поворот у &180° Rotate &270° Rotate| Поворот у &270° &Information... Edit| &ІнформаціÑ... Ctrl+I Edit|Information Ctrl+I &Metadata... Edit| &Метадані... Ctrl+M Edit|Metadata Ctrl+M &Color Display| &Колір &Stencil Display| &Шаблон &Foreground Display| &Передній план &Background Display| &Тло I&nvert Luminance View| І&нвертувати оÑвітленіÑть Invert image luminance while preserving hue. Інвертувати оÑвітленіÑть Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÐµÐ· зміни відтінку. Prefere&nces... Settings| Ðала&штуваннÑ... F9 Settings|Show sidebar F9 F10 Settings|Show toolbar F10 F11 View|FullScreen F11 &Continuous Layout| &Ðеперервно F4 Layout|Continuous F4 Side &by Side Layout| Сторінки &поруч F5 Layout|SideBySide F5 &File File| &Файл &Edit Edit| З&міни &View View| П&ереглÑд &Zoom View|Zoom &МаÑштаб &Rotate View|Rotate &Обертати &Display View|Display &ВиглÑд &Go Go| Пере&хід &Settings Settings| &Параметри &Help Help| &Довідка <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>ÐÐ°Ð²Ñ–Ð³Ð°Ñ†Ñ–Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð¼.</b><br/> Вибір Ñторінки надаÑть вам змогу перейти до будь-Ñкої Ñторінки за назвою. Вікно вибору Ñторінки можна відкрити натиÑканнÑм комбінації клавіш Ctrl+G. За допомогою кнопок навігації можна перейти до першої, попередньої, наÑтупної, оÑтанньої Ñторінки. </html> Thumbnails Мініатюри Outline ЕÑкіз Find Пошук Print - DjView dialog caption Друк - DjView Save - DjView dialog caption Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ - DjView Text files save filter ТекÑтові файли All files save filter Ð’ÑÑ– файли Save Text - DjView dialog caption Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÑту - DjView Error - DjView dialog caption Помилка - DjView Save Image - DjView dialog caption Зберегти картинку - DjView P%1/%2 %3x%4 %5dpi С%1 з %2 %3x%4 %5Ñ‚/д <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>ПереглÑдач документів DjVu<br><a href=%3>%3</a><br>ÐвторÑькі права© 2006 — Léon Bottou.</p><p align=justify><small>Ð¦Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° Ñ” вільним програмним забезпеченнÑм. Ви можете поширювати або змінювати Ñ—Ñ— за умов Ð´Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ GNU General Public License у тому виглÑді, у Ñкому Ñ—Ñ— оприлюднено Free Software Foundation. Ð¦Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° поширюєтьÑÑ <i>без жодних гарантій</i>. Щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ, прочитайте GNU General Public License.</small></p></html> Enter the URL of a DjVu document: Введіть адреÑу документа DjVu: Information - DjView dialog caption Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ - DjView Metadata - DjView dialog caption Метадані - DjView Open &Recent Відкрити &нещодавній &Clear History Сп&орожнити журнал Open &Location... File| Відкрити &адреÑу... Open a remote DjVu document. Відкрити нелокальний документ DjVu. Ctrl+F3 Edit|Find Next Ctrl+F3 Ctrl+F2 Edit|Select Ctrl+F2 Ctrl+F9 Settings|Show sidebar Ctrl+F9 Ctrl+F10 Settings|Show toolbar Ctrl+F10 Ctrl+F11 View|FullScreen Ctrl+F11 Ctrl+F4 Layout|Continuous Ctrl+F4 Ctrl+F5 Layout|SideBySide Ctrl+F5 Open Location - DjView dialog caption Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð°Ð´Ñ€ÐµÑи - DjView Open - DjView dialog caption Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ - DjView Show &Sidebar Settings| Показ &бічної панелі Show &Toolbar Settings| Показ панелі &інÑтрументів Show Stat&usbar Settings| Показ панелі &Ñтану %1 files (*.%2);; save image filter %1 Файлів (*.%2) %n characters %n Ñимвол %n Ñимволи %n Ñимволів Go: 1 page forward. Перехід: 1 Ñторінка вперед. Go: 1 page backward. Перехід: 1 Ñторінка назад. Copy &URL Edit| Копіювати &URL Save an URL for the current page into the clipboard. Зберегти адреÑу URL поточної Ñторінки у буфері. Copy &Outline Edit| Копіювати &еÑкіз Copy &Annotations Edit| Копіювати &анотації Copy text into the clipboard. Копіювати текÑÑ‚ до буфера. Save text into a file. Зберегти текÑÑ‚ до файла. Save image into a file. Зберегти Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾ файла. Zoom the selection to fit the window. Підібрати облаÑть переглÑду під виділене. Copy URL Копіювати адреÑу URL Save into the clipboard an URL that highlights the selection. Зберегти до буфера адреÑу URL, Ñку виділено у вибраному. Copy Maparea Копіювати облаÑть карти Save into the clipboard a maparea annotation expression for program djvused. Зберегти до буфера вираз анотації карти облаÑті Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ djvused. Ctrl+C Edit|CopyURL Ctrl+C Save the djvused code for the outline into the clipboard. Зберегти код djvused еÑкізу до буфера. Save the djvused code for the page annotations into the clipboard. Зберегти код djvused анотації Ñторінки до буфера. Copy image into the clipboard. Копіювати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾ буфера. Co&ver Page Layout| &Обкладинка Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. У режимі зі Ñторінками, розташованими поруч, показувати першу Ñторінку окремо. &Right to Left Layout| &Справа ліворуч Ctrl+Shift+F6 Layout|RightToLeft Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. Показувати Ñторінки лівопиÑних мов у режимі Ñторінок поруч. All files Ð’ÑÑ– файли &Hidden Text Display| При&хований текÑÑ‚ Overlay a representation of the hidden text layer. ÐаклаÑти на Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÑˆÐ°Ñ€Ñƒ прихованого текÑту. Hidden Text modeCombo Прихований текÑÑ‚ QDjViewApplication Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. ВикориÑтаннÑ: djview [параметри] [назва-файла-або адреÑа] Звичайні параметри такі: -help~~~Показати це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ -verbose~~~Показувати вÑÑ– попереджувальні повідомленнÑ. -display <xdpy>~~~Обрати диÑплей X11 <xdpy>. -geometry <xgeom>~~~Обрати початкову геометрію вікна. -font <xlfd>~~~Обрати назву оÑновного шрифту X11. -style <qt-Ñтиль>~~~Обрати Ñтиль показу Qt. -fullscreen, -fs~~~ЗапуÑтити djview у повноекранному режимі. -page=<Ñторінка>~~~Перейти до Ñторінки <Ñторінка>. -zoom=<маÑштаб>~~~Ð’Ñтановити маÑштаб. -continuous=<yn>~~~Ð’Ñтановити режим неперервного переглÑду. -sidebyside=<yn>~~~Ð’Ñтановити Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ñд. cannot open '%1'. неможливо відкрити '%1'. QDjViewAuthDialog Password: Пароль: User: КориÑтувач: Authentication required - DjView Слід пройти Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ â€” DjView QDjViewDjVuExporter <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> Цей файл належить до не порожньої теки. Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð½ÐµÐ¿Ñ€Ñмого документа Ñтворить багато файлів у цій теці. Бажаєте продовжувати з ризиком перезапиÑу файлів у цій теці?</html> Con&tinue Про&довжувати &Cancel &СкаÑувати Save job creation failed! Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð°Ð·Ð½Ð°Ð»Ð¾ невдачі! DjVu Bundled Document Зв'Ñзаний документ DjVu DjVu Files (*.djvu *.djv) Файли DjVu (*.djvu *.djv) DjVu Indirect Document ÐепрÑмий документ DjVu Unknown error. Ðевідома помилка. System error: %1. СиÑтемна помилка: %1. Question - DjView dialog caption Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ - DjView QDjViewErrorDialog DjView Error Помилка DjView &Ok &Гаразд Error - DjView dialog caption Помилка - DjView QDjViewExportDialog Dialog Діалог Export ЕкÑпортувати Format: Формат: &Document &Документ C&urrent page П&оточна Ñторінка &Pages &Сторінки to до Destination ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ &Defaults &Типове &Ok &Гаразд &Cancel &СкаÑувати Stop Зупинити <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>ЗбереженнÑ.</b><br/> Ви можете зберегти веÑÑŒ документ або проміжок Ñторінок у цілій низці форматів. Вибір певних форматів викличе додаткові Ñторінки діалогів Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² формата.</html> Overwriting the current file is not allowed! ÐŸÐµÑ€ÐµÐ·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ файла заборонено! A file with this name already exists. Do you want to replace it? Файл з такою назвою вже Ñ–Ñнує. Бажаєте замінити його? &Replace &Замінити This operation has failed. Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð·Ð½Ð°Ð»Ð° невдачі. This operation has been interrupted. Цю операцію було перервано. Export - DjView dialog caption ЕкÑпорт - DjView Error - DjView dialog caption Помилка - DjView Question - DjView dialog caption Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ - DjView All files save filter Ð’ÑÑ– файли QDjViewExportPS1 Form Форма Color Колір &Color &Колір &GrayScale &Сірі півтони Marks Позначки Print image &frame Друкувати &рамку картинки Print crop &marks Друкувати обмежувальні &мітки PostScript PostScript Language Level Рівень мови QDjViewExportPS2 Form Форма Scaling МаÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Scale to &fit the page МаÑштабувати, щоб &вміÑтити Ñторінку &Zoom &МаÑштаб % % Orientation ÐžÑ€Ñ–Ñ”Ð½Ñ‚Ð°Ñ†Ñ–Ñ Automatic Ðвтоматично &Portrait П&ортрет &Landscape &Ðльбом QDjViewExportPS3 Form Форма Print sheets suitable for folding a booklet. Друкувати лиÑтки, придатні Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð±ÑƒÐºÐ»ÐµÑ‚Ñƒ. Advanced Додатково Sheets per booklet: ЛиÑтків на буклет: Unlimited Ðе обмежувати at most не більше Print Друк rectos and versos. верхні та нижні. rectos only. тільки верхні. versos only. тільки нижні. Shift rectos and versos by ЗміÑтити верхні та нижні на points. точок. Center: ПоÑередині: points точок plus Ð¿Ð»ÑŽÑ /100 /100 per page. на Ñторінку. QDjViewExportPrn Form Форма Color Колір &Color &Колір &GrayScale &Сірі півтони Marks Позначки Print image &frame Друкувати &рамку картинки Print crop &marks Друкувати обмежувальні &мітки Scaling МаÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Scale to &fit the page МаÑштабувати, щоб &вміÑтити Ñторінку &Zoom &МаÑштаб % % Orientation ÐžÑ€Ñ–Ñ”Ð½Ñ‚Ð°Ñ†Ñ–Ñ Automatic Ðвтоматично &Portrait П&ортрет &Landscape &Ðльбом QDjViewExportTiff Form Форма Resolution Роздільна здатніÑть Maximum image resolution МакÑимальна роздільна здатніÑть картинки dpi Ñ‚/д Compression СтиÑÐ½ÐµÐ½Ð½Ñ Force &bitonal G4 compression. ПримуÑове &двотональне ÑтиÑÐ½ÐµÐ½Ð½Ñ G4. Allow &lossy JPEG compression. ВикориÑтовувати JPEG-ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð· &втратами. JPEG &quality &ЯкіÑть JPEG Allow &deflate compression. Дозволити &ÑтиÑненнÑ. QDjViewFind Case sensitive З врахуваннÑм регіÑтру Words only Тільки Ñлова Find Previous (Shift+F3) Шукати попереднє (Shift+F3) Find Next (F3) Шукати наÑтупне (F3) Options Параметри <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>Пошук текÑту.</b><br/> Під Ñ‡Ð°Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ відповідники з'ÑвлÑютьÑÑ Ð¿Ð¾Ñтупово, паралельно з введеннÑм вами Ñ€Ñдка Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ. ÐатиÑÐ½ÐµÐ½Ð½Ñ ÐºÐ»Ð°Ð²Ñ–ÑˆÑ– вводу задає перехід до наÑтупного відповідника. Щоб перейти до попереднього чи наÑтупного відповідника, Ви також можете викориÑтовувати Ñтрілки та гарÑчі клавіші <tt>F3</tt> або <tt>Shift-F3</tt>. Також можна двічі клацнути на назві Ñторінки. Щоб шукати лише цілі Ñлова або задати чутливіÑть до регіÑтру, ÑкориÑтайтеÑÑ Ð¼ÐµÐ½ÑŽ <tt>Параметри</tt>, </html> Regular expression Формальний вираз Reset search options to default values. Відновити типові Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² пошуку. Specify whether search hits must begin on a word boundary. Визначте, чи має шуканий Ñ€Ñдок починатиÑÑ Ð½Ð° межі Ñлова. Specify whether searches are case sensitive. Вкажіть, чи Ñлід враховувати регіÑтр Ñимволів під Ñ‡Ð°Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ. Regular expressions describe complex string matching patterns. За допомогою формальних виразів можна опиÑати Ñкладні шаблони відповідноÑті. <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>Коротка інÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ð· формальних виразів</b><ul><li>Крапка <tt>.</tt> відповідає довільному Ñимволу.</li><li>БільшіÑть Ñимволів відповідають Ñамим Ñобі.</li><li>До Ñпеціальних Ñимволів, <tt>()[]{}|*+.?!^$\</tt>, Ñлід додавати Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ <tt>\</tt>.</li><li><tt>\b</tt> відповідає межі Ñлова.</li><li><tt>\w</tt> відповідає літері.</li><li><tt>\d</tt> відповідає чиÑловому Ñимволу.</li><li><tt>\s</tt> відповідає пробілу.</li><li><tt>\n</tt> відповідає Ñимволу нового Ñ€Ñдка.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> відповідає діапазону Ñимволів <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> відповідає Ñимволам поза діапазоном <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> відповідає або формальному виразу <tt><i>a</i></tt>, або формальному виразу <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> відповідає формальному виразу <tt><i>a</i></tt>, повтореному від <tt><i>n</i></tt> до <tt><i>m</i></tt> разів.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt> Ñ– <tt><i>a</i>+</tt> — ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ñ–Ð² <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt> Ñ– <tt><i>a</i>{1,}</tt>.</li><li>Ð”Ð»Ñ Ð³Ñ€ÑƒÐ¿ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð¸Ñ… виразів додайте <tt>()</tt> перед <tt>?+*{</tt>.</li></ul></html> QDjViewFind::Model 1 hit 1 збіг Page %1 (1 hit) Сторінка %1 (1 збіг) Searching page %1 (waiting for data.) Пошук Ñторінки %1 (Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° дані.) Searching page %1. Пошук Ñторінки %1. No hits! Ðе знайдено! <html>Document is not searchable. No page contains information about its textual content.</html> <html>Пошук у документі неможливий. Жодна Ñторінка не міÑтить інформації про Ñвій текÑтовий вміÑÑ‚.</html> %n hits %n збіг %n збіги %n збігів Page %1 (%n hits) Сторінка %1 (%n збіг) Сторінка %1 (%n збіги) Сторінка %1 (%n збігів) <html>Invalid regular expression.</html> <html>Ðекоректний формальний вираз.</html> QDjViewImgExporter Cannot render page. Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ñторінку. Image format %1 not supported. Формат картинки %1 не підтримуєтьÑÑ. %1 Image JPG Image %1 Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ %1 Files (*.%2) JPG Files %1 Файлів (*.%2) QDjViewInfoDialog Dialog Діалог &Document &Документ &File &Файл File: Файл: &View Page &ПереглÑнути Ñторінку &Close &Закрити File # Файл â„– File Name Ðазва файла File Size Розмір файла File Type Тип файла Page # Сторінка â„– Page Title Заголовок Ñторінки <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ документ</b><br>Ð¦Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ показує інформацію про документ та файли, з Ñких його Ñкладено. Оберіть файл-компонент, щоб побачити детальну інформацію на Ñторінці <tt>Файл</tt>. Двічі клацніть на файлі-компоненті, щоб побачити відповідну Ñторінку у головному вікні. </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ файл та Ñторінку</b><br>Ð¦Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ показує Ñтруктуру даних DjVu, що відповідають файлу-компонентові або Ñторінці, обраній на Ñторінці <tt>Документ</tt>. Кнопки зі Ñтрілками дозволÑть перейти до попереднього чи наÑтупного файла-компонента.</html> Waiting for data... ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° дані... Page #%1 - « %2 » Сторінка â„–%1 - « %2 » Page #%1 Сторінка â„–%1 Thumbnails Мініатюри Shared annotations Спільні анотації Shared data Спільні дані File #%1 - Файл â„–%1 - Single DjVu page Одна Ñторінка DjVu Bundled DjVu document З'єднаний документ DjVu Indirect DjVu document ÐепрÑмий документ DjVu Obsolete bundled DjVu document ЗаÑтарілий з'єднаний документ DjVu Obsolete indexed DjVu document ЗаÑтарілий індекÑований документ DjVu n/a недоÑтупне Page Сторінка Thumbnails Мініатюри Shared Спільні 1 file 1 файл %n files %n файл %n файли %n файлів 1 page 1 Ñторінка %n pages %n Ñторінка %n Ñторінки %n Ñторінок QDjViewMetaDialog Dialog Діалог &Document Metadata Метадані &документа &Page Metadata Метадані &Ñторінки Page: Сторінка: &View Page &ПереглÑнути Ñторінку &Close &Закрити Key Ключ Value Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>Метадані документа</b><br>Ðа цій панелі показано метадані, що ÑтоÑуютьÑÑ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°, зокрема дані щодо автора, назви, поÑилань та інші. Цю інформацію може бути збережено у документі за допомогою програми <tt>djvused</tt>: викориÑтовуйте команди <tt>create-shared-ant</tt> та <tt>set-meta</tt>.</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>Метадані Ñторінки</b><br>Ðа цій панелі показано метадані, що ÑтоÑуютьÑÑ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ñ— Ñторінки. ОÑобливі метадані Ñторінки заміщують метадані документа. Цю інформацію може бути додано до документа за допомогою програми <tt>djvused</tt>: викориÑтовуйте команду <tt>select</tt> Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ Ñторінки та команду <tt>set-meta</tt> Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÑƒÐ½ÐºÑ‚Ñ–Ð² метаданих.</html> Ctrl+C copy Ctrl+C QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>ЕÑкіз документа.</b><br/> Ð¦Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ показує еÑкіз документа або назви Ñторінок, коли еÑкіз недоÑтупний. Двічі клацніть по будь-Ñкому пункту Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñƒ до обраної Ñторінки.</html> Outline data is corrupted Дані еÑкізу зіпÑовано Pages Сторінки Page %1 Сторінка %1 Go: page %1. Go: page %1 Перехід: Ñторінка %1. Go: %1 Go: %1. Перехід: %1 QDjViewPSExporter <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>Параметри PostScript.</b><br>Параметр <tt>Колір</tt> дозволÑÑ” друк у кольорі. Сторінки документа можна прикраÑити рамкою та обмежувальними мітками. Рівень мови PostScript 1 кориÑний лише Ð´Ð»Ñ Ð´ÑƒÐ¶Ðµ Ñтарих друкарок. Рівень 2 працює Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆÐ¾Ñті друкарок. Рівень 3 дозволÑÑ” пришвидшити друк на ÑучаÑних принтерах.</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Ð Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñ‚Ð° маÑштаб.</b><br>Параметр <tt>МаÑштабувати Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾Ñті</tt> приÑтоÑовує документ до того розміру паперу, Ñкий викориÑтовує ваш принтер. Множник маÑштабу <tt>100%</tt> відтворює початковий розмір Ñторінок документа. <tt>Ðвтоматична</tt> Ð¾Ñ€Ñ–Ñ”Ð½Ñ‚Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ” програмі обрати книжкову чи альбомну орієнтацію паперу на оÑнові Ð¿Ñ€Ð¸Ð¿ÑƒÑ‰ÐµÐ½Ð½Ñ Ð¾Ð´Ð½Ð° Ñторінка - один аркуш.</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>Ð’Ð¸Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐºÐ»ÐµÑ‚Ñ–Ð².</b><br>Режим буклета надає змогу надрукувати вказані Ñторінки у форматі лиÑтів, придатних Ð´Ð»Ñ Ð²Ð¸Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ чи декількох буклетів. Декілька буклетів буде виготовлено, Ñкщо зазначено макÑимальна кількіÑть лиÑтів у буклеті. Ви можете викориÑтовувати двобічний принтер або друкувати верхні та нижні боки Ñторінки окремо.<p> ЗÑув верхніх та нижніх боків може бути кориÑний Ð´Ð»Ñ Ð´Ð²Ð¾Ð±Ñ–Ñ‡Ð½Ð¸Ñ… принтерів з неÑкіÑним вирівнюваннÑм. Центральне поле визначає, Ñк багато міÑÑ†Ñ Ð±ÑƒÐ´Ðµ залишено між Ñторінками Ð´Ð»Ñ Ð½Ð°Ñтупного Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñƒ буклет. Ð¦Ñ Ð²Ñ–Ð´Ñтань повільно зроÑтає від внутрішніх лиÑтів до зовнішніх.</html> Save job creation failed! Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð°Ð·Ð½Ð°Ð»Ð¾ невдачі! PostScript PostScript PostScript Files (*.ps *.eps) Файлів PostScript (*.ps) Encapsulated PostScript ІнкапÑульований PostScript PostScript tab caption PostScript Position tab caption Ð Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Booklet tab caption Буклет QDjViewPdfExporter PDF Document Документ PDF PDF Files (*.pdf) Файли PDF (*.pdf) PDF Options tab caption Параметри PDF <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>Параметри PDF.</b><br>Ці параметри впливають на характериÑтики зображень, вбудованих до файлів PDF, що екÑпортуютьÑÑ. Поле \"роздільна здатніÑть\" обмежує макÑимальну роздільну здатніÑть. ПримуÑове двотональне ÑтиÑÐ½ÐµÐ½Ð½Ñ G4 кодує вÑÑ– Ñторінки у чорно-білому виглÑді за допомогою методу ÑтиÑÐ½ÐµÐ½Ð½Ñ CCITT Group 4. ВикориÑÑ‚Ð°Ð½Ð½Ñ ÑтиÑÐ½ÐµÐ½Ð½Ñ JPEG надає змогу ÑтиÑкати дані за допомогою ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð· втратами JPEG вÑÑ– не чорно-білі Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð· підвибірками. Крім того, Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÑŒ до Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ð¿Ð°ÐºÑ‚Ð½Ñ–ÑˆÐ¸Ñ… файлів. </html> Error while creating pdf file. Помилка під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° pdf. PDF export was not compiled. ЕкÑпорт до PDF не було викориÑтано під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸. Unable to create output file. Ðеможливо Ñтворити файл виведеннÑ. System error: %1. СиÑтемна помилка: %1. Unable to reopen temporary file. Ðеможливо знову відкрити тимчаÑовий файл. Unable to create temporary file. Ðеможливо Ñтворити тимчаÑовий файл. QDjViewPlugin::Document Requesting %1. Запит %1. QDjViewPrefsDialog Dialog Діалог Gamma Гама Darker Темніше Lighter Світліше <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐºÑ€Ð°Ð½Ð½Ð¾Ð³Ð¾ кольору.<br>ПереÑуньте повзунок так, щоб Ñірі облаÑті виглÑдали однаково.</html> &Interface &ВиглÑд Options for Параметри Ð´Ð»Ñ Standalone Viewer СамодоÑтатнього переглÑдача Full Page Plugin Додатка повної Ñторінки Embedded Plugin Вбудованого додатка &Remember initial state from last invocation &Запам'Ñтати початковий Ñтан з оÑтаннього виклику Show Показати &Menu bar Панель &меню &Tool bar Панель &інÑтрументів Sc&rollbars Смуги &Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Stat&us bar Панель &ÑтатуÑу &Side bar &Бічний пенал Display ВиглÑд Force inverted luminance Force inverted luminance. ПримуÑово інвертувати оÑвітленіÑть &Zoom: &МаÑштаб: s secs c Display page &frames Показувати &рамки Ñторінок Display &annotations Показувати &анотації &Keys &Клавіші Keys Клавіші For displaying hyper&links: Ð”Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ гіпер&поÑилань: For &selecting text or images: Ð”Ð»Ñ &вибору текÑту або картинок: For displaying the &lens: Ð”Ð»Ñ Ð¿Ð¾&казу лінзи: Mouse wheel Коліщатко миші Mouse wheel scrolls the page Mouse wheel scrolls the page. Коліщатком миші можна гортати вміÑÑ‚ Ñторінки Mouse wheel changes the zoom factor Mouse wheel changes the zoom factor. Коліщатком миші можна змінювати маÑштаб &Lens &Лінза Enable magnifying &lens Увімкнути з&більшувальну лінзу Lens options Параметри лінзи Lens &size: Розмір &лінзи: Magnifying &power: &Збільшувальна Ñила: x x pixels точок Cache Кеш &Clear Сп&орожнити &Decoded page cache: Кеш &розкодованих Ñторінок: &Pixel cache: Кеш &пікÑелів: &Network &Мережа Use pro&xy to access the network ВикориÑтовувати &прокÑÑ– Ð´Ð»Ñ Ð´Ð¾Ñтупу до мережі Proxy settings ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ– Pass&word: Па&роль: &User: &КориÑтувач: &Port: &Порт: &Host: &Сервер: Timer: Таймер: Interface ВиглÑд Force language (next time djview runs) Force language (when djview is restarted.) ПримуÑово вÑтановити мову Enable page animations Enable animations Увімкнути анімацію дій зі Ñторінками Show hidden text in status bar Показувати прихований текÑÑ‚ у Ñ€Ñдку Ñтану Render with openGL when available ВикориÑтовувати openGL, Ñкщо можна Override saving and printing restrictions Ðе брати до уваги Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‚Ð° друк &Defaults &Типове &Apply &ЗаÑтоÑувати &Ok &Гаразд Cancel СкаÑувати Preferences[*] - DjView ÐалаштуваннÑ[*] - DjView <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>Початкове Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ.</b><br>DjView може працювати Ñк ÑамодоÑтатній переглÑдач, Ñк повноекранний переглÑдач, Ñк додаток переглÑдача на повну Ñторінку, Ñк додаток, вбудований до Ñторінки html. У будь-Ñкому випадку, позначте <tt>Запам'Ñтати</tt>, щоб автоматично зберігати та відновлювати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ. Якщо ви цього не хочете робити, зазначте початкову конфігурацію.</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>Клавіші-модифікатори.</b><br>Визначте, Ñка ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ-модифікаторів показуватиме збільшувальну лінзу, тимчаÑово вмикатиме режим вибору або підÑвічуватиме гіперпоÑиланнÑ.</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>Збільшувальна лінза.</b><br>Збільшувальна лінза з'ÑвлÑєтьÑÑ ÐºÐ¾Ð»Ð¸ Ви натиÑнете клавіші-модифікатори задані на Ñторінці меню <tt>Клавіші</tt>. Ð¦Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ дозволить Вам обрати Ñилу та розмір збільшувальної лінзи.</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><p><b>Advanced.</b>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>Додатково.</b><br>Ви можете визначити мову інтерфейÑу програми, вимкнути анімацію на Ñторінках або увімкнути додаткові пункти меню, Ñкі можуть бути кориÑними Ð´Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ з файлами DjVu.Ви також можете вимкнути Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° друк та збереженнÑ, Ñкі визначаютьÑÑ Ð´ÐµÑкими з Ñайтів. Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² вручну може покращити результати друку на принтерах заÑтарілих моделей.</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ– Ñервера.</b><br>Ці Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ– Ñервера буде викориÑтано, коли ÑамодоÑтатній переглÑдач djview намагатиметьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ доÑтуп до документа djvu через адреÑу http.<p><b>Параметри кешуваннÑ.</b><br> <i>Кеш пікÑелів</i> зберігає дані зображень, розташованих поза видимою облаÑтю. Цей кеш робить переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð¼ плавнішим. <i>Кеш розкодованих Ñторінок</i> мÑтить чаÑтково розкодовані Ñторінки. Він забезпечує швидшу реакцію переглÑдача під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ñторінковим документом або під Ñ‡Ð°Ñ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ€Ð°Ð½Ñ–ÑˆÐµ переглÑнутої Ñторінки. Ð¡Ð¿Ð¾Ñ€Ð¾Ð¶Ð½ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ кешу може бути кориÑним Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ змін у даних Ñторінки без перезапуÑку переглÑдача DjVu.</html> Standalone Viewer (Full Screen mode) Окремий заÑіб переглÑду (повноекранний режим) Standalone Viewer (Slideshow mode) Окремий заÑіб переглÑду (режим показу Ñлайдів) <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ð°Ð¼Ð¼Ð¸ кольорів екрана.</b><br>Ðайкращого Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² можна доÑÑгти за допомогою ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ð°Ð¼Ð¸, Ñке можна виконати повзунком ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ð°Ð¼Ð¸, обравши таке його розташуваннÑ, за Ñкого Ñірий квадратик Ñтає Ñкомога більш однорідним.<p><b>Роздільна здатніÑть.</b><br>Цей параметр призначено Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»ÑŒÐ½Ð¾Ñ— здатноÑті, Ñка не залежатиме від параметрів, заданих операційною ÑиÑтемою. Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»ÑŒÐ½Ð¾Ñ— здатноÑті у 100 Ñ‚/д відповідає типовій поведінці інÑтрументів командного Ñ€Ñдка з djvulibre.</html> &Screen &Екран Force screen &resolution Лише в&казана роздільна здатніÑть dpi Ñ‚/д &Advanced &Додатково Miscellaneous Різне Manual printer color correction ÐšÐ¾Ñ€ÐµÐºÑ†Ñ–Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² друку вручну gamma= гамма= Enable advanced features in menus Увімкнути додаткові можливоÑті у меню MB МБ Layout ÐšÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Continuous Ðеперервно Side-by-side Сторінки поруч Cover Page Обкладинка Right-to-Left Справа ліворуч QDjViewPrintDialog Dialog Діалог Print Друк &Document &Документ C&urrent page П&оточна Ñторінка &Pages &Сторінки to до Destination ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ &Defaults &Типове &Ok &Гаразд &Cancel &СкаÑувати Stop Зупинити <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>Друк.</b><br/> Ви можете надрукувати веÑÑŒ документ або проміжок Ñторінок. ВикориÑтовуйте кнопку <tt>Обрати</tt> щоб обрати Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð° задати параметри принтера. Додаткові Ñторінки діалогового вікна буде показано, Ñкщо потрібно вказати параметри перетвореннÑ.</html> This operation has failed. Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð·Ð½Ð°Ð»Ð° невдачі. This operation has been interrupted. Цю операцію було перервано. Print to file Друк до файла Printer name: Ðазва принтера: Choose Обрати Print To File - DjView dialog caption Друк до файла - DjView A file with this name already exists. Do you want to replace it? Файл з такою назвою вже Ñ–Ñнує. Бажаєте замінити його? &Replace &Замінити All files save filter Ð’ÑÑ– файли Question - DjView dialog caption Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ - DjView (invalid printer) (некоректний принтер) QDjViewPrnExporter Printer data Дані принтера PRN Files (*.prn) Файли PRN (*.prn) Printing Options tab caption Параметри друку <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>Параметри друку.</b><br>Параметр <tt>Колір</tt> дозволÑÑ” кольоровий друк. Сторінки документа можна вклаÑти до рамок. Параметр <tt>Підігнати до</tt> приÑтоÑовує Ñторінки до розміру паперу, що викориÑтовує ваш принтер. Множник маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ <tt>100%</tt> відтворює початковий розмір документа. Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ <tt>Ðвтоматичне</tt> обирає книжкове чи альбомне Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð· міркувань Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð´Ð½Ñ–Ñ”Ñ— Ñторінки на одному лиÑті.</html> Cannot render page %1. Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ñторінку «%1». QDjViewSaveDialog Dialog Діалог Save Зберегти &Document &Документ C&urrent page П&оточна Ñторінка &Pages &Сторінки to до Destination ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Format: Формат: &Ok &Гаразд &Cancel &СкаÑувати Stop Зупинити Overwriting the current file is not allowed! ÐŸÐµÑ€ÐµÐ·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ файла заборонено! A file with this name already exists. Do you want to replace it? Файл з такою назвою вже Ñ–Ñнує. Бажаєте замінити його? &Replace &Замінити This operation has failed. Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð·Ð½Ð°Ð»Ð° невдачі. This operation has been interrupted. Цю операцію було перервано. Bundled DjVu Document Зв'Ñзаний документ DjVu Indirect DjVu Document ÐепрÑмий документ DjVu <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>ЗбереженнÑ.</b><br/> Ви можете зберегти увеÑÑŒ документ або діапазон Ñторінок. Зв'Ñзаний формат Ñтворює одиночний файл. ÐепрÑмий формат Ñтворює декілька файлів придатних до переглÑду у мережі.</html> Error - DjView dialog caption Помилка - DjView Question - DjView dialog caption Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ - DjView All files save filter Ð’ÑÑ– файли Save - DjView dialog caption Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ - DjView QDjViewThumbnails Control Left Mouse Button Контроль правою кнопкою миші Right Mouse Button Права кнопка миші <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>Мініатюри документа.</b><br/> Ðа цій панелі показано мініатюри Ñторінок документа. Подвійне ÐºÐ»Ð°Ñ†Ð°Ð½Ð½Ñ Ð½Ð° мініатюрі відкриє у вікні переглÑду відповідну Ñторінку. %1 надаÑть змогу змінити розмір мініатюр або оновить Ñ—Ñ…. У режимі розумного Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° Ñтворюватиме мініатюри тільки у разі доÑтупноÑті даних Ñторінки (відображених або кешованих.)</html> Tiny thumbnail menu МалюÑінький Small thumbnail menu Маленький Medium thumbnail menu Ðормальний Large thumbnail menu Великий Smart thumbnail menu Розумний QDjViewTiffExporter TIFF Document Документ TIFF TIFF Files (*.tiff *.tif) Файли TIFF (*.tiff *.tif) Cannot open output file. Ðеможливо відкрити файл виведеннÑ. Out of memory. ÐŸÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð°Ð¼'Ñті. Internal error. Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. TIFF export has not been compiled. ЕкÑпорт до TIFF не було Ñкомпільовано. <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>Параметри TIFF.</b><br>Поле \"роздільна здатніÑть\" визначає верхню межу роздільної здатноÑті зображень у форматі TIFF. ПримуÑове двотональне ÑтиÑÐ½ÐµÐ½Ð½Ñ G4 кодує вÑÑ– Ñторінки у чорно-білому форматі за допомогою методу ÑтиÑÐ½ÐµÐ½Ð½Ñ CCITT Group 4. ВикориÑÑ‚Ð°Ð½Ð½Ñ ÑтиÑÐ½ÐµÐ½Ð½Ñ JPEG дозволÑÑ” ÑтиÑкати з втратами не чорно-білі Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð· підмножинами у формат JPEG. Ðбо ж дозвіл на ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÑŒ до Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¼ÐµÐ½ÑˆÐ¸Ñ… (але Ñ– менш ÑуміÑних) файлів ніж звичайне побітове ÑтиÑненнÑ.</html> TIFF Options tab caption Параметри TIFF QDjVuNetDocument Requesting '%1' Запит '%1' QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code Отримано ÑÑ‚Ð°Ñ‚ÑƒÑ http %1 під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ %2. Received <%1> data while retrieving %2. %1 is a mime type Отримано %1 дані під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ %2. %1 while retrieving '%2'. %1 під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ '%2'. Cannot validate the certificate for server %1. Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸ Ñертифікат Ð´Ð»Ñ Ñервера %1. Authentication required for %1 (%2). Слід пройти Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð´Ð¾Ñтупу до %1 (%2). Authentication required for proxy %1. Слід пройти Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð´Ð¾Ñтупу до прокÑÑ–-Ñервера %1. djview4-4.10.5/src/djview_zh_cn.ts000066400000000000000000004464731264256014000170070ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language 简体中文 QApplication Option '-fix' is deprecated. 选项'-fix'已过时。 QDjView cannot open '%1'. 未能打开 '%1'。 FitWidth zoomCombo 适应宽度 FitPage zoomCombo é€‚åº”é¡µé¢ Stretch zoomCombo 拉伸 1:1 zoomCombo 1:1 300% zoomCombo 300% 200% zoomCombo 200% 150% zoomCombo 150% 100% zoomCombo 100% 75% zoomCombo 75% 50% zoomCombo 50% Color modeCombo 颜色 Stencil modeCombo æ¨¡æ¿ Foreground modeCombo 剿™¯è‰² Background modeCombo 背景色 Hidden Text modeCombo éšè—文本 &New File| 新建(&N) Ctrl+N File|New Ctrl+N Create a new DjView window. 新建DjView窗å£ã€‚ &Open File| 打开(&O) Ctrl+O File|Open Ctrl+O Open a DjVu document. 打开DjVu文档。 Open &Location... File| 打开ä½ç½®(&L)... Open a remote DjVu document. 打开远程的DjVu文档。 &Close File| 关闭(&C) Ctrl+W File|Close Ctrl+W Close this window. 关闭窗å£ã€‚ &Quit File| 退出(&Q) Ctrl+Q File|Quit Ctrl+Q Close all windows and quit the application. 关闭所有窗å£å¹¶é€€å‡ºç¨‹åºã€‚ Save &as... File| å¦å­˜ä¸º(&A)... Ctrl+S File|SaveAs Ctrl+S Save the DjVu document. ä¿å­˜DjVu文档。 &Export as... File| 导出为(&E)... Ctrl+E File|ExportAs Ctrl+E Export DjVu page or document to other formats. 导出DjVu页颿ˆ–文档到其它格å¼ã€‚ &Print... File| 打å°(&P)... Ctrl+P File|Print Ctrl+P Print the DjVu document. 打å°DjVu文档。 &Find... Edit| 查找(&F)... Ctrl+F Edit|Find Ctrl+F Find text in the document. 在文档中查找文本。 Find &Next Edit| 查找下一个(&N) Ctrl+F3 Edit|Find Next Ctrl+F3 F3 Edit|Find Next F3 Find next occurence of search text in the document. 在文档中查找文本的下一个实例。 Find &Previous Edit| 查找å‰ä¸€ä¸ª(&P) Shift+F3 Edit|Find Previous Shift+F3 Find previous occurence of search text in the document. 在文档中查找文本的å‰ä¸€ä¸ªå®žä¾‹ã€‚ &Select Edit| 选择(&S) Ctrl+F2 Edit|Select Ctrl+F2 F2 Edit|Select F2 Select a rectangle in the document. 在文档中选择å—。 Zoom &In Zoom| 放大(&I) Increase the magnification. 增加放大率。 Zoom &Out Zoom| 缩å°(&O) Decrease the magnification. å‡å°æ”¾å¤§çŽ‡ã€‚ Fit &Width Zoom| 适应宽度(&W) Set magnification to fit page width. 缩放到适应页é¢å®½åº¦ã€‚ Fit &Page Zoom| 适应页é¢(&P) Set magnification to fit page. 缩放到适应整页。 One &to one Zoom| 一比一åƒç´ (&T) Set full resolution magnification. 全分辨率缩放。 &300% Zoom| &300% Magnify 300% 放大300% &200% Zoom| &200% Magnify 20% 放大200% &150% 150% Zoom| &150% Magnify 150% 放大150% &100% Zoom| &100% Magnify 100% 原始尺寸 &75% Zoom| &75% Magnify 75% 缩放到75% &50% Zoom| &50% Magnify 50% 缩放到50% &First Page Go| 首页(&F) Jump to first document page. 跳到文档的第一页。 &Next Page Go| 下一页(&N) Jump to next document page. 跳到文档的下一页。 &Previous Page Go| 上一页(&P) Jump to previous document page. 跳到文档的上一页。 &Last Page Go| 末页(&L) Jump to last document page. 跳到文档的最åŽä¸€é¡µã€‚ &Backward Go| åŽé€€(&B) Backward in history. 退回到上一个历å²ä½ç½®ã€‚ &Forward Go| å‰è¿›(&F) Forward in history. å‰è¿›åˆ°ä¸‹ä¸€ä¸ªåކå²ä½ç½®ã€‚ Rotate &Left Rotate| 逆时针旋转(&L) Rotate page image counter-clockwise. 逆时针旋转页é¢ã€‚ Rotate &Right Rotate| 顺时针旋转(&R) Rotate page image clockwise. 顺时针旋转页é¢ã€‚ Rotate &0° Rotate| 还原旋转(&0) Set natural page orientation. æ¢å¤é¡µé¢åŽŸå§‹æ–¹å‘。 Rotate &90° Rotate| 逆时针旋转&90° Turn page on its left side. 旋转页é¢é¡¶éƒ¨åˆ°å·¦è¾¹ã€‚ Rotate &180° Rotate| 逆时针旋转&180° Turn page upside-down. 旋转页é¢é¡¶éƒ¨æœä¸‹ã€‚ Rotate &270° Rotate| 逆时针旋转&270° Turn page on its right side. 旋转页é¢é¡¶éƒ¨åˆ°å³è¾¹ã€‚ &Information... Edit| ä¿¡æ¯(&I)... Ctrl+I Edit|Information Ctrl+I Show information about the document encoding and structure. 显示文档的编ç å’Œç»“构信æ¯ã€‚ &Metadata... Edit| 元数æ®(&M)... Ctrl+M Edit|Metadata Ctrl+M Show the document and page meta data. 显示文档åŠé¡µé¢çš„元数æ®ã€‚ &About DjView... 关于DjView(&A)... Show information about this program. 显示本程åºçš„ä¿¡æ¯ã€‚ &Color Display| 彩色(&C) Display everything. 显示所有。 &Stencil Display| 模æ¿(&S) Only display the document bitonal stencil. åªæ˜¾ç¤ºæ–‡æ¡£çš„二值模æ¿ã€‚ &Foreground Display| 剿™¯(&F) Only display the foreground layer. ä»…æ˜¾ç¤ºå‰æ™¯å±‚。 &Background Display| 背景(&B) Only display the background layer. 仅显示背景层。 &Hidden Text Display| éšè—的文本(&H) Overlay a representation of the hidden text layer. 显示éšè—的文本层。 I&nvert Luminance View| å色(&N) Invert image luminance while preserving hue. åè‰²ä½†ä¿æŒé¥±å’Œåº¦ã€‚ Prefere&nces... Settings| 设置(&N)... Show the preferences dialog. æ˜¾ç¤ºè®¾ç½®å¯¹è¯æ¡†ã€‚ Show &Sidebar Settings| 显示侧æ (&S) Ctrl+F9 Settings|Show sidebar Ctrl+F9 F9 Settings|Show sidebar F9 Show/hide the side bar. 显示或éšè—ä¾§æ ã€‚ Show &Toolbar Settings| 显示工具æ (&T) Ctrl+F10 Settings|Show toolbar Ctrl+F10 F10 Settings|Show toolbar F10 Show/hide the standard tool bar. 显示或éšè—标准工具æ ã€‚ Show Stat&usbar Settings| æ˜¾ç¤ºçŠ¶æ€æ (&U) Show/hide the status bar. 显示或éšè—çŠ¶æ€æ ã€‚ &Full Screen View| å…¨å±(&U) Ctrl+F11 View|FullScreen Ctrl+F11 F11 View|FullScreen F11 Toggle full screen mode. 切æ¢å…¨å±æ¨¡å¼ã€‚ &Slide Show View| 播放幻ç¯ç‰‡(&S) Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. 切æ¢å¹»ç¯ç‰‡æ’­æ”¾æ¨¡å¼ã€‚ &Continuous Layout| 连续页é¢(&C) Ctrl+F4 Layout|Continuous Ctrl+F4 F4 Layout|Continuous F4 Toggle continuous layout mode. 切æ¢è¿žç»­é¡µé¢æ¨¡å¼ã€‚ Side &by Side Layout| 并排显示(&B) Ctrl+F5 Layout|SideBySide Ctrl+F5 F5 Layout|SideBySide F5 Toggle side-by-side layout mode. 切æ¢å¤šé¡µå¹¶æŽ’显示模å¼ã€‚ Co&ver Page Layout| å°é¢é¡µ(&V) Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. 并排显示时å•独显示å°é¢é¡µã€‚ &Right to Left Layout| 从å³å‘å·¦(&R) Ctrl+Shift+F6 Layout|RightToLeft Ctrl+Shift+F6 Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. 并排显示时从å³åˆ°å·¦æ˜¾ç¤ºé¡µé¢ã€‚ Copy &URL Edit| å¤åˆ¶&URL Save an URL for the current page into the clipboard. å¤åˆ¶å½“å‰é¡µé¢çš„URL到剪贴æ¿ã€‚ Ctrl+C Edit|CopyURL Ctrl+C Copy &Outline Edit| å¤åˆ¶æ ‡ç­¾(&O) Save the djvused code for the outline into the clipboard. å¤åˆ¶æ ‡ç­¾å¯¹åº”çš„djvu代ç åˆ°å‰ªè´´æ¿ã€‚ Copy &Annotations Edit| å¤åˆ¶æ³¨é‡Š(&A) Save the djvused code for the page annotations into the clipboard. å¤åˆ¶æ³¨é‡Šå¯¹åº”çš„djvu代ç åˆ°å‰ªè´´æ¿ã€‚ &File File| 文件(&F) Open &Recent 打开最近的文件(&R) &Edit Edit| 编辑(&E) &View View| 查看(&V) &Zoom View|Zoom 缩放(&Z) &Rotate View|Rotate 旋转(&R) &Display View|Display 显示(&D) &Go Go| 转到(&G) &Settings Settings| 设置(&S) &Help Help| 帮助(&H) Control Left Mouse Button 控制鼠标左键 Right Mouse Button é¼ æ ‡å³é”® <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>选择矩形。</b><br/> 选中矩形区域时,弹出èœå•让你å¤åˆ¶ç›¸åº”的文本或图åƒã€‚å¦å¤–äº¦å¯æŒ‰ä½ %1 和鼠标左键。</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>缩放。</b><br/> 选择缩放级别以查看文档。 缩放级别 100% 显示文档于 100 dpi çš„å±å¹•。 缩放级别 <tt>适应页é¢</tt> åŠ <tt>适应宽度</tt> 使整页或宽度适应窗å£ã€‚ </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>旋转页é¢ã€‚</b><br/> é€‰æ‹©çºµå‘æˆ–æ¨ªå‘æ˜¾ç¤ºæ¨¡å¼ã€‚ 亦å¯ä½¿å…¶ä¸Šä¸‹é¢ å€’。</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>显示模å¼ã€‚</b><br/> DjVu图åƒåŒ…括背景层和基于模æ¿çš„剿™¯å±‚。 æ˜¾ç¤ºæ¨¡å¼æŒ‡å®šå“ªäº›å±‚被显示。</html> <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>文档导航。</b><br/> 用页é¢é€‰æ‹©å™¨å¯æŒ‰å称跳到指定页é¢ï¼Œå¯æŒ‰ Ctrl+G 激活之。 用导航按钮å¯è·³åˆ°é¦–页ã€ä¸Šä¸€é¡µã€ä¸‹ä¸€é¡µæˆ–末页。 </html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>文档和页é¢ä¿¡æ¯ã€‚</b><br> å¼¹å‡ºå¯¹è¯æ¡†æŸ¥çœ‹æ–‡æ¡£æˆ–页é¢çš„ç¼–ç ä¿¡æ¯ã€‚</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>文档和页é¢å…ƒæ•°æ®ã€‚</b><br> å¼¹å‡ºå¯¹è¯æ¡†æ˜¾ç¤ºæ–‡æ¡£æˆ–页é¢çš„元数æ®ã€‚</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>è¿žç»­é¡µé¢æ¨¡å¼ã€‚</b><br/> 显示文档的全部页é¢ä¸Žå¸¦æ»šåЍæ¡çš„æ˜¾ç¤ºåŒºåŸŸä¸­ã€‚</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>并排显示模å¼ã€‚</b><br/> 将页é¢å¹¶æŽ’显示在查看器中。</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>页é¢ä¿¡æ¯ã€‚</b><br/> 显示ä½äºŽå…‰æ ‡ä½ç½®çš„页é¢ä¿¡æ¯: 页ç åºå·ï¼Œ 页é¢çš„尺寸(按åƒç´ ï¼‰ï¼Œ 以åŠé¡µé¢çš„分辨率(按DPIï¼Œå³æ¯è‹±å¯¸ç‚¹æ•°ï¼‰ </html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>光标信æ¯ã€‚</b><br/> 显示鼠标光标在页é¢å标中的ä½ç½®å€¼ã€‚ </html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>文档查看区域。</b><br/> 这是DjVuæ–‡æ¡£çš„ä¸»è¦æ˜¾ç¤ºåŒºåŸŸã€‚ <ul><li>用方å‘键和翻页键å¯ç¿»åŠ¨æ–‡æ¡£ã€‚</li><li>空格和退格键阅读文档。</li><li>按键 <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> å¯ç¼©æ”¾æˆ–旋转文档。</li><li>é¼ æ ‡å·¦é”®å¯æŒªåЍ页é¢åŠé€‰ä¸­é“¾æŽ¥ã€‚</li><li>%3 显示关è”弹出èœå•。</li><li>%1 鼠标左键选择文本或图åƒã€‚</li><li>%2 弹出放大镜。</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>文档查看区域。</b><br/> 这是DjVuæ–‡æ¡£çš„ä¸»è¦æ˜¾ç¤ºåŒºåŸŸã€‚ ä¸è¿‡å¾—è¦å…ˆæ‰“å¼€DjVu文档哦。</html> Option '%1' requires boolean argument. 选项 '%1' 需è¦å¸ƒå°”åž‹å‚æ•°ã€‚ Illegal value '%2' for option '%1'. å–值 '%2' 对选项 '%1' 无效。 Toolbar option '%1' is not implemented. 工具æ é€‰é¡¹ '%1' 尚未实现。 Toolbar option '%1' is not recognized. 工具æ é€‰é¡¹ '%1' 未识别。 Option '%1' requires a standalone viewer. 选项 '%1' 需è¦å•独的查看器。 Deprecated option '%1' 过期选项 '%1' Option '%1' is not implemented. 选项 '%1' 尚未实现。 Option '%1' is not recognized. 选项 '%1' 未识别。 DjView DjView Thumbnails 缩略图 Outline 书签 Find 查找 Cannot open file '%1'. 未能打开文件 '%1'。 Opening DjVu file 打开DjVu文件 Cannot open URL '%1'. 未能打开URL '%1'。 Opening DjVu document 打开DjVu文档 Certificate validation error - DjView dialog caption è¯ä¹¦éªŒè¯é”™è¯¯ - DjView <html> %1 Do you want to continue anyway? </html> <html> %1 是å¦ä»ç„¶ç»§ç»­? </html> Cannot find page numbered: %1 未能找到此编å·çš„页: %1 Cannot find page named: %1 未能找到此å称的页: %1 Unrecognized sidebar options '%1'. 未识别的侧æ é€‰é¡¹ '%1'。 Print - DjView dialog caption æ‰“å° - DjView <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html> 本文件有打å°é™åˆ¶ã€‚是å¦ä»ç„¶æ‰“å°ï¼Ÿ</html> Save - DjView dialog caption ä¿å­˜ - DjView <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html> 本文件有ä¿å­˜é™åˆ¶ã€‚是å¦ä»ç„¶ä¿å­˜ï¼Ÿ</html> Export - DjView dialog caption 导出 - DjView Text files save filter 文本文件 All files save filter 所有文件 Save Text - DjView dialog caption ä¿å­˜æ–‡æœ¬ - DjView Error - DjView dialog caption 错误 - DjView Cannot write file '%1'. %2. 未能写入文件 '%1'. %2. %1 files (*.%2);; save image filter %1 文件 (*.%2);; Save Image - DjView dialog caption ä¿å­˜å›¾åƒ - DjView Cannot determine file format. Filename '%1' has no suffix. ä¸èƒ½ç¡®å®šæ–‡ä»¶æ ¼å¼ã€‚ 文件å '%1' æœªåŒ…å«æ‰©å±•å。 Image format %1 not supported. å›¾åƒæ ¼å¼ %1 未支æŒã€‚ Cannot decode page %1. 未能解ç é¡µé¢ %1。 Cannot decode document. æœªèƒ½è§£ç æ–‡æ¡£ã€‚ Decoding DjVu document è§£ç DjVu文档 P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: 1 page forward. 转到:å‘å‰ä¸€é¡µã€‚ Go: %n pages forward. 转到:å‘å‰ %n 页。 Go: 1 page backward. 转到:å‘åŽä¸€é¡µã€‚ Go: %n pages backward. 转到:å‘åŽ %n 页。 Go: page %1. 转到:第 %1 页。 Go: %1 转到:%1 (in other window.) (在其它窗å£) Cannot resolve link '%1' 未能解æžé“¾æŽ¥ '%1' Cannot spawn a browser for url '%1' 未能用æµè§ˆå™¨æ‰“å¼€URL '%1' %n characters %n 字符 Copy text (%1) å¤åˆ¶æ–‡æœ¬ (%1) Save text as... å¦å­˜æ–‡æœ¬ä¸º... Copy text into the clipboard. å¤åˆ¶æ–‡æœ¬åˆ°å‰ªè´´æ¿ã€‚ Save text into a file. ä¿å­˜æ–‡æœ¬åˆ°æ–‡ä»¶ã€‚ Copy image (%1x%2 pixels) å¤åˆ¶å›¾åƒ(%1x%2åƒç´ ) Save image as... å¦å­˜å›¾åƒä¸º... Copy image into the clipboard. å¤åˆ¶å›¾åƒåˆ°å‰ªè´´æ¿ã€‚ Save image into a file. ä¿å­˜å›¾åƒåˆ°æ–‡ä»¶ã€‚ Zoom to rectangle 缩放到矩形区域 Zoom the selection to fit the window. 缩放选中区域适应窗å£ã€‚ Copy URL å¤åˆ¶URL Save into the clipboard an URL that highlights the selection. å¤åˆ¶é€‰ä¸­å¯¹è±¡çš„URL到剪贴æ¿ã€‚ Copy Maparea å¤åˆ¶æ˜ å°„区域 Save into the clipboard a maparea annotation expression for program djvused. å¤åˆ¶æ˜ å°„区域注释对应的djvu代ç åˆ°å‰ªè´´æ¿ã€‚ <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>DjVu文档查看工具<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>æœ¬ç¨‹åºæ˜¯è‡ªç”±è½¯ä»¶ã€‚ä½ å¯ä¾æ®è‡ªç”±è½¯ä»¶åŸºé‡‘会å‘布的GNU GPLçš„æ¡æ¬¾é‡æ–°å‘布或修改本程åºã€‚ 本程åºä¹‹å‘布<i>无任何担ä¿</i>。 详细请å‚è§ GNU GPL。</small></p></html> About DjView 关于DjView DjVu files DjVu文件 All files 所有文件 Open - DjView dialog caption 打开 - DjView Open Location - DjView dialog caption 打开ä½ç½® - DjView Enter the URL of a DjVu document: 输入DjVu文档的URL: Information - DjView dialog caption ä¿¡æ¯ - DjView Metadata - DjView dialog caption å…ƒæ•°æ® - DjView &Clear History 清除历å²(&C) QDjViewApplication cannot open '%1'. 未能打开 '%1'。 Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. 用法: djview [选项] [æ–‡ä»¶åæˆ–url] 常用选项包括: -help~~~显示本帮助信æ¯. -verbose~~~显示所有警告信æ¯. -display <xdpy>~~~选择 X11 æ˜¾ç¤ºçª—å£ <xdpy>. -geometry <xgeom>~~~选择åˆå§‹çª—å£å°ºå¯¸. -font <xlfd>~~~选择主字体的 X11 åç§°. -style <qtstyle>~~~选择 QT ç”¨æˆ·ç•Œé¢æ ·å¼. -fullscreen, -fs~~~å¯åЍ djview ä¸ºå…¨å±æ¨¡å¼. -page=<page>~~~跳到页 <page>. -zoom=<zoom>~~~è®¾å®šç¼©æ”¾å‚æ•°. -continuous=<yn>~~~è®¾å®šè¿žç»­é¡µé¢æ¨¡å¼. -sidebyside=<yn>~~~设定并排显示模å¼. QDjViewAuthDialog Password: 密ç : User: 用户å: Authentication required - DjView 需è¦èº«ä»½è®¤è¯ - DjView QDjViewDjVuExporter DjVu Bundled Document 打包的DjVu文档 DjVu Files (*.djvu *.djv) DjVu文件 (*.djvu *.djv) DjVu Indirect Document 间接的DjVu文档 Question - DjView dialog caption 问题 - DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> 此文件属于一个éžç©ºç›®å½•。ä¿å­˜é—´æŽ¥æ–‡æ¡£å°†åœ¨æ­¤ç›®å½•中创建许多文件。是å¦ç»§ç»­å¹¶å…许覆盖文件?</html> Con&tinue 连续(&T) &Cancel å–æ¶ˆ(&C) Unknown error. 未知错误。 System error: %1. 系统错误: %1. Save job creation failed! ä¿å­˜æ“ä½œå¤±è´¥ï¼ QDjViewErrorDialog DjView Error DjView 错误 &Ok 确定(&O) Error - DjView dialog caption 错误 - DjView QDjViewExportDialog Dialog å¯¹è¯æ¡† Export 导出 &Document 文档(&D) C&urrent page 当å‰é¡µ(&U) &Pages 页(&P) to 至 Destination 目标 Format: æ ¼å¼ï¼š &Defaults 默认值(&D) &Ok 确定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>ä¿å­˜ä¸­ã€‚</b><br/>ä½ å¯ä»¥ä»¥å¤šç§æ ¼å¼ä¿å­˜æ•´ä¸ªæ–‡æ¡£æˆ–æ¯é¡µã€‚选择格å¼å¹¶è®¾ç½®ç›¸åº”选项。</html> Error - DjView dialog caption 错误 - DjView Overwriting the current file is not allowed! ä¸å…è®¸è¦†ç›–å½“å‰æ–‡ä»¶ï¼ Question - DjView dialog caption 问题 - DjView A file with this name already exists. Do you want to replace it? åŒå文件已存在。 æ˜¯å¦æ›¿æ¢ï¼Ÿ &Replace 替æ¢(&R) This operation has failed. æ“作失败。 This operation has been interrupted. æ“作中断。 All files save filter 所有文件 Export - DjView dialog caption 导出 - DjView QDjViewExportPS1 Form çª—å£ Color 颜色 &Color 彩色(&C) &GrayScale ç°åº¦(&G) Marks 标记 Print image &frame 打å°å›¾åƒæ¡†(&F) Print crop &marks 打å°è£åˆ‡æ ‡è®°(&M) PostScript PostScript Language Level 语言级别 QDjViewExportPS2 Form çª—å£ Scaling 缩放 Scale to &fit the page 缩放到适应整页(&F) &Zoom 缩放(&Z) % % Orientation æ–¹å‘ Automatic 自动 &Portrait 纵å‘(&P) &Landscape 横å‘(&L) QDjViewExportPS3 Form çª—å£ Print sheets suitable for folding a booklet. 打å°å¼ æ•°é€‚应折å å†Œé¡µã€‚ Advanced 高级 Sheets per booklet: æ¯å†Œé¡µå¼ æ•°: Unlimited æ— é™åˆ¶ at most 最多 Print æ‰“å° rectos and versos. å¥‡æ•°é¡µå’Œå¶æ•°é¡µã€‚ rectos only. 仅奇数页。 versos only. ä»…å¶æ•°é¡µã€‚ Shift rectos and versos by åç§»å¥‡æ•°é¡µå’Œå¶æ•°é¡µ points. 点. Center: 中间: points 点 plus 加 /100 /100 per page. æ¯é¡µ. QDjViewExportPrn Form çª—å£ Color 颜色 &Color 彩色(&C) &GrayScale ç°åº¦(&G) Marks 标记 Print image &frame 打å°å›¾åƒæ¡†(&F) Print crop &marks 打å°è£åˆ‡æ ‡è®°(&M) Scaling 缩放 Scale to &fit the page 缩放到适应整页(&F) &Zoom 缩放(&Z) % % Orientation æ–¹å‘ Automatic 自动 &Portrait 纵å‘(&P) &Landscape 横å‘(&L) QDjViewExportTiff Form çª—å£ Resolution 分辨率 Maximum image resolution 最大图åƒåˆ†è¾¨çއ dpi dpi Compression 压缩 Force &bitonal G4 compression. 强制二值G4压缩(&B)。 Allow &lossy JPEG compression. å…许有æŸJPEG压缩(&L)。 JPEG &quality JPEGè´¨é‡(&Q) Allow &deflate compression. å…许deflate压缩(&D)。 QDjViewFind Case sensitive 区分大å°å†™ Words only ä»…è¯è¯­ Regular expression æ­£åˆ™è¡¨è¾¾å¼ Find Previous (Shift+F3) 查找å‰ä¸€ä¸ª (Shift+F3) Find Next (F3) 查找下一个 (F3) Reset search options to default values. é‡ç½®æœç´¢é€‰é¡¹åˆ°é»˜è®¤å€¼ã€‚ Options 选项 <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>查找文本。</b><br/> 输入æœç´¢å­—符串时命中数会递增出现。 敲回车键跳到下一个命中处。 è¦è½¬åˆ°å‰ä¸€å¤„或下一处命中, 亦å¯ä½¿ç”¨æ–¹å‘键或快æ·é”® <tt>F3</tt> 或 <tt>Shift-F3</tt>。 åˆå¯åŒå‡»é¡µé¢å. 在 <tt>选项</tt> èœå•设定æœç´¢è¯è¯­æˆ–区分大å°å†™ã€‚</html> Specify whether search hits must begin on a word boundary. 设定æœç´¢å‘½ä¸­æ˜¯å¦å¼€å§‹äºŽè¯è¯­è¾¹ç•Œã€‚ Specify whether searches are case sensitive. 设定是å¦è€ƒè™‘大å°å†™ã€‚ Regular expressions describe complex string matching patterns. 正则表达å¼è¡¨è¿°å¤æ‚çš„å­—ç¬¦ä¸²åŒ¹é…æ¨¡å¼ã€‚ <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>正则表达å¼å¿«é€ŸæŒ‡å—</b><ul><li>点 <tt>.</tt> 匹é…ä»»æ„字符。</li><li>多数字符匹é…其本身。</li><li>这些字符å‰é¢åŠ ä¸€ä¸ªåæ–œæ  <tt>\</tt> å¯åŒ¹é…相应字符 <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> 匹é…è¯è¯­è¾¹ç•Œã€‚</li><li><tt>\w</tt> 匹é…一个文本字符。</li><li><tt>\d</tt> 匹é…一个数字字符。</li><li><tt>\s</tt> 匹é…一个空白字符。</li><li><tt>\n</tt> 匹é…一个æ¢è¡Œç¬¦ã€‚</li><li><tt>[<i>a</i>-<i>b</i>]</tt> åŒ¹é…æ­¤èŒƒå›´ä¸­çš„ä»»æ„字符 <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> åŒ¹é…æ­¤èŒƒå›´ä¹‹å¤–的任æ„字符 <tt><i>a</i></tt>-<tt><i>b</i></tt>。</li><li><tt><i>a</i>|<i>b</i></tt> åŒ¹é…æ­£åˆ™è¡¨è¾¾å¼ <tt><i>a</i></tt> æˆ–æ­£åˆ™è¡¨è¾¾å¼ <tt><i>b</i></tt>。</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> åŒ¹é…æ­£åˆ™è¡¨è¾¾å¼ <tt><i>a</i></tt> é‡å¤ <tt><i>n</i></tt> 到 <tt><i>m</i></tt> 次。</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, åŠ <tt><i>a</i>+</tt> 为 <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, åŠ <tt><i>a</i>{1,}</tt>对应的简写。</li><li>ç”¨æ‹¬å· <tt>()</tt> å¯å°†è¡¨è¾¾å¼åˆ†ç»„ 于 <tt>?+*{</tt>之å‰ã€‚</li></ul></html> QDjViewFind::Model 1 hit 1 命中 %n hits %n 命中 Page %1 (1 hit) 页 %1 (1 命中) Page %1 (%n hits) 页 %1 (%n 命中) Searching page %1 (waiting for data.) æœç´¢é¡µ %1 (等待数æ®ã€‚) Searching page %1. æœç´¢é¡µ %1。 No hits! æ— å‘½ä¸­ï¼ <html>Document is not searchable. No page contains information about its textual content.</html> <html>文档ä¸å¯æœç´¢ã€‚ 页é¢ä¸­æ²¡æœ‰æ­¤æ–‡æœ¬å†…容的信æ¯ã€‚</html> <html>Invalid regular expression.</html> <html>无效的正则表达å¼ã€‚</html> QDjViewImgExporter %1 Image JPG Image %1 å›¾åƒ %1 Files (*.%2) JPG Files %1 文件 (*.%2) Cannot render page. 未能显示页é¢ã€‚ Image format %1 not supported. å›¾åƒæ ¼å¼ %1 未支æŒã€‚ QDjViewInfoDialog Dialog å¯¹è¯æ¡† &Document 文档(&D) &File 文件(&F) File: 文件: &View Page 查看页é¢(&V) &Close 关闭(&C) File # 文件 # File Name 文件å File Size æ–‡ä»¶å¤§å° File Type 文件类型 Page # 页 # Page Title 页标题 <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>文档信æ¯</b><br>æ­¤é¢æ¿æ˜¾ç¤ºæ–‡æ¡£åŠå…¶ç»„æˆæ–‡ä»¶çš„ä¿¡æ¯ã€‚ é€‰ä¸­ç»„æˆæ–‡ä»¶å¯æ˜¾ç¤ºå…¶è¯¦ç»†ä¿¡æ¯äºŽ <tt>文件</tt> 页中。 åŒå‡»ç»„æˆæ–‡ä»¶å¯åœ¨ä¸»çª—å£ä¸­æ˜¾ç¤ºå…¶é¡µé¢ã€‚ </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>文件和页é¢ä¿¡æ¯</b><br>æ­¤é¢æ¿æ˜¾ç¤ºåœ¨ <tt>文档</tt> é¡µä¸­é€‰ä¸­çš„ç»„æˆæ–‡ä»¶æˆ–页é¢çš„ DjVu æ•°æ®ç»“构。 æ–¹å‘æŒ‰é’®è½¬åˆ°ä¸Šä¸€ä¸ªæˆ–ä¸‹ä¸€ä¸ªç»„æˆæ–‡ä»¶ã€‚</html> Waiting for data... 等待数æ®... Page #%1 - « %2 » 页 #%1 - « %2 » Page #%1 页 #%1 Thumbnails 缩略图 Shared annotations 共享注释 Shared data å…±äº«æ•°æ® File #%1 - 文件 #%1 - Single DjVu page å•DjVu页 Bundled DjVu document 打包的DjVu文档 Indirect DjVu document TODO 间接的DjVu文档 Obsolete bundled DjVu document 过时的打包的DjVu文档 Obsolete indexed DjVu document 过时的索引的DjVu文档 1 file 1 文件 %n files %n 文件 1 page 1 页 %n pages %n 页 n/a ä¸å¯ç”¨ Page 页 Thumbnails 缩略图 Shared 共享的 QDjViewMetaDialog Dialog å¯¹è¯æ¡† &Document Metadata 文档元数æ®(&D) &Page Metadata 页é¢å…ƒæ•°æ®(&P) Page: 页: &View Page 查看页é¢(&V) &Close 关闭(&C) Ctrl+C copy Ctrl+C Key 按键 Value 值 <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>文档元数æ®</b><br>æ­¤é¢æ¿æ˜¾ç¤ºæ–‡æ¡£çš„元数æ®ï¼Œè¯¸å¦‚作者,标题,å‚考等。 这些信æ¯å¯ä¿å­˜åˆ°æ–‡æ¡£ä¸­ï¼Œè¯·ç”¨ç¨‹åº <tt>djvused</tt>的命令 <tt>create-shared-ant</tt> å’Œ <tt>set-meta</tt>。</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>页é¢å…ƒæ•°æ®</b><br>æ­¤é¢æ¿æ˜¾ç¤ºé¡µé¢çš„元数æ®ã€‚ 页é¢ç‰¹å®šçš„元数æ®è¦†ç›–文档的元数æ®ã€‚ 这些信æ¯å¯ä¿å­˜åœ¨æ–‡æ¡£ä¸­ï¼Œè¯·ç”¨ç¨‹åº <tt>djvused</tt> 的命令 <tt>select</tt> 选择页é¢åŠå‘½ä»¤ <tt>set-meta</tt> 设定元数æ®çš„å–值。</html> QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>文档书签。</b><br/> æ­¤é¢æ¿æ˜¾ç¤ºæ–‡æ¡£ä¹¦ç­¾ï¼Œæˆ–在书签ä¸å¯ç”¨æ—¶æ˜¾ç¤ºé¡µé¢å称, åŒå‡»é¡¹ç›®è·³åˆ°é€‰ä¸­çš„页é¢ã€‚</html> Outline data is corrupted 书签数æ®å†²çª Pages 页 Page %1 页 %1 Go: page %1. 转到:第 %1 页。 Go: %1 转到:%1 QDjViewPSExporter PostScript PostScript PostScript Files (*.ps *.eps) PostScript文件 (*.ps *.eps) Encapsulated PostScript å°è£…çš„PostScript PostScript tab caption PostScript Position tab caption ä½ç½® Booklet tab caption 册页 <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>PostScript选项。</b><br>选项 <tt>彩色</tt> å¯ç”¨å½©è‰²æ‰“å°ã€‚ 文档页é¢å¯åŠ è¾¹æ¡†å’Œå‰ªè£æ ‡è®°ã€‚ PostScript 语言级别 1 仅用于很è€çš„æ‰“å°æœºã€‚ 级别2ç”¨äºŽå¤§å¤šæ•°æ‰“å°æœºã€‚ 级别3åœ¨æœ€æ–°çš„æ‰“å°æœºä¸Šæ‰“å°å½©è‰²å¿«äº›ã€‚</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>ä½ç½®ä¸Žç¼©æ”¾ã€‚</b><br>选项 <tt>缩放到适应</tt> é€‚åº”æ‰“å°æœºä½¿ç”¨çš„纸张尺寸。 缩放率 <tt>100%</tt> 与原始文档尺寸一样。 æ–¹å‘ <tt>自动</tt> 按æ¯é¡µé€‰æ‹©çºµå‘或横å‘。</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>打å°å†Œé¡µã€‚</b><br>å†Œé¡µæ¨¡å¼æ‰“å°é€‰ä¸­çš„页é¢ä»¥ä¾¿æŠ˜å æˆä¸€æœ¬æˆ–多本册页。 若指定æ¯å†Œé¡µçš„æœ€å¤§å¼ æ•°åˆ™å¯ç”Ÿæˆå¤šæœ¬å†Œé¡µã€‚ ä½ å¯ä½¿ç”¨åŒé¢æ‰“å°æœºæˆ–分别打å°å¥‡å¶é¡µã€‚<p> 对于对é½ä¸å¥½çš„åŒé¢æ‰“å°æœºå¯å移奇å¶é¡µã€‚ 中间的边决定折å é¡µé—´çš„留白。 ç•™ç™½ä»Žå†…é¡µåˆ°å¤–é¡µé€æ¸å¢žå¤§ã€‚</html> Save job creation failed! ä¿å­˜æ“ä½œå¤±è´¥ï¼ QDjViewPdfExporter PDF Document PDF文档 PDF Files (*.pdf) PDF文件 (*.pdf) PDF Options tab caption PDF选项 <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>PDF选项。</b><br>这些选项控制嵌入图åƒçš„特å¾ã€‚ 分辨率框é™åˆ¶æœ€å¤§åˆ†è¾¨çŽ‡ã€‚ 强制二值G4压缩将全部黑白页用CCITT Group 4压缩格å¼åŽ‹ç¼©ã€‚ å…许JPEG压缩用有æŸJPEG压缩格å¼åŽ‹ç¼©å…¨éƒ¨éžäºŒå€¼å›¾åƒæˆ–å­é‡‡æ ·å›¾åƒã€‚ å¦å¤–, å…许deflate压缩将得到更å°çš„æ–‡ä»¶ã€‚ </html> Error while creating pdf file. 创建pdf文件出错。 Unable to create output file. 未能创建输出文件。 System error: %1. 系统错误: %1. Unable to reopen temporary file. æœªèƒ½é‡æ–°æ‰“开临时文件。 PDF export was not compiled. PDF输出未æˆåŠŸã€‚ Unable to create temporary file. 未能创建临时文件。 QDjViewPlugin::Document Requesting %1. 请求 %1. QDjViewPrefsDialog Dialog å¯¹è¯æ¡† &Screen å±å¹•(&S) Gamma TODO Gamma <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>å±å¹•颜色校正。<br>调节滚动æ¡ç›´åˆ°ç°è‰²é˜´å½±åŒºçœ‹èµ·æ¥ç›¸ä¼¼ã€‚</html> Darker æš— Lighter 亮 Display 显示 Force screen &resolution 强制å±å¹•分辨率(&R) dpi dpi Force inverted luminance 强制å色 &Interface 界é¢(&I) Options for 选项 Standalone Viewer å•独显示 Full Page Plugin 全页æ’ä»¶ Embedded Plugin 嵌入æ’ä»¶ &Remember initial state from last invocation è®°ä½ä¸Šæ¬¡å¯ç”¨çš„åˆå§‹çжæ€(&R) Show 显示 &Menu bar èœå•æ (&M) &Tool bar 工具æ (&T) Sc&rollbars 滚动æ¡(&R) Stat&us bar çŠ¶æ€æ (&U) &Side bar ä¾§æ (&S) &Zoom: 缩放(&Z): s secs .ç§’ Display page &frames 显示页é¢è¾¹æ¡†(&F) Display &annotations 显示注释(&A) Layout 布局 Continuous 连续 Side-by-side 并排显示 Cover Page å°é¢é¡µ Right-to-Left 从å³å‘å·¦ &Keys 按键(&K) Keys 按键 For displaying hyper&links: 显示超链接(&L): For &selecting text or images: 选中的文本或图åƒ(&S): For displaying the &lens: 显示放大镜(&L): Mouse wheel 鼠标滚轮 Mouse wheel scrolls the page é¼ æ ‡æ»šè½®æ»šåŠ¨é¡µé¢ Mouse wheel changes the zoom factor 鼠标滚轮改å˜ç¼©æ”¾çއ &Lens 放大镜(&L) Enable magnifying &lens å¯ç”¨æ”¾å¤§é•œ(&L) Lens options 放大镜选项 Lens &size: 放大镜尺寸(&S): Magnifying &power: æ”¾å¤§å€æ•°(&P): x x pixels åƒç´  &Network 网络(&N) Proxy settings 代ç†è®¾ç½® Use pro&xy to access the network 使用代ç†è®¿é—®ç½‘络(&X) &Host: 主机(&H): &Port: 端å£(&P): &User: 用户å(&U): Pass&word: 密ç (&W): Cache 缓存 &Clear 清除(&C) MB MB &Decoded page cache: è§£ç é¡µé¢ç¼“å­˜(&D): &Pixel cache: åƒç´ ç¼“å­˜(&P): &Advanced 高级(&A) Interface ç•Œé¢ Force language (next time djview runs) Force language (when djview is restarted.) 强制界é¢è¯­è¨€(下次å¯åŠ¨æ—¶) Enable advanced features in menus 在èœå•中å¯ç”¨é«˜çº§åŠŸèƒ½ Enable page animations å¯ç”¨é¡µé¢åŠ¨ç”» Timer: 定时器: Show hidden text in status bar åœ¨çŠ¶æ€æ æ˜¾ç¤ºéšè—文字 Miscellaneous å…¶ä»– Render with openGL when available openGLå¯ç”¨æ—¶ç”¨å…¶æ¸²æŸ“ Override saving and printing restrictions 覆盖ä¿å­˜å’Œæ‰“å°é™åˆ¶ Manual printer color correction æ‰‹åŠ¨æ‰“å°æœºé¢œè‰²æ ¡æ­£ gamma= TODO gamma= &Defaults 默认值(&D) &Apply 应用(&A) &Ok 确定(&O) Cancel å–æ¶ˆ Preferences[*] - DjView 设置[*] - DjView <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>å±å¹•颜色Gamma校正。</b><br>用滑å—调整Gamma值使ç°è‰²æ–¹å—区域尽é‡ä¸€è‡´ä»¥èŽ·å¾—æœ€ä½³è‰²å½©è¡¨çŽ°ã€‚<p><b>å±å¹•分辨率。</b><br>此选项强制使用指定的分辨率值å–代由æ“作系统æä¾›çš„ä¸å¯é çš„分辨率值。 强制分辨率为 100 dpi 时与 djvulibre 命令行工具一致。</html> <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>åˆå§‹ç•Œé¢è®¾ç½®ã€‚</b><br>DjView 坿Œ‰ä»¥ä¸‹æ–¹å¼è¿è¡Œï¼š å•独显示, 免屿˜¾ç¤ºï¼Œ 免页颿µè§ˆå™¨æ’件, 或 嵌入html页é¢ä¸­ã€‚ 对于æ¯ç§æ–¹å¼ï¼Œ å¯é€‰ä¸­ <tt>è®°ä½ä¸Šæ¬¡</tt> 框以便自动ä¿å­˜åŠé‡ç”¨ç•Œé¢è®¾ç½®ï¼› 或者,ä¸é€‰ä¸­è€ŒæŒ‡å®šä¸€ä¸ªå›ºå®šçš„åˆå§‹è®¾ç½®ã€‚</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>按键。</b><br>定义一些组åˆé”®ï¼Œ 如 显示放大镜, 临时å¯ç”¨é€‰æ‹©æ¨¡å¼ï¼Œ 或高亮显示链接。</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>放大镜。</b><br>用 <tt>按键</tt> 页中定义的按键å¯è°ƒå‡ºæ”¾å¤§é•œã€‚ åœ¨æœ¬é¢æ¿å¯é€‰æ‹©æ”¾å¤§å€æ•°å’Œæ”¾å¤§é•œçš„尺寸。</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>高级。</b><br>ä½ å¯é€‰æ‹©é»˜è®¤ç•Œé¢è¯­è¨€ï¼Œ ç¦ç”¨é¡µé¢åŠ¨ç”»ï¼Œ 或 å¯ç”¨æ›´å¤šç¼–辑 DjVu 文件的èœå•项。亦å¯ç¦ç”¨æŸäº›ç½‘ç«™çš„æ‰“å°æˆ–ä¿å­˜é™åˆ¶ã€‚ å¯¹äºŽæ—§å¼æ‰“å°æœºå¯ç”¨æ‰‹åŠ¨é¢œè‰²æ ¡æ­£ã€‚</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>网络代ç†è®¾ç½®ã€‚</b><br>本代ç†è®¾ç½®ç”¨äºŽä»¥å•独显示方å¼ä»Žhttp URL地å€è®¿é—®djvu文档。 以æ’ä»¶æ–¹å¼æ—¶ç»é€šå¸¸ç”¨æµè§ˆå™¨çš„代ç†è®¾ç½®ã€‚<p><b>缓存设置。</b><br> <i>åƒç´ ç¼“å­˜</i> ä¿å­˜å¯è§åŒºä¹‹å¤–çš„å›¾åƒæ•°æ®ï¼Œ 使平移更平滑。 <i>è§£ç é¡µé¢ç¼“å­˜</i> åŒ…å«æœ‰éƒ¨åˆ†è§£ç çš„页é¢ï¼Œ 使得æµè§ˆå¤šé¡µæ–‡æ¡£æˆ–返回å‰é¢çœ‹è¿‡çš„页颿—¶å应迅速; 页颿•°æ®æ”¹å˜æ—¶å¯æ¸…除此缓存而ä¸å¿…é‡å¯ç¨‹åºã€‚</html> Standalone Viewer (Full Screen mode) å•独显示 (免屿¨¡å¼) Standalone Viewer (Slideshow mode) å•独显示 (å¹»ç¯æ¨¡å¼) QDjViewPrintDialog Dialog å¯¹è¯æ¡† Print æ‰“å° &Document 文档(&D) C&urrent page 当å‰é¡µ(&U) &Pages 页(&P) to 至 Destination 目标 Print to file 打å°åˆ°æ–‡ä»¶ Printer name: æ‰“å°æœºå: Choose 选择 &Defaults 默认值(&D) &Ok 确定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>打å°ã€‚</b><br/> 你坿‰“å°æ•´ä¸ªæ–‡æ¡£æˆ–一些页é¢ã€‚ 用 <tt>选择</tt> 按钮选择打å°ç›®æ ‡æˆ–æŒ‡å®šæ‰“å°æœºé€‰é¡¹ã€‚ 其他选项页é¢å¯æŒ‡å®šè½¬æ¢é€‰é¡¹ã€‚</html> (invalid printer) (æ— æ•ˆæ‰“å°æœº) All files save filter 所有文件 Print To File - DjView dialog caption 打å°åˆ°æ–‡ä»¶ - DjView Question - DjView dialog caption 问题 - DjView A file with this name already exists. Do you want to replace it? åŒå文件已存在。 æ˜¯å¦æ›¿æ¢ï¼Ÿ &Replace 替æ¢(&R) This operation has failed. æ“作失败。 This operation has been interrupted. æ“作中断。 QDjViewPrnExporter Printer data æ‰“å°æœºæ•°æ® PRN Files (*.prn) PRN文件 (*.prn) Printing Options tab caption 打å°é€‰é¡¹ <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>打å°é€‰é¡¹ã€‚</b><br>选项 <tt>彩色</tt> å¯ç”¨å½©è‰²æ‰“å°ã€‚ 文档页é¢å¯åŠ è¾¹æ¡†å’Œå‰ªè£æ ‡è®°ã€‚ 选项 <tt>缩放到适应</tt> é€‚åº”æ‰“å°æœºä½¿ç”¨çš„纸张尺寸。 缩放率 <tt>100%</tt> 与原始文档尺寸一样。 æ–¹å‘ <tt>自动</tt> 按æ¯é¡µé€‰æ‹©çºµå‘或横å‘。</html> Cannot render page %1. æœªèƒ½æ¸²æŸ“é¡µé¢ %1. QDjViewSaveDialog Dialog å¯¹è¯æ¡† Save ä¿å­˜ &Document 文档(&D) C&urrent page 当å‰é¡µ(&U) &Pages 页(&P) to 至 Destination 目标 Format: æ ¼å¼ï¼š Bundled DjVu Document 打包的DjVu文档 Indirect DjVu Document 间接的DjVu文档 &Ok 确定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>ä¿å­˜ã€‚</b><br/> ä½ å¯ä¿å­˜æ•´ä¸ªæ–‡æ¡£æˆ–其中的一些页é¢ã€‚ å°è£…æ ¼å¼ç”Ÿæˆä¸€ä¸ªæ–‡ä»¶ã€‚间接格å¼ç”Ÿæˆå¤šä¸ªæ–‡ä»¶ï¼Œé€‚åˆç½‘页应用。</html> Error - DjView dialog caption 错误 - DjView Overwriting the current file is not allowed! ä¸å…è®¸è¦†ç›–å½“å‰æ–‡ä»¶ï¼ Question - DjView dialog caption 问题 - DjView A file with this name already exists. Do you want to replace it? åŒå文件已存在。 æ˜¯å¦æ›¿æ¢ï¼Ÿ &Replace 替æ¢(&R) This operation has failed. æ“作失败。 This operation has been interrupted. æ“作中断。 All files save filter 所有文件 Save - DjView dialog caption ä¿å­˜ - DjView QDjViewThumbnails Tiny thumbnail menu æžå° Small thumbnail menu å° Medium thumbnail menu 中 Large thumbnail menu 大 Smart thumbnail menu 智能 Control Left Mouse Button 控制鼠标左键 Right Mouse Button é¼ æ ‡å³é”® <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>文档缩略图。</b><br/> æœ¬é¢æ¿æ˜¾ç¤ºæ–‡æ¡£é¡µé¢çš„缩略图。 åŒå‡»ç¼©ç•¥å›¾è·³åˆ°ç›¸åº”的页é¢ã€‚ %1 设置缩略图尺寸或刷新模å¼ã€‚ 智能刷新模å¼åªåœ¨é¡µé¢æ•°æ®è¢«ä½¿ç”¨ï¼ˆæ˜¾ç¤ºæˆ–缓存)时生æˆç¼©ç•¥å›¾ã€‚</html> QDjViewTiffExporter TIFF Document TIFF文档 TIFF Files (*.tiff *.tif) TIFF文件 (*.tiff *.tif) TIFF Options tab caption TIFF选项 <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>TIFF选项。</b><br>分辨率框指定TIFF图åƒçš„æœ€å¤§åˆ†è¾¨çŽ‡ã€‚ 强制二值G4压缩将所有黑白页é¢ç”¨CCITT Group 4 æ ¼å¼åŽ‹ç¼©ã€‚ å…许JPEG压缩使用有æŸJPEGæ ¼å¼åŽ‹ç¼©æ‰€æœ‰éžäºŒå€¼çš„å›¾åƒæˆ–å­é‡‡æ ·å›¾åƒã€‚ å¦å¤–,相比默认的packbits压缩格å¼ï¼Œå…许deflate压缩能产生更å°çš„æ–‡ä»¶ï¼Œä½†ç§»æ¤æ€§å·®äº›ã€‚</html> Cannot open output file. 未能打开输出文件。 Out of memory. 内存ä¸è¶³ã€‚ Internal error. 内部错误。 TIFF export has not been compiled. TIFF输出未æˆåŠŸã€‚ QDjVuNetDocument Requesting '%1' 请求 %1 QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code 接收 %2 时收到httpçŠ¶æ€ %1。 Received <%1> data while retrieving %2. %1 is a mime type 接收 %2 时收到 %1 æ•°æ®ã€‚ %1 while retrieving '%2'. 接收 %2 æ—¶ %1。 Cannot validate the certificate for server %1. æœªèƒ½éªŒè¯æœåС噍 %1 çš„è¯ä¹¦ã€‚ Authentication required for %1 (%2). %1 (%2) 需è¦èº«ä»½è®¤è¯ã€‚ Authentication required for proxy %1. ä»£ç†æœåС噍 %1 需è¦èº«ä»½è®¤è¯ã€‚ djview4-4.10.5/src/djview_zh_tw.ts000066400000000000000000004466551264256014000170430ustar00rootroot00000000000000 Generic thisLanguage Name of THIS language ç¹é«”中文 QApplication Option '-fix' is deprecated. é¸é …'-fix'å·²éŽæ™‚。 QDjView cannot open '%1'. 未能開啟 '%1'。 FitWidth zoomCombo 驿‡‰å¯¬åº¦ FitPage zoomCombo 驿‡‰é é¢ Stretch zoomCombo 拉伸 1:1 zoomCombo 1:1 300% zoomCombo 300% 200% zoomCombo 200% 150% zoomCombo 150% 100% zoomCombo 100% 75% zoomCombo 75% 50% zoomCombo 50% Color modeCombo 色彩 Stencil modeCombo æ¨£æ¿ Foreground modeCombo 剿™¯è‰² Background modeCombo 背景色 Hidden Text modeCombo éš±è—字檔 &New File| 新建(&N) Ctrl+N File|New Ctrl+N Create a new DjView window. 新建DjView視窗。 &Open File| 開啟(&O) Ctrl+O File|Open Ctrl+O Open a DjVu document. 開啟DjVu文件。 Open &Location... File| 開啟ä½ç½®(&L)... Open a remote DjVu document. 開啟é ç«¯çš„DjVu文件。 &Close File| 關閉(&C) Ctrl+W File|Close Ctrl+W Close this window. 關閉視窗。 &Quit File| çµæŸ(&Q) Ctrl+Q File|Quit Ctrl+Q Close all windows and quit the application. é—œé–‰æ‰€æœ‰è¦–çª—å¹¶çµæŸç¨‹å¼ã€‚ Save &as... File| 存新檔(&A)... Ctrl+S File|SaveAs Ctrl+S Save the DjVu document. 儲存DjVu文件。 &Export as... File| 導出為(&E)... Ctrl+E File|ExportAs Ctrl+E Export DjVu page or document to other formats. 導出DjVué é¢æˆ–文件到其他格å¼ã€‚ &Print... File| 列å°(&P)... Ctrl+P File|Print Ctrl+P Print the DjVu document. 列å°DjVu文件。 &Find... Edit| 尋找(&F)... Ctrl+F Edit|Find Ctrl+F Find text in the document. 在文件中尋找字檔。 Find &Next Edit| 尋找下一個(&N) Ctrl+F3 Edit|Find Next Ctrl+F3 F3 Edit|Find Next F3 Find next occurence of search text in the document. 在文件中尋找字檔的下一個實例。 Find &Previous Edit| 尋找å‰ä¸€å€‹(&P) Shift+F3 Edit|Find Previous Shift+F3 Find previous occurence of search text in the document. 在文件中尋找字檔的å‰ä¸€å€‹å¯¦ä¾‹ã€‚ &Select Edit| é¸å–(&S) Ctrl+F2 Edit|Select Ctrl+F2 F2 Edit|Select F2 Select a rectangle in the document. 在文件中é¸å–塊。 Zoom &In Zoom| 放大(&I) Increase the magnification. 增加放大率。 Zoom &Out Zoom| 縮å°(&O) Decrease the magnification. æ¸›å°æ”¾å¤§çŽ‡ã€‚ Fit &Width Zoom| 驿‡‰å¯¬åº¦(&W) Set magnification to fit page width. ç¸®æ”¾åˆ°é©æ‡‰é é¢å¯¬åº¦ã€‚ Fit &Page Zoom| 驿‡‰é é¢(&P) Set magnification to fit page. ç¸®æ”¾åˆ°é©æ‡‰æ•´é ã€‚ One &to one Zoom| 一比一åƒç´ (&T) Set full resolution magnification. 全解æžåº¦ç¸®æ”¾ã€‚ &300% Zoom| &300% Magnify 300% 放大300% &200% Zoom| &200% Magnify 20% 放大200% &150% 150% Zoom| &150% Magnify 150% 放大150% &100% Zoom| &100% Magnify 100% åˆå§‹å¤§å° &75% Zoom| &75% Magnify 75% 縮放到75% &50% Zoom| &50% Magnify 50% 縮放到50% &First Page Go| 首é (&F) Jump to first document page. 跳到文件的第一é ã€‚ &Next Page Go| 下一é (&N) Jump to next document page. 跳到文件的下一é ã€‚ &Previous Page Go| 上一é (&P) Jump to previous document page. 跳到文件的上一é ã€‚ &Last Page Go| 末é (&L) Jump to last document page. 跳到文件的最åŽä¸€é ã€‚ &Backward Go| åŽé€€(&B) Backward in history. 退回到上一個曆å²ä½ç½®ã€‚ &Forward Go| å‰é€²(&F) Forward in history. å‰é€²åˆ°ä¸‹ä¸€å€‹æ›†å²ä½ç½®ã€‚ Rotate &Left Rotate| é€†æ™‚é‡æ—‹è½‰(&L) Rotate page image counter-clockwise. é€†æ™‚é‡æ—‹è½‰é é¢ã€‚ Rotate &Right Rotate| é †æ™‚é‡æ—‹è½‰(&R) Rotate page image clockwise. é †æ™‚é‡æ—‹è½‰é é¢ã€‚ Rotate &0° Rotate| 還原旋轉(&0) Set natural page orientation. 回復é é¢åˆå§‹æ–¹å‘。 Rotate &90° Rotate| é€†æ™‚é‡æ—‹è½‰&90° Turn page on its left side. 旋轉é é¢é ‚部到左邊。 Rotate &180° Rotate| é€†æ™‚é‡æ—‹è½‰&180° Turn page upside-down. 旋轉é é¢é ‚部æœä¸‹ã€‚ Rotate &270° Rotate| é€†æ™‚é‡æ—‹è½‰&270° Turn page on its right side. 旋轉é é¢é ‚部到å³é‚Šã€‚ &Information... Edit| 資訊(&I)... Ctrl+I Edit|Information Ctrl+I Show information about the document encoding and structure. 察看文件的編碼和架構資訊。 &Metadata... Edit| 元資料(&M)... Ctrl+M Edit|Metadata Ctrl+M Show the document and page meta data. 察看文件åŠé é¢çš„元資料。 &About DjView... 關於DjView(&A)... Show information about this program. 察看本程å¼çš„資訊。 &Color Display| 色彩(&C) Display everything. 察看所有。 &Stencil Display| 樣æ¿(&S) Only display the document bitonal stencil. åªå¯Ÿçœ‹æ–‡ä»¶çš„二值樣æ¿ã€‚ &Foreground Display| 剿™¯(&F) Only display the foreground layer. åƒ…å¯Ÿçœ‹å‰æ™¯å±¤ã€‚ &Background Display| 背景(&B) Only display the background layer. 僅察看背景層。 &Hidden Text Display| éš±è—的字檔(&H) Overlay a representation of the hidden text layer. 察看隱è—的字檔層。 I&nvert Luminance View| å色(&N) Invert image luminance while preserving hue. åè‰²ä½†ä¿æŒé£½å’Œåº¦ã€‚ Prefere&nces... Settings| 設定(&N)... Show the preferences dialog. 察看設定å°è©±æ–¹å¡Šã€‚ Show &Sidebar Settings| å¯Ÿçœ‹å´æ¬„(&S) Ctrl+F9 Settings|Show sidebar Ctrl+F9 F9 Settings|Show sidebar F9 Show/hide the side bar. 察看或隱è—å´æ¬„。 Show &Toolbar Settings| 察看工具軸(&T) Ctrl+F10 Settings|Show toolbar Ctrl+F10 F10 Settings|Show toolbar F10 Show/hide the standard tool bar. å¯Ÿçœ‹æˆ–éš±è—æ¨™å‡†å·¥å…·è»¸ã€‚ Show Stat&usbar Settings| 察看狀態欄(&U) Show/hide the status bar. 察看或隱è—狀態欄。 &Full Screen View| å…¨å±(&U) Ctrl+F11 View|FullScreen Ctrl+F11 F11 View|FullScreen F11 Toggle full screen mode. 切æ›å…¨å±åž‹æ…‹ã€‚ &Slide Show View| 播放幻燈片(&S) Shift+F11 View|Slideshow Shift+F11 Toggle slide show mode. 切æ›å¹»ç‡ˆç‰‡æ’­æ”¾æ¨¡å¼ã€‚ &Continuous Layout| 連續é é¢(&C) Ctrl+F4 Layout|Continuous Ctrl+F4 F4 Layout|Continuous F4 Toggle continuous layout mode. 切æ›é€£çºŒé é¢åž‹æ…‹ã€‚ Side &by Side Layout| 并排察看(&B) Ctrl+F5 Layout|SideBySide Ctrl+F5 F5 Layout|SideBySide F5 Toggle side-by-side layout mode. 切æ›å¤šé å¹¶æŽ’察看型態。 Co&ver Page Layout| å°é¢é (&V) Ctrl+F6 Layout|CoverPage Ctrl+F6 F6 Layout|CoverPage F6 Show the cover page alone in side-by-side mode. 并排察看時單ç¨å¯Ÿçœ‹å°é¢é ã€‚ &Right to Left Layout| 從å³å‘å·¦(&R) Ctrl+Shift+F6 Layout|RightToLeft Ctrl+Shift+F6 Shift+F6 Layout|RightToLeft Shift+F6 Show pages right-to-left in side-by-side mode. 并排察看時從å³åˆ°å·¦å¯Ÿçœ‹é é¢ã€‚ Copy &URL Edit| 複製&URL Save an URL for the current page into the clipboard. 複製目å‰é é¢çš„URL到剪貼簿。 Ctrl+C Edit|CopyURL Ctrl+C Copy &Outline Edit| 複製標簽(&O) Save the djvused code for the outline into the clipboard. è¤‡è£½æ¨™ç°½å°æ‡‰çš„djvu程å¼ç¢¼åˆ°å‰ªè²¼ç°¿ã€‚ Copy &Annotations Edit| 複製註釋(&A) Save the djvused code for the page annotations into the clipboard. è¤‡è£½è¨»é‡‹å°æ‡‰çš„djvu程å¼ç¢¼åˆ°å‰ªè²¼ç°¿ã€‚ &File File| 檔案(&F) Open &Recent 開啟最近的檔案(&R) &Edit Edit| 編輯(&E) &View View| 檢視(&V) &Zoom View|Zoom 縮放(&Z) &Rotate View|Rotate 旋轉(&R) &Display View|Display 察看(&D) &Go Go| 轉到(&G) &Settings Settings| 設定(&S) &Help Help| 輔助說明(&H) Control Left Mouse Button æŽ§åˆ¶æ»‘é¼ å·¦éµ Right Mouse Button 滑鼠å³éµ <html><b>Selecting a rectangle.</b><br/> Once a rectangular area is selected, a popup menu lets you copy the corresponding text or image. Instead of using this tool, you can also hold %1 and use the Left Mouse Button.</html> <html><b>é¸å–矩形。</b><br/> é¸ä¸­çŸ©å½¢å€åŸŸæ™‚,å³ç¾åŠŸèƒ½è¡¨è®“ä½ è¤‡è£½ç›¸æ‡‰çš„å­—æª”æˆ–å½±åƒã€‚å¦å¤–äº¦å¯æŒ‰ä½ %1 和滑鼠左éµã€‚</html> <html><b>Zooming.</b><br/> Choose a zoom level for viewing the document. Zoom level 100% displays the document for a 100 dpi screen. Zoom levels <tt>Fit Page</tt> and <tt>Fit Width</tt> ensure that the full page or the page width fit in the window. </html> <html><b>縮放。</b><br/> é¸å–縮放級別以檢視文件。 縮放級別 100% 察看文件於 100 dpi 的螢幕。 縮放級別 <tt>驿‡‰é é¢</tt> åŠ <tt>驿‡‰å¯¬åº¦</tt> ä½¿æ•´é æˆ–å¯¬åº¦é©æ‡‰è¦–窗。 </html> <html><b>Rotating the pages.</b><br/> Choose to display pages in portrait or landscape mode. You can also turn them upside down.</html> <html><b>旋轉é é¢ã€‚</b><br/> é¸å–垂直或橫å‘察看型態。 亦å¯ä½¿å…¶ä¸Šä¸‹å¾©åŽŸã€‚</html> <html><b>Display mode.</b><br/> DjVu images compose a background layer and a foreground layer using a stencil. The display mode specifies with layers should be displayed.</html> <html><b>察看型態。</b><br/> DjVuå½±åƒåŒ…括背景層和基於樣æ¿çš„剿™¯å±¤ã€‚ 察看型態指定哪些層被察看。</html> <html><b>Navigating the document.</b><br/> The page selector lets you jump to any page by name and can be activated at any time by pressing Ctrl+G. The navigation buttons jump to the first page, the previous page, the next page, or the last page. </html> <html><b>文件導航。</b><br/> 用é é¢é¸å–噍坿Œ‰å稱跳到指定é é¢ï¼Œå¯æŒ‰ Ctrl+G 啟動之。 用導航按鈕å¯è·³åˆ°é¦–é ã€ä¸Šä¸€é ã€ä¸‹ä¸€é æˆ–末é ã€‚ </html> <html><b>Document and page information.</b><br> Display a dialog window for viewing encoding information pertaining to the document or to a specific page.</html> <html><b>文件和é é¢è³‡è¨Šã€‚</b><br> å³ç¾å°è©±æ–¹å¡Šæª¢è¦–文件或é é¢çš„編碼資訊。</html> <html><b>Document and page metadata.</b><br> Display a dialog window for viewing metadata pertaining to the document or to a specific page.</html> <html><b>文件和é é¢å…ƒè³‡æ–™ã€‚</b><br> å³ç¾å°è©±æ–¹å¡Šå¯Ÿçœ‹æ–‡ä»¶æˆ–é é¢çš„元資料。</html> <html><b>Continuous layout.</b><br/> Display all the document pages arranged vertically inside the scrollable document viewing area.</html> <html><b>連續é é¢åž‹æ…‹ã€‚</b><br/> 察看文件的全部é é¢èˆ‡å¸¶æ²å‹•軸的察看å€åŸŸä¸­ã€‚</html> <html><b>Side by side layout.</b><br/> Display pairs of pages side by side inside the scrollable document viewing area.</html> <html><b>并排察看型態。</b><br/> å°‡é é¢å¹¶æŽ’察看在檢視器中。</html> <html><b>Page information.</b><br/> Display information about the page located under the cursor: the sequential page number, the page size in pixels, and the page resolution in dots per inch. </html> <html><b>é é¢è³‡è¨Šã€‚</b><br/> å¯Ÿçœ‹ä½æ–¼æ¸¸æ¨™ä½ç½®çš„é é¢è³‡è¨Š: é ç¢¼åºè™Ÿï¼Œ é é¢çš„大å°ï¼ˆæŒ‰åƒç´ ï¼‰ï¼Œ 以åŠé é¢çš„è§£æžåº¦ï¼ˆæŒ‰DPIï¼Œå³æ¯è‹±å‹é»žæ•¸ï¼‰ </html> <html><b>Cursor information.</b><br/> Display the position of the mouse cursor expressed in page coordinates. </html> <html><b>游標資訊。</b><br/> 察看滑鼠游標在é é¢åº§æ¨™ä¸­çš„ä½ç½®å€¼ã€‚ </html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. <ul><li>Arrows and page keys to navigate the document.</li><li>Space and BackSpace to read the document.</li><li>Keys <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> to zoom or rotate the document.</li><li>Left Mouse Button for panning and selecting links.</li><li>%3 for displaying the contextual menu.</li><li>%1 Left Mouse Button for selecting text or images.</li><li>%2 for popping the magnification lens.</li></ul></html> <html><b>文件檢視å€åŸŸã€‚</b><br/> 這是DjVu文件的主è¦å¯Ÿçœ‹å€åŸŸã€‚ <ul><li>用方å‘éµå’Œç¿»é éµå¯ç¿»å‹•文件。</li><li>白字元和退格éµé–±è®€æ–‡ä»¶ã€‚</li><li>æŒ‰éµ <tt>+</tt> <tt>-</tt> <tt>[</tt> <tt>]</tt> å¯ç¸®æ”¾æˆ–旋轉文件。</li><li>滑鼠左éµå¯æŒªå‹•é é¢åŠé¸ä¸­éˆçµã€‚</li><li>%3 察看關è¯å³ç¾åŠŸèƒ½è¡¨ã€‚</li><li>%1 滑鼠左éµé¸å–字檔或影åƒã€‚</li><li>%2 å³ç¾æ”¾å¤§é¡ã€‚</li></ul></html> <html><b>Document viewing area.</b><br/> This is the main display area for the DjVu document. But you must first open a DjVu document to see anything.</html> <html><b>文件檢視å€åŸŸã€‚</b><br/> 這是DjVu文件的主è¦å¯Ÿçœ‹å€åŸŸã€‚ ä¸éŽå¾—è¦å…ˆé–‹å•ŸDjVu文件哦。</html> Option '%1' requires boolean argument. é¸é … '%1' 需è¦å¸ƒæž—åž‹åƒæ•¸ã€‚ Illegal value '%2' for option '%1'. å–值 '%2' å°é¸é … '%1' 無效。 Toolbar option '%1' is not implemented. 工具軸é¸é … '%1' 尚未實ç¾ã€‚ Toolbar option '%1' is not recognized. 工具軸é¸é … '%1' 未識別。 Option '%1' requires a standalone viewer. é¸é … '%1' 需è¦å–®ç¨çš„æª¢è¦–器。 Deprecated option '%1' éŽæœŸé¸é … '%1' Option '%1' is not implemented. é¸é … '%1' 尚未實ç¾ã€‚ Option '%1' is not recognized. é¸é … '%1' 未識別。 DjView DjView Thumbnails 縮略圖 Outline 書籤 Find 尋找 Cannot open file '%1'. 未能開啟檔案 '%1'。 Opening DjVu file 開啟DjVu檔案 Cannot open URL '%1'. 未能開啟URL '%1'。 Opening DjVu document 開啟DjVu文件 Certificate validation error - DjView dialog caption 証書驗証錯誤 - DjView <html> %1 Do you want to continue anyway? </html> <html> %1 是å¦ä»ç„¶ç¹¼çºŒ? </html> Cannot find page numbered: %1 未能找到此編號的é : %1 Cannot find page named: %1 未能找到此å稱的é : %1 Unrecognized sidebar options '%1'. æœªè­˜åˆ¥çš„å´æ¬„é¸é … '%1'。 Print - DjView dialog caption åˆ—å° - DjView <html> This file was served with printing restrictions. Do you want to print it anyway?</html> <html> This file was served with printing restrictions.Do you want to print it anyway?</html> <html> 本文件有打å°é™åˆ¶ã€‚是å¦ä»ç„¶æ‰“å°ï¼Ÿ</html> Save - DjView dialog caption 儲存 - DjView <html> This file was served with saving restrictions. Do you want to save it anyway?</html> <html> This file was served with saving restrictions.Do you want to save it anyway?</html> <html> 本檔案有儲存é™åˆ¶ã€‚是å¦ä»ç„¶å„²å­˜ï¼Ÿ</html> Export - DjView dialog caption 導出 - DjView Text files save filter 字檔檔案 All files save filter 所有檔案 Save Text - DjView dialog caption 儲存字檔 - DjView Error - DjView dialog caption 錯誤 - DjView Cannot write file '%1'. %2. 未能寫入檔案 '%1'. %2. %1 files (*.%2);; save image filter %1 檔案 (*.%2);; Save Image - DjView dialog caption å„²å­˜å½±åƒ - DjView Cannot determine file format. Filename '%1' has no suffix. 無法確定檔案格å¼ã€‚ 檔å '%1' 未包å«å‰¯æª”å。 Image format %1 not supported. å½±åƒæ ¼å¼ %1 未支æ´ã€‚ Cannot decode page %1. 未能解碼é é¢ %1。 Cannot decode document. 未能解碼文件。 Decoding DjVu document 解碼DjVu文件 P%1/%2 %3x%4 %5dpi P%1/%2 %3x%4 %5dpi x=%1 y=%2 x=%1 y=%2 %3x%4+%1+%2 %3x%4+%1+%2 Go: 1 page forward. 轉到:å‘å‰ä¸€é ã€‚ Go: %n pages forward. 轉到:å‘å‰ %n é ã€‚ Go: 1 page backward. 轉到:å‘åŽä¸€é ã€‚ Go: %n pages backward. 轉到:å‘åŽ %n é ã€‚ Go: page %1. 轉到:第 %1 é ã€‚ Go: %1 轉到:%1 (in other window.) (在其他視窗) Cannot resolve link '%1' 未能解æžéˆçµ '%1' Cannot spawn a browser for url '%1' 未能用ç€è¦½å™¨é–‹å•ŸURL '%1' %n characters %n å­—å…ƒ Copy text (%1) 複製字檔 (%1) Save text as... å¦å­˜å­—檔為... Copy text into the clipboard. 複製字檔到剪貼簿。 Save text into a file. 儲存字檔到檔案。 Copy image (%1x%2 pixels) 複製影åƒ(%1x%2åƒç´ ) Save image as... å¦å­˜å½±åƒç‚º... Copy image into the clipboard. 複製影åƒåˆ°å‰ªè²¼ç°¿ã€‚ Save image into a file. 儲存影åƒåˆ°æª”案。 Zoom to rectangle 縮放到矩形å€åŸŸ Zoom the selection to fit the window. 縮放é¸ä¸­å€åŸŸé©æ‡‰è¦–窗。 Copy URL 複製URL Save into the clipboard an URL that highlights the selection. 複製é¸ä¸­ç‰©ä»¶çš„URL到剪貼簿。 Copy Maparea è¤‡è£½å°æ˜ å€åŸŸ Save into the clipboard a maparea annotation expression for program djvused. è¤‡è£½å°æ˜ å€åŸŸè¨»é‡‹å°æ‡‰çš„djvu程å¼ç¢¼åˆ°å‰ªè²¼ç°¿ã€‚ <html><h2>DjVuLibre DjView %1</h2>%2<p>Viewer for DjVu documents<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>This program is free software. You can redistribute or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed <i>without any warranty</i>. See the GNU General Public License for more details.</small></p></html> <html><h2>DjVuLibre DjView %1</h2>%2<p>DjVu文件檢視工具<br><a href=%3>%3</a><br>Copyright © 2006-- Léon Bottou.</p><p align=justify><small>æœ¬ç¨‹å¼æ˜¯è‡ªç”±è»Ÿé«”。你å¯ä¾æ“šè‡ªç”±è»Ÿé«”基金會發布的GNU GPLçš„æ¢æ¬¾é‡æ–°ç™¼å¸ƒæˆ–修改本程å¼ã€‚ 本程å¼ä¹‹ç™¼å¸ƒ<i>無任何擔ä¿</i>。 詳細請åƒè¦‹ GNU GPL。</small></p></html> About DjView 關於DjView DjVu files DjVu檔案 All files 所有檔案 Open - DjView dialog caption 開啟 - DjView Open Location - DjView dialog caption 開啟ä½ç½® - DjView Enter the URL of a DjVu document: 匯入DjVu文件的URL: Information - DjView dialog caption 資訊 - DjView Metadata - DjView dialog caption 元資料 - DjView &Clear History 清除曆å²(&C) QDjViewApplication cannot open '%1'. 未能開啟 '%1'。 Usage: djview [options] [filename-or-url] Common options include: -help~~~Prints this message. -verbose~~~Prints all warning messages. -display <xdpy>~~~Select the X11 display <xdpy>. -geometry <xgeom>~~~Select the initial window geometry. -font <xlfd>~~~Select the X11 name of the main font. -style <qtstyle>~~~Select the QT user interface style. -fullscreen, -fs~~~Start djview in full screen mode. -page=<page>~~~Jump to page <page>. -zoom=<zoom>~~~Set zoom factor. -continuous=<yn>~~~Set continuous layout. -sidebyside=<yn>~~~Set side-by-side layout. 用法: djview [é¸é …] [æª”åæˆ–url] 常用é¸é …包括: -help~~~察看本輔助說明資訊. -verbose~~~察看所有警告資訊. -display <xdpy>~~~é¸å– X11 察看視窗 <xdpy>. -geometry <xgeom>~~~é¸å–åˆå§‹è¦–窗大å°. -font <xlfd>~~~é¸å–主字型的 X11 å稱. -style <qtstyle>~~~é¸å– QT ç”¨æˆ¶ä»‹é¢æ¨£å¼. -fullscreen, -fs~~~啟動 djview 為全å±åž‹æ…‹. -page=<page>~~~è·³åˆ°é  <page>. -zoom=<zoom>~~~è¨­å®šç¸®æ”¾åƒæ•¸. -continuous=<yn>~~~設定連續é é¢åž‹æ…‹. -sidebyside=<yn>~~~設定并排察看型態. QDjViewAuthDialog Password: 密碼: User: 用戶å: Authentication required - DjView 需è¦èº«ä»½èªè¨¼ - DjView QDjViewDjVuExporter DjVu Bundled Document 打包的DjVu文件 DjVu Files (*.djvu *.djv) DjVu檔案 (*.djvu *.djv) DjVu Indirect Document 間接的DjVu文件 Question - DjView dialog caption å•題 - DjView <html> This file belongs to a non empty directory. Saving an indirect document creates many files in this directory. Do you want to continue and risk overwriting files in this directory?</html> <html> 此檔案屬於一個éžç©ºç›®éŒ„。儲存間接文件將在此目錄中建立許多檔案。是å¦ç¹¼çºŒå¹¶å…許覆寫檔案?</html> Con&tinue 連續(&T) &Cancel å–æ¶ˆ(&C) Unknown error. 未知錯誤。 System error: %1. 系統錯誤: %1. Save job creation failed! å„²å­˜ä½œæ¥­å¤±æ•—ï¼ QDjViewErrorDialog DjView Error DjView 錯誤 &Ok 確定(&O) Error - DjView dialog caption 錯誤 - DjView QDjViewExportDialog Dialog å°è©±æ–¹å¡Š Export 導出 &Document 文件(&D) C&urrent page ç›®å‰é (&U) &Pages é (&P) to 至 Destination 目標 Format: æ ¼å¼ï¼š &Defaults é è¨­å€¼(&D) &Ok 確定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Saving.</b><br/> You can save the whole document or a page range under a variety of formats. Selecting certain formats creates additional dialog pages for specifying format options.</html> <html><b>儲存中。</b><br/>ä½ å¯ä»¥ä»¥å¤šç¨®æ ¼å¼å„²å­˜æ•´å€‹æ–‡ä»¶æˆ–æ¯é ã€‚é¸å–æ ¼å¼å¹¶è¨­å®šç›¸æ‡‰é¸é …。</html> Error - DjView dialog caption 錯誤 - DjView Overwriting the current file is not allowed! ä¸å…è¨±è¦†å¯«ç›®å‰æª”æ¡ˆï¼ Question - DjView dialog caption å•題 - DjView A file with this name already exists. Do you want to replace it? è¡•åæª”案已存在。 æ˜¯å¦æ›¿ä»£ï¼Ÿ &Replace 替代(&R) This operation has failed. 作業失敗。 This operation has been interrupted. 作業中斷。 All files save filter 所有檔案 Export - DjView dialog caption 導出 - DjView QDjViewExportPS1 Form 視窗 Color 色彩 &Color 色彩(&C) &GrayScale ç°éšŽ(&G) Marks 記號 Print image &frame 列å°å½±åƒæ¡†(&F) Print crop &marks 列å°è£åˆ‡è¨˜è™Ÿ(&M) PostScript PostScript Language Level 語言級別 QDjViewExportPS2 Form 視窗 Scaling 縮放 Scale to &fit the page ç¸®æ”¾åˆ°é©æ‡‰æ•´é (&F) &Zoom 縮放(&Z) % % Orientation æ–¹å‘ Automatic 自動 &Portrait 垂直(&P) &Landscape æ©«å‘(&L) QDjViewExportPS3 Form 視窗 Print sheets suitable for folding a booklet. 列å°å¼µæ•¸é©æ‡‰æŠ˜ç–Šå†Šé ã€‚ Advanced 進階 Sheets per booklet: æ¯å†Šé å¼µæ•¸: Unlimited ç„¡é™åˆ¶ at most 最多 Print åˆ—å° rectos and versos. 奇數é å’Œå¶æ•¸é ã€‚ rectos only. 僅奇數é ã€‚ versos only. åƒ…å¶æ•¸é ã€‚ Shift rectos and versos by å移奇數é å’Œå¶æ•¸é  points. 點. Center: 中間: points 點 plus 加 /100 /100 per page. æ¯é . QDjViewExportPrn Form 視窗 Color 色彩 &Color 色彩(&C) &GrayScale ç°éšŽ(&G) Marks 記號 Print image &frame 列å°å½±åƒæ¡†(&F) Print crop &marks 列å°è£åˆ‡è¨˜è™Ÿ(&M) Scaling 縮放 Scale to &fit the page ç¸®æ”¾åˆ°é©æ‡‰æ•´é (&F) &Zoom 縮放(&Z) % % Orientation æ–¹å‘ Automatic 自動 &Portrait 垂直(&P) &Landscape æ©«å‘(&L) QDjViewExportTiff Form 視窗 Resolution è§£æžåº¦ Maximum image resolution 最大影åƒè§£æžåº¦ dpi dpi Compression 壓縮 Force &bitonal G4 compression. 強制二值G4壓縮(&B)。 Allow &lossy JPEG compression. å…許有æJPEG壓縮(&L)。 JPEG &quality JPEGå“質(&Q) Allow &deflate compression. å…許deflate壓縮(&D)。 QDjViewFind Case sensitive å€åˆ†å¤§å°å¯« Words only 僅詞語 Regular expression æ­£å‰‡è¡¨ç¤ºå¼ Find Previous (Shift+F3) 尋找å‰ä¸€å€‹ (Shift+F3) Find Next (F3) 尋找下一個 (F3) Reset search options to default values. é‡ç½®æœç´¢é¸é …到é è¨­å€¼ã€‚ Options é¸é … <html><b>Finding text.</b><br/> Search hits appear progressively as soon as you type a search string. Typing enter jumps to the next hit. To move to the previous or next hit, you can also use the arrow buttons or the shortcuts <tt>F3</tt> or <tt>Shift-F3</tt>. You can also double click a page name. Use the <tt>Options</tt> menu to search words only or to specify the case sensitivity.</html> <html><b>尋找字檔。</b><br/> 匯入æœç´¢å­—串時命中數會éžå¢žå‡ºç¾ã€‚ 敲轉éµéµè·³åˆ°ä¸‹ä¸€å€‹å‘½ä¸­è™•。 è¦è½‰åˆ°å‰ä¸€è™•或下一處命中, 亦å¯ä½¿ç”¨æ–¹å‘鵿ˆ–æ·å¾‘éµ <tt>F3</tt> 或 <tt>Shift-F3</tt>。 åˆå¯æŒ‰å…©ä¸‹é é¢å. 在 <tt>é¸é …</tt> 功能表設定æœç´¢è©žèªžæˆ–å€åˆ†å¤§å°å¯«ã€‚</html> Specify whether search hits must begin on a word boundary. 設定æœç´¢å‘½ä¸­æ˜¯å¦é–‹å§‹æ–¼è©žèªžé‚Šç·šã€‚ Specify whether searches are case sensitive. 設定是å¦è€ƒæ…®å¤§å°å¯«ã€‚ Regular expressions describe complex string matching patterns. 正則表示å¼è¡¨è¿°è¤‡é›œçš„字串符åˆåž‹æ…‹ã€‚ <html><b>Regular Expression Quick Guide</b><ul><li>The dot <tt>.</tt> matches any character.</li><li>Most characters match themselves.</li><li>Prepend a backslash <tt>\</tt> to match special characters <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> matches a word boundary.</li><li><tt>\w</tt> matches a word character.</li><li><tt>\d</tt> matches a digit character.</li><li><tt>\s</tt> matches a blank character.</li><li><tt>\n</tt> matches a newline character.</li><li><tt>[<i>a</i>-<i>b</i>]</tt> matches characters in range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> matches characters outside range <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt><i>a</i>|<i>b</i></tt> matches either regular expression <tt><i>a</i></tt> or regular expression <tt><i>b</i></tt>.</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> matches regular expression <tt><i>a</i></tt> repeated <tt><i>n</i></tt> to <tt><i>m</i></tt> times.</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, and <tt><i>a</i>+</tt> are shorthands for <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, and <tt><i>a</i>{1,}</tt>.</li><li>Use parentheses <tt>()</tt> to group regular expressions before <tt>?+*{</tt>.</li></ul></html> <html><b>正則表示å¼å¿«é€ŸæŒ‡å—</b><ul><li>點 <tt>.</tt> 符åˆä»»æ„字元。</li><li>多數字元符åˆå…¶æœ¬èº«ã€‚</li><li>這些字元å‰é¢åР䏀個忖œç·š <tt>\</tt> å¯ç¬¦åˆç›¸æ‡‰å­—å…ƒ <tt>()[]{}|*+.?!^$\</tt>.</li><li><tt>\b</tt> 符åˆè©žèªžé‚Šç·šã€‚</li><li><tt>\w</tt> 符åˆä¸€å€‹å­—檔字元。</li><li><tt>\d</tt> 符åˆä¸€å€‹æ•¸å­—字元。</li><li><tt>\s</tt> 符åˆä¸€å€‹ç©ºç™½å­—元。</li><li><tt>\n</tt> 符åˆä¸€å€‹æ›è¡Œç¬¦ã€‚</li><li><tt>[<i>a</i>-<i>b</i>]</tt> ç¬¦åˆæ­¤ç¯„åœä¸­çš„ä»»æ„å­—å…ƒ <tt><i>a</i></tt>-<tt><i>b</i></tt>.</li><li><tt>[^<i>a</i>-<i>b</i>]</tt> ç¬¦åˆæ­¤ç¯„åœä¹‹å¤–的任æ„å­—å…ƒ <tt><i>a</i></tt>-<tt><i>b</i></tt>。</li><li><tt><i>a</i>|<i>b</i></tt> ç¬¦åˆæ­£å‰‡è¡¨ç¤ºå¼ <tt><i>a</i></tt> æˆ–æ­£å‰‡è¡¨ç¤ºå¼ <tt><i>b</i></tt>。</li><li><tt><i>a</i>{<i>n</i>,<i>m</i>}</tt> ç¬¦åˆæ­£å‰‡è¡¨ç¤ºå¼ <tt><i>a</i></tt> é‡è¤‡ <tt><i>n</i></tt> 到 <tt><i>m</i></tt> 次。</li><li><tt><i>a</i>?</tt>, <tt><i>a</i>*</tt>, åŠ <tt><i>a</i>+</tt> 為 <tt><i>a</i>{0,1}</tt>, <tt><i>a</i>{0,}</tt>, åŠ <tt><i>a</i>{1,}</tt>å°æ‡‰çš„簡寫。</li><li>用括弧 <tt>()</tt> å¯å°‡è¡¨ç¤ºå¼åˆ†çµ„ æ–¼ <tt>?+*{</tt>之å‰ã€‚</li></ul></html> QDjViewFind::Model 1 hit 1 命中 %n hits %n 命中 Page %1 (1 hit) é  %1 (1 命中) Page %1 (%n hits) é  %1 (%n 命中) Searching page %1 (waiting for data.) æœç´¢é  %1 (等待資料。) Searching page %1. æœç´¢é  %1。 No hits! ç„¡å‘½ä¸­ï¼ <html>Document is not searchable. No page contains information about its textual content.</html> <html>文件ä¸å¯æœç´¢ã€‚ é é¢ä¸­æ²’有此字檔內容的資訊。</html> <html>Invalid regular expression.</html> <html>無效的正則表示å¼ã€‚</html> QDjViewImgExporter %1 Image JPG Image %1 å½±åƒ %1 Files (*.%2) JPG Files %1 檔案 (*.%2) Cannot render page. 未能察看é é¢ã€‚ Image format %1 not supported. å½±åƒæ ¼å¼ %1 未支æ´ã€‚ QDjViewInfoDialog Dialog å°è©±æ–¹å¡Š &Document 文件(&D) &File 檔案(&F) File: 檔案: &View Page 檢視é é¢(&V) &Close 關閉(&C) File # 檔案 # File Name 檔å File Size æª”æ¡ˆå¤§å° File Type 檔案類別 Page # é  # Page Title é æ¨™é¡Œ <html><b>Document information</b><br>This panel shows information about the document and its component files. Select a component file to display detailled information in the <tt>File</tt> tab. Double click a component file to show the corresponding page in the main window. </html> <html><b>文件資訊</b><br>æ­¤é¢æ¿å¯Ÿçœ‹æ–‡ä»¶åŠå…¶çµ„æˆæª”案的資訊。 é¸ä¸­çµ„æˆæª”案å¯å¯Ÿçœ‹å…¶è©³ç´°è³‡è¨Šæ–¼ <tt>檔案</tt> é ä¸­ã€‚ æŒ‰å…©ä¸‹çµ„æˆæª”案å¯åœ¨ä¸»è¦–窗中察看其é é¢ã€‚ </html> <html><b>File and page information</b><br>This panel shows the structure of the DjVu data corresponding to the component file or the page selected in the <tt>Document</tt> tab. The arrow buttons jump to the previous or next component file.</html> <html><b>檔案和é é¢è³‡è¨Š</b><br>æ­¤é¢æ¿å¯Ÿçœ‹åœ¨ <tt>文件</tt> é ä¸­é¸ä¸­çš„çµ„æˆæª”案或é é¢çš„ DjVu 資料架構。 æ–¹å‘æŒ‰éˆ•è½‰åˆ°ä¸Šä¸€å€‹æˆ–ä¸‹ä¸€å€‹çµ„æˆæª”案。</html> Waiting for data... 等待資料... Page #%1 - « %2 » é  #%1 - « %2 » Page #%1 é  #%1 Thumbnails 縮略圖 Shared annotations 共用註釋 Shared data 共用資料 File #%1 - 檔案 #%1 - Single DjVu page å–®DjVué  Bundled DjVu document 打包的DjVu文件 Indirect DjVu document TODO 間接的DjVu文件 Obsolete bundled DjVu document éŽæ™‚的打包的DjVu文件 Obsolete indexed DjVu document éŽæ™‚的索引的DjVu文件 1 file 1 檔案 %n files %n 檔案 1 page 1 é  %n pages %n é  n/a ä¸å¯ç”¨ Page é  Thumbnails 縮略圖 Shared 共用的 QDjViewMetaDialog Dialog å°è©±æ–¹å¡Š &Document Metadata 文件元資料(&D) &Page Metadata é é¢å…ƒè³‡æ–™(&P) Page: é : &View Page 檢視é é¢(&V) &Close 關閉(&C) Ctrl+C copy Ctrl+C Key æŒ‰éµ Value 值 <html><b>Document metadata</b><br>This panel displays metadata pertaining to the document, such as author, title, references, etc. This information can be saved into the document with program <tt>djvused</tt>: use the commands <tt>create-shared-ant</tt> and <tt>set-meta</tt>.</html> <html><b>文件元資料</b><br>æ­¤é¢æ¿å¯Ÿçœ‹æ–‡ä»¶çš„元資料,諸如作者,標題,åƒç…§ç­‰ã€‚ 這些資訊å¯å„²å­˜åˆ°æ–‡ä»¶ä¸­ï¼Œè«‹ç”¨ç¨‹å¼ <tt>djvused</tt>的指令 <tt>create-shared-ant</tt> å’Œ <tt>set-meta</tt>。</html> <html><b>Page metadata</b><br>This panel displays metadata pertaining to a specific page. Page specific metadata override document metadata. This information can be saved into the document with program <tt>djvused</tt>: use command <tt>select</tt> to select the page and command <tt>set-meta</tt> to specify the metadata entries.</html> <html><b>é é¢å…ƒè³‡æ–™</b><br>æ­¤é¢æ¿å¯Ÿçœ‹é é¢çš„元資料。 é é¢ç‰¹å®šçš„元資料覆寫文件的元資料。 這些資訊å¯å„²å­˜åœ¨æ–‡ä»¶ä¸­ï¼Œè«‹ç”¨ç¨‹å¼ <tt>djvused</tt> 的指令 <tt>select</tt> é¸å–é é¢åŠæŒ‡ä»¤ <tt>set-meta</tt> 設定元資料的å–值。</html> QDjViewOutline <html><b>Document outline.</b><br/> This panel display the document outline, or the page names when the outline is not available, Double-click any entry to jump to the selected page.</html> <html><b>文件書籤。</b><br/> æ­¤é¢æ¿å¯Ÿçœ‹æ–‡ä»¶æ›¸ç±¤ï¼Œæˆ–在書籤ä¸å¯ç”¨æ™‚察看é é¢å稱, 按兩下項目跳到é¸ä¸­çš„é é¢ã€‚</html> Outline data is corrupted 書籤資料è¡çª Pages é  Page %1 é  %1 Go: page %1. 轉到:第 %1 é ã€‚ Go: %1 轉到:%1 QDjViewPSExporter PostScript PostScript PostScript Files (*.ps *.eps) PostScript檔案 (*.ps *.eps) Encapsulated PostScript å°è£çš„PostScript PostScript tab caption PostScript Position tab caption ä½ç½® Booklet tab caption å†Šé  <html><b>PostScript options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with frame and crop marks. PostScript language level 1 is only useful with very old printers. Level 2 works with most printers. Level 3 print color document faster on recent printers.</html> <html><b>PostScripté¸é …。</b><br>é¸é … <tt>色彩</tt> 啟用色彩列å°ã€‚ 文件é é¢å¯åŠ é‚Šç·šæ–¹å¡Šå’Œå‰ªè£è¨˜è™Ÿã€‚ PostScript 語言級別 1 僅用於很è€çš„å°è¡¨æ©Ÿã€‚ 級別2用於大多數å°è¡¨æ©Ÿã€‚ 級別3在最新的å°è¡¨æ©Ÿä¸Šåˆ—å°è‰²å½©å¿«äº›ã€‚</html> <html><b>Position and scaling.</b><br>Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>ä½ç½®èˆ‡ç¸®æ”¾ã€‚</b><br>é¸é … <tt>ç¸®æ”¾åˆ°é©æ‡‰</tt> 驿‡‰å°è¡¨æ©Ÿä½¿ç”¨çš„紙張大å°ã€‚ 縮放率 <tt>100%</tt> 與åˆå§‹æ–‡ä»¶å¤§å°ä¸€æ¨£ã€‚ æ–¹å‘ <tt>自動</tt> 按æ¯é é¸å–垂直或橫å‘。</html> <html><b>Producing booklets.</b><br>The booklet mode prints the selected pages as sheets suitable for folding one or several booklets. Several booklets might be produced when a maximum number of sheets per booklet is specified. You can either use a duplex printer or print rectos and versos separately.<p> Shifting rectos and versos is useful with poorly aligned duplex printers. The center margins determine how much space is left between the pages to fold the sheets. This space slowly increases from the inner sheet to the outer sheet.</html> <html><b>列å°å†Šé ã€‚</b><br>冊é åž‹æ…‹åˆ—å°é¸ä¸­çš„é é¢ä»¥ä¾¿æŠ˜ç–Šæˆä¸€æœ¬æˆ–多本冊é ã€‚ 若指定æ¯å†Šé çš„æœ€å¤§å¼µæ•¸å‰‡å¯ç”Ÿæˆå¤šæœ¬å†Šé ã€‚ ä½ å¯ä½¿ç”¨é›™é¢å°è¡¨æ©Ÿæˆ–分別列å°å¥‡å¶é ã€‚<p> å°æ–¼å°é½Šä¸å¥½çš„é›™é¢å°è¡¨æ©Ÿå¯å移奇å¶é ã€‚ 中間的邊決定折疊é é–“的留白。 留白從內é åˆ°å¤–é é€æ¼¸å¢žå¤§ã€‚</html> Save job creation failed! å„²å­˜ä½œæ¥­å¤±æ•—ï¼ QDjViewPdfExporter PDF Document PDF文件 PDF Files (*.pdf) PDF檔案 (*.pdf) PDF Options tab caption PDFé¸é … <html><b>PDF options.</b><br>These options control the characteristics of the images embedded in the exported PDF files. The resolution box limits their maximal resolution. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact files. </html> <html><b>PDFé¸é …。</b><br>這些é¸é …控制內嵌影åƒçš„特徵。 è§£æžåº¦æ¡†é™åˆ¶æœ€å¤§è§£æžåº¦ã€‚ 強制二值G4壓縮將全部黑白é ç”¨CCITT Group 4壓縮格å¼å£“縮。 å…許JPEG壓縮用有æJPEG壓縮格å¼å£“縮全部éžäºŒå€¼å½±åƒæˆ–å­å–樣影åƒã€‚ å¦å¤–, å…許deflate壓縮將得到更å°çš„æª”案。 </html> Error while creating pdf file. 建立pdf檔案出錯。 Unable to create output file. 未能建立匯出檔案。 System error: %1. 系統錯誤: %1. Unable to reopen temporary file. æœªèƒ½é‡æ–°é–‹å•Ÿæš«å­˜æª”。 PDF export was not compiled. PDF匯出未æˆåŠŸã€‚ Unable to create temporary file. 未能建立暫存檔。 QDjViewPlugin::Document Requesting %1. è¦æ±‚ %1. QDjViewPrefsDialog Dialog å°è©±æ–¹å¡Š &Screen 螢幕(&S) Gamma TODO Gamma <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> <html>螢幕色彩校正。<br>調節æ²å‹•軸直到ç°è‰²é™°å½±å€çœ‹èµ·ä¾†ç›¸ä¼¼ã€‚</html> Darker æš— Lighter 亮 Display 察看 Force screen &resolution 強制螢幕解æžåº¦(&R) dpi dpi Force inverted luminance 強制å色 &Interface 介é¢(&I) Options for é¸é … Standalone Viewer å–®ç¨å¯Ÿçœ‹ Full Page Plugin 免頿’ä»¶ Embedded Plugin 內嵌æ’ä»¶ &Remember initial state from last invocation 記ä½ä¸Šæ¬¡å•Ÿç”¨çš„åˆå§‹ç‹€æ…‹(&R) Show 察看 &Menu bar 功能表欄(&M) &Tool bar 工具軸(&T) Sc&rollbars æ²å‹•軸(&R) Stat&us bar 狀態欄(&U) &Side bar å´æ¬„(&S) &Zoom: 縮放(&Z): s secs .ç§’ Display page &frames 察看é é¢é‚Šç·šæ–¹å¡Š(&F) Display &annotations 察看註釋(&A) Layout 佈局 Continuous 連續 Side-by-side 并排察看 Cover Page å°é¢é  Right-to-Left 從å³å‘å·¦ &Keys 按éµ(&K) Keys æŒ‰éµ For displaying hyper&links: 察看超éˆçµ(&L): For &selecting text or images: é¸ä¸­çš„字檔或影åƒ(&S): For displaying the &lens: 察看放大é¡(&L): Mouse wheel 滑鼠滾輪 Mouse wheel scrolls the page 滑鼠滾輪æ²å‹•é é¢ Mouse wheel changes the zoom factor 滑鼠滾輪改變縮放率 &Lens 放大é¡(&L) Enable magnifying &lens 啟用放大é¡(&L) Lens options 放大é¡é¸é … Lens &size: 放大é¡å¤§å°(&S): Magnifying &power: æ”¾å¤§å€æ•¸(&P): x x pixels åƒç´  &Network 網路(&N) Proxy settings 代ç†è¨­å®š Use pro&xy to access the network 使用代ç†å­˜å–網路(&X) &Host: 主機(&H): &Port: 通訊埠(&P): &User: 用戶å(&U): Pass&word: 密碼(&W): Cache ç·©è¡å€ &Clear 清除(&C) MB MB &Decoded page cache: 解碼é é¢ç·©è¡å€(&D): &Pixel cache: åƒç´ ç·©è¡å€(&P): &Advanced 進階(&A) Interface ä»‹é¢ Force language (next time djview runs) Force language (when djview is restarted.) 強制介é¢èªžè¨€(下次啟動時) Enable advanced features in menus 在功能表中啟用進階功能 Enable page animations 啟用é é¢å‹•ç•« Timer: 定時器: Show hidden text in status bar åœ¨ç‹€æ…‹æ¬„é¡¯ç¤ºéš±è—æ–‡å­— Miscellaneous å…¶ä»– Render with openGL when available openGLå¯ç”¨æ™‚用其渲染 Override saving and printing restrictions 覆寫儲存和列å°é™åˆ¶ Manual printer color correction 手動å°è¡¨æ©Ÿè‰²å½©æ ¡æ­£ gamma= TODO gamma= &Defaults é è¨­å€¼(&D) &Apply 應用(&A) &Ok 確定(&O) Cancel å–æ¶ˆ Preferences[*] - DjView 設定[*] - DjView <html><b>Screen gamma correction.</b><br>The best color rendition is achieved by adjusting the gamma correction slider and choosing the position that makes the gray square as uniform as possible.<p><b>Screen resolution.</b><br>This option forces a particular resolution instead of using the unreliable resolution advertised by the operating system. Forcing the resolution to 100 dpi matches the behavior of the djvulibre command line tools.</html> <html><b>螢幕色彩Gamma校正。</b><br>用調整器調整Gamma值使ç°è‰²æ–¹å¡Šå€åŸŸå„˜é‡ä¸€è‡´ä»¥ç²å¾—最佳色彩表ç¾ã€‚<p><b>螢幕解æžåº¦ã€‚</b><br>æ­¤é¸é …強制使用指定的解æžåº¦å€¼å–代由作業系統æä¾›çš„ä¸å¯é çš„è§£æžåº¦å€¼ã€‚ 強制解æžåº¦ç‚º 100 dpi 時與 djvulibre 指令行工具一致。</html> <html><b>Initial interface setup.</b><br>DjView can run as a standalone viewer, as a full screen viewer, as a full page browser plugin, or as a plugin embedded inside a html page. For each case, check the <tt>Remember</tt> box to automatically save and restore the interface setup. Otherwise, specify an initial configuration.</html> <html><b>åˆå§‹ä»‹é¢è¨­å®šã€‚</b><br>DjView 坿Œ‰ä»¥ä¸‹æ–¹å¼åŸ·è¡Œï¼š å–®ç¨å¯Ÿçœ‹ï¼Œ å…¨å±å¯Ÿçœ‹ï¼Œ å…¨é é¢ç€è¦½å™¨æ’件, 或 內嵌htmlé é¢ä¸­ã€‚ å°æ–¼æ¯ç¨®æ–¹å¼ï¼Œ å¯é¸ä¸­ <tt>記ä½ä¸Šæ¬¡</tt> 框以便自動儲存åŠé‡ç”¨ä»‹é¢è¨­å®šï¼› 或者,ä¸é¸ä¸­è€ŒæŒ‡å®šä¸€å€‹å›ºå®šçš„åˆå§‹è¨­å®šã€‚</html> <html><b>Modifiers keys.</b><br>Define which combination of modifier keys will show the manifying lens, temporarily enable the selection mode, or highlight the hyperlinks.</html> <html><b>按éµã€‚</b><br>定義一些組åˆéµï¼Œ 如 察看放大é¡ï¼Œ 臨時啟用é¸å–型態, 或高亮察看éˆçµã€‚</html> <html><b>Magnifying lens.</b><br>The magnifying lens appears when you depress the modifier keys specified in tab <tt>Keys</tt>. This panel lets you choose the power and the size of the magnifying lens.</html> <html><b>放大é¡ã€‚</b><br>用 <tt>按éµ</tt> é ä¸­å®šç¾©çš„æŒ‰éµå¯èª¿å‡ºæ”¾å¤§é¡ã€‚ åœ¨æœ¬é¢æ¿å¯é¸å–æ”¾å¤§å€æ•¸å’Œæ”¾å¤§é¡çš„大å°ã€‚</html> <html><b>Advanced.</b><br>You can override the default interface language, disable the page animations, or enable additional menu entries that are useful for authoring DjVu files.You can also disable the printing or saving restrictions dictated by certain web sites. The manual color correction can be useful with old printers.</html> <html><b>進階。</b><br>ä½ å¯é¸å–é è¨­ä»‹é¢èªžè¨€ï¼Œ ç¦ç”¨é é¢å‹•畫, 或 啟用更多編輯 DjVu 檔案的功能表項。亦å¯ç¦ç”¨æŸäº›ç¶²ç«™çš„åˆ—å°æˆ–儲存é™åˆ¶ã€‚ å°æ–¼èˆŠå¼å°è¡¨æ©Ÿå¯ç”¨æ‰‹å‹•色彩校正。</html> <html><b>Network proxy settings.</b><br>These proxy settings are used when the standalone djview viewer accesses a djvu document through a http url. The djview plugin always uses the proxy settings of the web browser.<p><b>Cache settings.</b><br>The <i>pixel cache</i> stores image data located outside the visible area. This cache makes panning smoother. The <i>decoded page cache</i> contains partially decoded pages. It provides faster response times when navigating a multipage document or when returning to a previously viewed page. Clearing this cache might be useful to reflect a change in the page data without restarting the DjVu viewer.</html> <html><b>網路代ç†è¨­å®šã€‚</b><br>本代ç†è¨­å®šç”¨æ–¼ä»¥å–®ç¨å¯Ÿçœ‹æ–¹å¼å¾žhttp URLä½å€å­˜å–djvu文件。 以æ’ä»¶æ–¹å¼æ™‚經通常用ç€è¦½å™¨çš„代ç†è¨­å®šã€‚<p><b>ç·©è¡å€è¨­å®šã€‚</b><br> <i>åƒç´ ç·©è¡å€</i> 儲存å¯è¦‹å€ä¹‹å¤–的影åƒè³‡æ–™ï¼Œ 使平移更平滑。 <i>解碼é é¢ç·©è¡å€</i> åŒ…å«æœ‰éƒ¨åˆ†è§£ç¢¼çš„é é¢ï¼Œ 使得ç€è¦½å¤šé æ–‡ä»¶æˆ–傳回å‰é¢çœ‹éŽçš„é é¢æ™‚忇‰è¿…速; é é¢è³‡æ–™æ”¹è®Šæ™‚坿¸…除此緩è¡å€è€Œä¸å¿…é‡å•Ÿç¨‹å¼ã€‚</html> Standalone Viewer (Full Screen mode) å–®ç¨å¯Ÿçœ‹ (全螢幕模å¼) Standalone Viewer (Slideshow mode) å–®ç¨å¯Ÿçœ‹ (幻燈模å¼) QDjViewPrintDialog Dialog å°è©±æ–¹å¡Š Print åˆ—å° &Document 文件(&D) C&urrent page ç›®å‰é (&U) &Pages é (&P) to 至 Destination 目標 Print to file 列å°åˆ°æª”案 Printer name: å°è¡¨æ©Ÿå: Choose é¸å– &Defaults é è¨­å€¼(&D) &Ok 確定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Printing.</b><br/> You can print the whole document or a page range. Use the <tt>Choose</tt> button to select a print destination and specify printer options. Additional dialog tabs might appear to specify conversion options.</html> <html><b>列å°ã€‚</b><br/> ä½ å¯åˆ—å°æ•´å€‹æ–‡ä»¶æˆ–一些é é¢ã€‚ 用 <tt>é¸å–</tt> 按鈕é¸å–列å°ç›®æ¨™æˆ–指定å°è¡¨æ©Ÿé¸é …。 å…¶ä»–é¸é …é é¢å¯æŒ‡å®šè½‰æ›é¸é …。</html> (invalid printer) (無效å°è¡¨æ©Ÿ) All files save filter 所有檔案 Print To File - DjView dialog caption 列å°åˆ°æª”案 - DjView Question - DjView dialog caption å•題 - DjView A file with this name already exists. Do you want to replace it? è¡•åæª”案已存在。 æ˜¯å¦æ›¿ä»£ï¼Ÿ &Replace 替代(&R) This operation has failed. 作業失敗。 This operation has been interrupted. 作業中斷。 QDjViewPrnExporter Printer data å°è¡¨æ©Ÿè³‡æ–™ PRN Files (*.prn) PRN檔案 (*.prn) Printing Options tab caption 列å°é¸é … <html><b>Printing options.</b><br>Option <tt>Color</tt> enables color printing. Document pages can be decorated with a frame. Option <tt>Scale to fit</tt> accommodates whatever paper size your printer uses. Zoom factor <tt>100%</tt> reproduces the initial document size. Orientation <tt>Automatic</tt> chooses portrait or landscape on a page per page basis.</html> <html><b>列å°é¸é …。</b><br>é¸é … <tt>色彩</tt> 啟用色彩列å°ã€‚ 文件é é¢å¯åŠ é‚Šç·šæ–¹å¡Šå’Œå‰ªè£è¨˜è™Ÿã€‚ é¸é … <tt>ç¸®æ”¾åˆ°é©æ‡‰</tt> 驿‡‰å°è¡¨æ©Ÿä½¿ç”¨çš„紙張大å°ã€‚ 縮放率 <tt>100%</tt> 與åˆå§‹æ–‡ä»¶å¤§å°ä¸€æ¨£ã€‚ æ–¹å‘ <tt>自動</tt> 按æ¯é é¸å–垂直或橫å‘。</html> Cannot render page %1. 未能渲染é é¢ %1. QDjViewSaveDialog Dialog å°è©±æ–¹å¡Š Save 儲存 &Document 文件(&D) C&urrent page ç›®å‰é (&U) &Pages é (&P) to 至 Destination 目標 Format: æ ¼å¼ï¼š Bundled DjVu Document 打包的DjVu文件 Indirect DjVu Document 間接的DjVu文件 &Ok 確定(&O) &Cancel å–æ¶ˆ(&C) Stop åœæ­¢ <html><b>Saving.</b><br/> You can save the whole document or a page range. The bundled format creates a single file. The indirect format creates multiple files suitable for web serving.</html> <html><b>儲存。</b><br/> ä½ å¯å„²å­˜æ•´å€‹æ–‡ä»¶æˆ–其中的一些é é¢ã€‚ å°è£æ ¼å¼ç”Ÿæˆä¸€å€‹æª”案。間接格å¼ç”Ÿæˆå¤šå€‹æª”案,é©åˆç¶²é æ‡‰ç”¨ã€‚</html> Error - DjView dialog caption 錯誤 - DjView Overwriting the current file is not allowed! ä¸å…è¨±è¦†å¯«ç›®å‰æª”æ¡ˆï¼ Question - DjView dialog caption å•題 - DjView A file with this name already exists. Do you want to replace it? è¡•åæª”案已存在。 æ˜¯å¦æ›¿ä»£ï¼Ÿ &Replace 替代(&R) This operation has failed. 作業失敗。 This operation has been interrupted. 作業中斷。 All files save filter 所有檔案 Save - DjView dialog caption 儲存 - DjView QDjViewThumbnails Tiny thumbnail menu æ¥µå° Small thumbnail menu å° Medium thumbnail menu 中 Large thumbnail menu 大 Smart thumbnail menu 智能 Control Left Mouse Button æŽ§åˆ¶æ»‘é¼ å·¦éµ Right Mouse Button 滑鼠å³éµ <html><b>Document thumbnails.</b><br/> This panel display thumbnails for the document pages. Double click a thumbnail to jump to the selected page. %1 to change the thumbnail size or the refresh mode. The smart refresh mode only computes thumbnails when the page data is present (displayed or cached.)</html> <html><b>文件縮略圖。</b><br/> æœ¬é¢æ¿å¯Ÿçœ‹æ–‡ä»¶é é¢çš„縮略圖。 按兩下縮略圖跳到相應的é é¢ã€‚ %1 è¨­å®šç¸®ç•¥åœ–å¤§å°æˆ–清除型態。 智能清除型態åªåœ¨é é¢è³‡æ–™è¢«ä½¿ç”¨ï¼ˆå¯Ÿçœ‹æˆ–ç·©è¡å€ï¼‰æ™‚生æˆç¸®ç•¥åœ–。</html> QDjViewTiffExporter TIFF Document TIFF文件 TIFF Files (*.tiff *.tif) TIFF檔案 (*.tiff *.tif) TIFF Options tab caption TIFFé¸é … <html><b>TIFF options.</b><br>The resolution box specifies an upper limit for the resolution of the TIFF images. Forcing bitonal G4 compression encodes all pages in black and white using the CCITT Group 4 compression. Allowing JPEG compression uses lossy JPEG for all non bitonal or subsampled images. Otherwise, allowing deflate compression produces more compact (but less portable) files than the default packbits compression.</html> <html><b>TIFFé¸é …。</b><br>è§£æžåº¦æ¡†æŒ‡å®šTIFFå½±åƒçš„æœ€å¤§è§£æžåº¦ã€‚ 強制二值G4壓縮將所有黑白é é¢ç”¨CCITT Group 4 æ ¼å¼å£“縮。 å…許JPEG壓縮使用有æJPEGæ ¼å¼å£“縮所有éžäºŒå€¼çš„å½±åƒæˆ–å­å–樣影åƒã€‚ å¦å¤–,相比é è¨­çš„packbits壓縮格å¼ï¼Œå…許deflate壓縮能產生更å°çš„æª”æ¡ˆï¼Œä½†ç§»æ¤æ€§å·®äº›ã€‚</html> Cannot open output file. 未能開啟匯出檔案。 Out of memory. 記憶體ä¸è¶³ã€‚ Internal error. 內部錯誤。 TIFF export has not been compiled. TIFF匯出未æˆåŠŸã€‚ QDjVuNetDocument Requesting '%1' è¦æ±‚ %1 QDjVuNetDocument::Private Received http status %1 while retrieving %2. %1 is an http status code 接收 %2 時收到http狀態 %1。 Received <%1> data while retrieving %2. %1 is a mime type 接收 %2 時收到 %1 資料。 %1 while retrieving '%2'. 接收 %2 時 %1。 Cannot validate the certificate for server %1. 未能驗証æœå‹™å™¨ %1 的証書。 Authentication required for %1 (%2). %1 (%2) 需è¦èº«ä»½èªè¨¼ã€‚ Authentication required for proxy %1. ä»£ç†æœå‹™å™¨ %1 需è¦èº«ä»½èªè¨¼ã€‚ djview4-4.10.5/src/images/000077500000000000000000000000001264256014000152115ustar00rootroot00000000000000djview4-4.10.5/src/images/DjVu.icns000066400000000000000000001601641264256014000167470ustar00rootroot00000000000000icnsàtics#H?þ?þ?þ?þ?þ?þ?þ?þ?þÿþÿþÿþÿü?ø?ð?þ?þ?þ?þ?þ?þ?þ?þ?þÿþÿþÿþÿü?ø?ðis32yÿÿ–—ßɘ„}tj_Yb€ÿ …´°ßÉŒzqg\Vd€ÿ ‰ß¨‡ßÉwkbXSf€ÿ ‚…™ß›‚ßÉa^RNe€ÿ |‰€•߇ŽßÉ›AH]€ÿr‚€r’ßÚ€ÿ7AU€ÿ ˆ|tph„ßÿÿöH8M€ÿ ˆrec]O¡ÿÿÂE3G€ÿ ˆˆ{wwbVj9)16A„ÿ ô™476445<ÿƒô è‰+453.17ÿ„ä‡'5,FjP7ÿ…‚,5.6‰Bÿ3(-543;B‚ÿ†39‘ÿÿÿshiâÁjNI@6+$A€ÿ QœŠcâÁ[F>4("D€ÿ Usâ†]âÁC8/$F€ÿ PQ„âubâÁ+(E€ÿ JUMƒâZlâÁ`=€ÿ@PKE†â˜€¾ 4€ÿ WJA;=yâ¾¾Ÿ-€ÿ W@20))k–¾q'€ÿ WWGB=(1!ÿƒ· ‘Vÿƒ‘‰Lƒÿ„ˆM€5!ÿ…L€U2ÿ‚1‚ÿ†(‘ÿÿÿ½éñØ×îéÜÐõ­œ€ÿ æãøäØ×æØË¾¯§Ÿ€ÿ è½Øéר×ÕŹª£¡€ÿ ÞæÀØã¾Ø×¿±¤¡€ÿ ÖèàµØÏ“Ø×^œ•–€ÿÒÞâÅ©ØH€6…Ž‹€ÿ µÖÐα¥Ø66fˆ‚€ÿ µÒÅ¿§U6Yƒy€ÿ µµŸšš•Xe}}~qÿƒL 1“„}|}jÿƒ '}~}tydÿ„ &z~k…àXÿ….y}raë]ÿb‚|y^‚ÿ†bT‘ÿs8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿICN#ÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿøÿÿÿðÿÿàÿÿÀÿÿ€ÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿøÿÿÿðÿÿàÿÿÀÿÿ€il32áƒÿ{œr¹tpstuvwxxyzz{{€r…ÿ{‰³©x·ŸŽÅ’Ž‹†|vqkf`[SVq…ÿwŒ©¡vÄŠ¸‰ˆ„€{vqlfa[TWt…ÿqÁ©Ÿ‘{Éw«§‚‚}xtojd_ZSWv…ÿk»·²Á˜‡‡Äk¶–{{vqlhb]XPUx…ÿfdÌ›¶µ’z–´k¹…utoje`[UNTy…ÿ`w‚oª£s³volgb]XSLR{…ÿ[‡„‰É…Åšf¼Š§jhc][VPIP{…ÿW‚—u—½„ÇŒwdÈqŽY`cXSNFMw…ÿQ€Žj¦«‰ÄhcÁk·»âÅJPKDJq…ÿM~‰†„c³•”¸|••Þýÿÿè7KHAFk…ÿH|„€ybº ÂÿŶý€ÿ];E=Cf…ÿEz~|zzlfºt§èßÄø€ÿ™,C:>`…ÿ@xywvst_n·jÌìþ€ÿÓ.>6;[…ÿ=vsrqollXm¡žïøýþþÿûM23:W…ÿ:smmkjgedRRíðôü€ÿj'39Q…ÿ7qghfdb`]\R:¼úõÜ«qB,139M…ÿ6gYZXVTROMRJ„¢L+#(/4438HÿÿîUJD73<;6€437Eÿÿïˆÿ þ÷ìêQ@C?=85‚46@ÿÿîÿÿÚj³ÿ¦ÇªÿýòåÎÚD;=:7„46=ÿÿîÿÿ½’ƒ§‡|¸®õãÌÙC585…45:ÿÿîÿÿ½¤‘u«Q“‰†ôßÅ×@0453./1347ÿÿîÿÿÉUŸ…Ê[ÇWñؼÒ>.40A^LA::6ÿÿîÿÿüèíŠøùÿâêçѱÎ?.€46’™†xY€ÿâõ€ñ ððååâåàÙÔÍÎ7/€450mŽ]‡ÿ 64'*++,-/+%‚47U‚\ˆÿ6H-„1ƒ46"Q^‰ÿ6I476ƒ5€4.LäÿƒÿU˜‰a°HBGGHIJKKLMMNNQQ…ÿV\‰{V³„ƒ´\ZWRMHB=72,&"K…ÿQ]|qjYÀm—žRUQLHC=83-( $N…ÿK«jm]eÁZ¨…KOJE@;61,&#Q…ÿF¹—Ÿ¬aTx¶Q²lEHC>94/)$!R…ÿ@Gʰ™ZKŒ¡W²U@@;61,'" T…ÿ:CmÉsº„RD¤Œe¦B;94/*%U…ÿ5QS{ÀlÁpIB¸qy“450*'"V…ÿ1NbF¯oÁ]?IÄV‹w'*,$Q…ÿ,L[X@¡šy¹L3SºLšt“xK…ÿ&JUSO?°€‰ªCOƒº¦ÁÑ¥ F…ÿ"HPNMDC¹iš¥˜u®¸³»¸2  @…ÿFKIGF8N¸Z¡Â›Á®¥¬·\ :…ÿDEDB@?-\³M|þ™œŸ¨‚ 5…ÿB@?=;97'\¡qŒ‘—˜˜šš!1…ÿ?::8641/:†–’—žŸ›5,…ÿ<4431/,*(p–’„e=&…ÿ3&'%$" @Z(‚"ÿÿ¥ÿÿ¢ÒÈÅÄÀ¸½º³­©£›" ‚ÿÿªòë¼WˆÃozfž—†wƒ „ÿÿ¥âá›patYNJnh’†v„…ÿÿ£ÕÖ•}iOl1YTP‘ƒr‚ˆÿÿŸÉÊ–=lX{7x3Ll€ƒ + ÿÿ›¼·°œœT˜˜›‡‹‰zd€ƒ deRD1€ÿ’ ŸŸ š¡¥¥•„‚„GYL6‡ÿƒ „5K5ˆÿ-5‰ÿƒ€*äÿƒÿÆ ¦¹Å¾¿ÁÂÃÅÆÇÈÉÊÔ±…ÿÆÚÿÿ¹½Ô¤çûôíçáÚÔÌž·¯¦©º…ÿÁáÿÿþ¯ËħéñêäÞØÑËĽ¶¯¥ª½…ÿ¹ìÿüÿ÷§×¯°çèáÛÕÏÈÁ»´­£©À…ÿ±¾ô×éÿê£ÝœºãÞØÑËÅ¿¸±ª¡§Á…ÿª—ÏÑÁíÿ×§×ÄÛÕÏÈ»µ®§ž¥Ä…ÿ£Ú¬×ÄÅì÷À²Ì‹ÉÒËÅ¿¸²«¤š£Æ…ÿœêæ¦ØµËèì§À·ŽËÈÁ¼·®¨¡— Æ…ÿ–âþΧիÒâݕΠ™ÍƱ¨®£”Á…ÿáñó¹®Ê§ÖÛ˘܅{eGDž¢š˜¹…ÿŠßêç覷º¨ØÆ_už!Hp1@£–”±…ÿ…ÜäàßÛ˜¼«·¶¯W>S;#““ˆª…ÿÙÝÚ×ØÊ¾¢º@ÈG11{‘„‰£…ÿz×ÕÓÑÎз¼Ÿ¡¼„ a…œ…ÿ uÔÎÍËÈÄÇ«Šµ{„E†|„–…ÿqÑÇÆÄÁ¾»¼¥€†€.y|ƒ…ÿmÍ¿¿½»¸µ±±§Š( %E_x|‚Š…ÿfÓ¾¿½»¸¶³¯¥ªq1Dh{€}{…ÿÿ9š›š”‡ˆ€€|{€ÿÿ-xh[K1' d–‹ˆ}| {zÿÿEàÄ=KP € IŽˆƒ„|~uÿÿ9·¥i>/(  H‡‚~…| ~qÿÿ1˜‹Y<-€ D€}€|}{uvxz{mÿÿ)ynJ€ B~|uŒ±›„ƒfÿÿWL?)B~€|I'íÿæÔ›€ÿ# #!A}€|~r ·óÞ¡‡ÿ fbKOONMLKIV‚|„2’䟈ÿfžy}‚~~‚|S£‰ÿfš|€~‚}|~l…äÿl8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿich#H?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿøÿÿÿÿÿðÿÿÿÿÿàÿÿÿÿÿÀ?ÿÿÿ€?ÿÿÿ?ÿÿþ?ÿÿü?ÿÿø?ÿÿð?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿü?ÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿüÿÿÿÿÿøÿÿÿÿÿðÿÿÿÿÿàÿÿÿÿÿÀ?ÿÿÿ€?ÿÿÿ?ÿÿþ?ÿÿü?ÿÿø?ÿÿðih32m‡ÿ#cMNS=]·}8 b^`bcefhiklnoprsuvwxz{|{d‰ÿ gRomkQ¨×apÖ¢kst‡utsvˆo‰ÿ#f|»±°_»ßi†Û±’•‘Ž‹‡„€}yuqmjfb^ZVPVˆr‰ÿ#fv°§¥§ŒfÎÌ[›ÖŸŽŠˆ…~{wtqmjfc_[XRXŠt‰ÿ#’©¤¡Ÿ£}pÛ¶T­Î“Љ†ƒ€}yvsoliea^ZWQXŒu‰ÿ#°À ¡žš› p‚ã›X¼Ãˆ†…~{xuqnkgc`]YUOWŽv‰ÿ#†Ý¼–¼È—™œf•æaŵ‚€}zvspmifb_[XTNVx‰ÿ#LœÞ¯‘ต˜”a¬ÞdrÌ£{~{xurnkhda]ZVSMV‘x‰ÿ#sC¶ÝŒÞ¯‘•‰_¾ÍQƒÍ”wyvspmifc_\XUQKU“z‰ÿ#uleÃØŸÛ¤Œ’|fÒ½G—Ç„tuqnkhda^[WSPJT”{‰ÿ#v}†iÐÏo®Ö›ˆnqã¥F§»wpplifc_\YURNHR•|‰ÿ#xyŸuuØÁd¿Í‘…‰^ë‡K¶­mljgda]ZWSPMFQ–|‰ÿ#zy—˜f…Û°a·‚S–ìhZ¾œehea\[XURNKEP”z‰ÿ#{y“‘[—Û™gÙ·~wN±áLlÀˆ[Y]gZVSPLICNv‰ÿ#}y‰U©Ù…sߪw{jOÈÊ=y¹‘«ÙèiRQNJGAK‰r‰ÿ~yЉŠ~Q¸Ïk„Ý›quQSÔ²±õÿ j6RKHE?I„o‰ÿ€y‰‡…„†pYÅÅZ™ÙŒ}À£…âþ‚ÿ PJFC=Fk‰ÿ‚x…„‚ƒac˶P°Ë¥ýÿ›ªí‚ÿ ÓHHD@;Dzg‰ÿ„x‚€~}{~TsÌ¢MÀÌëÿÒšáþÿ û?6GB>9Bud‰ÿ†w~}|{yxwxI…ÌP¾ÙàÕÄçý‚ÿw$E?<7?p`‰ÿ‡w{yxwvtsroA“ĈFœÇÏåôƒÿ·A=95=k]‰ÿ‰vwvutsqpnnfDŸ¾…X¹Ôïÿþ‚ÿê06;83=96‚438NGÿÿ–¾ JJIDBDB>;85ƒ438JDÿÿ¿ýÿ ûòÿ¯5GEC@?<975„437FAÿÿ¾ûÿíÝùÿÿïóþéüþû÷ñèÜÇç¤ DB@=;96‡46D?ÿÿ¾ûÿU=aøÿ|ÞKþÿÿøñèÜÈç¥@><:85ˆ46A=ÿÿ¾û€ÿþMÜ[§°¯[«e®ÞžëòçÚÅæ¤=;86Š46=;ÿÿ¾û€ÿþNã€SÏSs˜[ÂJàñä×Áã¤975‹45:8ÿÿ¾û€ÿþOåz’Oæc=ÍYÈOßîàÓ»à¤6†41134586ÿÿ¾ûÿF}?ÙHô{úSx9ßìÜ͵ܣ…467I?520/0155ÿÿ¾ûÿžvÕß4ôÑžÿ¶l™åå×Ç­Ø£„4 2"$y™ˆwh\VQ9€ÿ¾û„ÿ€ÿ üþÿüèÛͻΤ„4 6A¢–‰‚wMÿ¿ý„ÿý†ÿü÷ðåý¡„4 6/!“‹„}tJ‚ÿy „™•£|vw xxyzz}€M5„47ƒ„|tJÿi,‡(…46% t|rJŽÿ’W2‰65…45.npIÿŒQ/ƒ340&iIÿ‰P2‚6ˆ5ƒ4/<:876442>’ÿiZZWUSQNLJHFCA@><;98664438éÿ‡ÿ#T-04$U·k'Ž›F?CEFHJJLNOQRSUVWYZ[\^_]P‰ÿ L @=;5¥Î;a×…5€@‚ABABA@?CUL‰ÿ#KN“ˆ„pH¼ÐC|Ý\a^[WTQMIFA>:62.*&""UN‰ÿ#JE†{ww_Tж8–ÓsWZWUQNKGDA=963/+($%WQ‰ÿ#†P}wropQbݘ6¬ÆbUVRPMJFC@<952.*'#$YR‰ÿ#²«oqmhikGyâx@¾´TRQNKHEA>:740-)%!$[S‰ÿ#€à `¡´degBàXNÈLOMIGC@=962/+($ #]U‰ÿ#=“ߊtåŸ_d_C«Ó>e΃EKHDB>;851-*&#"^U‰ÿ#X#²Ûj{á‘[bUFÀ¹,|ÍmBFB@<962/,(%!!_W‰ÿ#[9KÃÑX“Û~V^JRÕ¤'”ÃV>A>;841.*'#  aX‰ÿ#[GVTÒÂJ¨ÓpSZ@cå‡+§°F<<962/,(%"bY‰ÿ#]EjHeÛ­A¼ÇaPT6zëf6¸š88741-*'# cY‰ÿ#_Edc>yÞ–C϶TMM1’çFIÁ‚/42.)(%!aW‰ÿ#`D`]]6ŽÜ|NÛ¥KJC3±Õ)aÂf(()/&#\T‰ÿ#cD]ZYU4¤Ùd`â‘BG89ʶv³W\„Œ/ VO‰ÿ#eDYVUVK7¶ËIvà|;A'F×g¤¯½Î¹8 QL‰ÿ#fDVTRQR?CÅ»7Úh@p\wÚ³´½ÂÆÄV LH‰ÿ#hDRPONLN4Qͨ/«Ëm˜Ÿa¬È«µ¸»Àƒ  GD‰ÿ#iDOMLKIHI*eÐŽ-¿Æ›šzͦ­±³¸¢  B@‰ÿ#kCKJHGFDCB#{Ïv2¾Õ§šÉÍœ¤¨«­®D  ==‰ÿ#mBGFEDCA@?; ŒÆk%“Ì×ܧ— ¢¤ªl  8:‰ÿoBDCBA@>=;:2&šÀj%x€•˜™™›œ 36‰ÿpA??>=<:9865,!¸ƒ‹’“–—˜ ™ž./3‰ÿ#r@<<;:9764210)U¥§Ž’“•––˜œ©Z+0‰ÿr?88765421/.+*(!b“ˆ‹Ž“›ž–Z(&,‰ÿt>453210/-+*('$$‡Œ”–‰lCƒ")‰ÿv=010/.-+*('%#!iƒU-‚&‰ÿu5#$##"!  ƒ#ÿÿ–v  „' ÿÿx«Ã¾º·»¼¸¶ºÂÄÀ¾¹µ²¯ª¥Ÿ–¡g  …%ÿÿvÁúîçßDzÇÀµ¡œ‰•—•“މs‹a ‡$ÿÿv¼îäàÚF1J·ÅbNŠ,ž›œ”Š‚t‹` ˆ" ÿÿv¹æÞÚÒ>«Exzu9j­nY9‡4F[7t,†‡~oŠa‹ÿÿw²ÕÏÍÇ<¯Zd5“=$|6{0…Ž…{kˆaÿÿx®ÌÈÆÀ4[,“/—J—2H!…‹‚xg†a‡ ‚ÿÿx«ÄÀ½»pQ‘“ “_ŸmA[‰‡~tb„bˆKgTD4("€ÿx¨¼¹¶³¸¶±aU››ž”—˜”ˆ€vjV}cˆ,lc]VNC2ÿy¤¢¡ ŸŸ¡£¯²·»ÀÀ»¶±«¥“¤eˆ_XQJA/‚ÿ]u‚prtuzQNSVWUSQPNMKK'ˆ QPIA/ÿX•EG?/Žÿw•><.ÿr•7.ÿoƒ‡„.‘ÿi20.+(%"  &’ÿW46420-+)'$" éÿ‡ÿ#y{zbhµ™T¨Ž’”–˜™›Ÿ¡£¥¦¨ª¬®¯±³´±Š‰ÿ Ž ¼½½€­ã¡ŒÒÑË€ÎÏχЀÏÎÍÑ貉ÿË€ÿñŒ¹û³™Ù÷þùõñíèäßÚÖÑÌǽ¸²­¨¡©é¶‰ÿÊÿäŠÈøŸ¤ÙòõïìèäàÜØÓÏËÆÂ½¹´¯ª£¬ë·‰ÿ¦Ó‚ÿÒŠÖï®ÜïîêæãÞÚÖÒÎÉÅÀ¼·²®©¢«îº‰ÿ#¬çÿÿþþÿÿÀ“ä߆¸ÞëéäàÜØÔÐÌÇþºµ±¬§ ªð¼‰ÿ#ŽØñÿðíýÿÿ­œïȃ¿ßæâßÚÖÒÎÊÅÁ½¸³¯«¦ž¨ò½‰ÿ#e©ÛøÉÔçÿÿúœ«ó¬ŠÆÝáÜØÔÐÌÈÿ»¶²®©¤¨ô¾‰ÿ#ž{½àÙ­Öëüûíºñ”‘ËÛÚÕÒÍÉÅÁ½¹´°«¦¢š§ö¿‰ÿ#¡Ë—Ãç̳ØìöøÛˆÍêÍÖÔÐÌÇÿ»·²®©¥ ˜¥ø¿‰ÿ# Þä‘Ì踸ØìïóĈÞ×u§ÍÐÍÉÅÁ½¸´°¬§£ž–¤ù¿‰ÿ#£ÚÿÍ”Ñä¥ÁÙééìÀq±ÌÉÆÂ¾º¶²­©¥ œ”¢ú¿‰ÿ#¥Úûÿµ›ÔÞ™ËØåãä’›ô¤u·ÉÃÀ¼¹¶°«§£žš’¡ø¿‰ÿ#§Ú÷ôø ¦×Ð“ÓØàÞÖ°ò‰~¼ÅÄõ¤­©¤ œ—ñ¼‰ÿ#©Úóïðí±Ø¿”ØÖÙÚÃsÅé}’³ŽZ5 œ¬¡™”šê·‰ÿ#¬ÙïëêìÞƒ»×ªœØÓÒÚµxÛ²!$&An<1„¤›–’‹˜ã±‰ÿ#®ÚêçåãèÊÃÔ–©×Õ³epÓB>@@BBC€EGG<ÙðÚÿÃ|l39´Õ§òÙ‰˜‡¢ˆ ÿ\>@ABCDEFGGHH7Më¡âÿ¤QB ;Ö»µùÌ`Z[\\]^_`abbcdefgghijjklmnoopqrrstuvvwxxyz{{|}}~€‚ƒƒ„……††‡ˆˆ ÿ\m@ABCDEFGGHJK,eÝšéÿ”S:!Gà­Àø»b\]]^_`abccdefghhijkllmnoppqrsstuvvwxyyz{||}~~€€‚‚ƒ„„…††‡‡ˆ‰‰ ÿ\mAB˜²±°¯­¬«ª¨§R6”Û¡øò¨Z=tæ Òö«˜——–•”“’‘Œ‹Š‰ˆ‡…„ƒ‚~}|zyxvutsqpomlkjhgedca`^]\ZYXVUSR_‰‰Š ÿ\mCD—±°®­¬«ª¨§¦žK6§Å°ÿà –N<’äŸäõž—–•”“’‘ŽŒ‹Š‰‡†…„ƒ€~|{zywvusrqpnmljihfedba`^][ZYWVTSR^ŠŠ‹ ÿ\mDE•¯®­¬«ª¨§¦¥¤ºÿ¾·à𔓓’‘Ž@;¿¡Ôÿljl4=¨»˜ÝÖ„}{zyxwvutrqponmkjihfedca`_]\[ZXWVTSRQONLKJ[€– ÿ\mZ[Šv<[ÚêžãðŸ˜XTÛÿ°ÔΔ“’‘ކ9QÈ“éÿ¶…`3<¹©©àÅ„{zxwvutsrqonmlkjhgfecba`^]\ZYXVUTRQPNMLKI\––— ÿYm[\‹š^;aðãžêß›—DSæø¡ÛÉ“‘ŽŒ‹z3dÖ“ñÿªƒP2OÆ—¸ß°{yxwutsrqponlkjigfedca`_^\[ZXWVUSRQONLKJI[€— ÿ\m\]Š™™S;uðפöÑ•=qòøšé­ŽŒ‹‹Šl-}Ì¡øÿž|A2gÏ‹ÂÞ›xwvutsqponmlkihgfdcba`^]\[YXVUTSQPOMLKIH[——˜ ÿ\m^_Š™™’L;•ýêöÇ•6ÿéšø§ŽŒ‹‹Š‰ˆY,‘··ÿò™v61{ÍŠÍÝ‘vutsrqpnmlkjhgfedba`_]\[ZXWVUSRQONMKJIGZ—˜˜ ÿm_`‹€˜R‹@;¦ü½½ü±“m0’ÿÛ¡ë Œ‹‹Š‰ˆ‡†G9´¡Ìÿß‹p10“¼•×шtsrqponmkjihgedcba_^]\ZYXVUTSQPOMLKIHGZ€˜ ÿm`aŠ€—U–…:E¹öª¼û¬‘`/°ÿÔ°ò“‹ŠŠ‰ˆ‡†…<8É“Ûÿß‚_0:¢¥ŸÛÅ}rqponmlkjhgfedba`_]\[ZXWVUSRQONMKJIHFZ˜˜™ ÿ\mabŠ—––••s9MØõÖîŸS;ºÿ··ß’‰‰ˆ‡†……„s0NÒ“éÿÅ~K/L½™¨Úµtqonmlkjigfedcb`_^]\ZYXVUTSQPONLKIHGFY˜™™ ÿmbc‰–••€”O`9YâèœÛ@QÛÿ°ÔÍŠˆ‡†…„„ƒ‚f*mÉ¡øÿ­y<.[ËŒ¹Øªronmkjihgfdcba`^]\[YXWVUSRQONMKJIHFEY€™ ÿmdd‰•””€“R’T8sîÛœæÛ“‡4Qæø¡Ôlj†…„„ƒ‚€T*†·¨ÿÿ r2-hÉŒÈבnmlkjhgfedba`_^\[ZYXVUTRQPOMLKIHGFDY™˜– ÿmdeˆ€“€’R‘‹H8€úÔ›óÉŒz-nòøšéª…„ƒƒ‚€~C)›¨¾ÿò”h1-½†ÒÖlkjigfedcba_^]\[YXWVTSRQONMKJIHFEDX—–” ÿmfgˆ€’‘‘€P„=7’ù»§òËg-ˆÿéšñ¤ƒ‚€~}w85³šÔÿß„Y,,–«ÕË{jihgfdcba`^]\[ZYWVUTRQPOMLKIHGFDCW•”’ ÿmgh‡€‘€PŽ}O‡†„ ÿmnoƒ‰,ˆˆ‡‡††……„„ƒd2=²ò¯¯ð¡|=)šÿÔ¡ë”utssrqpoD-l¡øææÿá +POMLKJHGFECBA@>=O…„‚ ÿmopƒ€ˆ‡‡††€…&„„ƒ‚‚^2RÐ뢳î•v75¸ÿÌ¡ò„srrq‚¥É÷~T•°°ÿÌŽÿ* ONLKJIHFEDCA@?>=<;:K~|{ ÿmst€€ƒ€‚"€€~~}}||{l4/‰ëȒݵwV&kòñ“隈ÿÿþ€ÿô^|¾¾ÿÌÿ\JIHGFDCBA?>=<:9I|zy ÿmtu‚‚#€€~~}}||{zzya/:¬ê¯œâ¤rB%ÿéšé£öÿþþ€ÿ”b̨ÿÌÿ˜<;:97Gxvu ÿmww~€€€~+}}||{{zzyyxwwvuH-LÇᚬã†n62¸ÿÔ¡øÙåýþþÿ¿ŒÛ¨ÿÌŽÿ3!FEDCBA?>=<:987Fvts ÿmxx}~~€}||€{'zzyxxwwvvutt>,]Úß“¶Ö…g11¸ÿÔšÛæËðþþ–ò¨ÌÿÌŽÿ}@DCBA?>=<;:876Etsq ÿmyy}||€{*zzyyxxwwvvuttsrn9+jãÒŒ¿Ãwf01™ÿ顨ÛÙÊ»ø°·ÿÿÌŽÿ·4CBA@?><;:9765Drqp ÿmzz€|€{zzyy€x&wwvuuttssrqqc/+ƒáφÇÂvd/"zòÿÔ¡“°°“¾ÿÿØòŽÿò*CA@?>=;:98754Dpon ÿm{€zyy€x(wwvvuuttssrqqpoo]**“ß½ŠÌÀsg;!R¹ÿÿøââøÿÿÖæÿSA@?>=<:987654Coml ÿm{|{€y€xwwvv€uttsrrqqpponnmS*5¢Ý»ˆÉ½reO) {´Ù€ÿÙ·ñþþÿœ:?>=<;:976544Cmkj ÿm|}zxx€w€v)uuttssrrqqpponnmllkQ)H¼Ú¹‡Á¼pcbIoiZkwÓüýý€þÿ Õ.>=<;:9765€4Bkjh ÿm}~yw€v€utt€s'rrqqpoonnmmlkkjiH(G¼Ø·€¯¿{a`›ÿüö÷øúúûüýý€þŒÿ 9$><;:98754Bihf ÿm~y€u€t€s,rrqqppoonnmmlkkjiihgG(<žÕÄ„˜Á‰crÿÿõõ÷øùúûüüýýþ‰ÿ r;<:987654Agfe ÿm€wtt€s€rqq€p(oonnmllkkjjihggfeN'1ŒÒÌ‘€®ªqáÿõóõö÷øùúûûü€ýƒþ„ÿ ¹1:98765‚4Afec ÿm€wsrqq€p.oonnmmllkkjjihggffeddL&&qÅΩµÒÿùðòôõö÷øùúûûüüý…þ ÿó):9765ƒ4@dcb ÿm‚vqpp€onn€m+llkkjiihhgffeddcbaR)%R§ËÅ–w§ÿýîïñóôõö÷øùúúûûü„ýÿÿI"9765„4@ba` ÿm‚‚u€p€onn€m-llkkjjiihggffeddcbba``T/$.~¿Çº—øÿîíîðòóôõö÷øøù€úû‚üþÿ 475…4@a_^ ÿmƒƒtoo€n€mllkk€j.ihhggffeedcbbaa`_^^Y<##G‘ÃÂëÿòêëíïðñóôõõö÷÷øøùùú üýþÿÿÖ -5†4?_^\ ÿm„„tm€lkk€j4iihhggffeddcbbaa`_^^]\\[I)#"S‡Ñÿ÷æèêëíîðñòóôõõöö÷÷ùüýÿó¹s %‡4?]\[ ÿm……s€l€k€jiihhggffeeddcbbaa`__^]]\[[ZYU<€!Mÿÿâäæèêëíîïðñòóôøûþÿ ÕœV !3†4>\ZY ÿm…†rkk€jii€hgg€f*eeddcbbaa`__^]]\[[ZYXXWVN8$ äÿèàâäæèéêìíñ÷üÿ ò©p8 %,3†4>ZYX ÿm†‡rjii€h€g€f*eeddccbbaa`__^]]\\[ZYYXWVVUTSRB¦ÿïÜÞàâäèðøþÿ Ô‹C!)/5‰4=YWV ÿm‡ˆphhgff€e'ddccbbaa``__^]]\\[ZYYXXWVUUTSRQQ‡ÿúØÚåñùÿñ¦k"%,5765Š4=WVU ÿmˆˆpgf€eddcc€b aa``_^^]]\\[ZZYXXWVUUTSRRQPONÿÿñýÿÃw;(0:98765‹4=UTS ÿm‰‰oe€dcc€b aa``__^^]]\\[ZZYXXWVVUTTSRQQPONMÈ€ÿç£V "/8<;:98765Œ4=<;:987654>=<;:98765Ž4=<;:9977554;ONM ÿmŒŒk``€_€^€]5\\[[ZZYYXXWWVVUTTSRRQQPONNMLLKJIHHGFEDCCBA@?>=<;:98765‘4;NML ÿmªª„†€…„„‚ƒ‚‚€~} |{{YMLLKJIIHGFFEDCBA@??>=<;:98765’4;MKJÆÿzLKKJIHHGFEDCCBA@?>><<;:98765“4:KJIÆÿxKJIHHGFEEDCBAA@?>=<;::98765”4:JIGˆÿù¥ÿ/þþýýüûúøøöôòðíëèãâïÿÿk::EGFFEDCCBA@?>>=<;:987765•49HGFˆÿô£ÿ/þþýüûúù÷õñðíèåáÚ×ÐÇÄÞÿÿ[##=<<;:98765—49GFEˆÿô£ÿ.þþýüûúù÷õñðíèåáÚ×ÐÇÄÞÿÿZ#":DDCBBA@?>>=<;:998765˜49EDDˆÿô£ÿ-þþýüûúø÷õñïìçäàÙÖÏÆÃÝÿÿY"":CCBA@??>=<<;:987765™48DCBˆÿô‰ÿ™€Df™…ÿˆDU€ÿ1îDDªÿÿþþýüûúøöôñïìçäàÙÕÎÅÂÝÿÿY!!9BAA@?>>=<;::98765›48CBAˆÿô‰ÿD‚3îƒÿˆ€ÿ»Ìÿ€þ(ýüûúøöôñîìçäߨÕÎÅÁÝÿÿY! 7A@?>>=<<;:987765œ48BA@ˆÿô‰ÿDf»ˆDƒÿ5»»ÿÿˆÿÿþþýýüûúøöôðîëæãÞØÔÍÃÀÜÿÿX6??>=<<;:998765548A@?ˆÿô‰ÿDˆÿÿªÝƒÿ2ˆÿÿfDÿÿþþýýüúù÷õóïîêåâÞÖÓË¿ÛÿÿW5>==<;::987765Ÿ47?>>ˆÿô‰ÿDˆ€ÿ:"ˆÿÌDDÿÿDwÿÿDˆÿwD˜ýüuC•÷õóïíêåáÝÕÒËÁ¾ÛÿÿW5=<;::9887655 47>=<ˆÿô‰ÿDˆ€ÿ8ffÿ»ÿÿwDÿÿ»ÿD‡ýüC…÷ôòîìéäáÜÔÑÊÀ½ÚÿÿV3;;:9987655¢47=<<ˆÿô‰ÿDˆ€ÿ6ˆDÿ»ÿÿªÿÌîÿD‡ýüC…öôòîëèãàÛÓÐÈ¿»ÙÿÿV2:9987765¤46<;;ˆÿô‰ÿDˆ€ÿ5ˆDÿ»ÿÿÝݪ3ÿÿD‡üüC„öóñíêçâÞÚÒÎǽºØÿÿV09877655¥46;::ˆÿô‰ÿDˆ€ÿˆDÿ»€ÿ)"ªˆfÿþD‡üûC„ôòðìéæàÝ×ÐËĺ¶×ÿÿU/77655§46:99ˆÿô‰ÿDˆ€ÿUwÿ»€ÿ'UˆU™ÿþD‡üûC„ôòðëèåàÜ×ÎËùµÖÿÿU/655©46988ˆÿô‰ÿDˆ€ÿ"ˆÿ»€ÿ%ˆfDÝþþD†ûûBƒóðîêæäÞÙÕÍÈÁ·²ÕÿÿT-5«45887ˆÿô‰ÿ DˆÿÿªÝÿ»€ÿ$ÌDÿþþC†ûúBƒòïíéåâÛ×ÒÊž³¯ÓÿÿT,¬45776ˆÿô‰ÿ Dˆÿ»Uÿÿ»ÿ€U€þe2úé‚òîìèäáÚÖÑÉĽ²®ÒÿÿS,¬45€6ˆÿô‰ÿD‚3îÿÿ»ÿ#Dˆþþý˜2!‚ðíëæâߨÔÏÆÂº®ªÑÿÿS,˜4•†pbN:‹45655ˆÿô‰ÿU€Dˆî€ÿ‰ÿ#ˆºþþýë22sîëéãàÜÕÑÌ¿¶ª¦ÎÿÿS,˜4 xž›š™™}cbJICƒ455>‰ÿô“ÿfD„ÿ þþýýüû·Æ÷õòñíêèãßÛÔÐÊÁ½´©¥ÎÿÿS,’4$'1Uœ›š™™˜•’Їƒ€}yvrokVŠÿô‘ÿîUˆ„ÿ þýýüûúù÷öóñðìèæáÜØÑÌÆ½¸°¤ ËÿÿS,’4'‚ ›š™™—•“Ї„~{wtplV‹ÿô’ÿfƒÿ€þýüüúùøöõòðîêçäÞÚÕÎÊ嵬 œÉÿÿS,“4‚}™™—•’‹ˆ…‚|xuqnVŒÿô’ÿˆÌƒÿ€þ ýýüûúù÷õôñîíèåâÝØÔÌÇÁ·²©˜ÇÿÿS,“41V˜–”’‹ˆ…‚|yvsoVÿô™ÿþ üüûúøøöóóðìëæâßÙÔÐÈý²®¤—“ÄÿÿS,”48•“‘Šˆ…ƒ€}zwspVÌÿS,”41€%’ŽŒŠ‡…‚€}zwtqVÍÿS,•4 ŽŒ‹‰†„‚}zwtqVŽÿ•Ä¥ÆD,•41 ‹‰‡…ƒ|ywtqV§ÿ33CDC$¢,–4€ n†„‚€~{yvtqV¨ÿ33CCB$¢,–4$€ c‚€}zxvsqV©ÿ33CBB#¢,—4 `}{ywurpVªÿ33o†„H½4 ^{ywusqoV«ÿ33o„‚G½4 [wutrpnV¬ÿ33o‚€G½4 -gsrpnlV­ÿ33o€~F¾4qpnlkV®ÿ33o~|F¾4 mljhV¯ÿ33o|{E¾4 (ihfV°ÿ33ozyE¾4 AedV±ÿ33oxwD¾4 \aT²ÿ33ovuD½41$^R³ÿ033otsfa``^]][ZYYWWVTTSRQPONNMKKJIHHGFEEDCBBA@??>=€<;:€98776554 PH´ÿ?33orqpomljihfedcb`_^\[ZYXWUTSRQPONMKJJIGFEDCBBA@?>=<<;::98876655ƒ43Eµÿ>33oponmkjigfedba`^]\[ZYWVUTSQQPNMLKJIHGFEDCBBA@?>=<;;:998776655ƒ4*C¶ÿ833oonlkjhgedcba_^]\ZYXWVUSRQPONMLKJIHGFEDCBA@?>>=<;;:9887€655„4Hÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–ÿ €.ÑðÚÿ´WJ&ªÕ§òÒf˜T¢U ÿ\ 9è¡âÿ‹ %λµùÀ/&'()**+,-.//01234566789::;<==>?@AABCCDEFGGHIIJKKLMNNOOPQRRSSTUU ÿ\: SÚšéÿv 2Ú­Àø©1()*+,--./012234566789:;;<=>>?@ABBCDEEFGHHIJJKLLMNNOPPQRRSTTUUV ÿ\: nŒŠˆ‡…‚}{<'ƒÛ¡øï†m>)aã Òöedccba`^^][ZYXWVUSRQPNMLKJHGFDCBA?>=;:9764321/.,+*('%$#! +VVW ÿ\:mŠˆ†…‚}{ys6&—Űÿ×wf5(äŸäõ{dcba`_^]\[ZYXVUTSRQONMLJIHGEDCB@?><;:8764320/-,+)(&%$"!+VWX ÿ\:k‡†„‚€}{yxvf*0¹°¾ÿÈl],(’Пîåucba`_^][ZYXWVUTSQPONMKJIGFEDBA@?=<:98754210.-,*)'&%#" +WXX ÿ\:j…ƒ‚€}{yxvus_%DΡÔÿªhW(2³Ã¥óÎma`_^]\[ZYXWVTSRQPNMLKJHGFECBA?>=;:9865321/.-+*)'&$#! +XXY ÿ\:hƒ~}{yxvusrpS$Uâšéÿ•gJ(Dʰ¶ò¯c`_^]\[YXWVUTSRPONMLJIHGEDCB@?><;:8764320/.,+*('%$#! *YYZ ÿ\:g€~|{yxvusrqonD$mâšøï‚f?'TÞ£Íñ™_^]\[ZYXWVTSRQPONLKJIGFEDBA@?=<;98754310/-,*)(&%#"!+YZ[ ÿ\’e~}|zywvtsrqonml9#‚Ì¡ÿïrb3'iå–Øð‹^][[YXWVUTSRPONMLKIHGFDCBA?>=;:9865321/.-+*)'&$#" +Z[[ ÿ\Þ;d|{yxwvtsrponmlke0-®··ÿ×i`*&|Ø•ãßx\[ZYXWVTSRQPONMKJIHFEDCA@?><;:8764321/.,+*('&$#! *[\\ ÿ\øÓ;czyxvutsqponmlkji_&-Ä¡Ôÿ·gX&0¤Å¡èÏgZYXWVUTSRQONMLKJHGFECBA@>=<:98754310/-,+)(&%$"! *\\] ÿ\ªù­dxwvtsrqponmlkjihhZ"BÙ“âÿ›bK&6Ʋ²íÇ^YXVVTSRQPONMKJIHGEDCB@?>=;:9765321/.-+*)'&%#" +\]] ÿ\¾¹ÿ¢vutsrqpommlkjihhggL"_Ú“ñÿ…a;%AÏŸ½ë©[WVUTSRPONMLKJHGFEDBA@?=<;98764320/.,+*('&$#! *]^^¡ÿ[¬¿ÿ˜srqponmlkkjihhggffC!vÔ¡øïw_3$ZØ“Îê†VUTSRQPONMKJIHGEDCBA?>=;:98654210.-,*)(&%$"! )^^_ ÿ¯ù¬Ùÿƒpponm–¿²tihhgg€fEe:!‹¾°ÿ×lZ+$oÙ—ØéwUTSQPONMLKJHGFEDBA@?><;:8764321/.-+*)'&$#" *^__ ÿDÓìŸßî†nmll¿ÿÿ¸j€g€fFed_-+®¨Åÿ¿aR'#‹Æ—ãÙqSRQPNNLKJIHGEDCBA?>=<:98754310/-,+)('%$#! *_`` ÿ63ÓëžëÖwlk] ÿÅâ¸j€fHeedcc^$AΚÛÿ¡[E#+Ÿ³¢çÁ`QPONMLKIHGFEDBA@?><;:9765321/.-+*)(&%$"!)``a ÿ\: TîØžøÖmj`Tïø¡éœffeedccbaU#GÚšéÿ‘Z:">À¨¬æ«SONMLKJIHFEDCBA?>=<:98764320/.,+*('&$#" )`aa ÿ\:mþÄ«ø¸kh3bÿ顸”eedccbaa`G]Íšøï{X2!MÓ›Ãå—ONMKJIHGFECBA@?><;:97653210.-,*)(&%$#! )aab ÿY:"#ƒþ¾¾þ£hZ&‚ÿâ¡èdccbaa`_^B€Å¨ÿßhS+!YÔŽÓã€MLKJIGFEDCB@?>=<:98764320/.-+*)'&$#"!)€b ÿ\:$!&)¡ø«Äþ”gP"–ÿÔ·ïxcbaa`_^]]5 °·ÿ¸ZJ# tÇŽÞâjKJIHGFDCBA@?=<;:97653210.-,+)('%$#! (bbc ÿY:&&K(2¹ø¤×ífH,®ÿ¾·×pa``_^]]\[)(´¡Ôÿ¶YC (›»˜ÝÓ[IHGFEDCA@?>=;:98764321/.-+*)'&%#"!(€c ÿ\:''XP(FÒêžãíye:BÔÿ°ÔÀc`_^]]\[ZU$?“éÿ R;(®©©à¼XGFEDCBA@>=<;:87653210.-,+)('&$#! (ccd ÿY:()Xg?(KíãžêÕqd-Bßø¡Û·b^]]\[ZYXL PÔ“ñÿŽP1;À—¸ßžKFDCBA@?>=;:98754320/.-+*)'&%#"! '€d ÿ\:)*Wff7(aíפöÅf^(^ïøšé’]\[[ZYXWWDjÌ¡øÿ}K'SÌ‹ÂÞ‚EDCA@?>=<:987643210.-,+)('&$#! 'dde ÿ\:*+Wffa3'‚ýêö¶dU#lÿéšøŠ[[ZYXWVVU8··ÿïuF gÍŠÍÝsCBA@?=<;:97654310/.-+*)'&%$"! 'dee ÿ:+,X€eR\*&•ü½½ü˜`GÿÛ¡è|ZYXWVVUTS,&¨¡ÌÿÖ`B‚¼•×ÍeA@?>=;:98764321/.-,*)('&$#! &€e ÿ:--W€dUcX&0­öª¼û‘^> ÿÔ°ïjXWVVUTSRN$%¿“ÛÿÕU8%•¥ŸÛ¿Q?>=<;987654210/.,+*)'&%#"! &eef ÿ:./W€cUbbK&9ÐõÖê{]5)®ÿ··ÖhVVUTSRQPE<Ì“éÿ³N,7¶™¨Ú©C=<;:98654321/.-+*)('%$#! %eff ÿ:/0Vcbb€aO?%CÜèœÛêjW)?Ôÿ°Ô¾ZUTSRQPON=[Ç¡øÿ”F#FÇŒ¹Ø™C;:987643210.-,+*('&%#"! &€f ÿ:01Vbaa€`R_7$_êÛœæÒiU!?ßø¡ÔµXSRQPONNM2s·¨ÿÿ‚ARÉŒÈ×v:987654210/.-+*)(&%$#! %fec ÿ:12U€`U__^^Z/$kúÔ›óº\M\ïøšéRQPONNMLK(‰¨¾ÿïp:l½†ÒÖ^97654321/.-,+)('&$#"!$dca ÿ:23U€_^^€]PU'#ù»§ò±[@uÿéšñ†PONNMLKJF!$§šÔÿÕX1‡«ÕÈU7643210/-,+*)'&%$"! $ba_ ÿ:34T€^U]]\\[[P&-ªø´´÷ŒU4ÿÛ¡èvNMMLKJIH>;Á“éÿÆF)!¥› Ô²I43210/.-+*)('%$#" "`_] ÿ:45T€]U\\[[ZZYD",´ò§¹öƒS-&­ÿÔ¨ïcLLKJIHGF6AÇ“øÿ¤=%4¬´Ó:320/.-,+)6.&$#"! !^][ ÿ:66S\\€[SZZYYXX<"@Íñ™ÑætN%%¸ÿ··Õ_KJIHGFED,X¹¡ÿÿ€;L¼„½Ò‡21/.-3Ni‹™Y%$#!  \[Y ÿ:78R[[ZZ€Y3XXWWV5!Qçä™ÖåbI<Ôÿ°Ì½PIHGFEDCB#~°·ÿïk7`½ƒÆÐh0C]~‚™|$#"  ZYW ÿ:88RZ€YXXWW€V,UQ* \æÖ˜âÌ`ACïø¡Ô³NGFEDCBA>›¡ÌÿÕR2y²»¨™£±¼™™*"!  XWU ÿ:9:QY€X/WWVVUUTTSP# |ôИì¬R9[ïñ“é‹FEDCBA@@7!§“âÿ£7,-T›™ œ§·ÅÌÍÏ£™H VTS ÿ::;Q€W€V*UUTTSSRRH"óµ£ëžK+sÿéšé‚DCBA@??>07µ“éÿ‹“™# ª·ÃÅÆÈÉÊ̯™a TRQ ÿ:;>=;%T¿¡øß–𣫴º½¾ÀÂÄÅÆÇɽ™‡ RPO ÿ:<=OUU€TSSSRRQQPPOON9=È뢳îtD $¬ÿÌ¡ï\@?>=I^v”L2|°°ÿ¯°²´¶¸º¼¾¿ÁÂÃÄÅÆœ™  PNM ÿ:=>OTT€S RRQQPPOONNML/<Òé”ËÞk=#Äÿ··ÕW>=ˆ™.’@=·“âï°±´¶·¹»½¾¿ÀÁÂæ™F NMK ÿ:>?NS€RQQPPOO€NMLLKK%WßÜ”ÉÎW;:Óÿ¨Å¼D<ˆ™.š‰4TǨÿ¯­¯±³µ·¸º»¼½¾¿À¯™k LKI ÿ:?@NRQQ€POONNMMLLKKJIF!míΓÚÄV1Lïø¡Ô²Cj‚™-›h4š“é®°²´µ·¸¹º»¼½¸™™  JIG ÿ:@AM€POO€N MMLLKKJIIHH?vëÈ’Ý£F0Xïñ“é}K™™˜€™,”:a¾¾ÿŸª¬®°±³´µ¶·¸¹ºº™4 HGE ÿ:ABLOO€N$MMLLKKJJIIHHGFF8%Ÿê¯œâŽ?$}ÿéšéˆ“™˜˜€™+ZCƨÿ¯§©«­®°±²³´µ¶··¦™Y FEC ÿ:BCKNNMM€LQKKJJIIHHGFFEED3%³è¨œå}=#ˆÿÔšø˜•™˜˜™™s<·¨ÿ®¥§¨ª«­®¯°±²³³´¬™‡  DCA ÿ:CDKM€LKKJJ€IHGGFFEEDCCB)8Àᚬãd; «ÿÔ¡øÀ‘€˜,™ssÛ¨ÿ®¢¤¥§¨ª«¬­®¯°°±±™™  BA@ ÿ:DEJ€KJJ€I5HHGGFFEEDCCBBA@#H×ß“¶Óa7«ÿÔšÛÚ””˜˜tï¨Ìÿ­Ÿ¡£¤¥§¨©ª«¬€­® ™G @?> ÿ:EFIJJ€IHHGG€FLEDDCCBBA@@?=UãÒŒ¿ºL5ˆÿ顨ÛÏ«¨ø°·ÿÿ•ž ¡£¤¥¦§¨©©ªª«£™l  ?>< ÿ:FGII€H€G7FFEEDDCCBBA@@??>=6páφǹJ3fïÿÔ¡“°°“¾ÿÿÄ•šœž ¡¢£¤¥¥¦€§¥™‘  =<: ÿ:GHH€G€FEEDD€C$BBA@@??>==<;2€ß½ŠÌ·I3>ªÿÿøââøÿÿÉ–€™ š›žŸ ¡¢¢£¤š™+ ;:8 ÿ:HIGFF€E€D"CCBBAA@@??>==<;;:9, •Ý»ˆÉ´G1&^£Ï€ÿÏ–”˜‚™š›œžŸŸ  €¡œ™Y 987 ÿ:IJGE€D€CBB€A$@@??>==<;;::988*4µÚ¹‡Á²E/."@?:LRa‚——€˜ƒ™š›œœ€žœ™~ €765 ÿ:JKF€C€B€A(@@??>>==<;;::988766%2³Ø·€¯¹W-,T™—“”••–——˜…™€š€› ™™ 643 ÿ:KLE€BAA€@??€>&==<;;::988776544#&‘ÕÄ„˜¾m28™™’’“”•––——‚˜Š™ =  432 ÿ:LMDAA€@??€>)==<<;;::988776554332&{ÒÌ‘€®L„™“‘’“””•––€—ƒ˜†™ k‚ 210 ÿ:MND?€>.==<<;;::9988776554332110$^ÂΩµ‘™•‘‘’“””•––—ˆ˜ ™‘ƒ 1/. ÿ:NNB€>€=<<;;€:+9988776554332210//.&>ËÅ–wŽ™—Ž‘’’“””••––ƒ—ƒ˜™™ „ /., ÿ:OOB==<<€;€:,99887766544332210//.--,&l»Çº——™ŽŽ‘’’“””€•–„—˜™O… -,* ÿ:OPA€;€:€988€7)665443322100/..-,++*'2‚ÃÂ¥™‹ŒŽ‘‘’““€”•€–—˜€™}† +*) ÿ:PQ@::€9€8€7.6655443321100/..-,,+**)(' =w ™“ˆ‰‹ŒŽ‘‘’’€“”•—˜™‘k;‡ *(' ÿ:QR@9877€6255443322110//..--,+**)(''&%# -™™†‡‰Š‹ŒŽŽ‘’•–‚™~X)‡ ('& ÿ:RS?7€6554433€2)110//..--,+**))('&&%$## ˆ™Š„†‡ˆ‰Š‹Œ”—™‘a<€ˆ &%$ ÿ:ST>€655€433€2)1100//..-,,++*))(''&%$$#"! ^™Ž‚ƒ„†‡Š”˜™~O €€‰ %$# ÿ:TU=4€3€2(1100//..--,,+**))(''&%$$#"!! C™–€‡•™a< ‚€Š #"! ÿ:UU<€3€2€100//€.--,++**))(''&%%$##"! ™™—™tE …‹ "  ÿ:UV;22€1€0//€.--,,++**))(''&%%$##"!! q€™ˆa1 € Œ  ÿ:VW;100/..€-',,++**))((''&%%$##"!! QyP.€   ÿ:WX9//.€-,,++€*%))(''&&%%$##"!!  € Ž ÿ:XX9.-,,€+€*5))((''&&%$$##"!!    ÿ:YY8€,€+€*€)4((''&&%%$$##"!!  ‘ ÿC:rsZQRRSRQQPONMMLKKJIHHGFEECCBA@??=<;;" ’†ÿ‰˜P™šœž ¢¥§©«®¯³¶¸¼¾ÁÄÇÉÌÊÉÇÅÃÂÀ¾½»¹¸¶´³±¯®¬ª©§¥¤¢ Ÿ›™9 “†ÿ˜ˆ™Oš›Ÿ¡£¥§ª¬®±´¶¹»¾ÁÃÆÉÌËÉÇÅÄÂÀ¿½»º¸¶µ³±°®¬«©§¥¤¢¡Ÿ›š8 ”†ÿ˜™ŸÈÇÅÅÃÁÀ¿½¼»ºº€¹€¸,·¸·¶··¶··¶·¶¶³°°¯®­¬«ª©¨§¥¤¢ Ÿ›™–“‘Šˆ‘œš3€ •†ÿ#˜™¦öôñðìéèäàßÜØ×ÓÐÎÊÈÅÁ¿¼¸·³¯®ª¦¥¡ œƒ™.˜˜——–•”’Šˆ…€~zsq…œš.  —†ÿ#˜™¦õóðïìéèäàßÛØÖÓÐÍÉÈÅÁ¿»¸·³¯®ª¦¥¡ œƒ™-˜˜——–•”’‰ˆ…~ysq…œ›.  ˜†ÿ#˜™¥òðííêçæâßÞÚ×ÕÑÏÍÉÆÄÀ¾»·¶³¯®©¥¤¡Ÿœ‚™€˜*——–•“’ŽŒ‰‡„~ysq…›- ™†ÿ(˜™¥íìêêçäãàÝÜØÖ776Pwÿ½º¶µ²®\-7¤ Ÿ‘))f™™€˜(—–•”“’ŽŒ‰‡„}xrp…›-  › †ÿ˜™¥ìëééæããàÜÛØÕ8‚'²½º¶´²®\¤ žrz™™€˜'—–•”“’ŽŒ‰‡„}xro…œ- œ †ÿ%˜™¤èçæåãààÝÚÙÖÓ8R”j 2¼¹µ´°¬}xŸžR€™)˜˜——–•”“‘ŽŒˆ†ƒ~|wqo…žœ,  †ÿ%˜™¤åäâáàÞÝÚØ×ÔÑ7lÈÄ‚¢·´³¯««Vž=)€™'˜˜——–•”’‘Ž‹ˆ†ƒ}|vpn…žœ+ Ÿ †ÿO˜™¤ãâáàßÝÜÙÖÖÓÐ7kÇÄÁc·/.«ª,Kž)R™G)[˜—F(Y”’‘Ž‹‡…‚}{vpm…ž+   †ÿB˜™£ßÞÝÜÛÙØÖÔÓÐÎ6jÅÁÀLJµƒ©©M+œ›p™)Q˜—(O“’ŒŠ‡…|zuom„Ÿ+€¢ †ÿK˜™£ÜÜÚÚÙ×ÖÔÒÑÎÌ6jÃÀ¾d1³‚¨¨mœ|™)Q˜—(O“‘ŒŠ†„{ztnk„Ÿ*¤†ÿJ˜™£ÚÙØØÖÔÔÒÐÏÌÊ6i¾½c1³€§§†g™™)Q——(O“‘‹‰…ƒ€{xsmkƒŸž)¥†ÿB˜™¢ÖÕÔÔÒÑÐÎÌËÉÇ5g¿¼ºb0±¥¤¡fR=™™)Q—–(O’ŒŠˆ…‚~yvrkh‚ ž)€§†ÿF˜™¢ÔÓÓÒÑÏÎÍËÊÈÆ4f¾»º=T¯~¥¤ 4R3\™™)Q—–(N’Ž‹Šˆ„‚~yvqjhƒ ž)©†ÿ˜™¢Ð€Ï9ÍÌÌÊÈÇÅÃ4e¼¹·^®}£¢ŸS=)…™˜)Q––(N‘Ž‹‰‡ƒ€|wtphe ž(«†ÿB˜™¡ÌËËÊÉÈÈÆÄÄ¿3c¹¶x—«{¡ œz) ™™˜)Q–•'NŽŠˆ…{usmfc€ Ÿ(­†ÿ˜™¡ËÊÉÉÈÇÇÅÃÃÁ¾3c¸… :­ªz Ÿœ™€3™˜˜=–‹ NŽŒ‰‡…~{urmeb€¡Ÿ(¯€†ÿ˜™¡ÇÆÅÅÄÃÃÁ¿¿½»2‚+#¡ª¨yžš™)R™˜˜[MŒˆ†„|ysokc`¡Ÿ(›fU?/‹†ÿ˜™ ÃÂÂÁÀÀ¿¾¼»º¸=€/]¡©¨¥X››™™Rp€˜EMŽŒŠ†„}{wqnh`^~¡ (› FnljhgfKJ0.ƒ ‡ÿ˜™ ÁÁÀÀ¿¾¾¼»º¸·¶´²±®­«¨§¥A*šš‚™€˜——–mv”’‘‹Š†ƒ|zvpmg_]}¢ (›"kihgfeb_\ZWSPMJFB?;7&ˆÿ˜™ ½½¼¼»ºº¸·¶µ³²°¯­«ª¨¥™6S„™€˜—––•”“‘ŒŠˆ…‚zwsmjd\Z|¢ (›igffdb`]ZWTQNKGD@=9&‰ÿ˜™Ÿ€º¹¸··¶µ´²±°®­«¨§¥£¢>…™˜˜——–•”“’‘Ž‹‰‡ƒ}yvqkhbZW{¢¡(œTffdb_]ZXUROKHEB>;&Šÿ˜™Ÿ¸€·¶µµ³²²°®®«ª©§¥¤¡ T|šƒ™€˜——–••”’‘ŽŠˆ†‚|wtoif_WTy£¡(œ:eca_\ZXUROLIFB?<&‹ÿ˜™Ÿ´€³²±±¯¯®¬«ª¨§¦¤¢ ž›„™€˜——––””“‘‘Œ‹‰…„€|ztqlfb\TQx£¡(œ%b`^\ZWUROLJFC@=&Œÿ˜™/šœžŸ¡¤¦¨«­¯²´·º¼¿ÂÄÇÊÌÊÈÇÅÃÁÀ¾¼»¹·¶´²±¯­¬ª¨§¥£¢(œ^][YVTROLJGDA=&ÿ˜™/š›Ÿ¡£¦¨ª¬¯±´·¹¼¾ÁÄÇÉÌÊÉÇÅÃÂÀ¾½»¹¸¶´³±¯®¬ª©§¥¤¢( [YXVSQNLIGDA>&Žÿ™ ‘“•—š™—–””’‘ŽŒ‹‰ˆ‡……ƒ‚~|{z XVTRPNKIFDA>&§ÿ33€+ À ESPOMJHFCA>&¨ÿ33++) À <&«ÿ33;POÀ4DB@>=:&¬ÿ33;NMÀ:@>=;9&­ÿ33;LKÀ=<;97&®ÿ33;JI¿ :875&¯ÿ33;HG¿643&°ÿ33;GE¿ 20&±ÿ33;EC¾,.$²ÿ33;CA¾+"³ÿ033;A?3.-,+))(&&%$#"!  €€‚#´ÿ?33;?><;:8764321/.-+*)''%$#"  ƒµÿ>33;=<;98754210/.,+*('&%$#!  ƒ¶ÿ833;;:97653210.-,*)('&%#"!  €„!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–ÿ‰‰‹’’€”7WãðÚÿÚ¶¢LRÇÕ§ò澘è¢é ÿ\‰‹ŒŽ’“”•––r2jð¡âÿÈ¡ƒ@\ỵùÝ®­®¯±±²´µ¶·¸¹º»¼¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÙÚÛÜÝÞßààáâãäåææçèéé ÿ\Ç‹ŒŽ’“”•–˜™Z3âšéÿÀ¤sAgé­ÀøÔ°°±²³´µ¶·¹¹»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÚÛÜÝÞßàááâãäåææçèéêë ÿÇã‡ÿN~T®Û¡ø÷æÿ“c•ê ÒöÚþýüûùø÷õôóñðïíìêéçæäâáßÞÜÛÙ×ÖÔÒÑÏÍÌÊÈÆÅÃÁ¿¾¼º¹·µ³±°®¬ª¨¦¥£³êëì ÿÇä‡ÿNôtT¿Å°ÿïïõ€c¯äŸäõÚüûúù÷öõóòñïîíëêèçåäâàßÝÛÚØ×ÕÔÒÐÎÍËÉÈÆÄÂÁ¿½¼º¸¶´³±¯­¬ª¨¦¤¢³ëìí ÿÇ‘’äˆÿMß^aÕ°¾ÿæ÷âlc¼ÐŸîìáûùø÷öôóñðïíìëéèæäãáàÞÝÛÚØÖÔÓÑÐÎÌËÉÇÅÄÂÀ¿½»¹¸¶´²°¯­«©§¦¤¢³ìíí ÿÇ“”ä‰ÿLÔTuà¡ÔÿÞÿØcmÐÃ¥óäèù÷öõôòñïîíëêèçåäâáßÞÜÛÙ×ÖÔÓÑÏÍÌÊÈÇÅÃÁÀ¾¼»¹·µ³²°®¬ª©§¥£¡³íîî ÿÇ”–åŠÿK¿T‡éšéÿÞÿºc~ݰ¶òÜð÷öôóòðïíìëéèæåãâàßÝÛÚØ×ÕÔÒÐÏÍËÉÈÆÄÃÁ¿¾¼º¸·µ³±¯®¬ª¨§¥£¡³îïï ÿÇ–—å‹ÿJžTžâšø÷æÿc‹å£ÍñÔöõôòñïîíëêèçæäãáàÞÜÛÙØÖÔÓÑÐÎÌËÉÇÆÄÂÀ¿½»º¸¶´²±¯­¬©¨¦¤¢¡³ïðð ÿʘ˜æŒÿI‰T®Ì¡ÿ÷æôbžå–ØðÔôóñðïíìëéèæåãâàßÝÜÚÙ×ÕÔÒÑÏÍÌÊÈÇÅÃÂÀ¾¼»¹·¶´²°®­«©§¦¤¢ ²ðññ ÿæŒÿIôtaÌ··ÿïîóka«Ø•ãçÛòñïîíëêèçæäãáàÞÝÛÚØÖÕÓÒÐÎÍËÉÈÆÄÃÁ¿¾¼º¹·µ³±°®¬ª¨§¥£¡ ³ñòò ÿøé©æÿHê^aÞ¡ÔÿæôÞakÄÅ¡èßáðïíìëéèæåäâàßÝÜÛÙ×ÖÔÓÑÏÎÌÊÉÇÅÄÂÀ¿½»º¸¶´³±¯­¬ª¨¦¥£¡Ÿ²òóó ÿªùØâŽÿGßTuè“âÿÝú¿`sÙ²²íÞàîíëêèçæäãáàÞÝÛÚØ×ÕÔÒÐÏÍËÊÈÆÅÃÁÀ¾¼»¹·¶´²°¯­«©§¦¤¢ Ÿ²óóô ÿ¾¹ÿÚÿF¿Tâ“ñÿÜø˜`zߟ½ë׿ìëéèæåãâàßÝÜÛÙ×ÖÔÓÑÐÎÌËÉÇÆÄÂÁ¿½¼º¸·µ³±°®¬ª©§¥£¡ ž²ôôõ¡ÿ¬¿ÿÞÿE¨S¦Ô¡ø÷âö…_à“ÎêÏëêèçåäãáàÞÝÛÚØ×ÕÔÒÐÏÍÌÊÈÇÅÃÂÀ¾½»¹¸¶´²±¯­¬ª¨¦¥£¡Ÿ±ôõö ÿÊù¬ÙÿÞ‚ÿ€Þï„ÿFþþ“S¶¾°ÿîèêp^¡Ù—ØéÎéèæäãâàßÝÜÛÙ×ÖÔÓÑÐÎÌËÉÈÆÄÃÁ¿¾¼º¹·µ³²°®­«©§¦¤¢ Ÿ²õöö ÿfåìŸßöæÿÞÿÿÞ÷‚ÿGþþýñr_̨ÅÿæìÖf]´Æ—ãáÔçåäâáàÞÝÛÚØ×ÕÔÒÑÏÍÌÊÉÇÅÄÂÀ¿½»º¸¶´³±¯®¬ª¨§¥£¡ žœ±ö÷÷ ÿHgåëžëîïÿÿ߯ÿÅâæ÷€ÿHþþýüûï\tàšÛÿÜñ¸]f¿³¢çÙÙäãáàßÝÜÚÙ×ÖÔÓÑÐÎÍËÉÈÆÅÃÁÀ¾¼»¹·¶´²°¯­¬ª¨¦¤¢¡Ÿ›±÷øø ÿ\Ç@†öØžøîïÿê‡÷ø¡éÞÿÿþýýüûúùÙ[}âšéÿÚïœ\wÓ¨¬æÑÝâàßÞÜÛÚØÖÕÔÒÐÏÍÌÊÉÇÅÄÂÁ¿½¼º¸·µ³±°®­«©§¦¤¢ Ÿ›±øøù ÿ\ÇTB¡þÄ«øæ÷ÿ~–ÿ顸Þþýüüûúùø÷¸QŽÔšø÷Ýíˆ[„Ú›ÃåÊáàÞÝÛÚÙ×ÖÔÓÑÐÎÍËÉÈÆÅÃÁÀ¾½»¹¸¶´²±¯­¬ª¨§¥£¡ žœš±ùùú ÿ\Ç¢U[²þ¾¾þÝÿß^®ÿâ¡ðæüüûúùø÷öõ¬P­Å¨ÿïáâuZÔŽÓãÈßÝÜÛÙØÖÕÓÒÐÏÍÌÊÉÇÅÄÂÁ¿½¼º¹·µ³²°®­«©¨¦¤¢¡Ÿ›š°ùúú ÿ\Ç«˜ccÈø«ÄþÝÿÉT¿ÿÔ·÷åûúùø÷öõôóŒOư·ÿÝäÎbY£ÇŽÞâÇÜÛÚØ×ÕÔÒÑÏÎÌËÉÈÆÅÃÁÀ¾½»¹¸¶´³±¯®¬ª¨§¥£¢ žœ›™°úúû ÿ\Ǭ­ÇcnÖø¤×õæÿ´aÌÿ¾·ïëùø÷öõôóòñm\ΡÔÿãâºYd»»˜ÝÛÊÚÙ×ÖÔÓÒÐÏÍËÊÈÇÅÄÂÁ¿½¼º¹·µ³²°¯­«©¨¦¤¢¡Ÿœš˜¯ûûü ÿ\Ç®¯ëÄcåêžãõæþ“tæÿ°Ôæð÷öõôóòñðåbqÒ“éÿÚå¦XbÈ©©àÓÎØÖÕÔÒÑÏÎÌËÉÇÆÄÃÁÀ¾½»¹¸¶´³±¯®¬ª©§¥£¢ ž›™—¯ûüü ÿ\ǯ°ëÿc‡õãžêííürtïø¡ÛåïõôóòñðïíÎWƒÛ“ñÿ×ã‹WrÏ—¸ßÌÑÕÔÓÑÐÎÍËÊÈÇÅÃÂÀ¿½¼º¹·µ³²°¯­«©¨¦¥£¡Ÿœš™—¯üüý ÿ\DZ²ìÿÿŠc—õפöäóïg÷øšéÛóóññïïíìë¸M›Ì¡øÿÔ×pV‡Ô‹ÂÞÃÔÓÒÐÏÍÌÊÉÇÆÄÃÁ¿¾¼»¹¸¶´³±¯®¬ª©§¥¤¢ Ÿ›™—–®üýý ÿ\Dz³ìÿÿôb±ýêöäñÙ[ÿéšøÚñðïîíìëêéšL¬··ÿ÷ÖÍ^U™ÍŠÍÝÂÒÑÏÎÌËÉÈÆÅÃÂÀ¿½»º¸·µ³²°¯­«ª¨¦¥£¡ žœš™—•®ýýþ ÿYÇ´µìþþýékb¿ü½½üÚ÷¸Q­ÿÛ¡ðßïîíìëêéèç|XÆ¡ÌÿíÖÃUT¬¼•×ÕÄÐÎÍËÊÈÇÅÄÂÁ¿¾¼»¹·¶´²±¯®¬ª©§¦¤¢ Ÿ›š˜–”­€þ ÿǵ¶ëý€üSÞalÌöª¼ûÚõ¢PÆÿÔ°÷ÜíìëêéèçæÚgWדÛÿíÓ§T^¶¥ŸÛÎÆÍÌÊÉÇÆÄÃÁÀ¾½»º¸·µ³²°®­«©¨¦¥£¡ žœš™—•”­þþ¡ÿZÇ·¸ëüûûúú¿auãõÖòßóŒ\Ìÿ··îáëêéèçåäãÆSnÚ“éÿáÔ„SnÈ™¨ÚÇÈËÉÈÆÅÃÂÀ¿½¼º¹·¶´²±¯®¬ª©§¥¤¢ Ÿ›š˜–”“¬þ¢ÿ\Ǹ¹ëûúúùùø¢`}ëèœÛòÝçmræÿ°Ôåäéèçåäãâá±I‹Í¡øÿÕÖjR}ÏŒ¹ØÅÆÈÇÅÄÂÁ¿¾¼»¹¸¶´³±°®­«©¨¦¥£¡ žœš™—•”’¬ÿÿþ ÿ\Ǻ»êùùøø÷÷öŽ_”òÛœæéãåXqïø¡Ôãâæåäãâáàß’H¢·¨ÿÿÑÌYQˆÉŒÈ×¼ÇÆÄÃÁÀ¾½»º¸·µ³²°¯­¬ª¨§¥£¢ Ÿ›š˜–•“‘«ÿþü ÿ\Ç»¼éø÷÷ööõõêz^ úÔ›óàçÏNŒ÷øšé×åäãâáàßÝÜvH³¨¾ÿ÷йXP›½†ÒÖ¹ÅÃÂÀ¿½¼º¹·¶´³±°®¬«©¨¦¤£¡Ÿžœš™—•”’«ýûù ÿǼ¾é€öUõõôóóßf^®ù»§òßå°M¤ÿéšñÕãâààÞÝÜÛÑcVÅšÔÿìÍŸPO­«ÕϺÂÁ¿¾¼»¹¸¶µ³²°¯­¬ª¨§¥£¢ Ÿ›š˜–”“‘©úøö ÿ\Ǿ¿èõõôôóóòññÕehÊø´´÷ÔéL¬ÿÛ¡ð×àßÞÝÜÛÚÙ¼OkÑ“éÿäˆOY¿› ÔÈ»¿¾½»º¸·µ´²±¯®¬ª©§¦¤¢¡Ÿœš™—•”’¨÷õô ÿ\Ç¿Àçôóóòòññðïï·\gÑò§¹öÓç|XÌÿÔ¨÷ÓÞÝÜÛÚÙ×Ö¨FvÍ“øÿ×Ë|Nj½´Ó»»½¼º¹·¶´³±š£­«©¨¦¥£¡ žœ›™—–”’‘§õóñ ÿ\ÇÁÂçòòññððïïîíí¤[yàñ™Ñí×ÛhXÔÿ··íÖÜÛÚØ×ÖÕÔŒEˆ¿¡ÿÿÍÈlM~Ľҹ¼º¹¸¶©{Ma¬ª¨§¥£¢ Ÿœš˜—•“’Ž¥óñï ÿ>ÇÂÃæñððïïîîííìëëZˆîä™ÖìÓÏSnåÿ°Ìã×ÙØ×ÖÕÔÓÑpDª°·ÿ÷ʾbL‘½ƒÆÐ´¹•g-‚*ª©§¦¤£¡Ÿžœ›™—–”’‘Œ¤ðîì ÿÇÄÄå€ï4îííììëëêéßtZíÖ˜âã׺Ix÷ø¡ÔáÔ×ÖÕÔÒÑÐÆ^C¿¡ÌÿìÅ­RK£²ƒ‹KDHNRW\`cgjmnq4Ÿœš™—•”’‘ŒŠˆ‡ãáß ÿ)ÇÊÌáèèçææååääãââáààßÞˆUsáé”ËæÌºNUÝÿ··ìËÌË%.È“â÷j8=CGLQTY\`begi!Žœ›™—–”“‘ŽŒ‹‰‡†œàßÝ ÿ)ÇÌÍáææååääããâááààßÞÝÝÜnU‹çÜ”ÉÞ̹Ekåÿ¨ÅáÈÉ%. Oͨÿ·27qËÿÿøââøÿÿÚ:€# *9@Œ‹‰ˆ†„ƒ€~}|ÈÆÄ ÿÇÙÚ×Ö€Õ&ÔÔÓÓÒÒÑÑÐÏÏÎÍÌÌËÊÉÈÈÇÆ—LWµÝ»ˆÉ˸»“L=i»æ€ÿæ—ƒ! ;=}‹‰ˆ†…ƒ‚€}||ÆÄ ÿÇÚÛ×€Ô'ÓÓÒÒÑÑÐÏÏÎÎÍÌËËÊÉÈÈÇÆÅÄÕKiÈÚ¹‡ÁÉ·¹¸‰€P€… =>e‰ˆ‡…„‚€}€|ŽÃÁÀ ÿÇÛÜÖÓÒÒ€Ñ&ÐÏÏÎÎÍÍÌËËÊÉÈÈÇÆÅÄÄÃÂÁ…JhÆØ·€¯È´¶µp€‡€ 6@Oˆ‡…„‚~|ŽÁ¿½ ÿ1ÇÜÝÔÑÑÐÐÏÏÎÎÍÍÌËËÊÊÉÈÇÇÆÅÄÄÃÂÁÀ¿¾„I_±ÕÄ„˜Æ²±œ€‚ (ACƒ†„ƒ€~}|¿½¼ ÿÇÞÞÔÏÏ€Î'ÍÍÌÌËÊÊÉÉÈÇÇÆÅÄÄÃÂÁÀÀ¿¾½¼HT¤ÒÌ‘€®»ª €€ƒŠ CDn„ƒ€}‚|½»¹ ÿÇßàÓ€Í+ÌÌËËÊÊÉÉÈÈÇÆÆÅÄÃÃÂÁÀÀ¿¾½¼»ººŽGGÊΩµM€€…†DE^ƒ‚€}ƒ|Œº¹· ÿÇàáÑÌ€Ë,ÊÊÉÉÈÈÇÆÆÅÅÄÃÃÂÁÀÀ¿¾½¼¼»º¹¸·šMFr¶ËÅ–wg€Š7FK‚€}„|Œ¸¶µ ÿ/ÇáâÐÊÊÉÉÈÈÇÇÆÆÅÅÄÄÃÂÂÁÀ¿¿¾½¼¼»º¹¸·¶¶´ŸYEP—ÃǺ—€€€ƒ†#HIw}…|‹¶´³ ÿÇâãÐÈÈ€Ç*ÆÆÅÅÄÄÃÂÂÁÁÀ¿¿¾½¼¼»º¹¸¸·¶µ´³²ªsDDi¦ÃÂ;€‚…€ HJh~†|Š´²° ÿÇãäÏ€ÆÅÅ€Ä,ÃÂÂÁÁÀÀ¿¾¾½¼»»º¹¸¸·¶µ´³²±°¯®PCBužf€ƒ‚,IJX‡|б°® ÿÇäåÍÅ€Ä0ÃÃÂÂÁÁÀÀ¿¿¾½½¼»»º¹¸¸·¶µ´³²²±°¯®­¬¤vBAAK €€‚ 1DEHJKMy†|‰¯®­ ÿÇææÌÃÀÁ2ÀÀ¿¿¾½½¼¼»ºº¹¸¸·¶µ´³²²±°¯®­¬«ª©¨šmF@  $4>@BDFHJXhy†|‰­¬ª ÿÇçèÌ€Á2ÀÀ¿¿¾¾½½¼¼»»º¹¹¸··¶µ´³³²±°¯®®­¬ªª©¨§¦¥£ƒ+ ‚ )57:<>ABK`m}‰|ˆ«ª¨ ÿÇèéÊ€¿€¾,½½¼¼»»º¹¹¸¸·¶¶µ´³²²±°¯®®­¬«ª©¨§¦¥¤£¢¡n  '-0257:µµ´´³³²²±±°°¯®®­¬¬«ª©¨¨§¦¥¥££¢¡ Ÿžœ›š™˜—–•”’pxŽŒ‹‰ˆ‡…„ƒ‚€~}|…Ÿž ÿÇîïĵ€´³³²²€±5°¯¯®®­­¬«ªª©¨¨§¦¥¥££¢¡ Ÿžœ››š™—–•”“’‘ŽŒ‹Š‰ˆ‡…„ƒ€~‘|…žœ› ÿǼ½œ‘€’;‘ŽŒ‹ŠŠˆˆ‡†…„ƒ‚€~}|{zyxw“œ›š™˜—–•”“’‘Œ‹Š‰‡†…„ƒ€}’|„œš™†ÿŠO #%(+.0310.,*)'%$"  u›š™˜—–•”“’‘ŽŒ‹‰ˆ‡†…„‚€}“|„š˜—†ÿ‰O  "%(*-0320.,+)'&$"! s™™—––•”’’‘Œ‹Š‰ˆ‡…„ƒ‚€~}”|ƒ˜—•†ÿ2vsonidc_ZXTQPLJHDC@=<9552..+'($"  € Zww•”“’‘ŽŒ‹‰ˆ‡†…„ƒ€~}•|ƒ–•”†ÿ$1êäÝÛÒÈÆ½³°§Ÿš‘‰…zune`XNJB86," „€)  7II}“’‘ŽŒ‹Š‰ˆ‡†…„ƒ€~—|ƒ”“’†ÿ$1çâÛÙÐÇż³°¦ž™‘‰„zune`WNJB86+" „€(  7HH|‘‘ŽŒ‹‰ˆ‡‡…„ƒ‚€}˜|‚“‘†ÿ#0ÞÚÔÒËÃÁ¸°­¤›—އ‚yrmc^VMH@74* …€'  6GG{ŽŒ‹Š‰ˆ‡†…„ƒ€~}™|‚‘†ÿ#/ÓÐÌÊĽ»³ª¨ —Y%#"/Cj`[TJF>5 …€% 5GGyŽŒ‹Š‰ˆ‡†…„ƒ‚€}›|ކÿ/ÐÍÉÈ»¹±©§ž–'‚YZSJE>4…€$ 5FEwŒŒ‹‰‰ˆ‡†…„ƒ€~}œ|ŽŒ†ÿ#.ÇÄÀ¿º´²ª£¡™’&3Y<WQGC;1" …€# 4DDw‹Š‰ˆ‡†…„ƒ‚€~}|Œ‹Š†ÿ#-¾»·¶²¬ª¤ž›“%BvmEIMDA8.,  „€  3DDu‰ˆ‡†…„ƒ‚€~}Ÿ|€‹Šˆ†ÿ",¹·´³®©§¡š˜‘Š$@tkf ,L5-* …$ 3CCs‡‡…„„ƒ€}} |€‰ˆ‡†ÿ"+°®ª©¦¡Ÿ™”‘Š„"=ofa$ G.*( …" 3BBr……„ƒ‚€~}¢|ˆ‡††ÿ"*¨¦¤£ ›™”Ž‹…!;kb^.C,'%„! 2BAq„ƒ‚€~}¤|††…†ÿ"*¢¡ž™•”‰‡€{ 9g_Z-B)$"„  1A@o‚€}}¥|…„ƒ†ÿ!)˜–””Œ‹†yt5`YT*<% … 1@@m€€~}§|~„ƒ‚†ÿ!(”’Œˆ‡‚}{up4]VR9%„€ 1?>l~}©|~ƒ‚†ÿ'Љ‡‡ƒ€zvtni1WPK 4 † />>k}«|~€†ÿ&€}}zwvqmlfa,PI.-/ † /==i¬|}€†ÿ&}{zywtsnkid_+N43-‡ /==i¬|}~~†ÿ%srppmjiea`[V‚ -,& Œ /==i˜|ï߯¶„‹|}~~}†ÿ$igfec`_]XVRN€ ,(& † /==i˜|΃ÿÝÛ¹·™˜ƒ|}~‰‡ÿ#edcc`]\YUTOKHC?<62-&# †€  /==i’|>6>U]t¥‚ÿýúöóïëçãßÚÖÑÍÈäˆÿ"[ZYXVSSPLJFB@:64.)&‡  /==i’|]‚ÿýú÷óðìèäàÜØÓÏÊŤ‰ÿ!SRRQOLKHED?<951-'$†€€ ! /==i“|.‚ÐÿþüúöóðíéåáÝÙÕÐÌǤŠÿ!NMKKIFFC@?:74/+(#‡€€  ! /==i“|týûøöóïíéåáÞÚÖÑÍɤ‹ÿ CCBA?=<9651-+&#  ‡€ "$ /==i”|>_ú÷õòïìéåâÞÚÖÓÎʤŒÿŽ2 !#&)+.131/.,*('%#"  /==i”|t€>õóñîëèåáÞÚ×ÓÏˤÿŽ2  #%(+.0310.,*)'%$"  /==i•|> ñïíêçäáÞÚ×ÓÏˤŽÿ•4…5#)+-/1355320/.,,*)(&%$#! 3==i•|t íêèåãàÝÚÖÓÏ̤§ÿ33rssJ¢=i–|.€ ½æãáÞÜØÕÒÏˤ¨ÿ33€rI¢=i–|U€ «áßÝÚ×ÕÑÎˤ©ÿ33rrpI¢=i—| ¨ÝÚØÕÓÐÍʤªÿ33Èæä–½| .¤ØÖÓÑÎËɤ«ÿ33Èãᕽ| M ÓÑÏÌÊǤ¬ÿ33Èáß”½| l·ÎÌÊÈŤ­ÿ33ÈÞÜ”¾|ËÉÇÅä®ÿ33ÈÛÙ“¾|&ÆÄÂÀ¤¯ÿ33ÈÙØ“¾|IÁ¿½¤°ÿ33È×Õ’¾|w¼º¤±ÿ33ÈÔÓ‘¾|­·¢²ÿ33ÈÒБ½|tD³Ÿ³ÿ333ÈÏν·¶´³±°¯®¬«ª©¨¦¥¤¢¢¡Ÿžœ›™™˜––”“’‘Ž‹ŠŠ‰ˆ‡‡…€„ƒ‚€€~}}|Mš´ÿ@33ÈÍËÉÈÆÄÃÁ¿½¼º¹·µ´²°¯®¬ª©§¦¤£¢ Ÿœš™˜—•”“‘ŽŒŠ‰ˆ‡†…„ƒ‚€~~}}‚|e‰µÿ>33ÈÊÉÇÆÄÂÀ¿½»º¸¶µ³±°®­«ª¨§¥¤¢¡ ž›š˜˜–•”’‘ŽŽŒ‹Š‰ˆ‡†…„ƒ‚€~~}ƒ|^†¶ÿ=33ÈÈÇÅÃÁÀ¾¼º¹¸¶´³±¯®­«©¨¦¥£¢¡Ÿžœ›™˜—–”“’ŽŒ‹Šˆ‡†……„ƒ‚€~~}}„|‚ÿÿÿÿÿÿÿÿÿÿÿÿÿt8mk@~~~~~~ &¯½§Ë§ƒn((“¡t¿³‹µµµµµµµµµµµµµµµµµµµµµµµµµµµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýýýýýýýýýýûûù÷õóïíëéçåáßÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿdjview4-4.10.5/src/images/DjVu.ico000066400000000000000000000163561264256014000165700ustar00rootroot0000000000000000¨6 ¨Þh†(0`€ ÿÿÿæ¢Gj™­Ð JrT#1Â}T¹ùãÅÒR}À'6o«hOVsž“Óûˆ,<Óç÷ƨ¹l¢Ö&„go2l9Ÿå´^…¨”­v‹¼&„Áïàç3'8;Q‹BQ½¹Ò#£øk.D5{¨Ÿu™z·çŽ[ˆ]‰Ÿcp´yƒQFK>¯ùÛ±ÄÀ—£;#„ ÉÉÌÞ'’׆NvaŽÈ†ÓM¨â"Nh v~x¿;ˆ¹íóú"nž‚¤{Ya2N¨Ññ«Px޹âá×àR.?|3K»n‘Й²¤l‰°š@_%œéV{•Pd¢\f½öžø—?]´¤º4Ea©ã=r´xJh mCLŠÉöÕ¥»"u«¦my2ŽÉ–MuÕÀÍ]>D[˜Ó_-6È‹§0áêõDž×ÓÝì·¤¦ˆ¢ôïò2¥î}ÅεÃE«ë„„«M$ŽÙZ²ë¬u’/BæÐØ“[|¿›¯‘8R¾³ÆP²ó„U€úöø­]yºŒ˜y„± ß»Ë,rž´j„N|F`k¡t`g³‚Ž—£Ë™Å‰nwsµŒqŸ,R,4’M[¦Lrh…^ŸSa2–×ë×à3«øG³ø˜ðqJS`h6·t¥Tz#7,EÚÓÞˆ:W¾…¡‰4KaŸ×Ê’«5H˜XeÇ¡­ÄŽŸ?df*=†/C°W‰Ñ›JmÜÈÒ@¥å?ªñ&i“·g‹½|™dIPpZar-B…Ç€¢Ñ j¨ª`„ëåë~½X¥á<š× &aCJCclU[º•ªŠÐû#—â\¼ù4à ø*§øË­¹Z8?ÒŸ·‘€Ä›,šðX§yyúúêêÈ’’’’’’³IÂkSb,ššÐ" @ÜyyúêêÈB’’’’’’ýáz·šÐ""ÏQ¢½yyyêêBBB’’’’’O´‚%Ù›¨šÐ"ÏÏ58üüyyêêBBBB’’’’’’IÿèÚjp{›PCÐÐ"ÏQ…ÕüüüüTêBBBBB’’’’Ií}ºäík‹›{öÐ""ÏQ §üüüüTêBBBBBB’’Oÿ} ëkËË}1,U&Ð"ÏÏ:RRüüüTê’±±BBBBB¡÷ºJ}™¿õÂh,Ð"ÏQ®ÛRRRüüTê’±BBB¡n©t} OÍ0A·¤fÐ""Ïœ¶üRRRRRTê~¹±BBx-Ikv’’Ž¤Í‹ZÐ"ÏQÀŸÈÈRRRRúê~G¹±JvÁí±’’’!4D<š""ÏQ@#ÈÈÈRRRúê~ñG¹¹t}Á÷}GBBBëv’xŠ"ÏÏóÈÈÈÈÈRRúê„ññGòÂ}GnàBBBò}í±J} – çV#ÈÈÈÈÈRúê„ò÷}dx[±BBOÿ}¹IkíB’³_ÈÈÈÈÈúê„àºø[ë} ±±¡´àOÿ}¹’’’’ÈÈÈÈúT à‚äkG¹ÁÓ¡´à’’’’’’ÈÈÈúT Ê™äÿkàGG¹i ±[BBB’’’’’ÈúTJ}í¦÷}Hññä}ÿi BBBBB’’’’’’úNí}[n-ààtíkºä}BBBBBB’’’’’’yÑ}-[} ©ddÖD©tíkñ±±BBBBBB’’’’’y´ßß[[ÓH©¦`-Ö÷}d¹¹±±BBBBBB’’’’’’yô­--[[Ó©vn[ñG¹¹±BBBBBB’’’’’’yTû‚--ßÓÊ©x ñGG¹±±BBBBBB’’’’’yTû‚‚--i}k[i}ÿdàññG¹¹±±BBBBBB’’’’’yTè ‚Êí}‚ikkH©dààññG¹¹±BBBBBB’’’’yêTÔÔÞv*Þvk—TTTTTTTTTêêêêêêêêêêêêêêêÿàÿÿàÿÿàÿÿàÿÿàÿÿà?ÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿàÿÿÿÿÿÿ( @€ÿÿÿ’å¡Fi™¯ÑJqV#3aq®Ä€ŸS¹ùáÂÑq¦"4Äåú‘j“ŽÑû‰.?o˜Èǧ¹:“Ë/ ZFLìáè/©ø´]„;O¿Èß~Ã)[zG¤Þ9+<°}‰•T~‡;Yk©Ýp(9b‘°­ÆÙÕá-´„“¼¬ÏíÚ±Äèòú 1½–«¦my™¾ãŸøœ]jB!(’M[«OxÌÀÏLp¯ª»×w2I¼o’R.B.>@±ùÕâñV~0u  eŸZ Û†Ô >cD]ŒJqϘ±ºŒ™Oªí—>[¢u‘ 4Nõïò F49èÒÝŽ6N0-,‡Á˲´~™¨c…%j–]µï­nÖ¨½<ÅŠ¦,"y°@+1c'99о&!]„ M(:™Lmv¼e¡Ö#¤øß»Ì˜ð<«ò„3JR:@ââëÞÌ×È”ª&UqԼɥKp5FLz´h…+<q.AËÞð8$±¦¾€Àk¡Æ£®F¥ìö…ŸÏ¢²±X€½{“‹Y}éÝãK¶ù]¾ù’:U##I,V@F RÅš° Vx4…¸QzšAa¼Ž¥ííóo$14§ñ(q /DµÖ±t‘CdÍܨ÷òõèçîJ-4=V¸gŒ7­ùºÌäN3:Àx™¬Xx¯z”ÀˆŸF'.¬Êç€6PV´ò®gŠFdŸô5y¤„Ð{½·nŠ$ÚÅщ2G>[,pšæÏÙòêî=',Ú·ÅZ&8ºu°^~½‚‡8G®a…Ý¿ÍÓ¦‡6OaŒ.w¥5 áÑÛ:#(6MC/5 FmO,?É©»¶nÓ¡¸Ä ´Z‚Ë‘«ªQsv-BÍœ­É•®¶cˆ²c\¹öíÝå)¦ø8K•¬¨Mt¤Hm¶t•ðïô†0Es+>Š4Jn¥Û•šiñCŒŠŠéä55ãããtÑŸUTo&ò0¥ài1võëŠQ×5555ã.¼U¼æó8¬àñ1-JJëQ¨„÷55UM›qX"•I Þi1g¿JJJQÁÛ„YMÂðqã6*zài1D¹““JQw:£¯Ú·+5ã.¼VêàñkRÿ“““öµ§Ò˾ѻ÷5©ŸÒsÅä 7!ÿÿ““ŠÀìsP.ú£÷V¼\Ô5täääÿÿ“Š…ú”M£ÄðZ‚MÛããttääÿÿë.Mâ¼Ó§Òs»›M§55ããttäääëM+‡jþúåî÷555ãããtäääë¾ZjGÖ.Ÿ\p £„555ãããttääJÙ+ZÓ.ŸZTß§:£„÷555ããttäJƒj+¼ ÔMÖ§:£Û÷555ãããtJƒÆ‡»”Ÿq…ÀµwÜÁ¨×tääÿëÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿ( @ÿÿÿã¦In©­ÇStV#-[½ùXrš»}›,CßËÖp¨K›Íˆ1E}[‹wªÛÓ¥º.©ø±Éå:C]¦mz0…»f9EAZKX%e4vŸ‚Ì+šâŠ»ãC¥ä U†Ä”£P3NÇÒåڹȵa‡d¯æŸ÷’9S¯S| eŸ”GkÅ­Áu5M4Fºo‘`/c‚Ì—± $5'|²ŠÏ`/;ºŒ˜š?^lBN›NuÒ±Â%s¥@žÚª^†6Pm/E8P¾Š¤O}Ä¥¹¯¨¿)\|ÜÁÏÅœ©%¥ø7­øR¹ù½v–ÏŸµ'`„Ce©Mue,AϬ¸|2J¡Rr5M\¼v”¦JpÔµÅs5MÓ²Ã_‘‘LY Fi¤Im¨Ls ÷Õ·Ç_0;f8D‰1F6N‘9TšA`žCd¥Jo¦Kq­Pz«Ox¥myػɎ7P‘KY¤Hm§Kq¨Lr¨Lt­Tz›Nt€€ˆ¦‘‡X-›gz@’¤K=JI¢f“¯²1.NV<3 l±97ž1FA]0e*?¨b–¥6d 4|5„ŽY_‰•§“¸:yh+‹u•”o¬ ZTDaQUµPx>`EW#~Sv}i°nqC—(mpœr,&'"©Š˜š;LBc†[O{k£M j…·¡«‚Ÿ8$s^G/­ƒ¶™³w\ t2Œ%)®P´ªRH!ðððððððððððøÿdjview4-4.10.5/src/images/DjVuApp.icns000066400000000000000000001453661264256014000174170ustar00rootroot00000000000000icnsÊöics#H?ø?üüüüüüüÿüÿüÿü~?ø?üüüüüüüÿüÿüÿü~is32†Uh˜“‡‡ ‹ïöõï×ÊÛÕÌ©‰€'©ÿøÞÿ§€ KÃÿûϲ±ºÝýÿÿ°€ fÝÿÁŸ°±¨¿Úÿý£€m}⬛­Â²½¸ÇáØt<ŒàŽŸž¶»»¾¿˜Óu”觘—²×Ìé̾ÑwM õ਷ÌÜÒúÈðÍyh´òòÆ®ÉØÖǺîÅ|]¾åàã̺ºÂÖìñÔˆ]~|}Š•›«ºÄñüË„ƒ 0-)Saj•îÿ×¢‰·ë𲊭§‘bœ“‡‡ UíöõïØ×ÜÕÌ‘#€ÿùõÿ}€ ¢ÿúáÙÛÞæûÿÿ€ "ÆÿÙØäáäêãÿÿ|€;×»ÏàçÞðäåäÚJNÞ¦ÔÐÝåçßÞ¨ÕG€M]ê¶ËÈÝùòøÞÆÒH tùàÌåóúüÿÌðÏG‘öñËÐñùóÍ»ç¿H9¤åàâÍÄÆÇØæ¾QDWcel{‹•¡²­¿»|^‚ 0-1KUUmÁÀ„\‰x½¹”Šn˜ªU|˜“‡‡ tïöõïÖÆÛÕÌšL€/•ÿ÷Ùÿ’€K³ÿûóøøïïüÿÿ£ XÑÿñúüöèúëÿþ•jßÔôööîêðííØfiwãÈøëîíåéèÈÔe_ZêÎïåëöåúçÙÐjm^õåæùø÷àÿÖóÎlbe¥ôñ×äøøê×Ìßµtsu¯äßàÒÏÐÑßÞ`&rÿ| „‚ƒœ£«¼žX<8 ¢‘ˆ{……\SAŠP[xЉÚs8mk0N>@3ÖÿÿÿÿÝÇÖ¹ƒV2 ôÿÿÿÿÿÿÿÿÿÿèDÿÿÿÿÿÿÿÿÿÿÿênÿÿÿÿÿÿÿÿÿÿÿç›ÿÿÿÿÿÿÿÿÿÿÿæÄÿÿÿÿÿÿÿÿÿÿÿäåÿÿÿÿÿÿÿÿÿÿÿâ.üÿÿÿÿÿÿÿÿÿÿÿà SÿÿÿÿÿÿÿÿÿÿÿÿÞ ¶ÿÿÿÿÿÿÿÿÿÿÿÿÛZ²ÃÑßêñòÿÿÿÿÿé =TnŠëÿÈ9íÿ]5wICN#þ ÿÿÿÿðÿÿøÿÿøÿÿøÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿÿðÿÿÿðÿÿÿðÿÿø?ÿüþ~> þ ÿÿÿÿðÿÿøÿÿøÿÿøÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿø?ÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿÿðÿÿÿðÿÿÿðÿÿø?ÿüþ~> il32­‚›kv•¬»Àº´¯ž|:UOC‹"{¿…ÿ ýÀ¾ÐÝÖÈ·«‹`F‘ÿ„D‡ã†ÿð×ê‚ÿüáÄ‘fƒT”ñ†ÿç¹Ö…ÿôœKƒc¢ý‚ÿûúöòïÝÕû„ÿþGƒn²ÿ üêÉ®£¢§µÇØîƒÿúšFƒzÀÿ ùÚ¨–œ¢§¥ ¥¸Ëâ‚ÿø˜C‚2‡ÕÿÿûÙŸ˜§®±´¯©¼½Èåÿû—C‚M“åÿÿ檗©³»Á¾¼¥µËÇÇÈ÷ÿÿé¼B‚`žõå˜Ã‘¨¼µÄ«¼·Â»¼ÑÇÜÿÿÕk†D‚o§ÿÅV³Œ›ºÂÒ˜®ÆÂ¡²¿Ô¦³ÿÔrˆ@‚|¯ÿÅw¬œªœµ´Æ¹¤Ë²¯È¨ÛkÿÑs‹<†±ÿÄ{¨›¨ˆ“ºÕµÆ°ÎծݖqÿÍtŒ8@’´ýÄjª‰†«˜ÄÜÊÂÃèæ¸ÔÿÊv7Z˜¿øìºªœ¢¢¢ÑØÞÉ×òóéײòþÆwŽ5nšÖôõﯥ±·®Â××âÈÖöøö¾ÉüüÂz0}˜ßòñõÇ£­ºÅÎ×ÖäÄÌøûã˜êöû¿|3‰™æðïðì­¥¶ÁÌÕÕãËÓô知Ñöù½~)€&”›ë€îð䦢¹ÈÒÓßäçÌ™ÁÅãòî¹€‘'€D£íììíìð赘¢³¿¿´›œÄÓìôä廑 €K™ªéæççèêïõäÄ©š¦²Ñïïìêéîè⤒€U ’š“Œ„‚ƒŠ”¥ÁÖÓàßàäêïÞøÿðèä¡ €"[egoty}~ƒ‚„|xŒŽ‘”›§®ÃýÿðêÜ´ˆ-9HU@6cjqz€ƒ‰—Çÿÿðêݵ“ 3AKÄÿÿðëÛµ–[Ãÿÿðîɪ–N¾ÿÿÙ·Ê—:½âÁ¨™˜k‰ˆi¾$šU%:—¯»Àº´¯ž|5UOC‹3%±…ÿ þÀÇÜÝÖÈ·«ŽQ‡'5ã†ÿñîƒÿüß¹V)ƒ$Lö†ÿâÕ†ÿûaƒ"iƒÿ€ùøñêòú…ÿa‚$!Œÿ ûêÛÒÐÒÕÚÜÜìƒÿþ[ ‚1#¯€ÿ øàÏÎÔÙÛ×ÙááØá‚ÿüV!‚.-ÎÿÿûÞÌÔßãääÚÛæêêÕäÿþR%‚,<çÿÿåÍÓàæêîéèæìñóîÌöÿÿé¿H)‚)Rúé¦ÏÈÖÝêßé׿ôòåæüÝÚÿÿÕn:3ÿ'nÿÎlÍÇÕÐæãíÇÚüïÏÛêô­ÁÿÔt:1?&‹ÿΆÏÓÝÐáÚéäÒüÝÕéÑú…ÿÑt838) ÿ͉ÎÒܼÌÄäúÜöØéðÑø¢‰ÿÍt8541±ýÍz˼ÄÙÉëüëõäùøÔëš–ÿÊt772<Ãøí»ÁÒÓÏÂÐ÷øùüôýþ÷å³ôÿÆt79/MÜôõî¶ÔãáÙêüöúýøüýÿÃÉüüÃt67€?-aåòñõÅ»áçíõüõûýùûýè˜éöûÀt5:€B-wéðïñì­Äçíóúõ€û ýî ¥Ñ÷û¾t5<€<3Žì€îð䦸äôúöýüù×›ÁÅåêØ¼t7;€;<¡íììíìðè´ž¶ÐÜ×áœÄÓížv;=€?G³ìèéèéëïõ䨚¦±Ðïïì⯌w>@€@Lmyzywy}ˆ”¦Ã×Ôâàâåëñ¸¿æ´ŒŒ`7€DDCFLQTZ\^adgmrz}‚ˆ’£§“ÇæµŽx†/=DUU[_WP_bbcb`bf‡Êæ´Ž‹w’ 8HNNP‡Ëæ´ŽŠr–„Êçµ}—Êé™Î˜€¬®ª™˜([‹i¾m]<™ªX]¤´»Àº´¯ž|:UOC‹fP´…ÿ þ½·ÐÝÖÈ·«ŽV…`[ã†ÿíÒë‚ÿüß½jQPƒ]iô†ÿá«×…ÿø|ZƒZƒÿùúýþöÚÕû…ÿ}X‚mX™ÿûïðõ€÷øñæïƒÿüy]‚sW¶€ÿ øëôøùùúôëóùæç‚ÿùv`‚p]Ðÿÿûéôù€ûüòÜêýüâéÿütf‚lgæÿÿêðùûûüýýöÜëÿþû×øÿÿé½mi‚jt÷ðÁâõ÷÷ûñ÷îóæïôòÿçáÿÿÕlbq‚f†ÿݘëòóìöòøâëìêâåò÷ÃÙÿÔrdrc˜ÿÝ©ñøùìòìõòâìââïâú¸´ÿÑsev|c¦ýÜ«ð÷øâçàðüçèáíöâù»¶ÿÍsgzzg±ûÛŸëìäãíâóûðââúúäñµÀÿÊti|xjÁøïÅÜõïéàâùøùßåþýøêÂ÷ÿÆtk|uqÙôôïÉõû÷ëòýöûÜàþüÿÐÒûüÃum}€syâòñôÏ×úúûûüõü×Öýýí­ìöûÀvo€„p…èðïñì¾Þûûúûõüßáþñ´¸Øøþ½wp€p’ë€îðæ¸Ðôüüöüüû߯ÎÑìÞµ¾xsƒ€€r¡íììíìïéÁ³ÉÜäßд¯ÎÚôçC qwƒ€n®ëç€è êïôæÍ¸«·¿×€î×z; R€…€‚z€‡„zz}†’¤ÀÔÑßÞáåëõ~8ŽD \›€ˆˆ„…††ˆˆ…ƒ‚…†‡…‡‹“£ ;>ŽE-…m™—¥¢£¦¢™œ˜•‰‰‡CBD "‘ ªª™ ‚#ED –EEK–E;€Þ— A À­˜ 6ª‡¾l8mk)" ¯þôåÞàâáÔ¹…00@5-þÿÿÿÿÿÿÿÿÿÿ÷ãüÿÿðÑŸh5ZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïåÄ#…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿf±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_lÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿWãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿT-úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿNÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@sÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>Îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3x£¸ÉÖâîöüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw%3BQecFƒ¨¿Ôçõþÿÿÿÿÿÿÿo#7NfÄÿÿÿÿÿo¾ÿÿÿÿþ3 ½ÿÿÿÿ? ¼ÿÿßbc"ich#Hÿøÿÿ~ÿÿÿðÿÿÿÿÀÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿà?ÿÿÿÿàÿÿÿð?ÿøüþþþþ~8ÿøÿÿ~ÿÿÿðÿÿÿÿÀÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿà?ÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿàÿÿÿÿÿà?ÿÿÿÿàÿÿÿð?ÿøüþþþþ~8ih32 ³6iafaYD&’)ðŠÿý±«åÛñîåÕ¸¢{S=–›ŒÿíÕòç„ÿúݼ›†~¥Ì‡T³ŒÿÞºà݈ÿû°…šm‡h‹ËŒÿÙ®ÐÖŠÿêŽ[‡yˆâŒÿéÅÅÏŠÿí‘[†Žˆõ…ÿ øñóïêâãíðäÕò‰ÿç‘Y†4—”„ÿûíä̱ šš¡«¾Ò×Þø‡ÿã‘X†Gœ¥ƒÿ÷æÑ§’–œ £¥¢¡¡©¾ÑÑð†ÿß’U†]˜¼‚ÿöá””ž¢¥¨ª«§£¡«²·ÏÉî…ÿÛ“T†rŽÓÿúàÀ™¢¨¬¯°³²«Ÿ™®»¹ºÏÅõ„ÿ×”R… †‹åÿäÊ’˜£ª°µºº·º·£›¸ÄÂÀÃÌÊ‚ÿüÿØ•O…$š‰÷€ÿóÔ¡”¡©±¸¾ÂÅÀ½À«¥ÀÌÌÊÅξæÿÜ”“—L…<£“ÿÿ×¥ÈÀ˜¢©¸½­·È³°Ä¸¯ÈƸÂÏËËÂÿØshšK…'R¡¦ÿÿ“º©‡•œ˜­Å½ÄΖ’È¸Ϊ—µÖÑÔ³íüÿÿÔxmœG…'hœ¹ÿÿ’FÊ—›¡™¤Ã¼ÉÚ¢Ž¹ËÁŸ¨½©ÃÚ»[‘ÿÿÑzmŸD…'}‘ÌýÿXÆ•œ¤¬ ¥Âº½ÍÁ—©ÍÆ­¢ÂÈŸ¼ÝÅBuÿÿÍzn¢A„(•ˆÕùÿ‘fÁ” ¨®Œ‘¸ŸšÉÔ¯­ÉŦ°ÝÍ¥ÂàÉPyÿÿÊ{n¤?„(/¦…Ù÷ÿd¿•›¢ªˆ|¬˜Í×Í°ÃÆªÊêÑ©ÀàÆNyÿÿÆ}o§>„(D¯‚ß÷ÿŒN¾”†‰‚”šµžÑÛÙ½¿È¸ãí⳯۾ƒ);+kÖðïïððòàš¿Úçëìò÷üô÷ûûýùüú÷Ë|¯°òôô÷°‰X0?‚U7/~Ûðîî€ïóÑ‘¾ÜéïñöûòùûúûúøôÈ|µÉóóöö®ŠV1?‚?67‘ßïíí€îíòÎŽ®Öèñöúòúûúøöè¬|×Ò½Üñê»ç®‹U4@‚A9AžäíëëìíñÚ™Œ³Ôèñóõóîݵ‰ÁÎÏîó󨋥£U8A‚@:M©çëêêëììïîÇ”„ª¨›ˆ{ˆÄðâÒïñô©ŠŽŽTD‚AAY‚‘‘Ž‹•¡®»ÆØèôìÒ÷ôòð€î ííè¸ß뱋{L@‚ ?DJKMQTVVW€XWVW\csŽ­¯¹±²·¾ÈÒÜå븤ÊÝ챋|Qƒ*BDFHKMQUZ\aeinqqpnibbhijmorv€Œ™ªžËÝ챋~sˆ%307A@GJNQUZ``YUcgjkoqqokhffn ËÝ챋‘|j—3FKPUUX\^__^hžËÝ챋‘‘xbŸ<4BDi›ËÝ챌‘u_£ išÌÝ챋‘oQ£ d˜ÌÝ챎„ˆ¯¤_–ÍÝîš{·ë¥[”Ï»‘¿©¡¦[‚|¾£€¨IfpHÿ„ª\U©d^Zeijnswnif_L;œiZMéîòöúú÷ôòíàÅžrAc_faYD&’fVlóŠÿý¯žãÛñîåÕ¸¢{PeQ’ŒÿëÑòç„ÿúÝ»“qKIP3†ÿbM±ŒÿÛ®á݈ÿü«jX[†r_OÍŒÿÔ™ÑÖŠÿña^ÿ…p\YæŒÿã±ÄÏŠÿð__ÿ…o]iø…ÿ øñôøûúúýùæ×õ‰ÿë^`ÿ…nYƒ„ÿüîëñôõö÷÷ö÷÷ðàãú‡ÿå^cÿ…jVžƒÿøèïõö÷ø€ùóðò÷øéØó†ÿá]eÿ„miT»‚ÿ÷åñöøù€ú ùùñéêóûúîÓñ…ÿÜ\f…wgVÖÿûäð÷ùú‚û ùîÜÜïýüûíÐ÷„ÿØ\i…we`èÿçëöùúûû€üûúõÜØñ€ýûâÔ‚ÿüÿØ[j…wfnú€ÿôàôøúûûüü€ý ù÷àÛôÿþþýùÌëÿÜ”’\n…ra†ÿÿèÌÖëõ÷øøüûðòúóï÷èßöúò÷ÿýäÍÿØsg^q…'q\ ÿÿÁ}Íóðôóìôýòñøáß÷íáõéÞæþþõÃóþÿÿÔxj_r„(‡oZºÿÿÁ‘ÝôïôòëíùðóýçÜïðäìâàéæòýË£ÊÿÿÑzkat„(n[ÏýÿÀ™âõ÷úùïí÷ïíûöÞåîæâàçòßéþÔ“¼ÿÿÍ{jcv„(zoaØùþÀžãöøúúåãóæàùþèäëèáàöóàéþÙ–¾ÿÿÊ|iex„(znlÜ÷ýÀœáõõö÷ãØîßßùþñäççàçÿóáèüÖ•ÀÿÿÆ}igx„(xivà÷û¾“ÛòéèáéåñßàúýõëáäßöÿøããøÌ¾ÿÿÂ~ijyƒ)ªxd‚à÷ùÍ“ÎòëêÝßéîæèüüóøßÝæþýþïå÷¼Ââüÿ¿€hkzƒv_—èõôóÝÁìööôôßÛÝìþúôþâÖëÿ€ý ùî«ïüùþ»hm}ƒv_²ñóòôöÄÙöùúùêäëúýøõþâÏéÿ€ý ûÓ°ø÷øý¸‚gp}ƒ)~w`ÁðòñòõÜ»îøúøùúüüýööÿâÊãþüüûñ©×ùööûµ„gr~ƒ~uhË€ð"ññò¼Íôúúùúúûýõ÷ÿâÃÞþüûøÆœïöõöú²†gt€ƒ)}osÔðïïððòä­Øõúúùúûüô÷þâÂÞþúùÖ—ÀÀóôô÷°‡fv‚j|j€Úðîî€ïòاÕôùûúúûòùüññøùöÓ—ÏÅÓóôùø®‰fy‚‚|fßïííîñÕ¤Äê÷úûûñúûûúøì½—ßÛËãöß|Ú±‰f{‚‚d›äíëëìíð߬¤ÈãòõõöõòäÄ™ ÍØÙòùêQK™Žgƒ‚‚e§çëêêëììîíШ¥²¼º°¡– ÍðåØïöëW8ƒj‚†‚ƒ|g¶î€íîïïððòðáɸ °¹ÇßîïìíîðÚ`>4cˆ„‚‚|aƒ‘ŽŒ‹‰‹” ®»ÅØèóêÑöòñï€î ííåQ3x¤>1Œ‚*‚ƒ}yxuqmhda^[XW[bqŒ«­¸°±·¾ÈÒÜåëˆ!=v¤>;qƒ „‡ŠŒŽ‘“–—™€›š–‰|zwqopqruŠ˜«`>v¤>!)ˆ%f…‡Ž”˜›ž £¤¢¡¢£ œ›–‡€zyP =v¤> )—™™šžŸŸžž›™_$?w¤> )žU‡ƒ™–3"?w¥> '£ ##@w¥>£ "#@w¥?P•¤""@w¥2MÃÿ¥"#B^m˽®¦""RÊ·š¨r‘mÿh8mk  fÙáÓÁ§Ÿ£¥¨«¡uM$)ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÀV!U}‘ŠzZ5iÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿÿÿÿÿÿý㹄O žÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÚ½ª˜l ÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ2ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯*ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬Qÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ” Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘(ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿNÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿƒP÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€2s‘©¾ÏÛäî÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ  +7GYk} ¯À©}©éôþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓ(=Rk†¡¹ÍàóûÿÿÿÿÿÿÿÿÿÓ2G‘ÿÿÿÿÿÿÿÿÔ €ÿÿÿÿÿÿÿÿÑÿÿÿÿÿÿÿï}ÿÿÿÿÿÿó(~ÿÿÿÿÿå}ÿÿÿð[PCT#it32\cÿ™ù™!+;bYÓ³—cP?0"Vø¿Ý( h€ŠyiWLDA?@EKLPXh…¾:‘Ô>/Ÿ€¤¡dczˆ–¤«²¹ÀÇÎÑÊÄ¿º´¯©¤Ÿ™“‚kPLU~ Ѐ¤¡bSå™ÿ ò×·fLLMq?†È Ù+c½4¼ d"¤¤£„VLºýžÿ ð¹sLK_Ì  MP‡LZm‰Ãiµ,A¤¤‘LM¯£ÿí˜LPoZt¢ë²ÀÄÈË̽¯¡”†hMLLMbŒòh±]¤¤‚LѦÿÎ`lÏûɈÿ úÞ¿ ‚cMLVv¶­y¤¤sMô§ÿí¥‚öÇŽÿ ùÙ»œNKeP¿§v•¤¤cb¨ÿâ ‚ñÅ“ÿ ûÓ¤wPNf‹ÐW»CSžŸ9 €¤T‚¨ÿÑ•‚ìÁ—ÿûÚ¥rNPf}–¤¤®ÁÞjÉ™&9¤¤L¢¨ÿÁŽæè½›ÿüâ¶pMx£¤¥†˜R¤¤ŽL¨ÿ³¥À㸞ÿ ûuLZvˆ£¤¤‡—k¤¤~Lâ¨ÿ§´«Þ´Ÿÿ ü«_LLNœ¤k%–?„¤¤oRü¨ÿº¤Ù²ü¡ÿþèR“¤n–S¤¥`o©ÿ”ÀŸÔ±ø£ÿN•¤p–2)€¥Q©ÿœÏ±ô¢ÿúL˜¤r–#B¥¦›L¯¨ÿþ‘­¶€Ê¯ï¢ÿôL›¤r–[¦¦ŒLϨÿ÷¤Â¾ €Å®ë¢ÿîL¤o•u§§}Lï«ÿöÓÐÁÀ¬æ¢ÿèL ¤m•™§§m\¢ÿþþ€ýþþƒÿúæÆâ¢ÿâL¢¤j•E¥¨¨]|–ÿþñãààßÞåìòõøøðæÝåî÷øõðêÞÔÒÑÑÐåü ÿÛM¥¥g•,2€¨Oœ•ÿôä€ßæîöñеª¡˜˜™š›œ§°¼ÑðöëÞÒÎÍÐèýžÿÕP¥¥d• K©©šL¼“ÿ%öåßÞßëöæÆ¨””•——™šœœžŸŸ ¡¢¢²ÌæöçÐËÊÏëþœÿÏR¦¦b•e©ª‹LÜ‘ÿýèÞÝÞèõÚ¢‘’”–—˜š›œŸ ¡€¢££¤¥¥¦§±ÛõâËÇÇÑú›ÿÉU§¦`•ªª{OùÿúâÝÜåó᪑”•˜™šœžŸ ¡¢£¤¥—¤¡¤¥§¨€©¹áóÛÆÄÉñšÿÃX§§]”f™««kiÿ,öÞÛÝîç±’•–˜šœžŸ ¡¢£¤¥¦§™§¢¢›¡¥©««¬¬¿èìÈÁÃç™ÿ½Z¨§Z”:!€«Z‰ÿïÛÚÝñÓ’‘”–—š›œžŸ ¡¢£¤¥¦§¨©œª¤¤œ€¡¥¯®€¯×ñÌ¿¾Úþ—ÿ¶]¨¨X”(;¬¬©M§Žÿ0ëÙÙàñÁŽ’”—š›ž ¡£¤¤¥¦¦§¨©ª«Ÿ¬¦¥Ÿ¢£¤¤±²±±²²ÌòÓ¼»Î—ÿ°`©©U”U¬¬šLÅÿ%ðØ×ã𯓕˜šŸ ¢£¤¥§¨©©ªª«¬­«ž®¦¤¢¤¤¥§„´ÃîÛº¹Ø–ÿªcª©S”o­­‰LâŒÿõØÖâ阓–šœŸ¡£¥§¨€©ª¬­®¯ ©°£—™ž¢¦ª¶¶··¶»êÙ·¶ä•ÿ¤fªªP!“ÑŠ­®yPü‹ÿùØÕÜ‘”—š ¢¥§©ª¬­¯¯®¯°±²¦£³¦˜˜™šœ¨¹¸¹¹º¹¹¸¸ÀíÍ´¶î”ÿži«ªM"“O¥®®hj‹ÿýÛÔ×𰌑”˜› £¦©ª¬­®°±²³±³´µ€¶ ¥¨¶¨™šš›œ«½ƒ¼€»Èð²¹ö“ÿ˜l««K"“3*®®¯Wˆ‹ÿ(ãÓÔìÁŒ“—›ž¡¤§©ª¬®°±³´µ¶¶±µ·¹¹º®¯¸ª™››œšµ€À¿¾½¼¼Ñì¹°¾“ÿ‘o¬«H#“$E¯¯©L¥Šÿ)õÒÑèÒ‹Ž“–𡤧©ª­¯±³µ·¸¹º»·´µº½½±¸»¬™œœ™ÀÂÃÀ€¿Û寭á’ÿ‹r¬¬E#“_¯°˜LÊÿÛÐÙé’•™ £§©«®°²µ·¹»¼½€¾¶·¸½À²¿¾®› ¡¡žÃÄ‚ÅÃÀÁéÊ«µý‘ÿ…u­­C&’mz°°ˆLà‰ÿ,ðÎÎ鵋”˜œ £¦¨«®±³¶¸º¼¾¿ÁÁ½¹º¼Á´Ã𣤥¢ÆÆÇ‚È ÆÅÅÄÃÃÏê­©Ø‹ÿïvv€ÿx®­@&’•±±vOûˆÿ-þÕÌÙá“—šž¢¥§ª®±³¶¹¼¾ÀÁÃÄÅÅÆÂ»½¾¿²Çǵ §§¨¦ÈÉÉƒÊ ÈÇÇÆÅÅäͧ¬ùŠÿë€wvvV{®®='’A­±±eh€ÿ€þƒÿêËËꬑ•˜œ ¤§©­°³¶¹¼¾ÁÃÄÆÇ€ÉȽ¿ÀÀ§Éʸ§ª««ªÊËÌÌƒÍ ÊÉÈÇÇÎ뭤͊ÿçxwU~¯®:(’-3±²²S†ÿÿ„þ€ÿÐÉÚØ‹“—šŸ£¦¨«¯²µ¹¼¿¸¥¨©«º€ÌË¿À¿©Éͽ­­®¯­ÌÍ΀ÏÐ ÏÌËÊÉÉàÑ¢¥ü‰ÿãxwT‚¯¯7)’"N²²¨L£ÿÿ€ý5þþ›rssÇÇè§’—œ  ¡¨®´¸»¾Á»¨ª¬®¹Ìý½ž¡¾¯ÉÏÁµ°±³±ÏÐÐÈ‚­ ÅÒÑÍÌËÊÎꤟâ‰ÿßyy€xR…°¯5)’i³³—LÁÿÿ‚ý3\lÅÍ呇Œ–šžš”¦¹¾Áþ«­°²ºÎʵ±‡‰Š¬µÊÐú´µ¶µÐÓÓ«€˜ ™ŸÌÓÔÑÏÍÌÌå¹Â‰ÿÛyxQˆ°°2,‘ "„³³…LÞÿÿüü€ý\€/ Ã×ÉŒ‘ЉŒ–œžšž—–š¥¿ÂÆÆ¼º½¿ÂÑÖ½¬‰‹Œ“»ÌÐÆ¿·¸·ºÒÕËš› ª¸ÖÖÕÒÐÏÎÜÏ›£þˆÿ×zz€yO‹±±/-‘ _Ÿ´´sNùÿþüFý\-ÁÁâ«“ƒ‹Ž–›œ”˜›Ÿ³ÄÇÊÇÅÈÊÍÕÙР‹ŒŽ¬ÎÑÉú¼¸ÀÓׯžž¡¶ÌÙÙØÕÓÑÐÔå›™æˆÿÓ€zyyN±±,.‘ 8#³´µafÿÿýûû€ü1]_ÀÅç‘“}Œ•ž••™ §ÅÈÇ¿ÂÅÇÑÜÝÛ›Ž’˜ÏÔËÆ¾¿¹ÄÕÍ‚Ÿ°¾¾€º»ÕÓÒÑæ®—Ž€…ЄÿÏ€{zzL’²²)/‘)=µµ´P„ÿÿû4üü]¿ÑÎŒ’‡’–™¡£¡ž—š¡¥¿Êij¶¹½ÌßßÔ¹’”•¶ÔÎÇÁºÉÖ± €¡¦¹Ñ¨¡ÖÕÔÔßÇ–ƒ€%«„ÿ Ë||{{zL–³²&0‘ Xµµ§L¡ÿúùúú€û2\ ½×¸Ž“’‘—›ž£§¦§œ›ž¢¥ºÊÅ´·º¾ÈÝÝËÊŸ’”•—ÖÑÉÄÆ¼ÊË¡¡€¢´ÂÞ©£€¢Æ×ÕÕÛՔހ%«„ÿÇ€|{xL™³³$1 s¶¶•L¿ûõú<ûû\¯»Ú¯”˜›¡¤§©­± ›Ÿ£¦¸ËÆ´·»¾ÇÙÍÊÌ”–—™šÂÓÈÇȿ̱££¤¤ª½Öß«¥€¤ ÄÙ×ÖÙÜ’‘+%%«„ÿ Ä}}||wLœ´³!5 ¡¶·ƒLÚöò‚ú0û\¹¹Þ¦•šœŸ¢¥¨ª«±¡›Ÿ¢¦¸ËÅ´·º½ÀÄÊËÎϧ—™›¶ÒÉÉÊÁÄ€¤¥¥¹Çáᬦ¥¥¦ÅÛØ×Ùã7&&¬„ÿÀ€}|vL ´´6 L«··pMïðïù<úú\.¸·á‘–›Ÿ¢¦©«ª¬›Ÿ£¦¸Ëų¶¸«ž¿ËÍÏÑÊš›žÀÈËÌÍ復¦§®ÀÛâ⮨€§ ÆÞÙØØä•A&&¬‚þÿÿ¼€~}uL£µ³7 1+··¸^cñëï‚ù6ú\>¶·ã”’–›ž £¦©¬­­†ƒ‘ ¦·ÊÄ®¡’‹šÁÍÏÐÒÔ­ž¦Ç·ÎÎÏæ§§¨©¼Ì€ã¯© ÇàÛÙØâœ‹J&&¬„þ¸€~}sL§µ±9 %G¸¸µN~ìåñ€ø€ù5\M´ºà“—œž¡£§ª¬¯­†wy{€¢¿¯†‰‹›ÂÎÐÑÔÖÉ  ½¸³ÏÑÒ稩©²Â߀屫«ªªÉáÝÚÙࣉT&&¬€ýþ´€~rL«¶®: b¸¹¥L–æßôø6ùù\S²ºÜ”˜Ÿ¡¤§ª­°±‡wz}¾¯ˆŠ‹ŽÄÏÑÓÕ×Ͳ©É¥²ÏÐÑ骪«ÀÐæ²¬¬«¬ÊäÞÛÚߦ‡X''¬„ý°€~qL¯¶¬< ¯~¹¹’L­àÜ÷€ø4[E°´à’“˜ž ¢¥§ª­°³Žy{}€ž¿°‰‹žÅÐÓÔ×ÙÉÌÊ®¤±ÏÏÐĪª«¶Æâçµ®®­¬ËåßÜÜß›…N''¬„ý­€€pL²·ª@ pš¹º€LÁÚÜ‚÷5øø[5®­Þš”™Ž“•˜›› £™€|~‚£À²ŠŒŽ‘ ÆÑÓÖØÙÆàȤ¥±ÍÎÏÆ«¬­ÃÕ‚èÀ¯¯®®¶ÈÛÞÛ߃D''¬„ü©€nL¶·§B @µººmMÔÕÞö€÷<\&¬«Ø¢”™„„†ˆŠx–™›‰ЍÁ±‹’¢ÇÒÕרÜ×ÝÛ©§¯ÌÍÎʬ­¹Éæéêêëëα±°€¯ ÝÞÝÞ…:''¬„ü¥€€mM¸¸¤D -4ºº»Z^ÖÐã‚öL÷÷\¦©Òª“š‡„‡‰‹wvŽšœŸ•œ¯Â­‹Ž’§ÉÔÖØÞäÉÙÞ§®ËÌÍÍ®°ÇØêêëëììè¶²²±°²àßÞ×€2((¬üƒû¢€‚lP¹¸¡F "P»»µMtÐÊé„ö4\–§Ë²“š‹…‡‰ŒŽ{tw†›Ÿ¬´¾ÃŒ’”«ÌÕÛáàÜ¿Ýßß­®ÉËÌͱ½Ìéìì‚íÔ´³²²¹áàÞÌ~|*((¬üƒûž€‚jS¹¹ŸH m»»£LˆËÅð‚õ3öö\‡¦Ä»“™‘…ˆŠuxzƒ¢®¹ÅÁ­¦£¢¨¿ÖÜÜÚÚÜÀÞàáÉ­ÉÉË̶ÉÜ€íîî€ïîÑ»´³ÆâáÞÀ}u—¬7¬üƒû›€ƒ‚hWººœJŽ Òˆ¼¼L›ÆÃƒõ7ööÈqnޤ´Ð“˜›‘“•—š“‹Ž™œžƒŒš¡§­²±´ÂÖÖØÙÛÛÁßàâã¼ÇÈÉËÁÎëíîïïðïíÙËÅÚãâܦ{žÿþúÞûƒú˜€ƒ‚gZºº™PŽ V¥¼½}L«¿Èƒô€õ3°­ª¢£× –›œž¡£¢Ÿ¢¬¯‚…ˆŠŒ’”«¿ÔרÚÛÙÄàáããÏÅÇÈÉÆØîïïð„ñðçÞääâÙ†yÆûùùüûƒú•€„ƒe]»»–SŽ 8#»½½iLººÏƒô‚õ2ó¦ŸÆµ–¡¦¨ª­¯±´¶¸«ƒ†ˆ‹’Ÿ´ÍÕØÙÛÜÖÈàââäØÃÆÇÈÊßîððñòó òñððìåäßÇwxëø„ù‘„ca»»”VŽ )>½½¾V]ÜÙçƒóƒô1½²Ê•›¡¦©«­°±³¶¸¢ƒ†‰‹Ž ²¼ÓÕ×ÙÚÜÓÌàâãäßÀÄÆÇÈßððòóóô óóòñêæåÛ¨u‘‚ø„ùŽ€…„bd¼¼YŽ Z½¾´LtÙÖìƒóƒô0×›ŸÕ™Ÿ¦©«®°±´¶¸°˜”ž§±ºÏÔÖØÚÛÜÐÑáâãåå¾ÂÄÅÅßðòòôƒõ ôóñéçå׈s¹‚÷„ø‹…`h½¼Ž\ ‹w¾¾¡LŠÖÓðƒòƒó1õ—ž£¨«®°²´¶¹»®¦¨ª¬³¼ÏÑÓÖØÙÛÜÌÔáâãåæ¾ÀÂÃÃàñòôõõ÷ öõôíèçßÈrqâ‚÷„øˆ€†…^k½½‹` „“¾¿L ÔÔ„ò„ó1¶—¤Ðž›¡¨«®°³´·¹»¾À¿¿ÇÊÍÏÑÔÖØÙÛÝÈ×áâäåçÀ¿ÀÂÁÞðóôõö÷€ø ÷öóêéçÕ”p‡ƒöƒ÷õ€‡††]o¾½ˆd G°¿¿zLµÑ׆ò‚ó0ä–”¾ºšŸ¥«®°³´·¹»¾ÀÃÅÈÊÍÏÒÔÖÙÚÛÝÅÚáâäåçÁ½¾ÀÁØðôõö÷ù øöîëéÞ¿pnσöƒ÷ò‡†[r¾¾…l 3+¿¿ÀfLÈÎÜ„ñ…ò<¹’›Î¢›¤©®°²µ¶¹¼¾ÀÃÅÈÊÍÏÒÔÖØÚÛÝÃÝáâäåçÄ»½¾ÀÓðóõöøùûûúùõìêçÒˆm‡ö€÷‡‡Yv¿¾‚q %HÀÀ¿RZÎËâ„ñ…ò<é”´¾› ¦­°²µ¶¹¼¾ÀÃÅÈÊÍÏÒÔÖØÚÛÝÁßáâäåçÆ¹º¼½Ðïóõöøùûûú÷îëêÛ´klÙ„õƒöꂈWy¿¿w eÀÀ²LqÌÈç„ð†ñ:¿Ž“Ë©ž£©¯²´·¸»½ÀÃÅÇÊÌÏÑÔÖØÙÛÜÁßáâäåçȶ¸¹»ÌîóõöøøúúùðíëåÍ|i‹…õƒö版U}À¿|} ÁÁžL‡ÉÅî„ð†ñ;ì•‹¡É¥ ¦¬²´·¹»½ÀÂÅÇÉÌÏÑÔÖ×ÙÛÙÄßàâãåæÊ´µ·¸Èíòôõ÷÷øøñìëçЙhi—Ä„ôƒõらS€ÀÀy„Œ cžÁŠLœÆÉ…ï‡ð;ÓŠ‰ªÄ¢¡©®´¶¹º¼¿ÂÄÇÉËÎÐÓÖרÚÕÅßàâãåæÍ²³´¶Ãëòóôõö÷ñìëèÒ©gf™²¼ƒôƒõàŠ‰Q„ÁÀw‹Œ >ºÂÂvL°ÃÏ…ïˆð;¼‡†´¾¢£ª°¶¸»¼¿ÂÄÆÉËÎÐÓÕרÚÒÉÞßáâäåЮ°±³ÁíñòóóôïêêéÖµjeŠÉÅ­¸‚óƒôÜ‚ŠO‡ÁÁt™Œ ,5ÂÂÃbOÀÀÕ‡ï‡ð,©„‡»·£¥ª±·º¼¾ÁÄÆÈÊÎÐÒÕרÚÏÌÞßáâãåÒ«±ÍÀ»îðñòòê€è Ú¾nd|ÍÌɸ}¤‚óƒôÙ‹ŠM‹ÂÁqŒ #QÂÃÁOaÀ½Ü…î‰ï+옂†¿¹¦§«±¹¼¾ÁÃÅÇÊÍÏÒÔÖ×ÙËÏÝÞàáãä×±Úéëèíîðîç€æ ×ÅxbpÍÔм€ð‚òƒóÕ‹‰LÂÂn­‹ $nÃðLv½ºå…î‰ï)ðä‹…¶¾©©¬³¸½ÀÂÅÇÊÌÎÑÓÕרÆÒÜÞßáâäâÞçééëìíé€ä ãиraeÈßØÃ‚¡ðƒòƒóÒŒ‡L“ÃÂkº‹ ŒÃÄ›L‰º¸ì…í‰î:ïï܉}~©Á­ª¬±·½ÁÃÆÉËÍÐÒÔÖØÃÔÛÝÞàáããåæçèéçáàáâÞʪhahÙÿÿ䆕íëð‚ñƒò΀Œ†L—ÃÃgÉ‹ O©ÄćL›·¾†í‰î€ï8å–zzšÁ³¬®°µºÁÅÇÊÌÏÑÔÖ׿×ÛÜÝßàâãäåæãÞÝÞßßÖÄ™b_xçÿÿ䈜ÏÍßÛî‚ñäç€òË…L›ÄÃdÚ‹ 5#ÂÄÅrL­µÆ†ì‰íîBë¦xw‹¾¾³¯±´¸½ÂÆÊÍÐÓÕÖ¼ÙÛÛÝÞààáßÜÚÚÛÜÜ×ɾƒ_^‹õÿÿ加âàÑÌÏÐóùúòàÜÜåòòÈ€Ž‚LŸÄÄaï‹ '>ÄÅÆ]Tµ²Ï†ì‰íƒî@ºwtv•º»³²µ·¹¾ÁÇÊÍÏÒÁØØ×ØØ××ÕÕ×רÙÖɼ’d]]”ýÿÿå‹§ðéäàÒäþÿÿøÞÚßÛÚäñÅŽL¢ÅÄ_‹ [ÅÆÁMg²¯×†ë‰ì„í?Ñrquš¼º·¶¸»½¿ÁÃÇÉËÍÌÎÎÏÑÒÓÔÕÕÑɾ™g\\h²ªÑÿå©ýõòéåùþÿÿûÞØÞèæÚØã€ŽL§ÅÅ['Š ayÅÆ®Lx¯¬â†ë‰ì…íìÀnnq•·¾¼»»½¿ÂÄÆÈÊÊÌÍ΀ÐÌÆ¿¸c\[e­êîқƧìóìîòö€ÿûÝÖÝ€èæØÖÌ}LªÆÅX MŠ n–ÆÇ™L‰¬¬êˆë‹ìƒíé³ukjjwª»¼¼¾¿ÁÀŠÄÃÂÀ¼¬Žp\[Z` åîÍŒ©íîïêÚí€ÿûÛÔÛ‚èæ×Ô¸{L¯ÆÆU Š D­ÇÇ„L˜©´‡ê‰ë‰ì诂hggfhŠ’›¤­µ®¤›‘ˆ|`\[ZZe¢æ„í ÞìííîîàëÿÿûÙÒÚ„è åÕÒ·yL³ÇÆR Ê 4 ÁÇÈnM¦¦¾‡ê‰ëŠìííݳ‰gdcbba``_^^]\\€[y§ÔìŠí€îùÿú×Ðâ†è åÓж‘wL·ÈÇN 6Š *1ÇÈÈYZ¦£È‡é‰êŠë‚ìèµ¥—‰ze^]\gtƒ‘Ÿ¯åëŠì€íÿúÖÎáÿÿ†è åÑεuL»ÈÇK Њ %FÇÈÀLj¤¡Ô‡é‰êŠëˆì ÏÚêˆëŠì€í½ÎÌßÿ†è åÐ̨M¿ÉÈH ߊ &\ÈÉ«Ly¡žà‡è‰éŠêˆë•Ùƒê‰ë‡ìéÉÊÞƒÿ†è åÎʘÄÉÈE 3Š((nÈÉ–Lt‘–—”‘Ž‹ˆ…‚{xvvuutwy|~ƒ†Œ›¨µÂÏÝéêˆëŒãŠêŠëìéÍÈÝ…ÿ†èåÌÈÈÊÉA Š/`ÉÊ€‚L NTX]adgikl€mjfgs€°Ëæ…ê‡éŠêŠëìÚǡÿ†èåÌÇÈÉ>‹`7ÇÊ¿±§“‰uj`UM„L NPRTVY[]_ace‰fg|–²Õ€êç‰èŠéŠêëèÊÅÛ‡ÿ†èäÊÅÇ<Œ#]ÅËÌÌÍÎÎÏÏÐÐÑÐÆ¼±§œ‘†|pfZO„L MOQSVXZ\^`bd‚fxžÅÙÞĬ¤Ÿ™’‘–™ ¥­¶¿ÉÒÛæ„êëëçÉÃÚ‡ÿ†èäÉà Œ&&&Ijwƒ‘žª·ÄÑÒÒÓÓÔÔÕÕÖÖ×רØÑÅ»¯¥™Ž‚wk`T…L NQSUWY[e~j‹Ž‘’œª¹ÇÕäé€êæÇÁØþ†ÿ†èäÇÁ…ŽO0# ‚!"$072.+(€)ƒ*+-4<3*Gau‰°Ã×ââ€á€àÝÓÆ¹­ ”ˆ{ocWMLLV§¹Óþ†ÿ†èäÀ¹$´ ª6É™uaSHHª3]-‚+ *3G[oƒ–ª¾ÑßÞÞÝÝÜÜÛÙÍÁ´ª³·Ñþ†ÿ†èã¾·ªÃ­Í‡dOB70+€*€).AUh|£¶ÉÚÜÛÛÚÚÙÖ»µÐþ†ÿ†èã½µÌ ìÿ—jUD93*'((€' *;Nauˆ›®À¸³Îþ†ÿ†èã¼³UÓA«uVE:1*€&€%1œ±Íþ†ÿ†è㺱ªÜ ØÈzZG:Fž¯Ëþ†ÿ†è㸯ã<Ò®Êþ†ÿ†è㸮 ªâ$ϬÉþ†ÿ†è㶬ãrΪÇþ†ÿ†è㵪UâY˨Æþ†ÿ†è㳨3ã?ʦÄþ†ÿ…èⱦ2ä“ǤÃý†ÿƒè⯤ÊÔåxÆ¢Áý†ÿèâ­¢§þçæ]Ä ¿ý†ÿèèᬠ£¢î†ç¸Âž¾ý†ÿ᪞¦¬¥Óè›Àœ¼ý„ÿö¬œ«´­¦Èë龚»ý‚ÿ õªš­Æ¸±«µ[êᾘ¹ý€ÿ õ¨˜®ÍÇÁ±¦©‘ëÒ»—¸ýÿõ§—³ÔÏÊĬ‘Úí´¹•¶ò¥•´áØÒ̧Åï ·“–“Ž¥¶»~qñªñµ‘æÚ“pf~²ô¿µÿÿÿÿÿÿÿüÿfù»R=459=BGO^xªÀÓ³—cP?0"Vø¿Ý t3*(&),6:>ADGILPXh…¾:‘Ôµ2$€#$Aczˆ–¤«²¹ÀÇÎÑÊÄ¿º´¯©¤Ÿ™“‚kPLU~ Ï>(€#$BSå™ÿ ò×·fLLMq?†È Ù+c½4¼4€#2GLºýžÿ ð¹sLKdBU˜kN‡LZm‰Ãiµz0##,LM¯£ÿí˜LJ6AÃ÷¿¸ÀÄÈË̽¯¡”†hMLLMbŒòh±N-##3LѦÿÎ`}åÿêˆÿ úÞ¿ ‚cMLVv¶­:)##:Mô§ÿíÅ‚ÿêŽÿ ùÙ»œNKa›P¿§P7%##Ab¨ÿâÀ‚ÿê“ÿ ûÓ¤wPIGHIK\x°+Ÿœ5€#H‚¨ÿѱ‚ÿê—ÿûÚ¥rNJ@5*##$(.Kj™g3##&L¢¨ÿÁ£þÿê›ÿüâ¶pL7‚#"ð˜N/##-L¨ÿ³œìÿêžÿ ûuLF90$##4˜>+##4Lâ¨ÿ§¡ÚÿêŸÿ ü«_LLK'#+i–o7(##\¢ÿþþ€ýþþ…ÿùô¢ÿâL$#,E•³9€$D|–ÿþñãààßÞåìòõøøôïêîóøøõðêÞÔÒ€Ñåü ÿÛL##,F•r6$$%Kœ•ÿôä€ßæîöôãÕÏËÆÇÉÉÊËÌÑÖÛåôöëÞÒÎÍÐèýžÿÕJ##-G•T3$$*L¼“ÿ%öåßÞßëöîÝÍÃÄÅÇÈÊÌÎÎÍÎÎÍÎÏÐÐ×ãïöçÐËÊÏëþœÿÏI$#.H•C/$$2LÜ‘ÿýèÞÝÞèõçÊÂÂÅÈËÍÏÐÑÒÓÔÕÕ€ÖÕÔÒ€ÓÙëõâËÇÇÑú›ÿÉH$$/K”E:+%%9Oùÿ*úâÝÜåóëÎÀÂÇÊÍÎÏÑÒÓÔÕÖÖרÙË×ÒÕÙÙ×ÕÖÖÝíóÛÆÄÉñšÿÃG$$/L” ;(%%?iÿ,öÞÛÝîîÑ¿ÁÇÊÌÎÏÐÑÓÓÕÖÖØÙÙÚÛÌÚÑÒÙÞÞÝÚØØÙàðìÈÁÃç™ÿ½F$$0M”“:€%F‰ÿ/ïÛÚÝñãÁÀÄÉÍÎÐÒÓÔÕÕÖÖØÙÙÚÛÜÜÎÜÓÔÜààáßßÜÚÛÚêñÌ¿¾Úþ—ÿ¶E$$1N”g7%%&L§ŽÿëÙÙàòÙ¾ÂÉÌÏÒÓÔÕרÙÚÚÜÚÚÛÜ€ÝÑÞÕÖ߀â àããáÞÝÝæóÓ¼»Î—ÿ°C$$1Q”N3%%-LÅÿ2ðØ×ãòϾÄËÏÒÔÖØÙÚÚÛÜÝÞßàßÞÝÝÞÛÎÞÕ×ãäååâåææäáßßäòÛº¹Ø–ÿªB$$2S”?.%%3LâŒÿõØÖâîþÇÍÑÓÕ×ÙÛÝÞ€àßààáàáßÜÜÕÈÛÉÌáãåæäç€è æäááâðÙ·¶ä•ÿ¤A%%2T“<*%&;Pü‹ÿ(ùØÕÜïȾÉÎÑÔÖÙÚÜßàáãäåäàááããäãÞÑÎÞËÐâããäáèê éçãâäñÍ´¶î”ÿž@%%4U“Ë='&&Aj‹ÿ$ýÛÔ×ðϾÉÏÒÔ×ÙÛÞàáâãäããååâäåææççÒÓàÌÓä€åáçèëìèääçñ²¹ö“ÿ˜?%%4Y“:€&Hˆ‹ÿ-ãÓÔìØ¼ÆÍÑÔ×ÙÜÞàááâããäææçæßãèééêÝÚâÏ׿ççååèééìí€îèææêì¹°¾“ÿ‘>%%5Z“\6&&(L¥Šÿ)õÒÑèá½ÄÌÑÔ×ÙÜÞßàâääåæèéêêëåßáèììàæäÐÛèèéãêë íïððîêèèí寭á’ÿ‹=%%5\“H2&&/LÊÿ)ÛÐÙí¾ÀËÐÓÖÙÜÞÞáãåäæèéêìííîíáâãëïâîêÒßêëëãì‚í îðòòðêéêïÊ«µý‘ÿ…<%%6^’‘=/&&6Là‰ÿ,ðÎÎéѾÈÎÒÕØÛÝÞáãäåæéêìíîîïððéãååîãòðÔãìííâîïï‚ð òôôñëëìê­©Ø‹ÿïvv€ÿ;&%7`’?>*&&€'Ch€ÿ€þƒÿ+êËËêÌ¿ÈÎÒÖÙÜÞßâäåçêìííîïððññòñçèéêÐõöæîððñâò€óƒô ÷÷õïîî뭤͊ÿçxwU9&&8d’o:€'I†ÿÿ„þ€ÿ,ÐÉÚâ¼ÄÊÐÔØÛÝÞáãäæéìíæÕÖ××ãñòóóèêëèÑó÷íñòóóâôõ†ö ùùóððîÑ¢¥ü‰ÿãxwT8&&9f’T6''+L£ÿÿ€ýþþ«€‰ ”ÇÇèÊ¿ÈÈÊÒÕ€Ø#ÝáæèëìíçÖ×רàïèäåÍÍÐæ×ñ÷ðõóôõâõ÷÷ðÚÚ€Û îøùûùòñðꤟâ‰ÿßyy€xR6&&:j’C3''1LÁÿÿ‚ýDv??@€ÅÍè½ÄÇÂÇÐÔ×ÒÔÔËÙéìíîçÖרÙÞîíÛÚº¼½ØÝòøñ÷öö÷ãöøùÙÉÉÊÊÏóùúüü÷óòì¹Â‰ÿÛyxQ5&&:l‘ Å?.''8LÞÿÿüü€ý2v?@@¨Ã×Ú½ÇÁÃÇÐÕ×ÒÖÎÌÏÙíîîíâßßàâïõßÔ¼½¾Ããó÷óø÷øøä÷ûòËÌÔÝûüüýúõôïÏ›£þˆÿ×zz€yO5&&;o‘ ë?*''>Nùÿþü4ýv?@NÁÁâËÀɼÅÈÐÖÖÓÓÊÍÑÓâîïðêæçèèñõî̽¿ÀÁ×õ÷õúùúøåøýÜÍ€ÎÐÛñþýööòå›™æˆÿÓ€zyyN4'&€'Efÿÿýûû€ü9v@@uÀÅè¿ÄÉ·ÇÉÎ×ÖÔËÌÎÒÔ×îðìãäåæíõööÊ¿ÀÂÄÈöøöûûüøçùõÏÎÎÏÏ×âç€äæÿúøöë®—™€œÙ„ÿÏ€{zzL3''=u‘c:'((K„ÿÿû;üüv@@™¿ÑÛ½ÆÆ¾ËÎÐÙÙ×ÑÌÏÓÕÖèðêÙÚÛÛæõ÷ôãÁÂÄÅÆßùøýýþ÷éùÝÎÎÏÏÑÜôÔÏüüùùïÇ–‰€M»„ÿ Ë||{{zL2''=x‘ M6((-L¡ÿúùúú€û1v@@§½×ѾÉÇÆÏÓÕÙÜÚÙÐÐÓÕÖäñêÙÛÛÜáñöòòÍÄÅÆÈÍûùþÿÿ÷éïÎÏØãÿÔÏéýùùòÕ”€N»„ÿÇ€|{xL0''>{ A2((3L¿ûõú ûûv@@²»ÚÍÀÊÎÐÔØÛÝßàâÕÐÓÖ×âñëÚÛÜÝâ€ñôêÆÆÈÊËçú€ÿöéÚÏÒÜõþÔÏ åþøøôÜ’‘RNN»„ÿ Ä}}||wL/''?~ ˆ@.((:LÚöò‚ú+ûv@C¹¹ÞÉÂËÏÑÔÙÛÞÞÙâÕÑÔÖ×âòëÛÜÝÞàéñóôöÔÈÊËÍÝú€ÿõã‚ÏÙåþþÔÏ äþøøõãXNN»„ÿÀ€}|vL.''@ƒ ¸@*((@Mïðïù,úúv@N¸·áÅÄËÏÒÔÙÜÞßÙÚÐÐÔרâòìÛÝÜÓÊèóôõ÷òËËÍÎâô€ÿõÕÏÓÜ÷þþÔÏ äþùø÷ä•^OO»‚þÿÿ¼€~}uL.''@‡x>€(Fcñëï‚ù+úv@[¶·ãÁÅÌÐÒÕØÜßàÜÙ¹¸ÆÔØãóìÙÎþÈèôõ÷øúØÍÎÒæê€ÿõ‚ÏÚç€þÔÏ äþú÷÷䜋dOO»„þ¸€~}sL-()@Š Z:(()K~ìåñ€ø€ù*v@f´ºá¾ÇÍÑÓÕ×ÜßàáÚº­®°µÎéܺ¼½¿Éêô÷øúûïÏÎÞÛç€ÿôÏÔÝù€þÔ€Ï Ðäþú÷÷壉jOO»€ýþ´€~rL,()@Ž H6((/L–æßôø,ùùvAk²ºß¾ÇÍÑÔÖ×Ûààáຮ¯±³ÈçÛº½¾ÀÊëö÷úûüòÚÓåÏå€ÿôÏÛéþÔ€Ï Ðäþú÷÷榇kOO»„ý°€~qL+(*A’@1))5L­àÜ÷€ø*vA`°´àÀÆÍÒÔÖØÚßàâä®°²´Éèܼ½ÀÁÌì÷ùúüþíïäÔÎä€ÿö€ÏÔÝúþÕÏ ãþú÷÷ã›…fPP¼„ý­€€pL*(*A˜ A.));LÁÚÜ‚÷,øøvAT®­ÞÃÆÍÆÇÉËÎÐÐÕ×ζ°³¶Íéݽ¿ÀÃÌíøùûýþéøèÎÏâ€ÿøÐÏÏÛê‚þÜÏ Õåõöõàƒ`PP¼„ü©€nL)(+Aœ ™A*))BMÔÕÞö€÷*vAI¬«ØÇÅν½¾ÀÃÄ®ÆÌÏн´»ÑêݽÀÁÄÎîøúüþþïùûÑÏà€ÿüÑÏÕÞú‚þçÏÏÐ ôöôÞ…ZPP¼„ü¥€€mL((+A¡k=€)H^ÖÐã‚ö,÷÷vAA§©ÒÉÄÎÀ½¿ÁÃÅ®¬ÃÏÒÔÊÉ×êÚ¾ÀÂÄÒïúûýýþçùýäÏ߀ÿþÖÐÜìƒýûÒÐ Òööñ×€VQQ¼üƒû¢€‚lK)(,B¦ R:))+LtÐÊé„ö*vAA›§ËÌÃνÀÁÄÆ²ª­¼ÏÔÝãêíÍ¿ÁÃÅÔòúýýþýàüýüÒÝÿÚÖßû„ýçÐ ÖööîÌ~}RQQ¼üƒûž€‚jJ))-B« D5))1LˆËÅð‚õ#öövAA¦ÄÏÁÍǾÀÂÄÆµ«®¯¶ÒÞèóïÝÖÓÑÕäùýþ€ýà€ýçÛÿÞÜî†ýâÓÐÐßõõêÀ}yª¼]¼üƒû›€ƒ‚hI)).B´Ž èB1))7L›ÆÃƒõ"ööÐ|z“¤´ÖÂÊÏÆÈÊÌÎĺ¼ÄÆÉ·¿ÎÔÙÝàÞàçúü€ýüàýãÿæßü†ýûçÛØíõõâ¦{žÿþûäûƒú˜€ƒ‚gH)).BºŽ ÏB-)*=L«¿Èƒô€õ°­ª¢£×ÆÇÑÎÏÑÓÕÒÈÊÍÖÙ·¹»½¿ÁÃÅÕæúü€ýùãýóÿìæ‰ý õíôõóÚ†yÆûùùüûƒú•€„ƒeG))/BÀŽ ƒA)**CLººÏƒô‚õó¦ŸÆÍÄÐÕÙÛÝßàÜßàâ×·¹»½ÀÁÄÌÚóûýöæýùþ€ÿñêŠýúôôêÇwxëø„ù‘„cF))/CÇŽ`=€*I]ÜÙçƒóƒô½²ÓÄÍÔÙÛÝßáÞÞáãзº¼½ÀÂÍØâùûýòêýúü€ÿóéŠý÷ôôá¨u‘‚ø„ùŽ€…„bE))0CÏŽ L9**-LtÙÖìƒóƒô×›ŸÕÆÈÒÙÛÝàâáÞáãÜÇÀ¿ÄËÑ×áöúûýïî‚üù€ÿôè‰ýüôôó؈s¹‚÷„ø‹…`D*)1CÚ çB5**3LŠÖÓðƒòƒóÃÌÅÏÖÜÝßáãßàâå×ÏÐÒÔÚäõ÷ù‚üêñ‚üø€ÿöçüˆý÷óóèÈrqâ‚÷„øˆ€†…^C**1Cã 3C1**9L ÔÔ„ò„ó¶—¤ÒÆÈÕÚÞßáäâáâåçéèçïñôöøù‚üæô‚üø€ÿúçû‡üûóóò×”p‡ƒöƒ÷õ€‡††]B**3Cí ¨C,**?LµÑ׆ò‚óä–”¾ÍÇÏØÞàáäåáãåçéëíðñóöøú‚üã÷‚üø€ÿýçú‡üöóóä¿pnσöƒ÷ò‡†[A**3C÷tA€*ELÈÎÜ„ñ…ò¹’›ÏÈÊÕÜàâãæäãåçéëíðñóõøúûüáú‚üøÿéù†üúòòïÒˆm‡ö€÷‡‡Y@**4D X<**+JZÎËâ„ñ…òé”´ÌÈÎØßâãåçãåçéëíðñóõøú‚ü߃üøÿëø…üûóòòß´klÙ„õƒöꂈW?**4D G8*+/LqÌÈç„ð†ñ¿Ž“ËÊÊÒÛáãåççåæéëíïñóõ÷úû€üû߃üøÿí÷„üûôòòëÍ|i‹…õƒö版U>**5D"Œ [C5++5L‡ÉÅî„ð†ñì•‹¡ÌÊÌÕÝãåçéçæéëíïñóõ÷ùû€üùâƒûøÿïö„ü õññîÑ™hi—Ä„ôƒõらS=**5D2Œ ãD0++;LœÆÉ…ï‡ðÓŠ‰ªËÌÍØßåçéêèèëìîñóõöùûöäƒû÷ÿñöƒü öññïÔ©gf™²¼ƒôƒõàŠ‰Q<++6DCŒ D,++AL°ÃÏ…ïˆð¼‡†´ÊÍÐÚáæèêìéêìîñòôöùú€ûóçƒû÷ÿ÷ø‚ûõ€ñ ÙµjeŠÉÅ­¸‚óƒôÜ‚ŠO;++7EVŒ gA++-GOÀÀÕ‡ï‡ð©„‡»ÊÏÐØáçêìíëìíðòôöøú€ûïëƒû÷ÿû÷øö‚ûó€ð Þ¾nd|ÍÌɸ}¤‚óƒôÙ‹ŠM:++8ElŒ P<+-/KaÀ½Ü…î‰ï옂†¿ÉÐÒØâèëíïííðñóõøù€ûìïƒû÷ùøûûú€ûùñ€ð ÛÅxbpÍÔм€ð‚òƒóÕ‹‰L:++8E‹‹ ‘D8-/5Lv½ºå…î‰ïðä‹…¶ÈÐÓØâèíïððïñòõ÷ùúûûèòƒûúùƒûö€ð îÓ¸raeÈßØÃ‚¡ðƒòƒóÒŒ‡L:-+9E§‹ lD5/0;L‰º¸ì…í‰îïï܉}~©ÅÏÔÖÝåìðòóòòôöøùûûäô‰û÷ð€ïê̪hahÙÿÿ䆕íëð‚ñƒò΀Œ†L:.-9EÉ‹ ·D202@L›·¾†í‰î€ïå–zzšÂÌÔ×Ûáéðóõõôõ÷ùûûâ÷‡û÷ðïßÅ™b_xçÿÿ䈜ÏÍßÛîñí±Â€òË…L;0.;Eð‹ zC024EL­µÆ†ì‰íîë¦xw‹¾ÅÑÙÛÝãéïô÷€øúûßúƒûú÷óïîåξƒ_^‹õÿÿ加âàÑÌÏÐóùú줕•½òòÈ€Ž‚L;20FW‹ J>458Lg²¯×†ë‰ì„íÑrquš¼ÉÓÞàâãæçêíïññðð„î"íáÒ¾™g\\h²ªÑÿå©ýõòéåùþÿÿõ¤’‘’’ºÂ€ŽL<53?FœŠ 0D<57=Lx¯¬â†ë‰ì…íìÀnnq•·¿ÈÔßåæèêë…íêÝÏÁ¸c\[e­êîқƧìóìîòö€ÿõ£‘‘‘‘¤}L=65@FŒ D:78AL‰¬¬êˆë‹ìƒí é³ukjjwª»ÄÉÎÓØÞãßÚÖÑÌǼ¬Žp\[Z` åîÍŒ©íîïêÚí€ÿô¡ƒ€ {L>86AFrŠ žE98:EL˜©´‡ê‰ë‰ì诂hggfhŠ’›¤­µ®¤›‘ˆ|`\[ZZe¢æ„í Þìííîîàëÿÿô Ž… ŽŽyL>:8AFŠ zE8:CLy¡žà‡è‰éŠêˆë•Ùƒê‰ë‡ì ⑈£ÕÜãéïö† ‰ˆpB@>EGÌŠ([A>@FLt‘–—”‘Ž‹ˆ…‚{xvvuutwy|~ƒ†Œ›¨µÂÏÝéêˆëŒãŠêŠë ì㓆žÉÏÖÜãéïö†‡†kA?EGŠkB?AH‚L NTX]adgikl€mjfgs€°Ëæ…ê‡éŠêŠë ì»…‰¼ÃÉÏÖÜãéïö††…kAFF‹ ÛDACEGIKKLMN€M…L NPRTVY[]_ace‰fg|–²Õ€êç‰èŠéŠêë⑃—¼ÃÉÐÖÝãêð÷†…ƒjFG‹UQEDFHIKMOPRTUW‚YXWVUSQOM„L MOQSVXZ\^`bd‚fxžÅÙÞĬ¤Ÿ™’‘–™ ¥­¶¿ÉÒÛæ„êëëá’‚–¼ÃÉÐÖÝãêð÷†„‚kGŒ&ªYFFHIJLNPRTWYZ\^_abdeghjkmljigdb_\YVRO…L NQSUWY[e~j‹Ž‘’œª¹ÇÕäé€ê à€”»ÃÉÐÖÝãêð÷†Ž‚€j±lPGGH(IIJMNPSUX[^adhknpqrtuvwxz{|}}yvrojgc^ZVQM€LSLLMRX_ekqw~„Љ‘š©·ÆÔÙ”»ÃÉÐÖÝãêð÷†ŽË …¼•}k`WRKJ€KL'MMNQTWZ^aeimquz~€‚ƒ„„……††‡‡ƒyppkf`[VQMƒL QX^djpw}ƒ‰„‘ •„}’»ÃÉÐÖÝãêð÷†Ž€}Èš ¼›'潟Œ|nd\U‚O€P€Q#RW[^bgkosx|zhXUUVc{ŠŠ‰‰ˆƒ~ysnid^ZUPM‚LQW]cipv|~|‘»ÃÉÐÖÝãêð÷†Ž|Ŧ ™–-êÁ¥€ri`XRS‚T!UZhxfT]ekpv{†ˆˆ‡†…„„ƒ€|vqmhc_ZVSO€L Psz»ÃÉÐÖÝãêð÷†Ž}zÀ³ w{“/íÅ©”‘UfºZƒU%W]bhlrw{‚€}|{yxwusojfduy»ÃÉÐÖÝãêð÷†Ž|y¾Ã f¡ÈŸ…qbWTT€SRSY^bfknruwwutrqonuwŽ»ÃÉÐÖÝãêð÷†Ž{wºUË ìø0Ùª‹tfYP€QPPQTX[_bdgjtv»ÃÉÐÖÝãêð÷†Žzv¸Ô ”`ó³xfZPNMPnt‹»ÃÉÐÖÝãêð÷†Žyt³UÜå¢Ö|kos‹»ÃÉÐÖÝãêð÷†xs±ã Uˆq‰»ÃÉÐÖÝãêð÷†vq®Uâ Hˆpˆ»ÃÉÐÖÝãêð÷†up«ã r„n‡»ÃÉÐÖÝãêð÷†tn§Uâ fƒm†»ÃÉÐÖÝãêð÷†smÆã Lk„»ÃÉÐÖÝãêð÷…qkÅä †€j„¼ÄÊÐ×Ýäêð÷ƒpj¡æ k~h‚¼ÄÊÐ×Ýäêð÷Œoh‚ýçæ]~g»ÄÊÐ×Ýäêð÷Œng¡î†ç{e€»ÄÊÐ×Ýäêð÷Œle‚«¥Óè{d»ÄÊÐ×Ýäêã|dˆ³­¦Èëécxb}»ÄÊÐ×Ý×xbŠÅ¸±«µ[ê¥xa|»ÄÊÐËtaŒÌÇÁ±¦©‘ë‡u_{»Ä¿p_ÔÏÊĬ‘Úíxt^z±n^’áØÒ̧Åï ¯r\_\k¤¶»~qñªð Ÿq[‘Ú“pf~²õÿÿÿÿÿÿÿüÿ™ù™¬llv~ˆ“¢Âú[>uÓ³—cP?0"Vø¿Ýñk^ZX[][ZZXVTPMLPXh…¾:‘ÔzhTSNczˆ–¤«²¹ÀÇÎÑÊÄ¿º´¯©¤Ÿ™“‚kPLU~ ÏZSNSå™ÿ ò×·fLLMq?†È Ù+c½4¼Ek€SPMLºýžÿð¹sLKp€ HˆLZm‰ÃiµÿfSSRLM¯£ÿí˜LMF/ašë‡²ÀÄÈË̽¯¡”†hMLLMbŒòh±¢aSSPLѦÿÎ`YÌûɈÿ úÞ¿ ‚cMLVv¶­w\SSOMô§ÿ휂öÇŽÿ ùÙ»œNKb›P¿§´pVSSNb¨ÿ│ñÅ“ÿ ûÓ¤wPKRa|¯Þ#«ÓŸBn€SM‚¨ÿу‚ìÁ—ÿûÚ¥rNLNPRSSXaoµj™ÔiSSRL¢¨ÿÁuæè½›ÿüâ¶pLP‚SUF˜ŸdSSQL¨ÿ³‚¾ã¸žÿûuLMOQ€St8—~_SSPLâ¨ÿ§Ž£Þ´Ÿÿü«_€LRS^×–qZSSORü¨ÿ“–Ù²ü¡ÿþèRRS^š–ÙrUSTNo©ÿ”˜‹Ô±ø£ÿNRS^’–o€TL©ÿ™Ï±ô¢ÿúLRS]–¾jTUTL¯¨ÿþ™‰¶€Ê¯ï¢ÿôLRS]‹–’eUURLϨÿ÷ š–€Å®ë¢ÿîLRS^‰–x`VVQLï«ÿðÐÐÁÀ¬æ¢ÿèLSS_Š•Ht[VWP\¢ÿþþ€ýþþƒÿúæÆâ¢ÿâLSS`Œ•ktXWWN|–ÿ þôéææååêðõø€ú€ù€ú øôîåÜÛÚÚÙëý ÿÛLTTa•èpWXXLœ•ÿöé€åëñ÷ù÷öõö‚õ€ö ÷÷øùøïäÚ××ÙìþžÿÕLUTb’•«kXXVL¼“ÿøê€åïøø÷öôõöö€÷ö÷øùøìÚÕÕÙïÿÏMUUd••ˆfYYULÜ‘ÿþì€äí÷øõö÷ö÷÷øùøùø€÷øçÕÒÒÚû›ÿÉMVUd—”¢uaYYSOùÿ ûèäãëõ÷õôôõõ÷÷€ø…ùëöïóöøø÷øõãÒÐÔôšÿÃMVVfš” v]ZZQiÿ ÷åâãò÷õôôõö÷ø‡ùë÷ííéïóöƒøñÓÎÎì™ÿ½NWWgž”-uZZ[N‰ÿ óââåôöôôõõöø‡ùúúëøííé€í ñùùøø÷÷ô×ÌÌâþ—ÿ¶NXWh ”Îp[[ZL§Žÿ îáàçöõóõõ÷÷ùú‚ùúìøíìêíûûú€ø÷öÜÊÉØ—ÿ°OXXi¤”œl[\YLÅÿ óààéöôóõö÷øù†ú ùùúú÷éøëéì€íï€üúù€øöãÉÈà–ÿªOYXj§”€h\\WLâŒÿ ÷àÞèöóóö÷ø€ù€úûû„úû€ú òåöÞÖßäéìðüúù€øöáÆÅé•ÿ¤PYYk«“?xc]]TPü‹ÿ ûáÞãõóó÷÷øùù€úƒûúƒûúúíé÷ßÖ€ÜÝëû‚üúùùøõØÄÆñ”ÿžPZZl®“›y_]]Qj‹ÿýãÝà€ó öøøùùúúûûú€ûúûüûúûû€üûëíøßÕÚ€Ûêûû‚üúùùøôÎÂÇø“ÿ˜QZZn²”v€^Nˆ‹ÿéÜÝðóóö÷øùùúúûúûûú„ûúûû€üðñøàÕ€Ú×òûû€ü€ýúùù÷ðÈÀÌ“ÿ‘Q[[n¶“¸q€^L¥Šÿ ÷ÛÚíôóõ÷øùùú‚ûƒüûúûüýýð÷ùàÔÙÙÚÔûƒü ýýûúùùö뿾ç’ÿ‹R\[oº“’m__ZLÊÿ ãÚáóòó÷øùùú‚û€üýü€ûüýïûûàÕ€ÛÕƒüýýþþü€ùôÕ½Äý‘ÿ…S\\q½’H{i_`XLà‰ÿ óØØîóòö÷øùú‚û€üƒýü€ûüîýüàÕ€ÜÖ†ý þþüúúøï¾ºà‹ÿïvv€ÿT]\qÁ’„ze``UOûˆÿ þÝÖáóòô÷øùù€ú‚û€ü„ýüûëþþåØÝÞÞׇý þþûúúõظ½úŠÿë€wvvVU]]sÅ’I{€aQh€ÿ€þƒÿ ïÖÖïòóõ÷øù€ú‚û€ü†ýûûüüàýþèÝ€ßØýý‡þýúú÷ð½·×ŠÿçxwUU^^tÊ’ßw€aN†ÿÿ„þ€ÿ ÚÔáññô÷øùù€úû€üøììííôý ûüüøáþþëáààáÙýˆþÿûúúôÚµ·ý‰ÿãxwTV_^tÏ’¨sab`L£ÿÿ€ýþþÆ®¯¯¶ÓÓîòóõóõ€÷ööøùû€üýøì€í ðû÷ôôééêõåýýìå€âÚüþþù‚ì øþþÿýúúùð¸³è‰ÿßyy€xRW__vÓ’‡obb]LÁÿÿ‚ý¢€}¦Ñ×ðñôôïñõööòóñêóüüýýøì€í îùùîìÜÜÝêéýþíé€ãÙûþþêà ã÷ýþþÿüúúòȱωÿÛyxQX`_wÙ‘ –|jccYLÞÿÿüü€ý¢}}~¿ÐàðòôðïðôöõòóíëëðüýýûòîùþïéÜÝÝÞíþþîëäåãÜúþù‚àÝßý€þýúúôÚ°¶þˆÿ×zz€yOY``wÞ‘ Õ|fcdUNùÿþüý¢}~‡ÏÎèðóõìððôöõóðêëëìõ€ý÷òúþøä€Ý ÞæýýîíææáÞùÿêáàÜòÿþúú÷ë°®ëˆÿÓ€zyyNZaayä‘|€dQfÿÿýûû€ü¢}~ŸÎÒîñôõéððóöôóìëëììíüýúôùþþýâÝÝÞÞßüþïíççááùù‚áÞâð€îðÿüúúï¿­¶€Ãè„ÿÏ€{zzL[aayê‘ÆwddeM„ÿÿûüü¢~~´ÌÚîñôñéðñòõõò€ë€ìöýø€íîôýþþòÝ€Þ ßëþðíééßã÷êáàÜôåâüýúúóÒ«¦€“Ö„ÿ Ë||{{zL\bb{ï‘ šseeaL¡ÿúùúú€û¢~~½Ëàîòõñîóõõööóòìë€ìòýø€íîîù€ý âÞÞßßàýñîêêàãñ‚áÝãÿäâéþúúõݪ¨€”Ö„ÿÇ€|{xL]cb{÷‘pef^L¿ûõúûû¢~~ÃÉâïòõ÷øøù‚úð€ìíðýùíí€îøüüýõÞ€ßàïñìëëàãçáàÜõþäâ åþúúö㨧•””Ö„ÿ Ä}}||wL_cc|ÿ ~lffZLÚöò‚ú û¢~ÈÈåïòö÷øø€ú ùùúðììííïýøí€îìôü€ýäßßààéî€ìàâáâÝåþþäâ äÿúú÷駦—••Ö„ÿÀ€}|vL_dc~ o~hfgUMïðïùúú¢~ˆÆÆèïóõ÷øøù€úøøîììííïýùîîíèàóýøß€àíé€í áâááââàÜ÷þþäâ äþúùùꫤ™••Ö‚þÿÿ¼€~}uLadd~ ï}€gQcñëï‚ù ú¢ÅÆéðóõ€øù€úùøãßåìíïýøìæßÝÞó‚ýåààãïá€îâáá€âÝç€þåâ äþûùùê±£š••Ö„þ¸€~}sLbee~ ´xghgM~ìåñ€ø€ù ¢•ÃÈèïôõ÷øøùù€úùãÙÚÚÜâúòÜÜÝÝÞóüü€ýòàáëé߀ðãá€âàÝù€þåâ äþûùùë¶¡›––×€ýþ´€~rLcef uhhdL–æßôø ùù¢˜ÂÉèðóõ€øùùû€úã€ÚÛßúòÜ€ÝÞóü€ýþòãäïâÞ€î‚âÝéþåâ äþûùù븠›––ׄý°€~qLdfh% ß~qhi_L­àÜ÷€ø ¢’ÀÄçðòõøø€ùúæ€ÚÛßûòÜ€ÝÞó€ýþþíðîåáÝ€ìááââàÝúþæââããäþûùùé°žš——ׄý­€€pLfgh- €niiZLÁÚÜ‚÷ øø¢‹¾¾åîòõïð ñðòòëÝÚÛÛàûò€ÝÞÞóýý€þéøîááÜ€êáàââÝê‚þé‚ã ïøø÷æ§œ™——ׄü©€nLfgj€52€€jUMÔÕÞö€÷¢„½½áíòõéèééêêÜèëìêàÛÜäúñ€ÝÞÞóýý€þïùüááÛ€çãÞâàÞú‚þðƒã ÷øö埛™˜˜×„ü¥€€mLhhj€A Õ|jjkP^ÖÐã‚ö!÷÷¢€€¹»ÛìñõëèééêêÜÚåììíæÞêúïÝÝÞÞßôýþçùýëáÚ€åäÛâÝìƒýü‚ãäøøôßš™€˜×üƒû¢€‚lMihl€K £yjkiLtÐÊé„ö ¢€€³º×ëñõì€éêêÞÙÙáêíîîøúçÝÝÞÞßö€ýþýàüýýâÚãÚàßû„ýìãçøøò×™˜€™Øüƒûž€‚jNiilU †vkkeLˆËÅð‚õ öö¢€€«¸Ðèïôï€éêêàÙÚÚÜæíôýùîéçåçéüþþ€ýà€ýíÙáÙÝî†ýãáããì÷÷ïΗ—ÍØ Øüƒû›€ƒ‚hOjincŽ Ãrkl_L›ÆÃƒõ ööÝŒ¥·Ãäðòô€êëëãÛÜÝÝÞÜàæéëìîìëê‚ýüàýÚÞ×Þü†ýûçÛÝð÷÷踖²ÿþýïûƒú˜€ƒ‚gPjjnoŽ ™ollZL«¿Èƒô€õ °­¯µ¶ßíñõðî€ïìääæíñÛÜÜÝÝÞÞßßéüýùãýçÜÖã‰ý õíö÷ö។Ñûùùüûƒú•€„ƒeQkjo‚|Ž lmmULººÏƒô‚õô¸³Òèïô÷ø€ùø÷øøùñ€ÜÝÝÞÞßßö‚ýöæýïÙ€ÚÖäŠýû÷÷îÓ“”îø„ù‘„cRkkp‚޽}€mO]ÜÙçƒóƒôʱÂâïóöøù€ø ùìÜÜÝÝÞÞßßçü‚ýòêýöÕ€ØÕãŠýùöö繑§‚ø„ùŽ€…„bSlkq‚œŽ —zmnkLtÙÖìƒóƒôÞ°³Ýíñô÷‚ù øøùóâÝÝÞÞßßçúü‚ýïîüûÒ€ÕÒâ‰ýü€öß Æ‚÷„ø‹…`Tllsƒ¬ ¹‚vnnfLŠÖÓðƒòƒóð°®Ðæïóö€ùúúøéßÞßßäëû„üêñ‚üÒ€ÓÐâüˆýùööíÓŽæ‚÷„øˆ€†…^UmlsƒÀ c‚tno`L ÔÔ„ò„ó Ä­·Ýìðôøùùúúù€øùùöóúûû…üæô‚üÓ€ÑÎàú‡üûööõßªŽŸƒöƒ÷õ€‡††]VmmuƒÓ IƒpooZLµÑ׆ò‚ó 謪Ëãïòöùù€ú€øùù€úûû…üã÷‚üÕ€ÏÎÛù‡ü÷õõê̌׃öƒ÷ò‡†[Wnnu„è äoopTLÈÎÜ„ñ…òÆ©¯Ùëïô÷ù€ú€øùù€úûƒüáú‚ü×Í×ø†üûõõóÜ ‹¦‡ö€÷‡‡YYnnv„Ž­~€pNZÎËâ„ñ…ò몧Äàïñôø€úùøøùù€úûƒü߃üÙÊÕ÷…üûöõõæÃŠŠß„õƒöꂈWZoow„ ‹{pplLqÌÈç„ð†ñË¥©Õèïòöùúøùù‚ú€ûüû߃üÜÈÒö…üöôôï×—ˆ£…õƒö版U[oox„8Œ £ƒxqqfL‡ÉÅî„ð†ñíª£´Øêîòö€úû€ù‚ú€ûüùâƒûÞÆÏõ„ü ÷ôôñÛ®‡ˆ«Î„ôƒõらS\ppy…VŒ À„uqq`LœÆÉ…ï‡ðÚ¡¡¼Ùìïô÷úúûúùø€ùúú„ûöäƒûáÄÌôƒü øôôóݺ†…®Â§ÈƒôƒõàŠ‰Q^qpz…}Œ„€rZL°ÃÏ…ïˆð ÈŸŸÃÜîïó÷úûûúø€ùúú„ûóçƒûäÁÍ÷‚û÷€ô áň„¢ÔѾ›Æ‚óƒôÜ‚ŠO_qqz…£Œ ÌrrsSOÀÀÕ‡ï‡ð ¹ŸÉßîîòöùûûú€ù€úƒûïëƒûç¿ÃÞÐÉ‚ûö€ó æÌŒƒ—ØØÔÆ˜¶‚óƒôÙ‹ŠM`rq{…ÎŒ ž~rssMaÀ½Ü…î‰ïí­›ŸÍÝíïòöùúûûúù‚úûìïƒûíÆíûû÷€ûúô€ó ãÑ“‚ØÞÛË›°ð‚òƒóÕ‹‰Lbrr|†Œ ¶…|stnLv½ºå…î‰ïðç¡™žÅØìîñõøûûüúù‚ú€ûèòƒûøóƒû÷€ó ñÝÆ…ÓåáМµðƒòƒóÒŒ‡Ldsr}†>‹ È„ytuhL‰º¸ì…í‰îïïá¡—™»Ôèîïòöùûüûúù€ú€ûäô‰ûøô€óî×¼†€‡àÿÿêž«ðîð‚ñƒò΀Œ†Lfts~†‹ h…wuvaL›·¾†í‰î€ï窕”¯Ïáíîïò÷úüüû€ú€ûâ÷‡ûøóòåÑ­“ìÿÿê ±ÚØæâïñèc‰€òË…Lhut†Ì‹ ð„uvwZL­µÆ†ì‰íîì·““£ÊÔåîïïóõøúüüûúûûßúƒûúøõ‚òê×Ëœ~£÷ÿÿ꡵éæÛÖÙÙóùúãL++€ñòÈ€Ž‚Livu‡'‹ µ‚vwxRTµ²Ï†ì‰íƒîÆ’‘’«ÈÖèïòôøúûúúçûùø÷÷öõƒñìÙʨ„~ªýÿÿ꣺ôîêæÜéþÿÿéL+(+ðÅŽLkwv€‡•‹ ’wxwLg²¯×†ë‰ì„í כޒ®ÊÙãîï‚ðñóôóóò…ñ!çÛË®†~}‡À»ÚÿꤹþøõîëûþÿÿìN+&+Á€ŽLmxw‡'Š <…}xyqLx¯¬â†ë‰ì…í ìÊ™Œ‹Ž«ÆÌÖáìï€ð†ñîäØÍǧ„}}…¼ëîÙ¯Ò¤¸íôðóõø€ÿëM+€&+i}Lpyx‚‡ÒŠ ÷…|yziL‰¬¬êˆë‹ìƒí êÁ‘Љ‰“§»ÊÒÖÚÞáæéæâÞÛ×Òʽ¥Ž}}|€²çîÕ¤¹íîïìáñ€ÿëM+‚&+U{Lrzyƒˆ²Š 8…{z{bL˜©´‡ê‰ë‰ìé½›‡††…‡š¢©°¶¾Ä¾·°¨ —}}||„´è„í âìííîîäîÿÿëL*„ %*TyLt{zƒˆáŠ ð…z{|ZM¦¦¾‡ê‰ëŠìííáÀ †ƒƒ‚‚€€~~}}|}”·ÙìŠí€îúÿêK*c† %*T‘wLv|{„ˆ‘Š Ã…{|}QZ¦£È‡é‰êŠë‚ìé¶«Ÿ”ƒ~~…›¦°½æëŠì€íÿêK*V®Â† %*TuLy}|…ˆEŠ ¦ƒ|}zLj¤¡Ô‡é‰êŠëˆì ÏÞ‰ëŠì€í¸F*HŠ°Â† $*GL{~}†ˆßŠ §‚}~sLy¡žà‡è‰éŠêˆë•Ùƒê‰ë‡ì ØC*:fx‹°Â†$*8}~†ˆ‹(²‚~jLt‘–—”‘Ž‹ˆ…‚{xvvuutwy|~ƒ†Œ›¨µÂÏÝéêˆëŒãŠêŠë ìÛC*,ASfx‹°Â†$*L‡‰ŠÒƒ€b‚L NTX]adgikl€mjfgs€°Ëæ…ê‡éŠêŠë ì*(.ASfx‹°Â†$*L‡ˆ‹®…€}xtplhd_ZUP…L NPRTVY[]_ace‰fg|–²Õ€êç‰èŠéŠêëÚC*.ASfx‹°Â†$*L†Š‹*ž„‚ƒ„…†‡ˆ‰Š‹Œ‰„€{vpkf`ZTN„L MOQSVXZ\^`bd‚fxžÅÙÞĬ¤Ÿ™’‘–™ ¥­¶¿ÉÒÛæ„êëëØG*.ASfx‹°Â†$*N‰Œ*­ˆ€‡ ˆ‰‰Š‹ŒŽ‘’“”•–—˜™š›–‘‹…ysle_XQ…L NQSUWY[e~j‹Ž‘’œª¹ÇÕäé€ê ×H*.ASfx‹°Â†$*M\Ô›‰€Š*‹‹ŒŒ‘““•–˜™šœžŸ ¡¡¢££¤¥£•‡yrkc\TM€LSLLMRX_ekqw~„Љ‘š©·ÆÔÑH*.ASfx‹°Â†$*B$ùío#òÏ»ª’Ž‘‘’’““•–—˜š›ž ¢£¤¥§¨¨€©€ª€« ¤”Œ…}ume]UMƒL QX^djpw}ƒ‰„‘ =).ASfx‹°Â†#)@šÆB;¸l3 íÔÀ°¢—•€–——˜˜™™š›Ÿ ¢£¤¦§¨¨£Ÿ£©­­¬¬«¥œ”Œƒ{skc[TM‚LQW]cipv|z8).ASfx‹°Â†#)@§ Uö <½s<óÙǵ¨œ€€ž2Ÿ©Ä⾞¢£¥§¨©««¬¬««ª©©¨§Ÿ—‡wohaYRMLLI/).ASfx‹°Â†")?´ U±:¿wAåa«  ‚Ÿ$ ¢£¤¥¦§¨¨§§¦¥¤££¢¡ ž–‡x6).ASfx‹°Â†")?U [{-úÖº¥€ œœ››œžŸ ¡¡¢¢¡ Ÿžœ‘<)/ATfy‹ž°Ã†")?UË 6¶BœBÝ¿¨š™™˜˜€—˜€™šš<)/ATfy‹ž°Ã†")>UÓæžÆXåë—•””““Š;)/BTgyŒž±Ã†")>UÜf%ôp!î³8)/BTgyŒž±Ã†")>Uâ æ0)/BTgyŒž±Ã†")>Uâ æ0)/BTgyŒž±Ã†")=Uã 0)/BTgyŒž±Ã†")=Uâ ò/(/BTgyŒž±Ã†!(Gã ò/(/BTgyŒž±Ã…"(Hä /(/BTgyŒž±Ãƒ"(rå 0(/BTgyŒž±Ã"(_ýçæ 0(/BTgyŒž±Ã"(^µò‘ç*0(/BTgyŒž±Ã"(a½¸Þ«è*0(/BTgyŒž¤A(gþ¸Õé*0(0BUgz‚;(jÐÇÁ¼Ä£êK2(0BUa5(lÖÓÎÁ¸½mëK2(0@/(qÝÙÕн§(íK0(*(sçàÜÖº›ïï _/'&'T·Åʱš6ªð _/'@¾‘…ªñâó¿tÿÿÿÿÿÿÿüt8mk@ ØþýêÛ̽«pQ1%%),/269íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ)/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&]ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿlÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø Åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûc¢ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿž.G`y’«¾Ñãöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿž .@SexŠœ¯ÁÔæøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ 1CVhzŸ²Ä×éûÿÿÿÿÿÿÿÿÿÿîͲÒþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ !4FYk}“? sìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡4Ok†¡¼×òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡*E`{–±Íèýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢:UpŒ§ÂÝ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£/Kfœ½÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥Ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦Ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‹Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ+Îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü]Îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø†ÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúgÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5ÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿýòÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿLËÿÿÿÿÿÿÿÿÿÿÿû ËÿÿÿýÿÿÿÿùøqÊÿž}¶ìúÃ…Sdjview4-4.10.5/src/images/DjVuApp.ico000066400000000000000000000163561264256014000172310ustar00rootroot0000000000000000¨6 ¨Þh†(0`€ ÿÿÿå®yYU$¥oÈðõÉ“f0BŽpµ²ÔÂ@x£jikÀ¢‘èøÅ;Þ|;ÈžV0s3z9Çÿeƒ“¤¹Žk¦Í"~ÁÛǵMVqNšPBi‹ãÿݳÛÙÙÛæ›Èþ·À²²«‰xynúà­ôóãU“¾…C9Y(‡v1¦–×¥už^Hƒ¨»ÎYX[Sv½ÒÿÒh0bŒnn¡¡¡uQIÊÊÊöâÌd±å‘ToŸbaÒ² o,¼z;R9´îß‘ž\Msáêð˜~~;„·bUsbÔÿáÿ᥎ŽÅÞÎæÒ¤üùÓåݹšd—0Ì`2›'¤ãSATo`†vG­·¤¢áó±€@fúìÂ^izê¿…Bo’ÚÐËtk{žu_t±Ù~ižîÿîÄñÇɽ¼j.‰ôÖ¼„„„U7‚Üî௭±èää¦qŒøÖ sKÉ‚š›g¨¥}nýýæ_,kòïÒT%™^B§µ¿k-±ìâ¢àリ—šŸ‡‡ñç¾bpâáÈõôóõͧt¹æ+|¹q/˜x4ˆåÝÓ±™‹v<»“X}v7`ÛןãùÍÓÿÁd-z.~ˆmª_Lx®š™jaxn2m¤kxŒ›±§Î¼ÖÑÑb©×~=F ‘ÎÌßÙÞÿÉáÊ›gR…Z3©©©xvw•]ŠîìÇè̶æðÛ»»»íÚ°ve6•ÔQbîíìòä׋KJ•ã_&®žu¨]UgâÒ¬q5Ye/¥Ÿ`VÑÆÅÙóÓz7kÝâ¨úç¸ëË•úúÜw3ÄQ-Žîú×ųªýýñb8“c.VñÃúñÉfT}%y¹Ü»ˆñâÀÓÄ·ËñÏŠI?pB¦}~}õÛ¦___rrrQ=r³³³`)•+„ÃéäÔ}C¹g0LåÒÆmP‘tK¤ñО¶ œìౘl³®‘†]Emƶµ‘ttÜí¥g)¶èϽñί÷áµ¥†|æõ½ãÞÛìݹùôÕ÷Û«hcoˆF0U&žãë³·œ‘[?€ã×µäÌ­ûûúá×À£€vWCt÷ЙðÇ›k³á–t¯ˆˆ‰÷öí˜C-´S˜E&a*E€“*E€*EÅY*EÅ?9{Lm/*E?³9’i+®ý^¦Q *EË«¨8† LmÞÞ^¦Qîî ПÍd3ÒÊOE€ÖRÚÙœÄD¯.....ÏÏ Ò•¤•ÊÊ55•©©©]OEŒ4UÌÐ3ggÒžžž333ÒÊ5©©©©Ò©©©©©©©©©©–=EÔkï<…Ÿ5©©©©©©©©©©©©©©h!SBGS!h©©©©©©}üMW'—» Ê©©©©©©©©©©©©aGyS¾ÈȾÜBya©©•©©ö7¬§l '»D¤©©©©©©©©©©•BëzÃqqqqÕZG2ah•©}ö7¬t »')óÒ©©©©©©©©©aG¥¸ÃÃJ¡ºººº%%´â´h´h©}A¤ »'‚Àžh©©©©©©©´õí¸VÃÃJ¡ºº½º%ÿ%êBá´´}}}}Ê ;—¶²xê©©©©©©õθ¸VÃJJ¡ºo‰ µ¿¿ÿêBá!}}}}Êþ ;—<;d©©©}}©Î$¸¸VÃJºqºo‰ µ¿öö}ZB©}}}}5þ u—;[}}}}}´áÛí$ç¸VÃJºìºo‰Šµ¿¿öö%Sa}}}}5þÐu—uŽê}}}}}SõÛ$$çIIëJJºqo‰Š£¿¿¿¿ÿêy}}}ö5dÐu—ó¤©}}©áûjÎíçÆÆ>zJºqo‰š£¿¿¿¿¿%hööö•dв<ÀÒ©}}„è¹>IÎIݺº¡ºwš|¿¿¿%÷%a¾:öödв<‡²3h}}\ߢÂXX¹›çÆ›JºqKw‰ô%ooô°qZ\öödÐN<—ä©öö\Ü¢újÎ¥Æ>JJ¡° °|oq°ôºƒøöêÍÐN<ä[}öö\S¢jÎí>ç>>ÃJ°¥ I°ºqõôºÕèhÍÐN±²Žöö\òåújí¹IV¥ëÃz›I °IKÃIôºƒnhÍбbehöö\"ØÂÂúÛ¹IV¥Çì›>¥ é¡›IzIzJZ\©ÍŸ±‘5\s´ÂXÛ¹íVÇÇÃ>>ÃéTÃI›ôJJìá©©Íб±²žÈ ´æÂúj$¸¸I¥V¥¥VñT¡VÝzJÃq!}ŸŸe±­hƒÂjÎ$¸VVV¸¸V·ãzÃÃÃÃÃZê}ŸŸe1­[cúj$$$¸¸ç¸çˆÝVVVVªae1Óùö}ê~újÎ$$$$$Iˆݸ¸¸6´©ó1‹eh©h~újjjÎÎíÛIvθç6Zh,11Ê}hcÂúújjjÛÛÎÎí6•©œ1×ð3}h©cúúÛÛ~6h•}œpþ}h©ª666ªªê©Qpð©™0`¦p(Ñö5”0É#ppe Fµ}x,pÁ¼Ê©H_fögŽrrð3hHöf}¤x©5ÍP@ÍÐÐ×(à[[ŸŸŸŸŸÍÍdÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿüÿÿÿÿðÿÿÿøÿÿ„à€€€€€€ÀÀÀÀÀÀàààààððððððøøøøø?øÿü‡ÿÿüÿÿÿÿÿÿÿÿÿ( @€ÿÿÿ‘é¬|bßÿW,ôË’Kƒ¬ª¢¸E²íÌÞÑ|a€ýòÈq¬ÏŒ‘œÅáÊ«šàéªGžÌ}:xâüâ„m£Ë½»³•‡sH™˜†°¼ÚîîØÆz½é4‡ÃbI€Mf¶ùÞ©žŸŸµÛ•gyãõ×åäàßûïâäÆ¦ã¾‰n2·¤£µµµ †×ÈÄÐêîòƒ„ƒÙоyb–ÓüÓ‚Nxˆlôæ»EÄøéÚ¡ÙÒÒ€ž~A‰Ê¸«éζïè̦³½½Ÿ‘ùõòZ(qgAq0}ûúת«ªâÇ•™¤ ’¶¹zäÝ´åõÕóÍ¡BˆÇ¼¬ªÕŬÑÅÅh£ÉîéçrX ᎂ‰}nƒúØžãèÅ–Ëëe/†Ä¶´ÁÂÁðâØÞëØìí¶ßýËŽhƒóÕ¶jO•åÕ«ÜÜÛÞÞ õòÓìúÇxk˜éΠûùç°ž›sT™ë˱¨¾ëÝÏüå³àÕÉÀ«žñâ§ðïïåçèe,|ëÚ¯»¼»þýôíòÁãòãY€ëêÜÑÒÑÓ»¬ÅãÌËËËüë¾óß³õקñ¨¤¤§õêÃçáÅ““•úúúéç«gJèõº‰{†”Œž°°°™˜ž±Ž}À¥˜§¨³o0‡ýùÏ÷М„…‡g6Ž×××¾Èúûá’„«ÚȾm8”eG†òãÂâÛÚïÓ¡ŠzŸ›‹²ÔÊÊI¸òàúÔöõ×|<„lA‘ôÝ»ñã¹íÞÈìÖ¨[+{_3…0ÂDºîÜǪ¨¤­íÉŸ ‹Þ÷ìÎøðëze›ØúÍçΪííìæßÔèÛÁäÍÆÊÍwbè߸ûæ·éíÀŠÚóóòêääàßßäڻƹ¸¾ª¤Á±¯qP”òï艓åÔ§äÕ²ÛÑËø÷äï˦Iu‰i‰úíÄÌÂÂ÷÷ö’Ž™üõÎäã゙ƬžqD•yfõԞ˹¯éééúâ±úÙ¢øÔ¡ìÏœ”€®³ ŸüüøúíßèôăR{’h}ôîÇðíË­¥½£–¶Ä¨˜iC‹FÂõù÷Ò®~füüñø÷êùúÛéÜÖöФµ –ø ø©-´7©¹#ñbÙÙ5jN7©¹Ø4ð~~~ ãWVÒÒÝ“ˆ,?7©È;Tà‘ÝÒ‹!Fz€œ€ËËwæ¿vµ©¹¬Äƒæææææ¿¿æ9\+m+OÛß¿æwZ UÐ]¿¿¿¿¿¿fOtPÌŠŠ1‡ìÍ9Ê/%Ršââ,¿¿¿¿v9ζ6 ù«žžÖÀOÍQ¤/Ú­¡·¿vvɡ¾ÆÚÞE«žaªûÑÏ+¨ÉÜ€š­*H¿ÉÉv(çÆÚÞE«ža½ííS+¤ÜŒœ0÷—¦æÉÜ&†ç…y‰E«žaªíí{ÕÛŒŒœ0÷D2fÜ&Í(ä¥kGÓùEýaLû{ü\SŒf0÷ЀŒá¸o)G±Âòýó$YÖlÁ>‡JAË0¢­ƒŒá@Mä†)kG6ùÅïK>«Ôh<úAß0¢›á@Mé ê…y‰6eiKÔ>eh<Aw0¢[pö”×ä¥6£ºÂyiÇÓK¯ùåíæ0x§ •=ä „¯‰±6|¯¯˜>9æ0ŒŒþMX Æ„„„6` sSÉ,2nvÉ™X rrÆ…g„„°¤ëCËv™™è †8uư¤Œ³.É^cÿéé醮qÊŒ§²ôŒÉ»'îî_ÉIBŸw"3íõ¼Üw‚ÜwdŽßf }ÉÉæf€:9fËßËfœƒ’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÿÿÿáÿÿÿÁÿÿÿÿÿÀ€€€€€ÀÀÀÀÀààààààððÿðÿÿÿÿÿÿ( @ÿÿÿ Þž’õÒœËîxH‡@·óÊÉÎ=ŽÈâüÓÇ«˜hh›­Ÿ½ôåÀÞÙåu‘öíæ[¹ç°¾Í‚_•!ƒÑáÔË6ÛÖ»£Ê»º”w¨ÓçÖ ‰²·±·éç®ìåÓ~o‰õ÷Õ°¦ªûÞ¨×ǹֳ”îÔ«”…“ÇÔÚôõôçìêçÌ›êï½Æ¼ÑõÚ¸º¯ÄR¿îÄÀÅÖÎÌûç¶äÞÙ©ž¥æóÍ~WŽøøçíâ·êõ×ãäâÒÈÂëáÂúýôõà°ùóÍïïïúìÀýõî~ÛëÕßÙÔª™¸æè¼A²íðèÆiŒñãÎîÌ™ÇÂÍìÛ¶ßÞÞÜÐÈîç¾öã·ûüûêèæôÕ­êПù÷÷÷ÚªöúÚÉÀÔÔ¹ßÕÐíêïðÞ°æààÒÇ·ßß㮢¹T¼ë“|’öòññóñóîã׸ ÓʺõîêïÞ¶~kŠüùøùû÷îäÐáßÛíÞ²ééé=·ôääåßÙÑßÔÍýþþ÷øÙùÙ©õäµìãÃ~i‹ß×ÒɾÓÒÇÀ~mŠßßáêèèòòñõÓäåäîâ¸þþþøóÍ0I deD'5"1t7u†P~`;}G4M+‡!68\qmQ%…WlRH|= F]i?r,9JU ^kV#3{BpXTc.zY_Lf[nChEo- ˆˆx*gAsÿÿÿÿÿøÿñ€€€€€€ÀÀÀÿÿdjview4-4.10.5/src/images/README000066400000000000000000000001231264256014000160650ustar00rootroot00000000000000A number of these images have been stolen from KDE. The GPL applies in full force. djview4-4.10.5/src/images/cursor_hand_closed.png000066400000000000000000000002311264256014000215530ustar00rootroot00000000000000‰PNG  IHDRµú7êsBITýòEéRIDAT(‘­ÁÀ C_ýÿ®gdÇÁq( ZùŽVôÿ$ÈògýIDD°’„‚‘£DÒž´¶ “'ÊÍ´®°²ÅmÃNóÑäaKi²àFˆ¥n IEND®B`‚djview4-4.10.5/src/images/cursor_hand_open.png000066400000000000000000000002531264256014000212470ustar00rootroot00000000000000‰PNG  IHDRµú7êsBITýòEédIDAT(‘}‘A! ÜþÿÏÞbA´7p”Ù'‚9oˆƒOY ,N-°ŸŠfâ'0¼°ÄÆÁãîqôb½üŒ¸v»›æ/ Ôìðš¦E0ÿÐ:Ü’|ÛX/—v?Þ˜)a/ðIEND®B`‚djview4-4.10.5/src/images/djview.png000066400000000000000000000353661264256014000172240ustar00rootroot00000000000000‰PNG  IHDR€€Ã>aËsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœí½y]×}ç÷9ç.o½7zAƒ¢¸H)Š–m‰¶•¡#‹±­—]åØURÙcÏ$^&OœŒ2Š“šÑ”#Å“”Çv<©šÈ#È&1²6Š¢ERE$¸`ín ÷ííw;'œ{ï{¯,Ešø§îíûî{w9ßóû}˹Wh­¹.ï^±wê‡îùµ]Bpˆ[¨kËUŸý7ÁNóº\½ˆ«Õƒ÷þÚð®æ†ThgµfMH*ÒÂñ#•r­p1gK9+¨d­Às­0°…ªÛ2ªÛR5ZVG³×ý ° ,¯kKÀIàôÑ£G£«º¨w‘\ïýµ2ˆoüT³rׇZuœŽßšÏ+^TÔmMËÖ„ÖæÇBÉdºš‚ ð}ß÷Óu¥Ô圖¼ œˆÛ ÀW=ZÛö…þ=–«À¯vàýö§«K]Û—rŠoì øéÿê8p`Cw6Çq.ûxa¦`H–žç1;;˹sçÒvᢨK xÀ×ÿ8zôèÑ Û¾è¿g²m ÞûëE3ÿ¤²PœÛf}²¬øÞHÀ ná3Ÿù ¹\n§Îõ²% C¦§§™œœLAqüøqêõ:€¾üúÑ£Gg;¿÷±}Lïn&:Zhõ޶œÆh›“Àù£G¾ãõUà}t< ÿ­µyû>¯ñÛ?W[`¦¨øÖDÀÃ?̧>õ)²ÙìNžçŽÊo¼Áç>÷9¦¦¦(µ)ß?Â#?ýsüÄ?@°â­°ÜXæÖ¾[7ý~†T«U*• «««LOOw™ XÓTg0`ø;à»G]}K.ò2eÛºï7žù™úê½´ ·zm âÃ!ø‡ÈÞ½{wð¯ø¾ÏŸþ韲P<Íoþüï!]Ÿ_<Î=ƒ÷lë·—––º199Éää$žçiàU žž:zôè›W{-W#ÛÀÐ}¿QV~cmÞÚú|w,dª¾ô¥/aÛ;^¸¦2??ϱWÿ#ÿàCŸÜðÙ‰¥Ü7pߎKkÍÜܧOŸæå—_æÅ_djj [±’ År¡xª¿%ž¸sÎþþ'O~©µc¾„l·§Þ+ÖXÔ&kÅØØîwLçT«U|¿EÀÆØTÄΆ„ŒŒŒ022Âý÷ßÀÚÚ/½ôRß‹/¾øðK/½ôðk33ÿlª¤xæƒúƒ ±¼«.'‹˜æâ¶ÐÑÎòä—N^íym¯·„8<…¸±öÐ@%£¹ý†®ö|ÞR©T*ÔV— 7|¶Ù¶–žž|ðA|ðA–——íà¾ð #Ï-.Ž”|qïXMrxÁÆ^G'ÿŸ›æ$ð§Ÿ<ù¥Ïl÷¶;\ŒvŒþš«‰ÜðÕkáy;ßõÙfZáZK?=ô=ô <ñÄ|ñ‹_äBQqß›Á¦ìüÊÍÀ¿øÝƒÿð[ÿòÕ?j;Ç”—Þe£Ä‘±°SýMðN@­Vc7ƒ¼ráëþ½àR244Äm·ÝÆÈÈUWó·{þ꟧Ç&Ëmu0gÙߺï7Æ·sŒ+ÖÃïûÇÁí£Ñß”œ «ÕʆÿÃЛI†ô÷÷S(X[[#ËSåM—B (h%_~ïJÿÊM€àF 0Ú¡V3 ×ußVŸË‘z½Î@Î&¬Õ7t¸ŠP…Øò‡KjÃÐh¢L&Ãððpºýĉø‚X ñþíüþ6®N±µfp˜˜˜@q‘ï½ý¤Q¯ãö¸Dµ• ÐBê{ç2æÛ’ëEkM’_“†Œo+ò¶pd$ €@ … êêwœúP*B¬4U³‹(©Ôß ÁÆsHb7VLâN|Ëpx, ÓÈY%£Ñï@ d¬±veÎW§»‰èm€Í4@’—±PB ÛÀë7!Ä‘ÑÐO°–1'óv€ïø~HE„a»%K)±,‰eYDQÀ­‘µ›8~ƒéÚ2C=m«¥&T?|O`3¤@›>P¦âÆÚ°ãeÈ`×ýÿM¸q,>)H=€={ölçøW-­–G½Þ¢^oE!Z·oPçÒ¬v¾{âÆx»æî5ŸV©Ž_l¢¤ÂWþåš:e3°^˜˜¥ØVèò 5€¸caj€ÕŒ"ŸÏ344´ãoKšÍVÚéJE]jY¶-‘Ò4³naY¥T—fÈ  ‚KÙÈ%›ÌR%4™|‰zÎCçõ•Ü^TÄ 2ç÷V€#y­èQµŒzËF³é±¼\Á÷}:sX®ëËeÈf3 $õ@Ó áC³¡i/dÈ;sùÈ9`¡©ÕšÔj jµ&:T*=Ô×^Y>ÅØØ0ýýå·ä×ËV€D Ñâ­Ð‚#ca˜Žˆ@jjε÷|?`y¹B£ÑN’e³.¹\–lÖ¥êéÍä´f¾ž˜'„ˆ×…6ëéß‚d`÷ç»K9ÆòŒŽB½Þ¢Z­³²R¥Ùô9ujŠ ²LL좧§xM¯u½le’Ñ/(£¯=âðXèLJ…Ê5&€a±¼\¡VkÄv\“Ëe)— T|ÉË‹šs«!+-q²e °ÀŠ{ZHL:¿#ë/âJe¬yšŠ¯.CÁ…±B†Ý½Ynìe~~™¥¥5jµ'Nœ¡\.pà £ oM©ÛV@js5©x«LÀX¦7qõ†€›MÙÙ¥´¸Óu]zz øÚæ[ç§—cê#ÁvÒ$H)2öo㥲=úã“Çv@h„°J#"M+„Ó8SÑŒä%‡ìåÂ…VV*¬¬TYY©róÍìÚÕ¿ã×½^¶r“ Ñ’kNG>ð[ãÑoÐ&€°óX[«±°°‚Ö`Y’ÞÞÂvyþ‚â•ù¥A:Ò1*%H!²­ÚeÜÑR®[Æš¡^÷p›Ào ¥Dg$®ë"•BÃB ž<»‹6ûw24ÔÇää,µZ“×_?K­ÖàÆǯ)IÜJXš´B£ý®±â@; (Xu===ôôôlçØDkÍÂÂ*««U@“ɸô÷÷pbž›Žð•Ær¶r!Ò¥LF¸46~«ŽOL…ËDh" ¬iIe#"ãj]hÀlö•²ÜrË LNΰ°°’‚áöÛoĶ·å†_R¶ä:¾`­Ñâ-ÐÀáþ("§5ÉlŸÕLÄ-;4ú£HqáÂBJôŠÅ¥r‰oœVœ\ÖX6ȬIJB ,[ ¥66ž Â=4X´«‚´ã1KK ,iö‹„²e¬5!JøDÊXW­9S‡Õ@pÇžQ²Y—sçfYXXá¹ç^áŽ;ö“Ïï|!ì–@ #‘ÑÛŠZ]A(8®0Ï‚¦½3€Rš©©9êõ&Zkz{KعÿéÕ¸ó]•³p2–ka»Ë2gKHK›m–ÀvÒ–XŽÀ’"6±©†:Y–@ÆŸ×|Nº¿eåHd&œ€µž[Ø¿RJªÕÏ>û ž·ó£­9@›Ò^ ¼l8’ämû¿1€™™šÍZkû¨ª _:±ÔÐØy‰•³°‰ekl[cÛ`;†ü%ͲD €dtÛ¶À²ã¥0Kƒ B"ÏÇÒ øDÊGë!4–ÔH©±bN!-L0)+‘‰-¾¼°* s%º Û¶i6=žþµË¾vÙ²U2¨“^Mà²0úÀï8Œ‡‰3µš1Ç»Z °°°Âêj ¥=Ì7m¾|Bã)U´°\‰e lœ¸“m lK`ÛÛ¸¶Àu¶+MçIL‡k%Œ–°m $†H RòZ´¼* ]¥®+x´ˆd„eI¤XR"¥À–Ç1 °,ÐNÔ$™å¶Ûö‚•• /¾¸³UÞ릸ë5€1\S ÄÎxê VܫוJ¹¹e”R”ËEZ:ÃWO)”vÁ1o Ët¨´ lK¦ÛmI ÇÒ¸N¼¿Û’FXqsÁrJ…¸®…´Œ¦6KƒˆhÒR¢°…­µ!‹²m>,G¤ °$œi ¢lžýû'RSvòäÔ¶ïÉz¹¸0Pfö55G,4ÃQ”š€•LÄàà …Ba;Ç¥Ùô˜ššC)E>Ÿ%W,rìME¨Á-XXŽÀ±;l½-b•.°mei„ÔHD:šeÏ%Éž:ý¾ŒÃɤ­q;æa™}¥Ô¡Ñ""keŒöP Ññç†<Ú¶ÑÒ6¦“M‹ò@{öìB)Å+¯œbvvéR·à²d3 `Œ§ƒ¯-8<FñôosØ•L´mõ¯5LM͆ŽcÓßßËßžT¬y«`–3tK‚e'ª?v÷0¬ßKj£â%ض¥¶%pAäit ‘Âh+fÿ™¼C&름OXÚ¸±Í×:¢`eÓãÛ€C ¬Li[HJÀ›žÍž½ã öEŠï}ïU‚àêÒÉa²ÙÄ.7P@d|ßk qd¼ƒÖE ·ï,/¯Ñh´Ð†‡ûyî¼fºŠ!|¶Qïɨµì ÆÝ³âp¯-M'é|c. '°bdò¡A@Ú&bhIM®ä˜}¥Ùnˆ£iB)\Ûn«})B`kb6^Gt,¤øÎúÞˆë:4›>¯½vv[÷'‘K•ƒ%Àp€kh„àÈxÐv¯†*eü}¥4¥RžOòÒ¬q·,l):ln¢¾E¬†c{Oüè„õÇœÀN¢m–¹¬4Zò5æ÷Ç1fF ¶9®-Vq°:Ñv!- ¶ÖØ:Ž=HŒËÿNUK*ØìÛ7ŽRŠ×_?Û•ÀºRÙ &ÔAcop;Ǹ$Æ>øOûAŒwj€•MBÀ—;Çp~~Ï3Ħ··Ä3S2æçðÍèJT¾©µ‰‰¤ÄΖqÇÇew4KÏ@Ä`BitdÖGbgŒÆ1dPbKãæÙˆ6ãsIø‚”¦ôÆŽƒL†¶1¯,FF‡Èç³AÄK/mß+‚`Ó0sÂÀŒÉÈtãµÒâ0@âÀ¤„'&&6œØf-‘0Œ¸pa­½½%ÎW%35qàFÊDEw¨^­ÊMB¾Ä€±ÚÚ"…€£ª-Žu{j¢0Œ½A¦àÆmþ€LÕ¿É1ˆ.`&àtDr.Ç5ß ¤` ‹ýûo@)Å©SçYY©n§oR `òí¦”ÂNse2^×ÌÉjÍ@¤R›³œ‰Åu]àÒ£?ÂùóóAˆ”år‘g§ ù’¶4l^´‰–ÕË7±~Gð¬$Ý«¾àÅÍ÷taÇo pìŽH -Íj3=–“±°ËŒ~!±„4&fJ€Ö-4`‹ÝÄ–€%,†úèë+Eßÿþ‰íô a\{±^ ´5€H5Àµ«íȬº÷®³ÿ› óÄM¢g¥4ýý%Þ\¬ú`gâfÅÙ¼$\+LÈ6–ЩvHFw(–Wigô3ä\;MûÚx1„€0T&1‚å€t$Y;“æ †3—P¦Û¶Ê÷Ù@(A#®D …`%’ìß¿‡ùù¦¦æh4ZWœ+èäë便MŠ’Àm¹—‘ ‡w5®"ú’öÿwþ÷ïðì+³ A£¹i$Ï/Ô …<ÇßiI¤%i!"2¤Mcn¦§–ÖFµj(8<+ÒÑ,‘úýù>D6kÍfÓ'Tš×§ÖÂD Þ8€ëXhenªšœíª“Tk,“^†åÕ:oœ3Â1÷Á\ïÁ›Fé)æ°5„Rc9¦î a³§·D.—¡^o299Ë{¯¨sÂŽê«ÎûlÜ@ËœÐ׎Ž=ôß ‡Ò°¬d ÐÖ`½Í_«ù,­µÒvãH¥¹\†š/XmtL"(R ê*ÙR‘B MË Y­4Y\n)Õîl[OÛ=ŒU²ú . i´¢HE-?`fa×uLç*£mœ¤\\H,aH H"€¦fWÒߣˆ0Rd\ ª(…¢$2 ZB2<ÜRгgg®¸sÖ{‰9XŠä5"nQØE±J¬¸Ý.àfÉÍ4Âá½e”Ò 9&×âÑ%^’×q‘Zëx„KµÖf„'Ç(ˆZ·µ‚R¬T)¤€¬ãPÈeÓVÌeq,‰%`°§€„qÑH| `a¥nH’R†8J‰\i˜š]îˆG÷3Ÿd3‚á¡4ÝlI<ÃeLXÙslúúJضEDLNÎnz¶’Íâ Í\E2èâ@p¤¬E¥H¬ß²²{÷nÀtˆÖzS;Õ)wì+¡”"›Í"Yh€•Õh¡ ÂÈDb -õ–B£€V<ú“J)Àó#´RHKâÕJ3}PÎ;rquŽm‘q%VS ¤NKÅVk!ad€l©Äû0¤JE GJ„Ð,¯Õi¶,‘X}sÃ{rPÊçyóÜž¢“O…àÎC7 l Eh!,‹]»8{öÿÇŸã©3é=ú½OÿüäÃwlyû×s€äþ&5×"±}/àRnà‘Ý£_ Íš211O· /:ò¹q$—ªÿ銹 ˲ÐQH9§ÈÚšœ Ka¡pmÈHE9«ãÈ]»i­ñ}?fç:¶ÉQl£Q"•ÂP 5û&M5‘ %‘˜<¿³}ŽÔ ±¤©¸ŸšYI›ð޼Y[000@«åÇ- Õòi6<‚VË´0fÀw,víê7….y‡“çæã6Ç /Çó¼-ïÛfHÄÖ2íC¯‘ :SÀRDQ”žàVÁ€RÖB)…ãØ¬¶â¡*À²-òù<¶ec;6ŽëÄs÷Û!_ÈáØ±+&b”ܘ®ÓI”š(ŠP*¢¡ rY‡á¾LÜѤE¤Ë…)ѳ¥!2YË«MšM?žÝAoNP*É:N×öd½ººÚž{D–E>op>Ó­pŸÿþó[=tØ<Ô9/0áe×$4þ¡ßË7uj€„ކáeW¿”r¥4–%i† …!NŽmẎcáX–eaÙ–±Í¶c;X–•xfÄ)pT°¸×EºnöiiM-Ô©Ý¿qb»³ä+Þova)ÌóÉ%"N-›Òùùê†Ñ_tÁµ` ¿¿k{ç:aoÓ4Z ²Y¥Ìlžõ ¸Ú,”Üs;áâêæ^L w'A !XΘþØØXjÿ×_Äú Ê8&¾®”¶-š¡aßÐæB‹Ž€‹‰ôE e|õôN‰æKñB˜êÌÕZ,4ÂÔÞ !Ⱥ6#¹ÔH€šPGiðÇÂÔT‘ñ>èîàžœ §\Ƶí.³Ô©À(8 H Z\׌í.dÝ-oøúû·>´AÄ7B]‹š@‡…Œ…QÚ9KnH&“a```Ë\õz)çúWJcÛ6­Èxé´-ÏuëÚ°éÐS¬®zDña"–Üid 4È7fªÌ¯µ@Äùý8w $ì›±âÊaË„—‹›Z«…•t~ëXX‹6¨þbFàX‚þÞÞ›5AüRƒÄ,Åué®k´@1»¹ØLÖ»ÉþÐÖóŽí’À­½!Ž E.I,gÆÆö ” ŠØ¶}Ép9g¡”ŽÃ»Ð Â1ùùÄVš¸¿JC¯`J·t iÔf< 9›|Þ"Ÿ·)el" -_1½ÔÀ÷#ü˜”óí92àØ’‘þ,3+-$‚rÖØðÕ¦ÏX9×1¢A¨»F´Г…Þr§ãA˜û$’‚@Tì(aÌ@µZ§˜Ûüñø[™€õ÷µ­dLÌSU¸ã¡à#»ƒ¶ý÷%Tíˆ;ÆÇShY›O†è¼˜RÎh×u #M¨À•æW»n êÞ&mRµ¯•¦Ñ4 ŸÕ5°|I>S¢RY­øíÊždn€$ù†ôPŒ Yªx a¼'Ï|µì0Δ)¥ŽîqFàÚ’þÞÞ®Oí>‰vÚÜ$h!Èd”Òä3ݸ˜ÝÌ hss´¨}F;‡ww$–]SóÞ’Rv]Àæ¹kb`ƃ±ÿ´™}âæ Ž4éœ.0Eœv{^_¢ý“¾¡¥Y?Ñž!”€B€VŠáG9„‘b­áÓSÖhI¤Ã¶%B*DdÀ-”³ÐÛÓƒ½ðÓÒø€F£”Žó;|+-ºU= €m V<'@zç8Àî‡ÿ‡1``wØžj½ìšõ‘‘‘Ô²ûë›1ÚJ#D)ç™K9‰ÍGwºd´¢º~.oÇê¼²bs"h»‚€H]2)ƒ€‰Á2½y›©•º¹mq"i–K¥[΂k[ôõôt?8–ÜÀÂÈä"Ð â¦CE½ÞD)Mµyy“G¸Y-€H'…°]/`+ pa”j€%×x###›Úÿ­Õf”j€(2AŸfü› +Ž;2žêenX.'Bàd$½=ªUü±âÒ¯¤’ÎîÌšó!åIØW*EÉu©;&pd§Ñ‰˜p¯»–4èëé‰ëtû@1ëÒìèP \Xh±ZŸâæ=ƒmEÔë-´VÔZ[?ñcý½Lâ,Ÿ§@u”„ ÌÇmÈæ^€àˆ«a(ŒRb´” Èår”J¥Tý¯¿ˆÍÜÀJ3J׾b5( Š4~¨BEF„" 3³5VÖZi' ä-àØ’œŽã˜ Z¥#<Ñ"iåmz3ZZ3Ø_&çŠXh S ÄÓÄ0ÄϱmzÊåT­K­Ó6Гߠ´ÒÔj-liHšˆŒ»\¯7PJSo]úÉcÉýK欙sIŠAbæ´“ 8<†©;ƒ€e7`tt4µÿ[yëÅ5ž¥f +Uì¼Ä5qï%˜ŒòåÅ&+k­Ôfær6{v—Îɘyá~vñ0Ú!õ„ÉÒ儩㛯ÕL=pè!tJiº£É¸Æ°”‰Ý>Ñ&§)€ÑùŒÜÜ4ˆØI‹"šM04Z°î­{ åE"¨‰X²UÛv&^€Øá@БÝaû9@-KѰ¢Ôþ‡a˜¾àRu€k cÞ\l¤^@²mk ú:F?°a ÐW.róîæ×høDšÞb¶½OR©ÔÐZÓô~ò=ž=i¸Cç€YÏ£:s-ɾíyÆymÓÕíy›‘À[ww¥»`hh(=©õ.`§!øì§ïãÿþóOF3¥zYY©°d!²¨H‘u%h…%eWf2f$ZI­ Òœ›n0u¡I¡`“ËZ8ŽÄµ%vìYØBáùŠPõk²{ĪÞx-Ø×Sd8pS˜€ ˜§a’>Êi¢Jexp¬ë²¸´D¤}ùtÿ¨é199‹RŠŒí±{Ðåž{î὇f8yêL×ïlfÖß×´@„ŽËÁ wÎ 8‚˜:Àn`pp0 /ù.@­5Y×âÞ÷ÞÖÏ‹˜šª²¶VC‡>}NH%rBÏf»æîK 9×!Ìd°¤Ie² ™Zž­i6MpZ§sÇú4Ž]N½hw˜)o[¼ÔÍ+©QiŸ;¦’¸˜mgûÖƒ`3é)—)‹´<Út`Ôò8wn¥4÷ß'øÀ]”J%^{íµ´²z3Y¯ ³È˜¢DoíØ#b„8RPŠ>Õ.Xt} …Ùl6Uÿ— ÜyçéúÂÂwh4Z,-­1TʳְAƒí88¶lgêb&›1S¾bP¬Õ½6Ûï:¦i}pmA©\LÏ¥s¿(ŠL Gë®íY;Ú±b[ªikœPlÀf Hr–”¸Ž‹„hÌ蟛[¦Ñð°mÉÃßol,0¿±…&½ØÔpÓ3šH&k;:<ÑáþÑö+Ô^ŒŽ ¢”bqq•A×øô*ŒRBØõ;„Õ &Ï »î|秃EA1 ÅR;ÎÔuŠTát|–thVfLÀȱgIDAT Aç?¡R ¬o[‘ÁÔÔDm«6šœ={¥{÷ŽáºöEÉòzÙ,¤µN5€ö©°c¹€#ADr‹kN„/Ujÿ\N(­5ãーöÚ9–—+Ü¢ 2¢€Î$7¢ýcˆÚàìÍjÑl™ì cAÎ…¬k&‹ô”KôÅ«‚Ô}Lƒ*žK'é "gïM+`3¬»VCÆLSJ¡£˜O(…ßð8sæZkØ|åÅx”RjC H)…Û9)¤}>Wo&>ü?ö ÄîÝIÅ,Ä9€$ljûº'8\ì"îö-G¡˜ß\CÄç„!ùMÞf*0dJÅ|ZÈx\iÝ1'm«Q+aÐ{•:óóæé'BlñÛL:ÝÀõq€Ä 41ÌØêðD\<Ç M⢻ •—ºˆNÙ·o”W_=Ë™3¸çž^.È,­@ 3º+·ŒDi‹vnA±XÄ’¥Žm‘’ÇŽ£¶ë:$ Ã44Û©oŒZ—(’Âж&$Úë~99»(j‡—£HÑ\«ò쳯 ”âÖ[÷P.o|ÆÅxÔf. ´I 9wAØf»;ÂŽŒwp€ÅXôõõ†áû9 D6ÏÓk4ZLOϳǭƒÖ„~D¤6ùN\ÀiFcçAÍÀîLÁvÃî]Òôõf(µìâØ_ø¬g'[q€ÀMàGC}¥Ê¹³³LOÏ¡5|ô£ï»l»¿YÚ ¥I(- ‡ŠTŠ|œkÀ’ëS*•°m›(ŠÈd2—Þ ™ŒËí·ïC)Å™3(ªe ü­*J’2‰UíIë$¹fÏN.¾¹(¥L%ò¦£® €eÞ$£®ÔíÅ:? M¨ Bê«Užyæ8JiÞóž[¼ä½Y^—šb4¿¸jÐ ‡€I\ Á’ã§ö?Š¢4p%#¿óÂÜK6ëâyçÎͰÛ1S§ÃF`¦ˆ­ÓZ¶ãÝ—èãîïmrl™þN|®ñÒBÒéD("¹1w¯;–ɺIr…éÖÊòo¾9Éââ*R >ò‘û®xôw¦‚;¥íÈtD2ÕW€=þŸˆCA;¼êDBÓßߟ–]êµð—†m[Üyç-h­8wnÙª3,h Q+ ŒT×}˜G¸l8NbÒ¢‹Mk-ÒsºøM°’nO[ "”V]ž'n‘Ö´ZJ›7’4j-Ö–*©íß³g„r¹ûñò—;p’Àz-EQš ‰á7Œý*5@ü>À‰ °°Îþ'`»£?iû÷ï¡Tʆ!/¾ø&#¬QÔQ¨ ý0ŒºM¾hKl©tçLV;FyEHËêê¼Îß²buh€ÐŠº´DÒTGK;óNƒÅ™E¾ùÍç©Têæ¡ŽÃ_ÿõÓæz®àþtj€Í" ŠXâêM€yôDg8cÐÛÛ›Úÿõu»ˆ­.ZJÁÃß…‚ÕÕ*¯¾zŠ=b‡ÈˆS : 5’é¿Z·»Ðtt×lì]Œ=µ69ïdW‰µnü+ÏyìØ/93m- Tæ £(b~zžï=÷ §NMÅaß;¸ùæqNšâK_úQ\p¹ƒ¦3 ¸áé *éô„ú‹ñ[ÀX¨Òƒ.¸>BÊåòEGÿÅd+m1<ÜLJ>ô”Rœ?¿À¹ÓÓLDË­Z¡Q{¤9ßt‹îÑÆ3ØH ; X7;[ »mûMHÛÝ 5B ÍV€šs‹”fnz×_;ËsϽŠRŠ»ï¾›n§§§Ä¡C7óÚkgùÊW6·óV÷çò5ÀÎ‚ŽŒ…ÊÌÚŠ싎G©TJmO>ŸßôG.'´Ùwn¹e7 «<ÿük¼ñÆ9òù,cÃ3N?¡"P±n™ß -ÐÚ‹tgï´9¼1Š",ÇIwYo×ml"E¿Àžh‚š¨ÐˆêˆŒìŒR¯åwrqv‰©s3|ãßC)cÞÞ÷¾Cqš»ÑhÑhx ¹ ÷éb÷g«§ƒ/ ­Ò8À„‚LaÚù‘„Çg¢w$µÿù|¾ë".'¼^Öçýï¿¥¥5N:Ï‹/¾Á{ß+ï ™Ë ùš@yÈ‚ƒ6R˜Q¶DhÒ ‘&„­ÝhLÐlK–pE†B«È!ëv2ŽË0CH»#…×ê¨ÿSŠÅó ÌLÏqìØÓø~À®]|ìc¦ûœ;7ÃÓO¿Äáþû²îOr¶ªâXsØŽ\… Øó£ÿ"/7MD âçó,»>èééIsÅâöížð‘ÜKßøîw_aaršÑæ,Nä£"ך!SÊè}-A9rH€3ˆ9@GI÷zFŸ“y[‡±E[å'ö>Òš¦Ðhz)ù ü€ §Ïóú«§ùË¿ü&Õjƒ\.ËÏýÜGÈf]ÇfrrŽ'Ÿü>££<ðÀ‘+¾G[Õ€) 'ñ ’tèU’ÀÛ9EˆØÎ&@­u¸Ô\ 0Çæãˆ‘oøÁÞàÍWO2\›#ë×ÑJ4ZÕ^+ ͼAÐ`K´@wy£°$çÑe9„D »k»Òš–P«·ð‚…E³Þâü©i^xþ5üi<Ï£¿¿‡_ýÕŸ¦¿¿˲8sæ<_ÿúsìß¿‡›oÞÍ×¾öý Š»Ôýé¬ÜPŽLû)©åÛ>”+eÛ ­ÎçóTÒNB€|>ËcýH)úÑûìák_{ž™™%jµ¸ýö›è Qè!(”¨ûD-IèJ쌅ãZ8¶y¥Œ¥M:a :âéyÅ+¥‰âw ëŽ|¾À «æJ•µ¹%f—yúé™]BkÍÃßÃÇ?þ#€&Н¿~Ž'žøwß};øÀ‘ô‰¨û÷OðÒK§xâ‰g¸óÎ[ð¼€Z­IŸ³Èй?@ÂúQðÛô~èAX™®@Ðúûdžf"Œ¼Ê8@’ ?2ªôù|HÁ‚Ó¢X,¦ö(±ÿÛeüWò»ï>ÀÀ@ù—ßbm­Îw¾ó"CCý<¸—r/­R?Q±ˆŠ"/" C¢– p-Ç2o‘æ]2Òd ÅØ~c†s¤¢` R´Jcüt,[••™EVWyþùœ<9•NtýàïâgöÇbí bWïÛ8°GyÚù`vããÔëMæç×p׿@ï¹…V52z‘PäiM?ÃÊ×›Þ‡?»ááæwk¿1ÌÈUi€#‘J;ß·40^N `RǶ•ì40öíå—ù§øú׿ÏË/Ÿbnn‘ÙÙEvïæàÁ}ä{Ê„ù"ºP@g2(4x!: ¥™JfI3ÍÜu2Ô“’2­7-ócã•àUj´VªT—+üàopâÄ™˜™Ñü£?z/o¾9Í“Oþ€~ðN^ý_þò“Ü~û>lÛæÍ7§¸åóÝ ˆ˜Ÿ_"Š47Ü0†ãXDk§°_ü"ª‘µkdÃE´‚šØCóü3¨oüjàç7ÜÃÂp ¨ä —Û­ ¾áÇ>3 ìI<)X´Í®ûEåryÇ:ùrMB¹\àÑGä¾ûòÕ¯>ËéÓ3œ;7ÃÔÔããCŒ ±kW?2“A‹èb•¼ÑSj„$9ÚôY´Y~2êƒF ­fZ½Åìì"çÎÍròädšèâÑGäàÁ}!îåoþæï˜]äÔ©)î½÷6zè=LMÍóì³'ðýÛoßÇ©SSHiqÓMãh­WO!^øçè B¡ìPp\t³ÕZ¡¨'©è=4§ž¡´ZÁâý(ao®„™ÛŽl_Án­ ³FýäóùtØÅÞ r¥|¥@à~áÞ|sŠcÇžcnn‰³gg8sæ–eÆ8>>ÌØØ nÖ%²”c9ÒqŽ…åØè(‚ DFSèx=ðΟŸçܹY¦¦æâ·o¢··ÈÇ>ö÷Ýw°K%öðc?vO<ñ ÷Üs<ÀÄÄ0añío¿D«åÑl¶8p`/®kã/¿IðÝßEûkô SîqQÍ•4Þ Z+”™dMïAUNp„*/ñã¨ØCÙ T p5eá·ŒÄá3! ¶ñ …aÒ××wÍ;ùr¾sË-Ü|ón^yå /¿|š7Þ˜¤Õò™žžgzz”Ëòyó&ñ\.iÙ8íÓhxqt®E£Ñ¤Ñh±²R% Ís´Ë’Üzë ÜqÇ-Ü{ïm8N{TçùŽðK¿ôÎïÞÂ0âäÉóÜpÃ¥RoéMêOþÊ[£ï­ôŽ £›«éw;AÐÃ$+j½zšCâ?óŠõ”°7؉çˆ}Ðm `5‘Ò¼J5Qÿ›É[A7ûÎí·ï‹ÝEÍɓӼòÊ^}õ,kk5–—+,/'‘A~_Ç£Îe’XÒr¹ ‡ÝÈ‘#7qðྮòíKÿfç~óÍã,.®Q,PÕ3,í7Q­U†¾½·¢Z«]‘FèAŸ5Ér¸‡^5ÍA}ŒWìtÀ‚’GÄWaö(3±"ÑóV‹B¡Ö¬·ÿ×Ò¼’ïH)Ø¿‚ýû'xôÑ2==ÏÂÂ*•Jµµkku&'Ïfbj.—¥TÊÓÓ“§§§H¹\ §§Èà`ûöuÕ^IÜ~+Pû~@&¸ÀìßüwDÍUv½÷†¾ÝZI÷¹ú­IÃ=ôDÓܦq^ÀÆJI á„Þv.`|H·@uÑ!»bûE½½½—uÁoµIèÞfìïÄÄp×ö/ùËÜu×]ŒoyœË‘íœ^ÍSûö¿±ûcäž¡Z+[vúú¿Uk…A{’…`½Ñ4(µx]–p¤$y|Nǰ߶ˆ†’ m ŸÏ§I Û¶©V«$sׇ(7Ûv¹7éZ£Ñh¤!ì·ò\ü•Óôœþר Êø÷0vç½à¶³©Wg’o»ìE;PÇ~^#”ɇD"™(º}4{Ð ‰Õ07n~~˲øó?ÿó´¤ý´¨«uÊVàØj=›ÍR,)—Ë”J%Êñ<»äïR©”&s®´3šÍfWû­Ð^þê$çþÚ¯0~Ë ã7@í4²°/ÝïrA@k…¡Ì$sÞûz4âÎïÂîG„2!úì±ß¹x~ ±S«B>œäÛ¤ÑsssÌÍÍmø‚”˲âGºÈ´3“ÖùYòù¥dmmmÓcuJ>ŸOÁ0<<ÌØØccc ^´J)‚t&Ó[1ú…TO‹ ±J626R…ú™®}¶ ‚]™)f›4{gGžÆzñ~"³ó¶F?üÅ«Rþ²¯!ø©p/?¦n a…4DHS„Ô¥Y¯Ð ¤Ô£€†¨ãã_$µ ›d}ÛLFƒ¹¹9Nž<™nÏd2ŒŽŽ2>>ÎÍ7ßÌÞ½{Ó)`ÒÀ–<²FA&“Ù²£·ãþöú8µsߥ1û2'^¨pÛ§7Ôßo#¹).4&höÍ < ¯}”uâk‹ðן³ŸüE#²B’ÃfP´³NI”Ptx ÉgÐ4hP×õxÙÐ>uPÓ>u·À§®š­ð¾\ H)iµZœ={–³gÏòï|×u¹ñÆÙ¿?###d³Y&''YYYannÏóðO±XÜ‚ˆšmÒɱû'ÿW¦¾òß²4ó2¯|¿ÊíwíÆòSœ¯OÐèáÞú þ·×dÛZköþø¿Ìƒø·~~ä z”„ ,ã¥%( AÉ2ëE)p;@ÀzpÄËä³d"ÒTìÔ•H-ò 0"ŸZäS<³-ò©…ñzèé­L½8òù<ƒƒƒ¬®®211‘vòÅLÆåˆ”’r¹œ¶žžž”¯tþ¶ šL~å·h̼L¯Ç¡»JÈòPØÅM+ìCù ã4WÐñRµVQÍets5ýLµVÐñR)˜ªMÐó¼º6ì=UúÐ??sÅo©*nïG>{ÄÏ xÄÝò$凈™gVŠJRR–P”’²eþN€R²eÇŠñ[>SЈp$ëI‚#ÝMRZÔBŸZØ¢/ka‹ZйîQ [xQ{båz5î8N †õ#ýú•€E31D¹\¦\Ȱúägḩ¿×ãÈÝ; ‚Éêõ F³¬Æ£W ±ùØ÷Ñ?è1*`!Æ€Q£b@Ðb@@+FKzCâÃÄÿÍß9))ÛP²%KR¶;–vçRRr=–¤h‹ôyÃÉï% l¦ Òj2Ýl²èµÈ ­<ªA‹ªß¢´¨íe5láG›ÇQlÛÞŠ­@³X,BöÕžÀmN3ÐëqÇ=; ‚³´8f;W‚‹àJäæŸüœ@РĀèGÄ Aôw€&Ý.ý@OgÇuÆlH'ª,AÉik•²#)Ù‚’-(Û%GP 5O¯†¼\ éœe6š±xlÌåǺøªMQ©…~“ªïQ [Ôü¦HXj¡Ñ0Úhv°l’œ+9ÌÓ”õ"}ï¹wgApzµ­ 2îåƒ`ǰ]¹õÑ/Ø M"bÀí’€dD§¶‘kçA:5A'9¯§,cÀ{Š–ÎH]Á +rD¼.t$ƒ¶ kA2Ñ@'E$Iî ^oE5¿I-ð¨MУST ½”ÃÔ"Ãa©øØ¾Fó-û<îºogApju‚šŸılæò@ðCÀvåàÏüq–ÐÇh@}å/~ñÎïzìÏ$ðIàŸ‚Þ¯;‰vGyqÞ 80äJÑÝlÁ€c¸Z›âÔ¤¶Që¸j¹c{üw34¤¶Öð‹Ç°œ†ú=Þû¾Á›Ëq,—»4Þ±¸Z9ôØŸÙÀ(èq »q4ã Í:z\kÆl»Ä8)5×d„`ÐAG2àm°ã¥%´e „ŠÁ¡Ú`ˆ´ÏŒóiZê÷¸ûý;‚HÁÉ¥ ª±&(ä/‚w-.WþÌ¿=Œ£õn f=Žfw  ~ÒûØN9Û"…%°1ÚC 2À)ü'ëñùã5+’(%žº0—áÛßÜYA øˆ›Ïýk¸ÔÛïË[.ŸøüñÚ_|úÐ#êñóó™¾õ =|º;|ÍöRÉ­jfà$Säfà:Þ–’€ ¥Õãçç2|óë>ô#W‚ºÏNÐò%öØû×F£=ÿ3\7o[ùÄçײB>¢´xjz.Ã׿¶}sТÄw»4<‰?pjß'z¦nºç\ÀÛZ>ñù㵺e8Áôl†¯ý핃 eùöÓ‹Ô =|?þØOÑhza«å½®àm/ŸúüñZÓ‘h¥ŸšžuùÛ¯®]6š¾Í7½D½æáîygÿDZ›F£Õj­ýpïùÔç×Zû­xjj&ÃWÿó¥APo ¾úÅ'¨®5(ÜôaJ‡?‰eÛX–¤Ñð¬VË; ×ðŽ‘O}þxÍËÚ(ÍS“3ŽÛõzÈãü郞Vè=ðã ßû‹ØŽm›y7›M»Vk¾×ðŽ’O}þx-¬ÙDЧ&/dx≠¨N=ÏWþÕ¿ º´ÌðáŸ`âÁÿiYX–©²žŸ_QͦwaqÑ~®‡‚ß‘ò…ÇÉ…ìõx䑬ž©†#üÕ¿ŽêJ•‰÷~Œ}ÿ*-/ Õòhµ|¦¦fùÞ÷^#Šøñ?ú£ßú*\À;V¾ðØ¡b” 1|°Ì—ŸPT+{ï{”Û>úiŽæ!L¹âjæ€*Ýþ 14Ü/¤”œ??Ç™33ÁÚZ=TJýãÿð>óouG§_À;\¾ðØ¡¢os ‘ÿ×÷ô£o ­h­ß§”Ê Áóa¨¿+„þ£/~ñ³“ë¿äâ–Œ_–GþÉÿûÆ÷.ù´Îurïr¹î¾Ëå:Þårïr¹€w¹\À»\®à].×ð.—ÿ€Íïáwi—IEND®B`‚djview4-4.10.5/src/images/djvu_fail.png000066400000000000000000000127071264256014000176710ustar00rootroot00000000000000‰PNG  IHDRoVÁ°ÈsBIT|dˆtEXtSoftwarewww.inkscape.org›î<YIDATxœí]Ùo\×yÿÝuVr†C)S¤*’’,Û”-Û²x‰ã8 b;(ܦ ¨§AýZô%Aš¾4}*Ú¢è ¤M‘ 0\´qÇuÜÄŽ9’,‰RLQ)‰ÎpÖ;s·Óå;:÷Ìò’5dÊ@Ìv—ï|¿ó­çÌPaŒa»j¿ØÃÖ±GÞ.Æy»{äíbì‘·‹±GÞ.Æy»{äíbì‘·‹±GÞ.Æy»{äíbèý`#‹EÀ!ÇÜ©)N^SÝ~P>ÓW]ßœpÀ §Ÿrß(;qU¡X,Ž)ð¿djí¯:¾y4¦·œ‘ä"JÜH›Z[1u ¦Öàúl/ކují‘vÙº–“ŠZç”ãſϠþK¡P¸Ðï1mvyÅbñ˜©Yßò˜öØÌ9ÿÐð{ɱô ÍÞÔuÏÄõú®TïìÌWŽyl/ñ ÿV(¼m¾Øä‹Å¼¡¶ÿVQØ3Œ¿?2òŽª©¿3¦àjí0Þ[zºQmÔ\?öÕB¡ðŸ¿–‹÷}'¯X,>¨)öŽŽ¾•ºÿŽÆ mûBÕbí~réù¦ãÅ~ìøñ …ÂÚ¶Ýì6 ¯ä‹Åºj¿úäÔ¿¦dÏ­{,c ß„¡v ([¿§çkxóʳ_–¯¹¾ùd¡P8¿õ«õ}#¯X,Žèª=÷Ééï Mfæ6<þÃò½øŸù/z P4Õu’z£½?s!>>x1618‡ÍºÙ ¥ûÙO/¡æ1óÉB¡ðþVÇÑOô­Î3Ôöß~'…88sãÑ:ƒú, šžoNÔíÜgϯ<ôõ7.=ÿóïüâO[§®?î9žùþ‡GÞS?øýAMµ_-‹¿µÕqô}±¼b±8ª)Ηïý«xLoox|µ=Œ—ÎþñªãÇG …‚r½c†Úù¦®užüì¡o§rÉë‘e9}ã1ïäÒSç?~ßnËDûey¿=‘™ó¢çW¶”¿ # …©þàkÏZÎà‹/Ÿÿ£æÆÈ‚ÌŽ½¡ '—jŠóg‘OÚ!P°Ûýw×Ñ™M_NEÐg*>\{Ä|þw_øó®[(¾ûÔÓÏ¥~4ÿ‡hØ™ÈJxâà÷Rº®ÿ…eY·]å¯/–ç:mÄ4+Ò± kwcx8‡t:éø‰‰ Ü3û ~võK‘åIÇÖ05ôΜ>ùœÕó<0Æøßí€KÁr#Η?‰#wØÔõeë JÍñÈçù .^8ßõÌ;j?–üè8®5ïÝð¸zgkÖ>LNNnêúš¦aö¾8³òéÈç %–‘0jXYYÙÔ½ú ]ùUÅ[­VaY<σëºð}ªzÓ«ªª UU¡i]׊¢ðs ÃàÇÑg„ÉÉI¼õ³q¬4'O]í)ÜùÒÇ0<2†¹¹9hšÏó iZàºÁè:ÿ<ÄÉÚCä¢~<}—æ‰T*×u¡ë:\×ø¾Æ4M ¼_.—qíÚ5˜ŽUUº®ó?”ÎÑ4 ¾ï£ÓéðkŠnY×u<úاðÿŠëõðËg*.¬>„±}œ,zô¼îŒžd£ç‰Dºn`­=YÉ˨®]‡¢(|\$¯x}"–Ëú«‰.{±íöjº¢(ü&ªªÂó¼P«S%@PØ h Š¢p `ŒÁu]~ÆEÁäxüÉgðÚë&rñ˘ʾ‰¡Äu$ŒTø¸R½Éd‰D‚[p“8Ó4»"N0’{p …zgC‰åHÊÈÄWÐ(5ºÆGžHœ|ôc ªª&©¨¿í×¼çyœ8+ô}Ÿ+†„I“Ý% ‚ Nœ¡ø/þ>æçç±xõAœZ,£Ývà3]S1søN~]"0w)‡& ='¥š±Ú#ˆéç–U‹îQUU8ŽpÙDª(<Á·]+éä&IÁ¢1Æ8i¢Õѱ¢@„{ž˲`š& Ãà×;räŽ9Æ*•J öÊ®Ç÷}î6iRˆ÷Ò4»½X< ÛJDV†¡Úp½[ç†a•åºÝLŠ,PNDrt]ç®”Ž‘ !ºœz½Žv»p5ÏóÐjµ¸›¢cD9è¹è%lÛ†eYØdw,j'²2<¦AU‚ºÐu[¶è.Eyå±ß."–' **”H"¥Ð ÈEd+ ø&~±X¬+c¤cWVV`ÇÕ â!ˆ •ªªˆÇã\nJ¤ÛB,ÙŠ¬ ÛMÀÐoɯë:lÛæ“Èu]”Ëe.¯ÃdÛnbžèäDE*Œ¸|= ”®·¼¼Œl6‹x< æî»ïc §NÂÒÒR¨‹ŠÇãH¥R˜œœD:F§Óái¼˜6šM¤²ÕÈʨu†‘J'»ÊÆ<ÏÃÜÜ*•J×y”]ÓDºí ‹˜qÒ#)‚f³ëº¨V«\8Ã0‹ÅJ¥øD¡E«£çäf‰Êå2r¹·Ñšòù<²Ùl „!òs¹w]D¼m÷¹Ø¶VËÁpòZde¬¶ö#;tGW¢ÂC³Ù„ã8˜žžÆÔÔT`l¿iœ·«Î MXÄBœ„¡ºmii Õjp6 aß¾}B"‘$ ñ…œ‚·,‘Ôn·‘Ïça‹º®Ã0 är9Äb±À (^ˆpœ››Œâñ8Çá3\<‡\YX ÏÍÍáÌ™3¨V«ð<©TŠÇN]×±ººŠêZ 3¹è»æJ`rr‚F%‰¢(hµZ`ŒappÉd’G“GôT¤ÇÓ§Ocuu•OÆ0ˆV+êêí·ßÆõë×»š2º¢*]LNRÈjäLTD¶:V\¹;-¢€b Mìô’ĸIŸ‹.™îsúý·0;ú£ÈûZ:nçJâλîãcå&—lF`üò#+ö‡Eå‹®V>@Ç7 žéF"O¼°¨0ñ=Ù„ÅÙGVHŠ®… BhV˳‹ˆ k#…ˆîJ&NÜÜÜY°Î<î}#tÀaxgé9LLD"‘x’‡bðÐÐb±X¨HNÜÝ‹uª8Ù@èsñµYŽëõƒøß«_ÆÀÐA|îóOVâÃbÉÑjµ ª*†††xSBtia]a: {/Ìól„y² äJÉ ¢ ¬.¡x*»IŠuƒƒƒ•z:‡\f¥Rb½‹ß›ýâzô%žRs'o<ƒUk œx ¡.JlÐgív›o¹]¦\h‡!êDcÜzõ\/t‘×+õJ6DeÈñ„>s]­V Žã```€“GîS¬ïTUE&¾™¸•æ~œ¼þʸçžðñé™®® ÉÛ+[¬T*ð<ãããÜ3„e޽¬MÌŽEýÈ1½i›ŠyòMÅ”žjòù<ï_RA-ºD¹S"·¾ÄNõ åX×kðëÁöb˜¯Ìâbåh:#˜=öŸžæ[×Sˆ\cù¾VëæDÉf³<Þ…MpŠ¢ðÅ`9܈™dX¶Yë '' r=‹a||œ Fè7ÄÏek´, Žã ™Lv]/¬YÆ\«OãBùQ\­ƾ}y{è8ÆÇÇ{½½”#fÃõzÇâ°=¢T„&ùððp€$™x±¾ËŸÍ$=]–× ¤H¹o)Î*9v„5œi¹§V«ÁqLNNò%¤°ØzÖ·ÒÜW/½ˆûŽ?„‡¦gH$ø9rGŽq@x,nn@n·Û8pà¿&V;Äkˆ$7—¤ÄÂ_.¾e×)Ê´tÕyaõ}N¯Ãf/½/—"y¤¨J¥‚V«Ó4y&'^—\f×92qôè]]r‹ U¶NÏóÐnßüêY˜Ë4M“/iÉMlQ_òF]ùÞt¿°I]ij=„µnd×& uèËå2cØ¿?’ÉdOK“­p3 âÃ\'Q®ë Óép—)îËÆEë[O?âc¯ÆDXÞ°BÉìU§ÈI†œ9Éä¹®‹µµ5ܸq¾ï#•Jall,à2Å{RÜjç"¬Jg¸ªÕ*ÇÁèè(‰DèD!ë(ÌS‰èƒÅö`T¨tŠeQÚb²2äL’@Jét:(•JXYYA»ÝF:Æääd Fõê^lÅêÄû‡)©×X|ßG³Ùäkw´ü#Ë@ûODkKœ^rËÍgQ&ù½(èùÛc4c{í¯_Ë7¤Þf§ÓA½^GµZÅÚÚÚÍz-“ÁÄÄÆÆÆnI„Øç)&rò÷E6=¡K×®]C½^ïY€ŠI€¸A©y§Ó ìv6 ãããH$ ì,SµZ –eAÓ44›MžÊîs+–G_8Y[[C©T⊖³DS½^‡mÛÜe®EQ`š&<ÏãÛEÂUUE½^‡eYh6›¨T*H&“¼þ+—Ë|,pËuÒ†,`ãä%@ÍÚ—ØKhúL,/ÈŦÓé_}7NçÍe±×¼*• êõ:oüRœë>XkàBéþ€,õNnCÓ^Ïv» ˲r‹žÄ÷}†Ó4‘ÍfC·†!‘H ÝnCQ4›MÔëu.s­VãëétšO^Ú‰×l6Œä@6›íVÞ&c £££æïÉÅøzŠRét¦iv‘ßKžçuÕDrÁ>88ˆFæa\õ¾YnÔkPétwìÏo¨`ÚO›žÂ"Ö˜©T*4y 3c Ùl°¶¶XÂà8‹!NóL:ŸÏó×aÅ{:^·V… ZcB¯Ze#ˆD9vaa½$¬¸'T\Ò4 µZ /^D,ÃÌÌ ’É$?¾—¬a=Ã^ä…¥ýQÆCº ‹¢u‹9CXòv¯^Ùkhcú£`³ †hmbOS|OD©T‚ã8ã¤m„­ÔŠ›™„t\/Ý…•?Q'÷z2ôýgŠI±”ÝŠî’>§ç”xxž‡L&°¸’•†á×}½­\s£ãwy²µ·f)•‹‹‹¸re¶UÀpê} £ûbjj Éd²#è1ïvƒ1†Z­×u±ººÈr‰PÇq°xåZÍ*¦s'1šZ@L·Ð´±Ô8†ÅÚ ŽÅñûOl¹º[Ñwò(П;w¥R)ÈÇÁÊË8œ{ìÿtµû‹–M{o\ù X|Oæ ]¿Nñ›Œ¾’Gð<+++èt:îÍÏß| G2/ãØ¾××=ßg ~|éEĆŸÂc?};DÞØÓTQäóùÀëΜƠqiCâ@Už8ðÏøÞÙI”J÷addd;ÅÝ1ØÿÑ„j8úSUçΞÄñ±—"_ÃÐlýo|púm”tgAðõ~ !cyy9kwZ2’\Œþ»Ã&3gñî¹+¹M¢í(è¾Ño!d¼üòËŸÈ%Ê/* ²›9o Vç1µX,þu¡P¨o—|;;Âm†ÀcØZʯ)® Ú/«îrìTò–švfý5™¸¾×7MÑ~)n—cG’W(æ}¦ZeklSç-ÖÃÐÚoï¶_iß*v$y7¡üý©ëODþbcÀ»‹ŸnØ^ò[Û)ÕNÂŽ%ÏõÍo^^»«±°v4Òñï.}ÆiÚ™9ßÝ^Évúþ ÖC±X¼_Wí×>~àßÓ‡†ßÍ`\_ÇÛW?×¹°úÀ²ëÇ, »çG¢?"v4yP,guµóR6±<|wþg#©«0µ6vKµCÞ™åGÛŒ©¯Ú^â…B¡ýWâ~°ãÉ€b±¨ø’©µ Œ©÷úLMhª·â3í×7ÿ±P(üÿi«Øäí!;6aÙÃÆØ#oc¼]Œ=òv1þ-ú³Ù™þeIEND®B`‚djview4-4.10.5/src/images/djvu_logo.png000066400000000000000000000042551264256014000177150ustar00rootroot00000000000000‰PNG  IHDRo0:v{ž pHYsHHFÉk>çIDATXýXkkÛÊíÿÿ;†:·§Ž8˜ÔY $„,1zóAƒ=ÏÚ{dÇéíMôžÈm)öXk¯µ×~È_Ο{}ùl¼ižçÏÄ?oš•Hã(Ž“Tu­TÛê®{E[d§ÀÇ+â+Éòª6Waº¶mU«”lèßÈɆéSø2Ÿe–&qeyQJ \ß›[U‘Å_Ÿ²²jT9a´ÖŒ(¬Š6¢'G_γ¿$IDQÖÒÒÓfÆ×(¡€HÀ.ð™Þ 'A%mG{ÂtÀ#8â׆NÖÓ{xÑ‹“¬jê+½¾¦á欠@@’=ŽR!*è^ʆÔ[~JU¤gð!¿*O rRâ&Ø™¾qM}Ûóg™%áEAÈT”˜W±èz0\MpÀË>ÂCÐq–çIµÚÒ°7MG æ*ˆÃKöèªqRë 1îÜYv­lØ5>ñûHÏèÜ¢ü4¦µ¡zHÝÑ'<Èã$eÙä>y†ä$·È¦RT8~¨gNÙƒ*EQk‚c¼¾3¦`E÷÷wt=<¥ªÈk´ ˆ;÷‹[êÜá3_3ó¾_Ü™æE!ë0“‚óGô(Õ$ìÂI$1‚À«S%㵦Cljå¤Ä5á¯3ÆLãø^ýèÁ-u¶¡øœPvز:TPGÆ¡ô~z¡Ô}ßì+mÆP‚ß"gSW»‡ *«ºA4½Eìqœ¬w#/á!{µ–|»×Ã`ºRà=­B¿æ"òï¼n˜ZУ²1S}Ä­uUçëoaU•Ìž}†Ô.JÝ´+«§@úd›²µèsà TÆJe‡¦Ÿ‹0ôö?÷~à>×ýL·‡ûIïJ3õìNÙ4ÑWÔà‡ž¡ÊmÉV261­+Pª¯x¨½RJ%¨õ‘—§‘䤼H±-Ì$BŸèÁãSÞ-¹S›~4[ w,gS½üØ—àÇÉÍ6‚8MVÎQ=½ 7¼êI"e޵òLˆL¯­ràÍYx8ì½£mžr=âm*Òa¼ƒ2­…kŠÇU©›¢"8%6BÃ5à ¦q~Bù+·NÎ¥Tçy`·ÈJ<Ô”ùžwØûa´q =ÎàdH©^݉âKœ'¥%ð¨Ä5[¼ièçE™W<‘Ü1rà-™HNÐ+Åv¯ÆÌ?ì÷^·ìO³õqk¡ô½¬žU×°šyGül›êjg§úñ‚WUñ[jgdzª,3w§†ÌƒšAÅn…û˜óô!]j¯)ÖßJܘäT¯xœ½®+6û¼J Ö©¢nø†²×TEêºMŸ }ÐK7n~gv9f¤ŠÓ'e•­7 xu-ÉNbñ wý^›—¼¦°“ÁâÙÓ¡ç#{ež¸ÏrH¼ÃÁãèdñæâ™…ŠAÖµ÷°^ÓPœ™ ?ª«·x5ZSE•W~}·ÐËÂÇ­¸Ýú$î3!lÓñ)Êž¬6¨¸Žz Q?cùÁ½ÎÁ³Auå ?ÐSMY½ScháRÂãûà˜mš_Sgë5€R ž#¨io€êZPþ®þT´Ðœ½òÃ$‚Íe]ŠÓþ?ÂÌ1j==±ÙÚ™7±œ—=¢®Ê໋;jiñtá,ü&Š toù©Ò>S-ü&KÅ'bçžñà–4ù’?à ”b;×Á¯Ú¬J„ªyÿÁÅýŒºÝê¿ðêe(vÜ‹²R—y|_¡¿DD/ÎÊüÂì,=2'èeOß Â£¼ðÌÚ½•“è©ì-ž sÝP¹Œƒ=„ì¥énÛcϱžæ¹ûÌùC½,p¶øªŸ+È Ã»ð[¼ÙZJ/GèPg‹!sïWåˆ~bzeýÊ+Ô®IàüåHrö™üª1Š©O#×(JoùÑ|i»ËÖ‚sÜUžlîö¼¾¤œ½º‘W~gsqgS–ÉÉahŽxV©ÁÂÉøñ&gÍrêÁ§X³[Â÷/-ͧ9hƒ_ù]·NCæ\ðfÍÆÓ‹š¯$„÷+?:Ò/Ó1É*vïïí™§!pìðrÁc~]k³[‘œÍ²sÎ:»el“¦ã)ÓüŠ·¸xñ@‡Ï+ìš®ì–#¢Än7üfÝ”Ø!sºvëC{Ùqg))7ƒiOkWPo%›ÿu‹7ŸwwöúJèµr¶‡ÖnÖ$Z÷ jÅζ¹ìZ³xä/ð_a.73šQ„áäui_ùó»yïæX÷ŽGÏ;zGºü ¥i?ŸC‹èiâ×-y:îÛ/ðb¦¦)qŸžÖ›ßv“ð}ì=G_™áo†OÞ¬Ä7ÿ§Ú£b(葨qÜ+¿óDþÂ:‡ýdšnŸf~wž46 :`߸â½wÜÂÏ ]²~–¿8øíÿ; âûd}ªuŠnø³4>ÄKñT›ÑÛ*ïÛªäôý›x">ÑtSÅw;õÞ³Öÿo~Þ/ŲziÍÊù~ÏšŽî–^;_Ïã8ý½‚G¿UX7Ûg‹?ûüßë>ïo¤=¶¼9>»ltEXtComment CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) CREATOR: XV Version 3.10a Rev: 12/29/94 ¼ÞuXIEND®B`‚djview4-4.10.5/src/images/djvu_stop.png000066400000000000000000000131161264256014000177360ustar00rootroot00000000000000‰PNG  IHDRo6ÉDÇ_sBIT|dˆtEXtSoftwarewww.inkscape.org›î<àIDATxœÝœÛSW~Ç?§§{† „X¶‘dÉ’A²0B y×UvÖN¶v³UN^’”«ògäi·j_÷=µµ/[Þ¬7eÇNmR›²%!Ù  YF`Ä}`nÝ}ò0œætÓƒcIV~USÝÓsºÏïü¾çw=§GH)yÞIZ#‘È `ÊqœsRʹgÍד&ñ<ƒ'„À˲ºmÛ®|ï½÷tS©”R^ÎK)ÓÏšÏ'EƳfà»’¢Ù²¬Þ=}útââÅ‹|úé§LLL¿üå/E"‘xÍ0Œ„ÝBˆØ³æ÷IÐs§yBˆ&Ó4OÙ¶½ë7Þ¿þõ¯Åüã íæææøÕ¯~Åo~óéºnÁqœಔÒ~ú\?RÊyÖLl…ÆÆÆ*>úè£Ý7oÞ¬Ùµk—üÙÏ~&ÚÚÚyßÇùøãéë룲²2ÿöÛoßy÷ÝwS†a<_³6„„ü«Þââ"½½½ŒŽŽRYYIgg'‡¢èî¶N>¤§§‡[·nQ[[KWW{öìyB\?ŽãH]+”'E+++ 0<Ö'AB‰ÙÙYr¹œžÞ¹išž¶)­R38¨uÁs]HêúíÛ·éééaff†¦¦&ºººhllDJI6›¥P(xf*•JÑwîßܺE›eÑnZ”iϼI¢ƒ¦ƒ¨žwײèG©¨ ëÍ7Ù»w¯÷5a¤”,//Ó××ÇÈÈ•••´··³ÿ~\×õd¡4rff†<[ð>|H.—óix$Á4MŸ¶éZøÌdiu~ÿþ}zzz˜œœdÇŽtwwóòË/û|P6›%ŸÏxî×®_ç`Ää˜aP¹òG:5\çO’H$0£Q®9Ò¥²¦†î7ߤ©©É·ŠéÅÙ³g¹uë555ttt°oß>Ïç¥R)O×” ‰Ôý\Ðd–Ò8€¯¾úŠ3gÎH$èì줥¥eà •è9{–ááaöNÕkæX=³Ô¹îu-„b¾XQQA,+ú0—탎Mm]]§OS__¿!@BpïÞ=Μ9Ãôô4MMMüô§?õÚMOO333ãïi-fð‚ÞYP»tPþIX—––¨¨¨àƒ>ðü˜þ{.—ãËK—øË_þB‚÷­(5!ÏQý…RêwunY…BÁ7" Ý²8lYô§òáïÏžæf:»»I&“¾>xÿý÷éííeppL&ãAø,R,<Å„¢0”i+¤‡ÙRJ …–e!¥ä믿æB?uBðwñ -‹ååeV³YÏ„é¼(‹P^^î=/èï‚÷Äb1VVVˆF£¾8 tG£ýwîò»ßþ–ƒ‡q¢³“ŠŠ /mRÇùùy&&&¼Éçº.ù|ÞûœhO’|àé&3LRJ2™Œ—>(3ª¢Ñ­œmÛ¤Óiþø‡?p\Þ3#¼1¡Ê`uu•H$â›T H˲0MÓ;Ú¶íñ®ûOÅ3€iš>w…!xK˜´=ããüëµk¼ýÎ;ì߿ߋ|———q]—D"áÈ4MâñøS×¾ fü9“ú.„ ŸÏ333C&“ñEUUUTUUQ^^ŽeYž6è‚TÂU`D"–––˜[XàŸ·m÷E}ʼ•——ûf¸ÒÜx<îó±ºù*Eúxt š4 þZXü+™žžæ•W^ðÒ¨ŠŠ ššš|²ŠD"H)±íâ‚…žZ5Q¥?¥ªZ›åÄAò§ƒ¥§ <×uÉd2ضMMM͆t!—ËyÌCyevô¾\×õ„¢ž•ËåÈçó^^¥¯ÀÑͤî{KJº_ŽF£>¿äQ?F¾‰¡Ò(Ã0<3©÷§ËÌqb±˜×ÞÖqdEºÕ º} ›‚.˜ë)ÚµkXVÑÄ)!çóy]ëÂ@ƒ¢ùËår^Τª·û®Lj<÷ª?a%½ E£Q<¿¶ 4·€'p=ÚÊLï/›Í277ǶmÛ<¿ õ{õ¾óù<³³³ÔÔÔøLqØx|œèŽ?Œ1eûãñ¸Ïéëe³`ž¨;ò ‘HW«¢x”LÂ޽Ȋ „m#ïßGܸQ¬]¶¼F:½‚aXÛ¶)++ÎÔBwx¸(ø^€—^B”—!Ò+ˆñqX\,úÇÝ/à46Ay9Ù,"•BÎÎúøv5~”E‰ÅbV5‚·aضÍÔÔ±XÌóËj²”² ŠÇarr’\.GCCƒ—Ú<¼ ù æJ¥Bô°ÀF¡4"X\ÖCmŸfÕÖ»?ÁÑ4IìqðUøô3èìÄ]ZBD"ÈmÛee‰@¡W®ÀñcˆÃ‡ýéÌáVäŸÿ q÷.‘ÇɿôÑD›_j6 Š—×ÀšR¢ Q†a”••y |B ø°R¼/Ì:mv¿¼`q7ÈHXgAf6 T½x”RBeåzûáa˜ž^ç-‘@üÛá“ÿðóôÙbüñ#"µÛAŸÍ!/®3·¶V‹Å¼ÈÀÒ¤ÓPUµÎ¿cƒVýRÂZð¢YÖ4»øûÆ`duuÇq¨®®ö­–„Y¤õ!m œÂªD:‹4ðÔš•þðï ž>˜°ÅMyí¦gjE»å5ˆÅ0. vQ`›„ІiMdrͲ¨@ð/Nœõ\Ñ]¤Š2Unæ§T´»™¹Ü ¸0—ò¨4³¶œì|+|ëpzàTØ5¾þº¨Iêú+ûàç‹Ø^ëãE?z×CŠÂ¾6kcTo¼ûö­÷¿V=R}«¥¤° a3?÷¸&‡Í|×§ÎŒœºù»,oè ¶bNåwúìr]d@Èù<üéßaâözÎY™€¿yÊÊÉC˜¹RG/WæOøè® Ž ^)P¥FAY© ¶DµUÚmo4E>ŸÔº`c«àéŒèárÇÁqýy¡!]Ñß_ôuo¬íÍ,+ÃØÓŒ+Ýá#Jd¸~s+¯"oÞ,úË…?ï5OijÐßÁFm 0LfaׂñÀVdí/ȈòQÊ_m…‚3I=+ òuHIÙZ¢-„@v„¦F„a`|þ9Œ!^}µø{r};_¨é\ËÙJÎ^Çö iq&'CÓ™B¡°aÛÃféN[èA+ô8Z³©K­XoFú楠ÖÍ—ZJq]׫\!®–F±²ºnT€G޽.¸H¹=z&ÓÙÈK)Êd2ÅÕ÷µ5hŠ•œÂâƒà¢¬’®Y›¶ 7TXT§º¶(­°,‹ºº:b±˜×J`Õ÷`€VaQ×U×7K—Ö½ÿX[~B VV½<.”æ×MŸŒÅàÈáuA,."ei³ŒŒóùå@YYYÉp¥ÌdpϺ.‡° ý8Ú·!I×™Ô}ž”’X,FCCƵ+µ&¬„ý®˜- 8ŽCt­vçÑè"—+ò²{7b-m…|óÇO¨ÙL§áêUOóØ·×˹0èõFú$Êår8®ã-oéäQ%HMòíÛ·oIçWÉ$8†G-méº$TŠ)}OKÐy‡%ãÁèRÝã8ÙlÇq¨\3K +iÄG‚–¨ß0 ÄÜ<\½«+Ef 6òÒ%¨­…hÔKÚdObzv¿PÔ¾¥%¸z9ý Ø`l 99YÓôÌ €¢É,Ø6ñx|=Ä¿KM·JALÓ¤¶¶Öç2ôä[7º…z\ò%éa>.h"Ja6<žúd2 …‚·•AäŒl.^,§>ºÿ° È‹— ®®žahæTÂŲW˜@ÆÆ½*NØXTbx¼é\M Û>x; Â"X¨^ß*m(L+¦6£0“Ü®VI‘²¸µouu)%UUU¡5CýüqÓ“Íî š¯°I¨¶T(áŸ\© v Ë;õh¾”ë £MÍf)ÄôkAðÔ*|:FÊâ.lU¥'¤*Rê³U –â‚ü–šxÊœW$*K¾Üì'h ÕõR² ;êµÍ-Qu ïÏÔéQ3X}×?Š ¹\ŽÅÅEo*’L&©ªª"‘Hð»Bžk¦*4ÑøxœÔ%¬rÆ»~>—Íñßùw͵kKPÁ¶ÊêÚ¢W[JM´`ñYn³€¯…n@‚uÚüଠëPÕ6s¹ËËË,..2??”’òòr’É$•••†Á?~ðW®\ዞóyŽ8 !ææ»šP}Gœâ7Œ÷Œ”ô®®r6³ÂÞ}ûø§ŸÿœúúzŠxjÛGPfúwu¯mÛ¬¬¬`Y–w˜•zò§«¬Z¶×¯)æôÚ§€ ýóù<+++¬®®zfÒ¶m"‘±XŒÊÊJ‰„Ϭ´¶¶rðàA. ðñ石SNELvò«Ç%e:ƒ“â çJ¾´ |iØ^WËßÿ䝨¹s'555ž—Ïç=@ÔžÓl6ë“™…«~3™ ©TŠB¡@]]· ¡~WE|5é·j:=ð,Ë"‰pÿþ}–——K& z#Äú˹\ÎRÊbE¾¡¡Û¶áÃ?¤³³“ÖÖVÔ{…BÃ08xèÍ{öpéâEþ04Ä^ Ë4ÙVbÓB)ðLÓ$“ɰ²²âE‘BlW2d¸àØìع“wÞy›êêjo޾Ñhvv–ÞÞ^n޼ɮ]»¼gD£QÇaqqÛ¶=©Ìûòò²×÷üü<ñxÜËÿæææX\\ô¥ ®ëR(¼=32£Þ;éªáèè( %oò…ôZz¡LlEE…·ä¢„WSSƒeY,..Ò××Çøø8ÕÕÕtuuQ__O.—óf­:f2ΟçÚµk´ÄÊè´,kýLOOcµµµÞ¤+±ª 5;;[œ`ÀUÛæ¼c“H&éþÑØ½{·/ਫ«#’N§9¿ÆCee%'Nœ ¥¥eÃÄ™ŸŸ'ŸÏ³ººÊòò²÷ûÒÒ¹\ÎÛ \[[ËŽ;ˆÇãܽ{—™™Ÿ%е¶¡¡íÛ·F½ L%ÁSèÏÍÍy‹²º¦=Ê|©¶‰D‚h4º|]“§§§9wî·o߯²,:;;yùå—6¼ªµ´´D_O´YG…Áb*å y+àIYÜ.8V(Ðç:ñ¸÷Š—ÞNŸ.\`dd˲8~ü8GŽñŠ :éÚ±°°@:½þŸ=ªthš&±XÌÛimYétÚÛ¼–¼«šª "C-¡žîãJå*¢`ȼ}ûí·|üñÇÌÌÌðâ‹/rúôivîÜúºV*•¢ïìY&&&Ø»°H[¬ŒuÖ<€oí=¶CÖ29yú4Ø )‹{&¿üòK.]ºÀÑ£Gioo'‹=rô9r)‹Û¾¯^½Êää$ ¼õÖ[=z4´X<×izzšžžnß¾Mmm-ÝÝÝ477?•q>)úAü÷˜ã8¤R)rk‹°zD¦Âä……†††˜œœ¤®®ŽS§NñÒK/ùžÜüü<½½½Œ“L&éììäÀßk ò¬è^Ø»{êòÄÄçÎóÒ‹îînêëë7´K§Óô÷÷322B<§£££d´ù¼Ò¼ïB£££ôõõ±°°Àþýûéêê"™L’ÍfäòåˆÁ±cÇ8Z"Ú|Þé¹ù¿Í0²m[|òÉ';¿øâ‹2™LäèÑ£bddD:Ž#ÛÛÛü⿸—L&ÿßü9jž»º #!„´†ÑæºîÐ/¥\~Ö|=iú_@°ïáYIEND®B`‚djview4-4.10.5/src/images/djvu_wait.png000066400000000000000000000155341264256014000177230ustar00rootroot00000000000000‰PNG  IHDRo8óN¦/sBIT|dˆtEXtSoftwarewww.inkscape.org›î<îIDATxœíœip\U–ç÷m™ÊEÊT¦$K¶lÉ ƶl0^Á`첡 Š¥ ª¦¡&º'fž1f‰©é‰˜ˆ™þÖ1KwôеtOUôTK†²‹ìòXÆ–llí»r}ËÉ}z/•² U@Õ0'B¡Tæ{ïž{þ÷üÏroJH)ùÿR[„Óß²ù¿¤”å/ZŸjѾh¾hBt !æØA!Ò)ík[6D"ɤ¶ñ‹ÐíZò¥/b‰;Ò Ú !ZƒïÇãÚÍÛ7E’Oý¬fêt !¢Õ÷ !Ú„«>?mÃò¥Ï0àÙï7×/]l|£1¥Ea !ê#&[þâÏ2V2¡ñ/þaÒlLi›Õ=Bˆæ¦FãÑdBûV&­µ^íùŸ¥|©ÁBè–)äúÕG^jü“?J®j¨×þ8™þù¿K[™tÅ<ÿü»õº¬B,jÎßìê0ùïÿ¹qáù7)­T¢øEéÿ¥0cQ!LCðoÿ´ÁØÿTKü};Ùø­¯Ç…º(^'øWÿ¸Þìh7ü‹?K/9¶·-rïÎ:r9I¾è}aà ù%H7¥”¸®‹a¡÷§¦¦xþÙóð½úu<„¿wø„C<½µk×þ.Õ½n1®}ɾ8ŽÃ“Oþ5®k£ëB,ÓDh±¨\¼jàJeAÚ²~÷ _§Çq¤¦Í²§¨¥åÿrìè†ÞáÎÍžÛ–”m‰ˆÍRÂLÎ#×jðê[Ãc1R©zLÓ²"¦‰iFéî^G$ùLçdü>±f±X$“‘û"¥üÔ‹kÍÚuüàÈ;LÏx$K±æ>ëx¯Ã™ó09íבËå©Ot-õ7! 7¬ÑÈ 8NÛ‘8œ9 ‰D6}*=?‰Ê“““ \×Åq<ÏCy¤¦ihš†®ëþoÀ!ê·¿Ç4Mÿ:õÙµäàÁ}¤Rtt,õu(‹¸®‹®ëžç¡ë:†a ®Õ4 Ã0ü§ë:žçQ*•ügJ)¹š——Ëe>¼pžß>ÄÀÀ®ëúÏ;ú›®\þsgOûïWMÄ7–ÒCáƒïy«nZÍÀ°Æødø~Ç‘<û²Íú[v²{Ï}¤ÓéPrÓØØÈÎ{ذq'Ïïs)]‚¡Fõê[’Í›o'‹ùï–¢ !üA‚€)ƒ ªLÚ™ó@µ„躎”Ò÷¢r¹LoooMEz{OÒµDãž:û÷½H¡PðÇêí}Ÿþ+§yä¾gÏž y´Å ÊèŠ! Ã`hhˆB¡À… À¹íavYqãZ–-[z¦ã8¾÷yžGGGÝÝ·òz 1“‚¾ 6År’WÝä/ØÏZ|$\×õW(òD¥¨2ZÐó”òAºÔ4Í÷4)%š¦ùøâ‹/ðÓŸüˆááá"'Žá¦å‚Ɣζ °÷¥çp]—>úˆzrßNƒ†zT½ÁÈȈ¿¸4M£\.s¸çMzÍ_8 ÇqãožüK½ö wmqX¿º’!J)Éå=.öklÚ´mŽÑpjΞç±zM7ã“Æ&+¶’RR,y|ÛåöíwÍYàŸ¥Ì)MªÉ«ø¡€P€©U ³ôäøjZÑ4R©DsÆdÝÊIž}æ)–v­`ëÖíLLL`eS:…B™¥‹ †G ì}éy&&Fyðn‹èljÛò¥.gNŸ$›Í"¥ä½wsêÔû4g!–ìðcaT@~óבÞ4›×ͰliÑhØk†š›Ûp]×(¼Çq0MÃ0XÐÚÆàp •gY¦`Ý*_>ÿs¶ß±“•+oüíP¹N -¥¬ò@œ’ 8†aøTôH%Õ|¯èÓ45Z›=¾W {§ùÑŸdß¾—Y½¬r½çyض͆µ:ñè÷ì0¨OÌÆà:L.}t‰Ó§?àïŸþ1åüI¹Ï`e8¶Š}…B™™‹t¶Fjê7<¦Ñܼл8Ã0|oVžØÚÚÎÐÈlˆnYcñÀãG÷ó³ÿóÓÓÓŸŽO&!ðT|SñC‰I%H'A©¦jmÛÆÐ+Þl™:›ÖG½ºõKñiS•JT< ‚¦U” ×2::Jss3ÙlÖ§#Û¶Ñ 033C4%7Ù½}¶KÑÒÒ‚”’&''kÿ[×ÔE#¤RX–õqBacZfHGÃ00M“Û·ßE× +ùÙÏžâ£Á2;¶XV…-š2’¾K±jÕìÎN0QÙöÚéÓ§çý÷ŽÑÑ6ÈÐéÛE…•Ký.ïž’´´´ÐÖÖöiq¹.ñÁ«Î8ƒô£bã8¾A5MÃ4M"‘ñxÜ/T2sàÀ¯hk‰16éˆÇhjjAb  LÓ¤P(ÌYRJâñ8uuu!*S‹ÅBzHt­H©Tbbb‚ééi&&FI&X»¶›ÛnÛÁ¯àöM`}„×÷¾÷½ïA%Ù¶ígUÁöŽ®ë˜¦I>Ÿgdd„ööv‰„Ÿ–+O­««ócd<žäð‘^V-ÓæÐžêH))—ËX–…'uú‡=Þ?]àð ‡_qxçX‘Sg=G< EC׈Ç4&&&Èår>è†a`è•=9ÅB>8ë‰/eáÂvö¾ô÷î4(•rX–òvt-=q‰Sœ'™Laš¦¿˜.^¼Èë¯í§\àᯥˆÇf×¼ÓÐp=Áåþ"‹ÚW<ôÌ,˲¬P§gu¨ìaÛ6ÇŽÃ0 ¿Ï[}’9´ÕuÊ#•q‚R„”’L&ƒãšLç\1jUhÎEã8œ.W/XŒ«‚©w°÷Yà(±m›±±1FGG1L‹Óç¦X“é+,†‹%øå~›dCЇyˆL&Õ+W(‹äóy"‘ˆ¥KBÐß…Ÿ½øK6®ƒ;¶Ön!ŸòDÉd2tv.Ƕ;±í2Sų Ÿ/‰D1µ î¾C„:I+»,–u¸@Ç•<†‡]G#™LúÙíØ„ã@$¢±À47¯6xûíClØàw™Ó¥ª^dA ƒ]®`²8Ÿ„ÀSYe0ƯÕöñ<ÞÞ^Þï7LMÏ`Jé4Ö»t¯piΆ»0P¡Íþ!‡½.êæÆo -Û¶ýqU cY¦i²dI;wÝÃñ㇙|Åæ¡¯Z̶å”G÷]p™É9Øÿ2 ZÛikk£±±‘ŽŽNFFFBpîô«¡VšZTþ|…Äq*‹-‰„lñöQÉT>†¡ lÛÁu=ÇErÕ«×ówœªEéP«‰ š%µ$žây5Xõj®¦'å•üúÐAîÛ©Ó”Ñ?¤ÔüW)¢iù|™W^wÙ½çëäóy_Ñj€Õßj«GˆJ‰QWWǶmw2ЉžãýÜv+sôÚ¼>Êêƒ#ùˆzatܦ.!“m%•JaèR¶#1ôYƒçóyÊå2uuu¾lWãÎ;¿Bss³¯£ÊR§§§}vªnöײ¥bºàœk±\µøPÏשWŠÍ·¥ãyñxœû¾ö {_s)•g¯ Rpðú×Þq¹qU7©T*Ô*®XÀ4Mß«`¶°iómœ»d08↼G]›ˆit-6Ùr‹Áƒ{tîØ¤ã8.íí혦¢\Þ36?|ºÀ;Çf·‹\×¥P(ðê›%f ÉP†Z¶e(ݯÕqšOjÙQÍIÑfõy›ZâƒWzW»ù|º®µµ• ·ÞÆ‹¯:uSAY­¼óËŒMÅX»v½?‰r¹*‚ÉŒ2Šòº`–hY_ùÊWÙ÷†‹ë1‡ò•ÎRJú‡Þè‘ÜÿÀ7ikk«êïœCÅp«nZÍ¥~ÁÄ”ËþCEººVÒÞÞŽeYÜ|Ë­<ôÇ8y6ÅäTÙ§Qߘ5t«e³«9Áµ ó ø~^«V îo]kƒqbb‚Co`lô ÷ïŽÒÚîH)vÈfù€Ú¶çyÔ××û@cWu  !hjjbdÌôPöpòtÇÕü£>[¼xq(‘R: !¸ùæ<ûò>FÆtvï^b¢D"Á×ïÿçΛ×׻Ѓ‹»V÷Z2¼`Ì«U›TK¡Pà­·^çü¹3lZ§±k‹¢€àŠÆL‹¿·—Ïç±m›d2éƒ-ù^8ÜOéìÚ¨‰ âUÇÖÕ¸§Î:üø›’{>ö8Ýënžszíº.Åbå‹?µ(S•.Ê&ÕFWת]ZL‚ãRCeüÕ¸¼ÖuÕîn…Bž%‹tbus½£)£ñFχd2 R²hÑ"W¼Ú³Ôëꣵddd„L:Ü‘P÷¼üZñéz|ð>‰„¯kµ×))•J8ŽC$ m¬•[XÕcת9ƒ ´zÑ3ûë{W¥ÍZ› µ&£<¡§ç-ò3—ؾј£¤çyXF‰ÁÁAòù<ñxœ–––eÇTq0èuóxáÂY4…'¬ ºy½E!?sÕîE0þLNNút®ö'kÙf>U;À|ÅzõoÜ'Žyóe™ê³«u Ôß|pоÓÇØ}{們z_QQ.—cff†ëàÔ©wioo5{k­ÒZ^X,LLLpòýct¯š›DH)I&4îÜ"øåó¿ðëÊùæây¹\×uI§Ó¡îNPTO3¸O,qæ[dA€ªéò“z\å›±ÊÅ«WV-à._¾ÌÛo¾Ê×véÆl†å8…B©©)fffR²î¦$M‚ñ±Q¿½TËã•êïêÄEýÊË¿äŽM–YÛ3<Ïcq›ÁŠ¥6¯¼òœ&8Ÿb±èo?]í¨‚iš5¿ÍT}]DÇqüc"Õ¶ü4­1¨ŠyÁU©6b«ûu P5ã8¼óö›ÌäK<¿Ï$“²I×—IÕ»ÔE\Êå²c‰±XŒû÷DùùÞC,íºx<îOpzzÚ߬ &,óQÖ±cGH×çX¼°ö÷àTñªõUk|UH)ýäFÙ,ï”7 ?Ënjjò›Ðêóê¦üõR§ž*úûûýý¨j ¦éÁ »zM7ËWÜÈøø8œ½x…‘á!òùO<'›©dmñxÜe·Ýêð÷Oÿo6ܺ͟P.—óž>¡²`Ž;Œ®•xôëñš›tw—\(qéò4ã“EbsÄbÉP ¬ïÊå²O™W!–eẮ²,¸¦iLOOS(ÈårŒ‹Åüúoll,t.UiÛ¶ï×¢Ñxj•(Š›OiõY°…&eå¬åÚµk©«ÛÄÄÄo¿¹—E #¡ŒR°t±IcÊåéçžÁ´ÒlÙºH$âÇ™àõÁ2áòå˼òò ¬Z&¸gW+æ*qIr²o’;¶h46T6a«7t¿ ò¹'¥Äõ<¾åqi@°uë¬X±‚R©Ä¾’í›â>¸}<®ŒX\ì/Ò¾È ¯PÞÔŒG¾¨óøßáÂ… ¼xàe–,tX±T`š_Š£’Ï-T V“¦¶M<ñÄŸ°bÅ  óZ[py°—.z¼s\çá‡ãÎ{xaÿìÎü{xtwß‚‚ÎÎNâOˆ7tóܯtýËžRþ‡Ïc ÏóD¹\ÑhtN×õÀ™Óïÿü†Û4ýþ­mÿé¿ü×ï.Y²¤ð£üõ’™Éc ¾ûHTÿ÷ÿ5ïüÇÿôçG‰Dè_]¾|9ÒÓÓ“~à>¹ü¾ˆø¤ÛŸ‰B õÚ?5 äȘ÷´”r0øycÚxä–5æ¢ãïÛ}C£Î³_”ž¿oò{@"¡µXôzGž¯þLaE#â‰bI>'¥üRy×Õäÿƒvº„IR,ŒIEND®B`‚djview4-4.10.5/src/images/icon_back.png000066400000000000000000000012121264256014000176230ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk>*IDAT8ËÍ”MHTQÇ÷_cŽ8ij a‹œURd´¢m-ªEBD‹ 0iqÌEPFC¹©$¨¡$ŒÈMÒEEie΄húHŸó|óN‹ ˜`ƹèÀ]{œsþçþ•ˆ°˜¡-*ío€ç/\vÔŠ#` –+‘¾Å©0 Ëížg¸<Þ6µwÊèl>ßz§“!'SâtG—Lp`Ï6N†»‰ÇãDîÝ—‚b/†ibÛ‚¤,*KóñûëTV`S{§ÄgmïÝÉ«I ½¼šÜ©DúÞPã[‡9—dtÆäÆÍ[|Eøýu™+ „Âb؅ٷ•a•í˜ÎDa ê·Ó°i%5Ë–`X6}Ÿuܽ/Q¹ÉÌ-Ba‰éóklà£aq=ªóôÛ‰¸É{»: ƒ„ ¾3).Ô2¤­ñA¼žàQd y«ª1¦LÌ™JÓ˜Kšô~¦w`K¶ra‹†¨ôõL÷µÕþÚ2=ݤ¢#”—âYQFniÅTzó©¬(¢¸$岑¹Øvv•ÛZš•ʵ‡wpçí¦duÉþú‡wŒÅ>JÐ4Á‰"Ë}iïU&s8Þ|F.>³¹cè+Þ±A‚»~ç].”eRUáM[•ÍmŽ‚rõÅ(.·‡µîÏ»Z DÖŸr¶å„:T»}»Çð—P§ÔÁIM;#Šˆ£s®ã’8¹§þ{Çþ ÜÑóGIEND®B`‚djview4-4.10.5/src/images/icon_close.png000066400000000000000000000021371264256014000200370ustar00rootroot00000000000000‰PNG  IHDRÄ´l;gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ñIDATxÚbüÿÿ?-@±€FFFœ ¬­£€”Ì ˆœ8±ò.= 5Ä&Ð ¶±‰RÿÿÿËgdd`eea`cckøùóï_?þþýó¨f"PlÂéÓk?  @ 5R󙘘 LMüý45常Øáj®_̰k×q†Í›·3üùóûÐŒÄ3gÖ]@6 €P †º_HHH °0‰A]]o8>~üŠaòä¥@‹®‚\ìxöìú 0ƒn0Ôûû $%…ÞýÇÀÌÌ„ÕP˜Ü÷ï?º»ç1ܺud¨ã¹s>€Ì d] ïy1pp°]£  Î *ÊÏðþýgüäÉ+mm`¸³0üøñ‹!&ÆŸ››×h`Ì0€bB„Ë¿|e A Ÿ>}e°²Ò*ædæg——€úîÝ'°%%)vv60ÿþýˇ™@,°$Š}eey°Fxñâ=ƒ²2'˜-%% L ¿.\¸Í` ÷â³go6m:Àðôé  ¥€AÃ, §çJžˆªÆ–¤Þ½ûغõ(ƒ««0Eȃù ` ½d¨­ÊðõëW¸;0•ü @L°Xdeeeøüù Ðàp¼rå. +ï`D6CA€“““–‘ˆf0¼}ûÃÓ§¯1¨ ˆ=xðÃPø÷”+ÿÙ pŽz÷î=ŠBKKc†ÔT? ììôdäI‹PÄ¿}ûw$@Á‚â(›þúõ‹á÷ïß`lffÀ“ŒâýC‡.¢ž—Î0üãǰY y€ *P@yÿû÷ï ˜ecÈÏCÉaMM3¦O_ÎpäÈeÃ]]mXXX¾|ù .?®]Û 6 €3ÈÄÞ#€,?-Ú|úô Coïb`æaàååŠod8yò:XDŸ9s¬çõëW`3`† RÁ1þ¯^½6PSS¦†ëàðº}û!ØPn¸ V®ÜÁððás O/‚ů\¹ ÌÚß@YzL @¡B&&A l¹_ZZV@KK”¶ñP¦¹té*0•ÜBׯï‚B„Ql‚ ŸÏÉÉe ££̶ØK¸;w2\¼x˜ö? K„ 3 €°ô††þà‚”÷ÙÙÙ„„D€¥XógÏÞ¼y Lßá=ÐPŒ‚ €°Œ  y\5ýû÷¦ñ,öqUMÄH«Ê ÀàØúÄ`ÃæèIEND®B`‚djview4-4.10.5/src/images/icon_continuous.png000066400000000000000000000014371264256014000211420ustar00rootroot00000000000000‰PNG  IHDRÄ´l;tEXtSoftwarewww.inkscape.org›î<ÁIDAT8­•½o\EÅ3;»’‘b0’XT.ŒH%Qè"Q„bÓ%%%ü?P¹scd)´¦tCJº(²×Š2öó¾õ»çRÌûŒWQ FºšyóqæÌ¹/|óó ·É5dÞš™#f 2P%LÃ=våŒcUŸ:%Ù俸EYÒÚrÙË%,ßWPUõÞz¾=[œñéô¢Ëù¿›ËIã‹¿ùþó[ȸ;ò¼Øõy­íå¸¯Ú §ÿüøÓ?$d|2냃ßxðà)FF£1FBHBEQprrÂb±ÀÌ03$ðúõ1Ϙ F”gPwÇ]¸{ VU———˜Y;|| @£ÑˆÃÃÃú|~ r’›Ú I„ˆ1®Ô.ÆÈb±`{{›#ãñ˜66>áÑ£¯…qwRÖŠöƆͪB ( ÌŒóósö÷÷ aÄlölÀØÍI®>ã¼ø.ÆîŽ™±··GJžŸ³¾þ!³ÙÓÕ 5rò^LÞ¹óåJÀU­y~Ž€xK vÀïùÎËÜ=g^çMÇì”ùü¤ýVíX©?îúììœ<Óé ®_߬5öN €££#nÞÜĘôÒLŽ×Œ$Ïß½'®¥ ^¾xÉtºÙ’8Or<®ñû_\,¡(á¢o½¹~ûa6§IŒc dmâ|uäµ)›É©LTæ˜i ÉÆ¼ê”~[c01ÂÇëW“uö¶ 5V–%R¼r±_ûº AEßÉ}«ªj5ã:Üš §!4Œ¾-—K «-ýº“šÄíÛ÷qwÞ¼9ë5Œs ðF’^ÈÉ*¶¶îrvvN¹(q‰°õÝöÑ%nMp«þ“7¯Áò·¬Y¯_ ï.’òš9þò-ÿø•?Ÿ•[XIEND®B`‚djview4-4.10.5/src/images/icon_djvu.png000066400000000000000000000021151264256014000176760ustar00rootroot00000000000000‰PNG  IHDRÄ´l;IDATxœ}”KlTe†Ÿ33i§)Ó Ði±¥Ó`¤šxcš4®tiâVãŽeÃÆ•+·¸1®Ø Ä/„‹‚ré-ÚN;¶ô"½ÎœÛu1CÞx““óçËžï=ïù¿ã°E—¿ÿÃ6fšqÍ™Æ4Ú(ܧIò£ËžÄ/ ¼¢À/ Ü‚À+¸ë!«QFc¬¡æ‚Û VR!Š*Ôâ4Æž¡ýx Zæ¦Vp"±ª(Uñ‰šÕÉ8' BI(C˜ÈVpË¡=(eHV§È=#Ó”büñ4¯¼ÑLU<ŠV£-FŒ1XcÁZ¬±Ç`ÊÄmàéÙ-íõ´vÔÑܰŸ·&8t¸•{w‡8s®Ç%ÍæK”1hJ÷Á£þ¥>c~nžŽ’Ñ&®_âÕS] Ðs® ¥4R*”T(©Kp«ÑÖ ±;ƒëâ Ü»ž¥¹%M6;Áñ3­Düzþú}ˆŽÃí¬x3œz« %*ëTƒ±»8ÿ ÅXnÛÙÃŒ/uèƒ$«Ó›8±wº_¶•…w»4f\°%%F”£¹ùp%öñíOŸ0ï-‘ˆ§‰&b$ËGlø»'è»z€‹ç€ ô]=ÉÅóôýv²\+éšîB©ÏPNœÚäÞŠålìqÊë(.žØhP©Ê¦Öj«PÖ ”O*-q¡B©%þzÝÎW6ÙÖÌjB#1,‚/¿ê¥ýàòcKä?ãþ,CÅ;@Åq{Ú©É×èòßËbÂJ@qUºšÜè#3·(&FÿwüüáJw•Àçk/P5­5óùUªtŠ·ŸpãáϬEÇ™š,eýÑûgídvÛœl“ƒÁ—I2é×r÷º! þù•5²äg‘J:¥ý[túHß.3I)‚òt…b™–X5‹Þ4…hŽÜÌCTºE¥Vfþ¦®áW¾ð ´ 5ëØše&'ï£Þdò?š°’qk§ážIEND®B`‚djview4-4.10.5/src/images/icon_down.png000066400000000000000000000005421264256014000176770ustar00rootroot00000000000000‰PNG  IHDR‰ )IDAT8íÓ?NÃ0Çñ¯ÇñŸ4iU¡R–P ¦n,\ƒKp&F&.báŒl¬Ý¸\€‰%©ªJi©R uèÀÛ<øã÷ž~!¶Yr«Ú?¸› ªF§wA© tѺK–Ò4˜ù»±’X+ñ>‰R€«ËB¬'_ïDÒP–ŸTå„Yè)ÞG8+ѱ@(Ë@U-çX¬ûðè"H£ÍÖ8_¶:ô÷5YKáìò–n®‡¢\ Jç8_àü€¼}@§­°&BΛåáöD¬Þ] ÖQ)c\:$͎Ѻ‹u ±<=Ž~a`MLÄöp~€ŠsÆÏgk1Ø›·×{ð=ý *'ØFpJå˜US^Æçlù/µû_o÷ÁpˆH3Œ(æ$IEND®B`‚djview4-4.10.5/src/images/icon_empty.png000066400000000000000000000006151264256014000200670ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYs  šœtIMEÖ ÎË/6IDAT8ËíÓ±JÃPÆñî½IÚ*mCÕ¨EqGwGC»ˆ ‚‹ }_Ä7pt´T„bi2$iî­C±‚´Šš1ßtá\~çœáXƒÁ€,#È898>û÷6²w÷îFﳋÇÿ[;·¤iðùYÀÕÍÓßÀÍí&ZGĉ!Ž Æ k×Íçß«§ô“.ÆD¤iH´_Þº}z=M™‰“Z_/ee½1ì$]¤,a;Uw¥¦©z‹Ìûþ¬C±(±m‹“ãåÉ`}í­#¤,€%j )KX–@ÙåìûKxž¢RV\Áåy}d¨qc º`tŒ.i’D¯8…9Z­NgZ­‚ç©ïWÎO/Î;ÿe]$FËyIEND®B`‚djview4-4.10.5/src/images/icon_erase.png000066400000000000000000000060601264256014000200300ustar00rootroot00000000000000‰PNG  IHDRÄ´l; pHYs  d_‘ 9iCCPPhotoshop ICC profilexÚ–wTTׇϽwz¡Í0R†Þ»ÀÒ{“^Ea˜`(34±!¢EDš"HPÄ€ÑP$VD±T°$(1ET,oFÖ‹®¬¼÷òòûã¬oí³÷¹ûì½ÏZ’§/——KÊðƒ<œé‘Qtì€`€)LVFº_°{ÉËÍ…ž!r_ðzX¼pÓÐ3€NÿŸ¤Yé|蘛³9,ˆ8%K.¶ÏŠ˜—,f%f¾(Aˉ9a‘ >û,²£˜Ù©<¶ˆÅ9§³SÙbîñ¶L!GĈ¯ˆ 3¹œ,ß±FŠ0•+â7âØT3IlpX‰"61‰ä"âåàH _qÜW,àd Ä—rIKÏást–.ÝÔÚšA÷äd¥pÃ&+™ÉgÓ]ÒRÓ™¼ïüY2âÚÒEE¶4µ¶´4432ýªPÿuóoJÜÛEzø¹g­ÿ‹í¯üÒ`̉j³ó‹-® €Î-ÈÝûbÓ8€¤¨o׿ºMîòÐ]9ñLaŠ€.®+-%Mȧg¤3YºáŸ‡øþuAœxŸÃE„‰¦ŒËKµ›Çæ ¸i<:—÷ŸšøÃþ¤Å¹‰ÒøPcŒ€Ôu*@~í(  ÑûÅ]ÿ£o¾ø0 ~yá*“‹sÿï7ýgÁ¥â%ƒ›ð9Î%(„Îò3÷ÄÏ H*Ê@èC`¬€-pnÀøƒ VH©€²@Ø A1Ø ö€jPA3hÇA'8΃Kà¸nƒû`L€g`¼ a!2Dä!HÒ‡Ì d¹A¾P ÅB ByÐf¨*ƒª¡z¨ú: ‡®@ƒÐ]h š†~‡ÞÁL‚©°¬Ã Ø öCàUp¼Î… àp%Ü…;àóð5ø6< ?ƒç€¢Š" ÄñG¢x„¬GŠ ¤iEº‘>ä&2ŠÌ oQEG¢lQž¨P µµU‚ªFFu zQ7Qc¨YÔG4­ˆÖGÛ ½Ðètº]nB·£/¢o£'Я1 £±Âxb"1I˜µ˜Ì>Læf3Ž™Ãb±òX}¬ÖËÄ °…Ø*ìQìYìvûGÄ©àÌpî¸(—«ÀÁÁ á&q x)¼&Þïgãsð¥øF|7þ:~¿@&hì!„$Â&B%¡•p‘ð€ð’H$ª­‰D.q#±’xŒx™8F|K’!é‘\HÑ$!iééé.é%™LÖ";’£Èòr3ùùùEÂHÂK‚-±A¢F¢CbHâ¹$^RSÒIrµd®d…ä Éë’3Rx)-))¦Ôz©©“R#RsÒiSiéTéé#ÒW¤§d°2Z2n2l™™ƒ2dÆ)EâBaQ6S))T U›êEM¢S¿£Pgeed—ɆÉfËÖÈž–¥!4-š-…VJ;N¦½[¢´Äi gÉö%­K†–ÌË-•s”ãÈɵÉÝ–{'O—w“O–ß%ß)ÿP¥ §¨¥°_á¢ÂÌRêRÛ¥¬¥EK/½§+ê))®U<¨Ø¯8§¤¬ä¡”®T¥tAiF™¦ì¨œ¤\®|FyZ…¢b¯ÂU)W9«ò”.Kw¢§Ð+é½ôYUEUOU¡j½ê€ê‚š¶Z¨Z¾Z›ÚCu‚:C=^½\½G}VCEÃO#O£Eãž&^“¡™¨¹W³Os^K[+\k«V§Ö”¶œ¶—v®v‹ö²ŽƒÎ[º]†n²î>Ýz°ž…^¢^Þu}XßRŸ«¿OÐm`mÀ3h01$:f¶ŽÑŒ|ò:žkGï2î3þhba’bÒhrßTÆÔÛ4ß´Ûôw3=3–YÙ-s²¹»ùó.óËô—q–í_vÇ‚bág±Õ¢Ç⃥•%ß²ÕrÚJÃ*ÖªÖj„Ae0J—­ÑÖÎÖ¬OY¿µ±´Ø·ùÍÖÐ6ÙöˆíÔríåœåËÇíÔì˜võv£ötûXûö£ªL‡‡ÇŽêŽlÇ&ÇI']§$§£NÏMœùÎíÎó.6.ë\ι"®®E®n2n¡nÕnÜÕÜÜ[Üg=,<ÖzœóD{úxîòñRòby5{Íz[y¯óîõ!ùûTû<öÕóåûvûÁ~Þ~»ý¬Ð\Á[Ñéü½üwû? ÐXðc &0 °&ðIiP^P_0%8&øHðëçÒû¡:¡ÂО0É°è°æ°ùp×ð²ðÑãˆu×""¹‘]Qب°¨¦¨¹•n+÷¬œˆ¶ˆ.Œ^¥½*{Õ•Õ «SVŸŽ‘ŒaÆœˆEdžÇ‰}Ïôg60çâ¼âjãfY.¬½¬glGv9{šcÇ)ãLÆÛÅ—ÅO%Ø%ìN˜NtH¬Hœáºp«¹/’<“ê’æ“ý“%J OiKťƦžäÉð’y½iÊiÙiƒéúé…é£klÖìY3Ë÷á7e@«2ºTÑÏT¿PG¸E8–iŸY“ù&+,ëD¶t6/»?G/g{Îd®{î·kQkYk{òTó6å­sZW¿Z·¾gƒú†‚ =6ÞDØ”¼é§|“ü²üW›Ã7w(l,ßâ±¥¥P¢_8²ÕvkÝ6Ô6î¶íæÛ«¶,b]-6)®(~_Â*¹úé7•ß|Ú¿c Ô²tÿNÌNÞÎá]»—I—å–ïöÛÝQN//*µ'fÏ•Šeu{ {…{G+}+»ª4ªvV½¯N¬¾]ã\ÓV«X»½v~{ßÐ~Çý­uJuÅuïpÜ©÷¨ïhÐj¨8ˆ9˜yðIcXcß·Œo››šŠ›>â=t¸·Ùª¹ùˆâ‘Ò¸EØ2}4úèï\¿ëj5l­o£µDŽǞ~ûýðqŸã=''ZÐü¡¶Ò^ÔuätÌv&vŽvEv žô>ÙÓmÛÝþ£Ñ‡N©žª9-{ºô áLÁ™OgsÏÎK?7s>áüxOLÏý nõö\ô¹xù’û¥ }N}g/Û]>uÅæÊÉ«Œ«×,¯uô[ô·ÿdñSû€å@Çu«ë]7¬ot.<3ä0tþ¦ëÍK·¼n]»½âöàpèð‘è‘Ñ;ì;SwS—yoáþÆèE¥V}šaòäÉ ¥Ï°¹kPDEEýGØø™™™`Œ,Èf#r€#dðY†·oß2\ºt Ã!zzz ÂÂÂ(bQR@³àÁ@X –ó_¼xÁ€&Ï“CPµŒ0>@±àR„‘| |ḂÎ ‚îR\ Yˆb#@Ìy0õø\ʈE €XˆO —¡ @d—ø €Bwñsb ~|†‚@1Òª š›D3ƒˆfŸ À‚˜FÃIEND®B`‚djview4-4.10.5/src/images/icon_export.png000066400000000000000000000014651264256014000202560ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓ/§â×ÂIDATxœÕ”=E†ŸÙ5w>ðÇÈ2’‚€ˆ?1"uÑEübH@ A‚!sB2úddɾw»3»ÓÝUÕÕ3;ÇÉk;vK­ªî½ýôÛÕ O[«6É?þúQ]OT3³zBÓvĤdËÌê)fÅ,£j¨n¢qçŸ9ó£ÅwÍbõñÏ7>_Ôẞ¼ôʵKPqíê>Ÿ~ñ Ë&pá¹]>ûäýÇÒ}ãÞºýÁ·_ýðáá””. Õ°‰›¿rùÂyêzòÄm/šÜó»#è&‘a{UÕ ï_Üãå¯ð•ËO1–Ë)É8w*,Ѝ1©z·ßx•«Ï_dÿÒ³u/,›–å¢Á,?,œÄÍ”bœ4ï½õ:¥Jùq;äýxÍŒ““–£Çt!bfÛˆ{+º˜øí;¨eÌ2–}Ƚ¯ˆœ1bH4Ë–õ:p|Ò£<ŠXUBJÊr_R–ÿ˜”…¶]ºHJBJŠˆc$ç-Â:Xáîœß=‡ejרŠã“’™–ÌÎlÊd÷³IÅl:á(RröG;ÏÌxçÍ×pwBBH¤¤¨Ú`—õ-6ö/¿þ‰yH÷À,B"AÕ¶Ÿ] ‰ ¢Û­HI͘wïþËýû ª6\a®°Žö˜õâ;;5) IÒvaÈL•ª*ìíÕˆ€*Ôu¡®a:-˜ÁdRP-TUˆÝ·yœ”Õº#›±ZE‹n¤ê O!¡Ù¬¬íÄ1$Öë@qGÕpÏäüp7룻BýB²8ÄD ¼`f”â¸÷½Ïó0îcΛ¼ "¨(î[ˆÃ:²^´äl¬VËñäO«àì!ªæñŸuÛº5¾­Žç‹ë÷þ~pSâö_‡ä\F✠¥øÿæN¿¹îÎé‚âÎužÚöàÿßyK¼IEND®B`‚djview4-4.10.5/src/images/icon_find.png000066400000000000000000000016451264256014000176550ustar00rootroot00000000000000‰PNG  IHDRÄ´l; pHYs  šœWIDAT8•”OLcUƯ´ÐN: Ó> ) °ñ“` 5Ê4Ú ÊLbÈíÓ¤ ºœÛ.ìÆ­ 7*º±IÁn›4  ]‰‰5}ü'$-ÂÐÖæ½Îô•w]Ôb_iù’³8ß=÷ËwOÎ=ÿ"™J ®€s÷¤ç[“{wïàtØLºå2hheÐ4AQýd*-ž'n¹Ì™Ív{CtÕø—_z‹d*- «-_jmE6£³ £gg5Î}Ã>$³úO %ázáºÉý¥Žë¨;î²×ra)ÓÙeàr¿ÉÚ·?°{xbrþ¿7Š×ïìœsÞ›¬ÿ¸nª½’°Å‡„âšÛÛCH§ZÎ\{a«µÝÝ0>.á°×r©i>®,Ü ÆÎ$\yVm{yii ŸÏG,;çb±úøiý«K„õÖ-Ïf³Äãqü~?‰D‚ E!‘Hà÷û‰Çã OLwÎ;“L¥Eðí;¸{Í?/“ɰ¸¸ˆaH’ÄÑÑVkÍ@µZE–e$I"_Ôøâ³O™™™‘.8¶6ÞÚÚbaaééi„ "I³³³LMM!ICCC!ø0tŸh4ÚºÖ³p,£¯¯EQär9ü~?ËËˬ¬¬099I.—# ( ‡ùùyÍsÜ02™L†ÕÕUæææèQ¦\Ñ)‹¨ªŠÍfÃãñ ( Õj•žžúd7Ù¿ŽI¥R{ܸ݂Á î½ìoüŠÅоIÿ+,“ÂétP*•xðÁûdÿø™Ý½ ‹¡WÇ89Í·ÿy›››èn'ƒŽ§Ü¡\1ØÏí ë:v{maäóy´Ü·zʼþÆ0ßÿ²Í៿±{Rj/¬i•§¨ÏÑò\ë„îþwB°¶¶Àèè(Ý×l8³”Žªèš…3!S©TÚÿ¼p8LáÌÊÈä;ô¼vïÌ#ï …p¹\¸\.B¡÷NñÎ<¢wâ=¼c·)œÙ‡Ãÿ %SiQÒ*¢Žr¹,¢Ñ¨¾‰q!˲ˆD"BUÕóUUE$², ßĸðz½"š³p†aˆããcaÆ…³Æš>þ¤ý>þü˯ÛuæR8×Mù?~š%+_AIEND®B`‚djview4-4.10.5/src/images/icon_first.png000066400000000000000000000011061264256014000200540ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk>˜IDAT8Ëå”ÁNA†ÿž%²{ÑçàL†ÜŒ'cHˆ‰"qXØžÙ]º§««ŠÃÂÀ2CŸðÄ«îê/ý•´QUÜ¥²;¥ýàÜõbyuWË2âÔ>¼_0©‡¯–~ëáqhôÍ8¬*‹ÂÚ˜tñúížúJZûÀñ„á¼Ü {·¾¯DŠ¢ŒœŒÒ@ç“ ƒ¹}ók5’¢,#¬ðî ¡ó _ B Vgpæ§–Ðï Tƒ4|˸˫»še€0´„¼ãÁ¥Þ ºóÆã+‡‹/¶õÑù:ãþa@as„jUI/s®êzçϽÞôºÙEÆP"RÙšsȬ¹~Þ|lž<ý¨ÅEãDP³KoB PΜ}ùôÌx—ûé¨1`vP ià¿ü ¡:™:¸¡ï_Ÿ_Ã"hÓ Pdê.†öæß^fWÊìÓÀH%ˆlk6—ú¹µbnƒ5€ÞåõH)ýÚ~c:.:nãÎÜ¿ö°ju]ÝŒ÷BtEXtComment CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) ‹3ôIEND®B`‚djview4-4.10.5/src/images/icon_forw.png000066400000000000000000000012111264256014000176770ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk>)IDAT8Ë­”]H“QÇç}ß½¹UsƒÁ¨5("E"ê"¤ Aa± Œ «Š("B”.‚´ï‹ ›Hú!A©œÒEÐÙ"L­tl8Ýæ¶œ{Owáp›o°?œ‹sxøñ<ÿÿÃRJ )¥ 4³Àö›wMa xïÙ[.´Þ75T——ð¤{ÐÔ´‡n÷F&â×ä…jó/>߀ü=õ¡j(ŠÀªë$#A"‘¶òuœ;PMçóš;ÉÆSµ"PÌ_›ºÃ^Ùçq¨neËtô¢%|òñ.Ò½™‹5T94Ú¾ÄnSh>st4cda±b-]‰kÛª÷ïÁ³×ƒ§þå;w¶óxtŠqÅÂéúÝÄRzVO3(LI•^€¾ï“¼Ñåñ9œ$™e`lšÛ_B %àÈA£¡Ôh†‡RH ©ð&¡?FT )CE( ñXšžñ$ýñIfG~2÷þÞJgîP0 dr¡Ø—ê8lÂBc:¦PTlÇá´þ:ÆL÷ NV­ ­å²ÈÝa*ÁÜ?¢s’€!H”UëÑ7l¢xuÉá1b¯žr¬²„¶–¦¡d¤ìó È_ATM'6þ½7Ýê"Xº«k ÑÁ^¶»h½tvñµÉ¥­µçå·„J:Å»¥ŒëY:Ëšr>‰‘4T9óÂLÓÑ Çk*i»zE,Z,¥\ôÜè¸#ÍÔI)Íyø?*øý,j"0à:IEND®B`‚djview4-4.10.5/src/images/icon_fullscreen.png000066400000000000000000000016201264256014000210700ustar00rootroot00000000000000‰PNG  IHDRÄ´l;gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<"IDATxÚbüÿÿ?-@±XM{6Ÿ›ƒ9™‰áÏï¿ ~ýâ¿ ¿¡4ˆÿ› R÷÷÷?†ôÏÏ ÿ~}Z@, CÝÄ~þb`øùƒáÇO þÅß¾éïß¡™ Äÿ˜~= 4—á?Ä¥ŒŒŸ€»ˆ‰“…á'а_ 4ü7ÿ†â? €èFbÿCÂ(¡ÉÌÊÀÈÀÆ@,|¬ÿ¬%@ýò ÿFfÿFпÿëÅÈ‚¿@/,^ÇÄ@,üì r¤GÈaÿþÃöß0ñýüϰï@±ÀRÅw7i„.vVÎ͈2ôW¬ÃÿÇïþ¿ú Øé×`ÄÄð-¹ñri(3Í¿ÆÀ(ÎÇÀ(È–‡¸œ €˜þà fef`æa`åcøQî@„¡ `šÉÀ$) ÔÇÃÀ ÀÆð(R@L° `æeà\~“AL„QLŒá×¼ ¼†‚ø,ç30H+00JI2üYz‹I„*÷Ÿ €à.æXtB7í,ÅÀ–4ÍàÿH‘Ä6à§~4еJ ?sVÅ,¿ — &lYš-v f ,æaÁb3JD“ƒÐÄD¨¬À4“Êÿò@!" üZ”‡ÇÐ(†rm*Çb @1¡§ãù– ÿ_=gøµ¢ n .—r­/aøÿòw·˜Ï›mÀs(@¡¤cáÿ_û‹— L!X\‚šË>ûuñŠáß«· ¼z ÿß|1 €˜0‚(ÉÒq‡¡ ®þX²•áõG†ÿo¿2üÿðƒ ãaüÛ_Kø2`„/ØûÉZ ÿß },S?ÿÄ €bù÷÷?°„úÃÀ¼åˆ ÒüdØ_( Œ –ƒ‰ƒ’Û¤³`ÿ@Eï/°ÁÄhZå¿’3°–þþBh Ep6þ‡,¥ÿýý‡3‰Þzò €iUç@€´àö¾÷!1IEND®B`‚djview4-4.10.5/src/images/icon_last.png000066400000000000000000000010751264256014000176750ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk>IDAT8ËåÔ¿nAÇñï‘@ŸGHÉÐ „h ä (i(‘@PÑÐ¥ÌãСˆ"‘ÆÂ(R¸ó÷ÿì,…-#Ǿs*®\Ý~f~»£­J)\çwãZµî^]x÷~\BP޼ܯ†6¾~;*u#´pxp{ùïÆwv*^¼:<ܘ )&¿âpd‘Bµ¨÷ôÙI/Z´à|Æ;WDþ:ŸoD§mÆ{E¤É„ hžG»ÿèóê|f2ñ¤XoéÐ)—¿ëtÉ»†{?­ Þ+ª 3 &Q´ÚN¨!„ œý³çÜ}ðq‰“7žíî¦Ec2u#L›ŸÌÚSR¬¹ykoÑͬSTývÐ{Ř̬«±f„5#4Rjørô|p6{/¥i,ÖœcÍÍ€o§V0IóȪ[æ°mÁO°³3$Nøþõ`­3‘ŽëµØk`X3&¥¦ÈÙ‘RGZíc¸œWΡÐìÉyF)iiÉê1€kRœRtu|ªÿïý‹ù Îû’Y—BtEXtComment CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) ‹3ôIEND®B`‚djview4-4.10.5/src/images/icon_new.png000066400000000000000000000014711264256014000175230ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÕ79ùHwÆIDAT8˵“[Ha†ŸæŸu77-×ÒÜŠˆXŸíx&\)Hl½E°û=âãüehJ *5Áë«íéPÒÛô³·ýîü9άj“éÏu¼´dÚP'…ÇËÈŒŒ’ê  {½¨T†çJíZ[yc—êײºÆdöRBúÛ3&‡ù1z 4%4"Þ³Äß~V%+Tí¢7Oç'¾ÆfRfØÓ[hñ…u[¸ñ¢^¸Åè¥3¹¬4€.%K–ùœžl»Â¸%ßå\ÞSèK‘+x¦òý•äg‹ÿ¤ÿžEó{ÿüþS!=p~/IEND®B`‚djview4-4.10.5/src/images/icon_next.png000066400000000000000000000007161264256014000177110ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk> IDAT8ËåÔ=NÃ@†áw“Tœ… ‰.-%7 äTP„DAÉ%¸ @ ŒP„ÿd¼ëõ.4`;QDÃTÓÌ£™¯cd“5Ú¨öçàùeOÏ’•2éÝp<ŸÌ£ ÷!>ûã‡Ah'hê€÷ßÎþÁ]/Ú *Õbm ´ÐøÈtï6® Èm¦n1Úâ›’ÝéM\ l| ÄHµôä…ǹ ­¬³½sõ#:éËD©–¼ð”Å+²z¤q9[0šl±2X×)[ä2G«-g„Ðð|!V>YÊ–¢”h•¢Uú…½<]‹ßf:Áªª±æ £S¼+{±^й kç¸ú}ÖÚ kæ„Ð ÂzAï+ÚPÆÄÿ{°þÀ´†‹âceBtEXtComment CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) ‹3ôIEND®B`‚djview4-4.10.5/src/images/icon_open.png000066400000000000000000000025141264256014000176720ustar00rootroot00000000000000‰PNG  IHDRÄ´l;gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ÞIDATxÚbüÿÿ?-@1ÒÊ`€b$UCyãI…þÏgec2øüù·âä.ëØÔI¨¢édAç„‹ï¯ßúòÿÎýoÿ³J¯Ç¥ €@A Ã@më)ƒªæSç÷xñÿë×ÿÿ_½úýÿýû¿ÿ§Ï»õ?9÷P6sˆQ>ñúÿ1†ÿ~ýe`øýçï? k¶?ýð}‹¾`Cç™zW'y~^V†?þ3üþýLsp03Ô´üðñÓOÅ¥³Q‚ €mËîýï¯Wöh0ˆþù›áéï ßbr‘e01”ûÅÀð÷/Â`¯î>þÂÐ<éÒ†ÝW .9<€ @,è©âPó³SOxÿü`¨ËÓgàâ†=ÿýûÏ £&À`k(ðïßÛ…{/1À  –¿ÿxôáéÙ >. rœx#òý—? 7¼d:èn†[ïÞ÷3è4‡)P €X]óéÅ'+SI‚†~øúÁ»öƒ‹ƒ’,Ø,u …Ï_ÿýþÃðabï^€º¡IZŒ¡jÞsÓ ÿþý÷ ÿ€é–á0lÿ@Ù[O¼cñ”g``8øl0;ÃÅóyï½ó hÔ€B Šõ{^3(¨Š2èI³0Šp1|Ê}ÿ ß~ügøöûà éj ?YYN݃ÊÈÄÀðöáw†WÇüeø÷Eñ @¡¼çð+†[KtÞ¾úÍÀ/ÌÂð‡áõg†7@üð9×÷@öO ºé݇¿ o^ÿdøöö Ãó«¯><ûúáãcÞ¿ê LÿËŸ?C÷ŸúÎ`«ËÇÀ ô«+Ãù[ŸDåøn=a`¸ôî‹×^¿ùËðò ˆþÃðíÃw†ï¾ |Ïðè+†o ¯Xþ²ðÃ-·ÄòšÜž|Çd-ÄŒ†—@W½bâc¸qè³ÿÌà`¥á¿þ1üòãç? k¿1üþLÜÜÜ@³€€˜ù—Ãÿ³@æÓ?`„|úÊÀpùÚ†p`²a`xÄÀ dx÷ùÃÇ/@Ã~ ø h·¿^¼øÆð—…‰ƒ5¹0ÿágøË°Ä pªØsü3ƒ?Ë/ <@ÏHƒƒ˜*ø$Y>¾ûÅð‡…‘Aèß¾ß?xÅ1( 03üûù“áß·Ÿ €Ùôû7`ð¼ý'üðñïW û,²£˜Ù©<¶ˆÅ9§³SÙbîñ¶L!GĈ¯ˆ 3¹œ,ß±FŠ0•+â7âØT3IlpX‰"61‰ä"âåàH _qÜW,àd Ä—rIKÏást–.ÝÔÚšA÷äd¥pÃ&+™ÉgÓ]ÒRÓ™¼ïüY2âÚÒEE¶4µ¶´4432ýªPÿuóoJÜÛEzø¹g­ÿ‹í¯üÒ`̉j³ó‹-® €Î-ÈÝûbÓ8€¤¨o׿ºMîòÐ]9ñLaŠ€.®+-%Mȧg¤3YºáŸ‡øþuAœxŸÃE„‰¦ŒËKµ›Çæ ¸i<:—÷ŸšøÃþ¤Å¹‰ÒøPcŒ€Ôu*@~í(  ÑûÅ]ÿ£o¾ø0 ~yá*“‹sÿï7ýgÁ¥â%ƒ›ð9Î%(„Îò3÷ÄÏ H*Ê@èC`¬€-pnÀøƒ VH©€²@Ø A1Ø ö€jPA3hÇA'8΃Kà¸nƒû`L€g`¼ a!2Dä!HÒ‡Ì d¹A¾P ÅB ByÐf¨*ƒª¡z¨ú: ‡®@ƒÐ]h š†~‡ÞÁL‚©°¬Ã Ø öCàUp¼Î… àp%Ü…;àóð5ø6< ?ƒç€¢Š" ÄñG¢x„¬GŠ ¤iEº‘>ä&2ŠÌ oQEG¢lQž¨P µµU‚ªFFu zQ7Qc¨YÔG4­ˆÖGÛ ½Ðètº]nB·£/¢o£'Я1 £±Âxb"1I˜µ˜Ì>Læf3Ž™Ãb±òX}¬ÖËÄ °…Ø*ìQìYìvûGÄ©àÌpî¸(—«ÀÁÁ á&q x)¼&Þïgãsð¥øF|7þ:~¿@&hì!„$Â&B%¡•p‘ð€ð’H$ª­‰D.q#±’xŒx™8F|K’!é‘\HÑ$!iééé.é%™LÖ";’£Èòr3ùùùEÂHÂK‚-±A¢F¢CbHâ¹$^RSÒIrµd®d…ä Éë’3Rx)-))¦Ôz©©“R#RsÒiSiéTéé#ÒW¤§d°2Z2n2l™™ƒ2dÆ)EâBaQ6S))T U›êEM¢S¿£Pgeed—ɆÉfËÖÈž–¥!4-š-…VJ;N¦½[¢´Äi gÉö%­K†–ÌË-•s”ãÈɵÉÝ–{'O—w“O–ß%ß)ÿP¥ §¨¥°_á¢ÂÌRêRÛ¥¬¥EK/½§+ê))®U<¨Ø¯8§¤¬ä¡”®T¥tAiF™¦ì¨œ¤\®|FyZ…¢b¯ÂU)W9«ò”.Kw¢§Ð+é½ôYUEUOU¡j½ê€ê‚š¶Z¨Z¾Z›ÚCu‚:C=^½\½G}VCEÃO#O£Eãž&^“¡™¨¹W³Os^K[+\k«V§Ö”¶œ¶—v®v‹ö²ŽƒÎ[º]†n²î>Ýz°ž…^¢^Þu}XßRŸ«¿OÐm`mÀ3h01$:f¶ŽÑŒ|ò:žkGï2î3þhba’bÒhrßTÆÔÛ4ß´Ûôw3=3–YÙ-s²¹»ùó.óËô—q–í_vÇ‚bág±Õ¢Ç⃥•%ß²ÕrÚJÃ*ÖªÖj„Ae0J—­ÑÖÎÖ¬OY¿µ±´Ø·ùÍÖÐ6ÙöˆíÔríåœåËÇíÔì˜võv£ötûXûö£ªL‡‡ÇŽêŽlÇ&ÇI']§$§£NÏMœùÎíÎó.6.ë\ι"®®E®n2n¡nÕnÜÕÜÜ[Üg=,<ÖzœóD{úxîòñRòby5{Íz[y¯óîõ!ùûTû<öÕóåûvûÁ~Þ~»ý¬Ð\Á[Ñéü½üwû? ÐXðc &0 °&ðIiP^P_0%8&øHðëçÒû¡:¡ÂО0É°è°æ°ùp×ð²ðÑãˆu×""¹‘]Qب°¨¦¨¹•n+÷¬œˆ¶ˆ.Œ^¥½*{Õ•Õ «SVŸŽ‘ŒaÆœˆEdžÇ‰}Ïôg60çâ¼âjãfY.¬½¬glGv9{šcÇ)ãLÆÛÅ—ÅO%Ø%ìN˜NtH¬Hœáºp«¹/’<“ê’æ“ý“%J OiKťƦžäÉð’y½iÊiÙiƒéúé…é£klÖìY3Ë÷á7e@«2ºTÑÏT¿PG¸E8–iŸY“ù&+,ëD¶t6/»?G/g{Îd®{î·kQkYk{òTó6å­sZW¿Z·¾gƒú†‚ =6ÞDØ”¼é§|“ü²üW›Ã7w(l,ßâ±¥¥P¢_8²ÕvkÝ6Ô6î¶íæÛ«¶,b]-6)®(~_Â*¹úé7•ß|Ú¿c Ô²tÿNÌNÞÎá]»—I—å–ïöÛÝQN//*µ'fÏ•Šeu{ {…{G+}+»ª4ªvV½¯N¬¾]ã\ÓV«X»½v~{ßÐ~Çý­uJuÅuïpÜ©÷¨ïhÐj¨8ˆ9˜yðIcXcß·Œo››šŠ›>â=t¸·Ùª¹ùˆâ‘Ò¸EØ2}4úèï\¿ëj5l­o£µDŽǞ~ûýðqŸã=''ZÐü¡¶Ò^ÔuätÌv&vŽvEv žô>ÙÓmÛÝþ£Ñ‡N©žª9-{ºô áLÁ™OgsÏÎK?7s>áüxOLÏý nõö\ô¹xù’û¥ }N}g/Û]>uÅæÊÉ«Œ«×,¯uô[ô·ÿdñSû€å@Çu«ë]7¬ot.<3ä0tþ¦ëÍK·¼n]»½âöàpèð‘è‘Ñ;ì;SwS—yoáþÆèE¥Vüß½ûäÿõë$k@aE«Ví™òäÃýúýçÎÿW¬Øå@Œ„-^¼mþ‘#P ÿøñËÿE‹¶Þ'F?@1Ìœ¹nþŒk °ÉÍž½~ý… ·àÿôž='ÿõ2 €˜ØØX÷O˜° E1ˆÏÅÅé ¤$ÍðçÏ_0þû÷ƒ  ÃÏŸ¿@ faðð°Þѱl8ˆæããÞïîn!ÀÌÌÄ _a`ÌÂÂÌðãÇ/BPÐOO+°á ³ †Z 011 û Æ¿~ýã§O_ƒ, ˜ìˆ ˜”>@ ç.))2äfff°KÑñýûÏ@é› ÁĬ§g¯ÁÉÉn ""ÀÀÁÁΠª*Ëréß¿Q0ÈÕOŸ¾bd¸}û±Á¼ˆ‡œ¹^b7&o{ý›ÁÄtEãž=§>¼yóîmþÇß¿ÿbxðàÃçÏ߀‰ƒ!LûŠ›8kÿï? û/÷k¡„7PÌ F‘’ÒLûmm ÔÔä€ÄS&AYû7ÐVVÆëSø~íe`÷‚UG†áù•þýcp4)¿öÙ€b„1bbj €¶õËqq!N`†G˜ ??Ã÷s¸¿ídüö’A„ù7ÃGV†ï Ò .ýn]‹0 €ÑÃ&4´BH0(­bqqáù~ïad{Ë ÀÆÀÀÕùé#Ãg~†Û†ÿwtn¾6 €‰ÉkJäe¾×kH`àfcf`DÓõíç_†·ÿy®g»Ü«ãú€"Êà­åš@ ûõÿÈJý‡úªõ×_p\€råó7¬ çÎ1ƒ  &b öî¼þÔŽ'3]xð(ÀÇÁÀÀÏ ‘¦ †—Ÿ˜ŸdáýΠ©öÛà÷_†ùÄDliÜýÃï?ÿaºp÷"0éò°30|Ò_~20¼þÌÀðûÃ÷ ªßXYþ)EiÔÔ@Ãbºpkÿ; ÷ÎÀðã( !©˜æÙ˜ÿ1©åtâl á÷d¾pã ÐÀßœ5ÄxÁ–üüò—áù[¦ÄLN%°å›®ÚÂ+o¿`÷`ÿû[BòÓK «A¹Xµ]dxý…¥ €)©e:CÕA©e=û~Ž? ¯¾²}øõ—ibÅš› ÒSÉÐ+FIEND®B`‚djview4-4.10.5/src/images/icon_prev.png000066400000000000000000000007321264256014000177050ustar00rootroot00000000000000‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYsHHFÉk>,IDAT8ËåÔ»JA€á²yßÀ±³ÔÊN+A-Að,í-ÅFlDxC’Õ]vs1;3;3ÇB’;XxªS>ÎŽ–•¥jîî½ÊÆfm쎦O¢M ËÜâžž¿IY Ýž#M»‹gMq¥Pž,shÝ[¿2©3€aˆ?,qÜÄšd>pÿ¨.• „Y^Ò‰-Î °ú}vp{çytIcíŽ%ÏZX“ÄÍÖz”ôû87À•½I+ÿý(W—«*M»Äq“a¢1¢O>ÙÞ¬´„²¤,PíeÓÒ­,ÝËï×ß\|è¶írù&“Éœsæ3'3gޠІ‡SÙd2‘¨æ¸s'“:y²ï“Í|NµMÛ¶%“ííoZëíJ´1ss¹€ÌKƒÙ‹Ò¥ Ri„h­ªm¯VJV…*m„aøê`)Ÿ‚×C¥2ئ2æ2VU¡Jk´6H¹T¼áqzzzÚ¥ «B}?DK…ïûÑÎÎκçfÜÛÛû™RêÃãÇO|ÞÜÜܦµ¶V¡òhà‡()QÂÆóÜÄÙ³çæoݽ12ò÷_–eý><<|@ô÷÷Ûû÷4>0ðõ.Ïó˜™ù‡¢{Þ{‡P­B ~° µžÃ•ËC=|!lŒ1äóyÏÿ28øÃWvKKËé3g¾=‰Ô`Y–eqïá»:Þ¥¼¤ BM(5J„X¶ãº(,ˆ7£ ³a±Tµ=ÚÚ:ºÆÆF†œºOG"5÷ó°¡Ñ®­¥†bh(Ið•Aêe{àzˆÿîÓøú®gïñ~c D£Ñ/œ®®®·Ç^©M¹ì“ 8óÅÆó†Ù,°õ²Ù¿`8ñ†Çá{Ö¬Û·ïØíÁ’çºRJ‚` Ïs™Ð¯qãžàú\5àS 1NEܵµëÚ$“ÉF'• #‘$MM ’ÉŽÿÎ×qûþsykš··F(ÊÌÌ,Ë=ann^9BPTJ×OM嘚Ê!„àü¾8=OQ:<ö¹’!óH«ìHµPZâ©W¯ÎV¦µzìA9Fš—M†¡¡?7ͬaežY¾†ûö}¼L0š|~aÆ)ŸLE£µ]KK>×®]¡µµ•ÖÖÖ—ºŠT*E]]œC‡Ž°¸øß÷'\îÑÏB¨¾X,Žïúúú9räS¶nmxrY]d³Yâñ`1=ýÀLNNþáÄb±_ÇÇoÿØÝ}´¦¾>ÊÁƒ}ìÝû6âùÅ€”Šd²‰»w'¨¯Nf2™LÚ¹xñb˜N§ÛnÞý.‹í>vlà!6oNë¡R*ÇæÁƒûþ¥K?]Ïf§Ç._þ¨ì§.üÖ»¸X2/RJS.¦P(›|¾hÒéqÓÝÝßù,«¢×ÕyßÌÎ.0[Y=dŒAJ‰RË# C\×ý8·ó?…׆â/äêIEND®B`‚djview4-4.10.5/src/images/icon_quit.png000066400000000000000000000023051264256014000177110ustar00rootroot00000000000000‰PNG  IHDRÄ´l;sBIT|dˆtEXtSoftwarewww.inkscape.org›î<WIDAT8¥•ÍOTWÆçœ;w`f˜–ñbCC”ˆ,,(’X£56qa⊅ѥ W¦KWê®$êÂ…[úˆdìÆ„¸‚Q:RÅT‹¬|ˆÀ̽Ì3çtqïŒØ6Ýø&'çMî¹ÏyÎó~‰¡%¤Ôµ]Ž3d)eóV®TJ³++#›•ÊU+¤Ôµ+'O^Èçó¬¸.óÙa)RJ¤¨`—ÿÜ?ZWg—áÂObu8ÎÐF.ÇÂîÝ$z{?ÕŸ„@…Ã!å2Rß¾Uýçω¦Ót8ÎeIi¯¸. èrù3¦ÑŽìŽÂMMD 6>~dci‰Ü«WÄÖ×a p¸½R*…%¥mÀÃf6‹ÞÜÀª¯gÛ‰4öôüKǘãsèîæÏ‰ T*E½1 %¢XD,Œc(e2¨b;aç¥KÔ {ôˆÏžQYZ"c57“èé¡}`€âîÚÅû»wi²,ØÜDƒ¥AÃêä$‰}ûøæÜ9ê r™ ¿ ³ýý{Zb1_ëbéºÈׯy“NÓ<4Dƒã f3™Ä6hcÆ_Š…BÑ(N?c7nÐ>;Kc¥‚ñ<¾:yuô(…L<{zšÌ½{t9»ÆFÈå´²š\J)šNà×û÷‰§ÓXù<Æu©ooÇ9}š¶3g|×ÏäR¬Žïë#·´„ øŒ¥XJïî`vt”mÙ,:›Å¸.R©Zðt(ž®‹ðh?ö•+¼ãÛéi,)1Z£«Y!À¶RlÜºÅÆþýD››é¾y“¹ML`½yCêêB 9v oa¹Û·ù>C¤ñ˜9ÚÙI$®=†B—/ÓúÃüŸý>:ÊÒ;ô†BØJ!„`ymŸ''ýt«j\[ùEMMQ–Ãa6ÊeÊešl›VËBl­6üëëT´.Yk…ÂÈb&sA õõÿ9ª{4èµËÕ3à7züi³’Íòvy™µBaÄÒÆ\M-._]’B|Ñ0ÕÆ”²¥Òˆ6æêßDËð,†XUIEND®B`‚djview4-4.10.5/src/images/icon_rotateleft.png000066400000000000000000000022041264256014000210760ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“tIMEÕ%”nZvtEXtCommentCreated with The GIMPïd%nýIDAT8ËÕ•mLeÇÿûÜÞî Çéäô*-%C¯’FÚÚŠ¢V#Si”BãKÔh´¶Ñ6ÄPÛ4¶ú¡J#å¥%!V´`LÑ1Ázå-”‚òzpÇqp»{»ûøÁÄ€@Z¾˜8Ÿgæ—™ÉÌ€ÿ›17sX÷îgŸØM ”ò†Y¿žu«¤küº—’ñIªõP¹/ŸV—_¿epBañ¡Œøô[⣸îaš®ƒÀŸn@£aª)ÔŸdE×X©T˹)ø‘~yçv‡ªÕ?t„P*B#ÃT aX½¤aøüµ£’Ü´‘ÖÔ ûo¨£è\Iác:¦|ož'FßGEÚ2¬¨š8ù øüXý«X·ùqáak™Ðà—¢F]jëj¢ejxñíûÛýÔ9¤Q[žF͹ Éi–t{^Ë:ÌbïÄù1BvÁ·ç~+'î×h\Þ²ò«€ÌwJ[ÿÐÙØHå?^PI§*±µùjéÉJÀÀt#†ÌË>Þï‘>/˜óµÑ“áBZûôΤ`GÌZ›{¨úà9@ÒÚF§Ÿ^P–&.ªT:Wö©ËSC`ÄFï`9²æ°¤œgõ¡9@¬&®}P) ƒ²odJ·;ÿ PÙ¯VŸ<€jXrмÓ-Oºš³F§3DZ]xRöÆ´ A<¯Ÿ µгÏò¸Û²oCÞ{üÆDݰ 8µ\Æ ÿ®SzùÉÀÃÄ›#Ø+…O%úß)»8áÚ’z§ùfNô:ÀA°ÚHájìw¡}3žÝ›Ž-„*ˆFÆ®t@TP€*ƒø¦¾SÕ&f&¸v${«[­¨êëÒf%@às°½#_õ¶ͱAV‰ ;¡°1šb$*µ“ìD¡vB5;¨dÑ(ÏzÖ+þ3Çê™÷²ü9þiŸ˜ù¯"¿ÔüÞÿQÁ½€Ê2§8ñÄ“F›VW}r©v„ðæPŽVK¾ 8sdŸwèžõ„Ýï/=¼méfJK>³>lY'D‡p-0ùǢ͓KO\^’<€ºäOœÅQ»))… L\¡}#—_'+ÖCeqÆQÏg~¸5%ËrB³ó|ÓxUCËÊÀÜø%Ó_.€>·«$9~wÁºØõLÇÕ†™‹G‹¶Ý’/gäá[¤)©Þ‘”k·˜LŒ{ôûé ­ÉžºK½+“ôÍ,Ç_5ß“gÜ´Æ~×v]Ow]À/¶|í,.Î\Ñù˜jÕ«¶KÌ\DL¨ÉLõÊò˜[Gf|=¯¨ —»þ³›÷/çµÀ ?è&IEND®B`‚djview4-4.10.5/src/images/icon_rotateright.png000066400000000000000000000022141264256014000212620ustar00rootroot00000000000000‰PNG  IHDRÄ´l;sBIT|dˆtEXtSoftwarewww.inkscape.org›î<IDAT8µ”]L›UÇÿ=}ûöh)0`0 AÆÄmÙ\ &Œ°Mö¥nFܲ SQ£q7È^(jt‰ûˆ&2Äap‚Y6†¡H¶ƒbËJ ”·}û¶ï·fŒÙ↉ÿ»óœçüÎÿ9Ï“£QUÿ‡¨U7\Z‘‹sÓé' ´æ!P`= ܨÀ‡T92 u— ÿÖüÓ1µÏÿL•éëŠBý6ÄâaåZ$˜Y¦½B\D1Þ<ç?f}ÍÒµÒ}Áå'ý/«1½—“F']®Ž¾€ ­Mœ„x@’IŒ¨>÷øHpéöSÜ÷5ã«‚ëßeZÞ9÷b—CC>éU ø7Ñü¤Ý$ÌÒ”BëuÚ´ÜõæÍzsb*ÃÌúA¦Æ~ò¹Æª¥¾Ãþ(pÞñù’'\뢌ß\ã#ìÒ\;ÇúŸ“ºJ#+“ žý%ù±Â”O7d¦Uå8Ó”`y£Ž¾žùÛ{¤þÆåò µÏ­=ReìpÎSÆöAf\-¯²®„RõOjê&ô£§+|_¾šßÐ?8Ö–ljùé€Ù@°éá¢]F“qÏJdóF݉òBcÖg—–ñ^åÃ7¢:!±„]š;˾–­/93#i6 )HIIÒ[­Ö§ï§ÚHåДFóçË a¦Iêz4z°å`ThÚ½0d5)°[ $&Ù˨íïÓËUê´šŒI@ŒgÃE½QC €£§®ß¬+ÏNn¨ÌVô”Œ8?›³2I#²3°ÓòZÀËŸ¥¶«Âj_×–•WRàqÍ»Ç^aºw®Éf,0P»Úl¶äŒ7lÚRKÀ+>×ÍÁ ö4³à>' ¾óß} ðÙjϰÄÛö úõP…Lž]%‘—Eîì‚çÖçÒpë}/‰ ^)ªìõš¦Ë´±¨rDˆ„–~û(z$× þ¯ú 5™ù‹¾ÎC°IEND®B`‚djview4-4.10.5/src/images/icon_save.png000066400000000000000000000014651264256014000176730ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓ/§â×ÂIDATxœÕ”=E†ŸÙ5w>ðÇÈ2’‚€ˆ?1"uÑEübH@ A‚!sB2úddɾw»3»ÓÝUÕÕ3;ÇÉk;vK­ªî½ýôÛÕ O[«6É?þúQ]OT3³zBÓvĤdËÌê)fÅ,£j¨n¢qçŸ9ó£ÅwÍbõñÏ7>_Ôẞ¼ôʵKPqíê>Ÿ~ñ Ë&pá¹]>ûäýÇÒ}ãÞºýÁ·_ýðáá””. Õ°‰›¿rùÂyêzòÄm/šÜó»#è&‘a{UÕ ï_Üãå¯ð•ËO1–Ë)É8w*,Ѝ1©z·ßx•«Ï_dÿÒ³u/,›–å¢Á,?,œÄÍ”bœ4ï½õ:¥Jùq;äýxÍŒ““–£Çt!bfÛˆ{+º˜øí;¨eÌ2–}Ƚ¯ˆœ1bH4Ë–õ:p|Ò£<ŠXUBJÊr_R–ÿ˜”…¶]ºHJBJŠˆc$ç-Â:Xáîœß=‡ejרŠã“’™–ÌÎlÊd÷³IÅl:á(RröG;ÏÌxçÍ×pwBBH¤¤¨Ú`—õ-6ö/¿þ‰yH÷À,B"AÕ¶Ÿ] ‰ ¢Û­HI͘wïþËýû ª6\a®°Žö˜õâ;;5) IÒvaÈL•ª*ìíÕˆ€*Ôu¡®a:-˜ÁdRP-TUˆÝ·yœ”Õº#›±ZE‹n¤ê O!¡Ù¬¬íÄ1$Öë@qGÕpÏäüp7룻BýB²8ÄD ¼`f”â¸÷½Ïó0îcΛ¼ "¨(î[ˆÃ:²^´äl¬VËñäO«àì!ªæñŸuÛº5¾­Žç‹ë÷þ~pSâö_‡ä\F✠¥øÿæN¿¹îÎé‚âÎužÚöàÿßyK¼IEND®B`‚djview4-4.10.5/src/images/icon_select.png000066400000000000000000000012441264256014000202070ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÖ /7ïŒÝÏ1IDAT8˵•¿kSQÇ?'&CƒTºµthýêPŠBÁ —N%.Ž  Ò¥ƒC—¥‚KA§àPi) Á!i³”GP^Þ»ïÝwjâKMú#Ú.÷r?ç{Ϲ÷\QU®Â\‘%Dž-[õ™ ÁTk-ÖZTU%Š"T•0 ñ}×uq]ß÷™Ÿ¶â“È ýÆq·ÖEÑårÜÅÇýüÂà~›Ïƒ x!p<ϧOñ{×ùÅë%~+:àÓÅ(‹À"’PÕh â zÜó×\ç6DQÄîî.³³5êõº‘kcÃ0 »€x ¬µ=kãã㬯¿duuu ˜‘ïqå]ÅžçÑn·ûºçyø¾ß ®ªˆ“““ …ìÂÂÂkàF\yO*Œ1=OC†ÝS$ DazzšÍÍÍ;ssso€›¸œD¿l¯ˆ˜™ùL¹\ÂóÐJžÕH™ˆ$FFn5ÆÜ ‚ [Ðåå廵Z-ï8΋äð]Mñ}ŸããcR©kkkÎááá—t:½å8ŽÝ›Í&6—Ëý¨V«d³Ù±J¥²Ýh4¾î°` ‚àq©T*îïï¿ÚÙÙ1KKKd2™À —ê§žv ¸¾¸¸85::ú©^¯k¡Ph´üëŸ'"²²²rÏuÝw"Ò¬V«OÞÊÿøLE$ <š˜˜øyttôhüi¿P®ü~IEND®B`‚djview4-4.10.5/src/images/icon_sidebar.png000066400000000000000000000013071264256014000203410ustar00rootroot00000000000000‰PNG  IHDRÄ´l;gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<YIDATxÚbüÿÿ?-@±XM{6Ÿ›ƒ9™‰áÏï¿ ~ýâ¿ ¿¡4ˆÿ› R÷÷÷?†ôÏÏ ÿ~}Z@Œ.s_üw7gøù‹áç†?øg`ø¤¿‡bd6©…{üû'†¿Ÿv1 ' ÃO a¿~Aðoþ Åþ1Ð!ŒÄþ‡„QB“™•‘ €XøXÿ3XK"4€ ú5äþÌþ ÿþÖŠ+ýgX¼Ž‰ €XøÙäH! Ãþý†í¿ÿ` âÿúùŸaß&€bBN?¦ÊÁ1Ô­¸E’¡06H@±0ü#.¹­\¹’ //¨% ÄòŸHƒÃÃÑ\Šp-²KAì¿@q @,ÈAÁ‘ýˆ"»»û‚-™ @(.ž={6œššŠ¢)44 -<1]Œg` £¨šp ãƒh€bAOèÁ‚M#>CA–c‚ €FLãúõk†±ƒƒ'<(ˆWéöj!$Gýgðó ‚jú‡×Õ0‡J:F÷>2{Ó¦u]lkë4¢ €XŒœ*’P öö%~xrÂö @À0þ7,99Ea¥¿"Ÿ8CÿC –ÿK¨?!±ú÷$¬Ë"‡†é¿ÿCÊ^  FÓú+ÿ•„˜5°ôÿóB-‚³ô?d9(ýïï?œa}ëÉw€b¤U@43 Àù¿§¾^PIEND®B`‚djview4-4.10.5/src/images/icon_sidebyside.png000066400000000000000000000013351264256014000210550ustar00rootroot00000000000000‰PNG  IHDRKÖûltEXtSoftwarewww.inkscape.org›î<IDAT8¥T»nA½3;¶d¤L0Øš R§L‰"[¢H ø$(øþ€o@Š”"RÓ„–"RÈ %E ?(@˜¬wÇ{Ï¡˜ÝµcK4\­fG3gîœsîÝ5/>œkuÊð¨ U*È ˜mé55Ë*Ùo§Õ•­ÍvšJx¼Ï'©??É$Ë$Mŧ’ÿ¹×üj ÊAW™ü|ó¤ ’’ åHBtrõ/ßÿr½áxzú…$€0–ïfó~£Ñ&ÇÃáh2I0ëëO¨)"ÍöcR*HæÒjnrq~Ñh´ûý~«õàÊ» )º°pxrwâ%Ne’ÎH¾í E("ik‡'õÌ»Ý>IG )¯:Ì™Ru&£^“ïÁ3²Vå2†*’­;‚Â<Ò4lФ k¥u{3›'[Š,Ëf•Ë•/‡âŠ0çU„÷^DŒ1E ˆ®ƒ¼÷!‡%®±à½`­Í=0Ϣħ]™€ªN§S‰¢¨àŸK0Æ,cHOЕ¬â8FI’¨ªª†K’$ vŠÈ2fmíÁ™cÌ`0c¢(:;;+ŒÌ]XÀ„ÅÜNk­µ6I’ km¥R988¨××¶·Ÿ…Bc–1——ÃÀdž5ŽcUÇûûû€t:{e9Ë›ç1_苜IUíõzÆDÝî^Ù¡šË˜à€HJØ6Æ9Wív÷ŠJçE-…ÌcTÉ¢¨ìõ>‡««7;Ýò|°Ð9w|üɹh4ºÐ=;;ÏËcE¤dsskáO£Ê⯳þúóÃ[Sª„¾#„•`>‡†u Hä*¿ý¿˜yx]Å’IEND®B`‚djview4-4.10.5/src/images/icon_slideshow.png000066400000000000000000000006671264256014000207410ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“lIDAT8í”=KBaÇÇ[„JYKïTCÑEKÔÔj--%¸Þ‚Úú¦- X-ö ¢ µ Dƒ7‡+v}‚Ì—«7Ë­3ÎË?ÿçð@‹BMíÆzyÇ@·uÌþ¦Ùh¥Í¸àEÔ!i‚]ŽÀMDµÛ§)´Š) Eçg.”RßÛJÉ=á…ïµZVô ty\}>;1e»—4Y³àSC5=^ž$º>o.‹•È%×Ï©ªzË<þ·\ó*züÚà)•s~0²<Y§â©öNú›êbƒ_aõ¶*IEND®B`‚djview4-4.10.5/src/images/icon_up.png000066400000000000000000000005401264256014000173520ustar00rootroot00000000000000‰PNG  IHDR‰ 'IDAT8íÓ½JQ†áw÷ìO%ÉuU‹ˆ"ˆØˆ¥½¥—¡iDÁF„\‚7âXÚ!²[ìß9ÇBŒ¨ÙD0•äkgx˜aCkÍ(cŽTƒ¹ÙÝ»Õû»_]o(¸½sÓƒNÎÁ­keÁg³ WÑ\p}³©¥ŒˆE+”z¯]6sѾàòÚ±N“JEdYH<='¼vRº]I©ÜI´ÚЦp¢„íTqÜ),k’ª7ϬïàO;‹Û68:\4rÁúÊ–2Bˆ&š@ˆ†abÙåìû xžE¥lQpMÎOë=Ôê7ö*Ó%cLá’e!Iô‚S˜¡Õ i·ç¨Õ*xÞWâÇÊÍ?y½180o71iì]ÍÀIEND®B`‚djview4-4.10.5/src/images/icon_web.png000066400000000000000000000025651264256014000175140ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÖ 9"mÈÊIDAT8˽•MlåÇ3³»3cïÚëïõ:Ž?;´µchP) &%m%„B€¸€„â> R*ÔSÕªR=T(´*mUõ’V@X`œØ&);^{×_k¯wvgwgvfÞ·Ljšrê#=zo¿çÿþõ×ó(ü:zôy6¢‡ªEûÜøøé,ß¡”ÿÓb{’ï8fì>Ûõíªö…ÀŒ„…¡á„‘Ùr¡øì—ïÿâÂw?ñÚˆÛÒ~.[pš{ûö’èl#ÖE„© ¶]fiq¯fç‰iòй–?íÝüÒëxu6ï½éGê”þ½ vǩנ'%ÑÚˆ¦:uR™-\¡pñ‹ë,-­z™•ü³§Ÿ¹±“R6}üñtÿÓÙW~z$©$;ÛL˜Dëëhˆê˜aU!$ŽP°þôî fOmrcy‹‘ý=ØŽ4¢L]ˆõ½SHߺiÅìÜÚ½ù²š¸šåŽþNöõÞFD×ËU)s™"{ïV¹F¼©‰Ù5ªv‰7ž>Fus”·Ï~~70|áÒBß¡á!Žl6 …$BJòU…@‚第ùÝ?Âõ|j^ÀÒJ!¡ÎÔyë—9>ÚºøÙ¿†¾õXJ©¦–­DgG3ÝÍÚba̰‚ãúXe—RÙŲ¾^X¡æ@Èo{~€‡B{“ɇ3Ëê½GúÞ™ é Ñõ0ñz¦85×m ŽvS±®ëBI BH„”Š6Ë›Uü)ÿþÏË-»âæº57“+ŠŠ¢ ‡5*%›¥MìÃЦqdxˆšçóõ\–ÕµM„üäG˜õ²ö *Š"]Ç›mŒHÊnÀW ¤W-öw7” LÎ\g«X¡Pª1"¨¡0MñÉÖz:ãDë ÒËyJ¥²‚¢ÌîRñçõ•Üà•t³1sm«h3um…_>wœ#•ç¯l°Urqk>š ý{š0ºêØ—lBÓTrVEÞ˜Ë)À»rܸÿxæö=•ÞòÍé´¥L|™¦d;¼ûiвü¸ŸöFÕ|™HHåð¾8Žäà¾v*N¥"|:>-ý@9€ëÚ4#M¤¯ ……ø§R[J\ÛF)Eÿ¾~ÆÇ£Öv+•¬·øa´Vkà{.RX-¿8trˆãƒÌž}ïhKðŸŒÏ–r_÷}E­ÞÀóœk§ ƒÖ­5(â×ßO°mëÌŸŸ!™ 2w´+V­ÊuÝ•n˯~|e¸hÉb<×ÁV×ú«”bÿ¾~ö÷Ï‚R©™˜+'¸ûìVªWë…ÕÛÎån X±âÅÐq›¦§]íSbi)-@ðÇo§¿k4ìÞÎÎjµZŠ ùù•¾ôòL‚‘¡ þåžÙ1|ÜÒZ/”Ò0aÃÿê£u³FžÞðBÄÛ¨ÿ’? rìŒ_xùóábrÂÞyáðíwmù*݇ûöàN ‰-y’¹Ë²xV%ûΚYù ppD˜ÉÕ=Â=7Æ&kCßpáèOs_¼» wê bKÖ°°ó>–ßSξ¾²#`ù‡0{çmü_òŸ¾Meƒié½×éÈf–ÎÈ?÷f7µKÃTŽïáèÁAöü- Æ?„ùöÂF3qß‚1Æp»“[63ûáK÷›èbÁT~ÙlÎì\f^yxŽånm•»õ •Ý,v+íü¹X8üc1÷ñ=4ývv|AæÙI®˜ÔÓëÐ[¹âfÊ.Må}_dÕ¢u «»ÿcn¯£‹… IEND®B`‚djview4-4.10.5/src/images/icon_zoomout.png000066400000000000000000000020701264256014000204420ustar00rootroot00000000000000‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÔg̨ ÅIDATxÚ­Ô]ˆ”UÇñïs^ž×™ÙÇM··bÈP2“±Ú,è"I‹jƒ4¨™(ºð¢6Hº(¥ BJÉê˜]‚ðªÕìF1 •؛ݛ¶qt]ue×Ý™qž™yžÓ…/$ådÒÎÝùøŸÃïËõڳç@^ëdK«×&´0(iabFLlÖ­{ú3n±¬kðÀÀ`1VÖ§~à†~*…ç9!hµZÔ+ª³³#QR©ôÂÈ-Á»v}[Ô¾(ÏÏeI§l[!¥ nÅh[#¥¤Z©21~bæÒtkÅÆN¶ƒ¥ëæóÒc0ww·†:2é´ï¹h­‰“„V³…RŠL&…v\wêüd¡ç‘Â@;XÄqõ­°3Gxd2):2iÂtЏ³`þ<|ßŶÙ\óÃ'·ný¼ÐŽâFoxG'Zk\ׯsÒžGG$ ¶Rø¾Kà{x®ƒ­ùEyšÍ¹WÛÁJ“wlRa……”’Ùj ÇuplMb„X–…1†l.K½^k;±Ò¶DJ‰eY\š­R©Ö¹è:Hi‘I§ÐR+uH’„(ºÜ6jn¶z½Ás”V “J8õF¥J„ch% µZ½-,λx2Žc„LÏÌÑl4‘J'1µF)%ZJ´ÖØJa+Åä™ *•FÛ,‹©É™½§NŒà8šVœ'W……¸:©–Gk”R bn.n·JÅúðð¡#3QÔÄs¤°ÚqüÄ8£#ctwß;Ó>th÷ÌäéJé‡Áï‰M\×¾òâƒÁ$ I’ÐŒc~ýý8;w|ÁâÅ2™ pKÅêÕ¥Þ»òåµÏ<.]¾ ×±ÑêÊý*¥8x`ˆƒC?±dIlöNÌ¥ãÜszõËþµ;Ï”n ¬ZõzhÛÍ- ²éÞÎy~^J üñÛ©›M=ÐÓ³r$Š¢0çË‹kƒùG i¦Ç3vÖë_ÿõĸ1æ?¯¯Öç¦/ ¿ojcŸ˜©=›Ÿ7…æË—rå¿îÜFU/Ówlpμùó,zè~–-¬?~naùúUxG1ÿØ} jFdóš\ñ”_ÜÔGtñµÑ½Œcè¿ÛÁ³%Ë;ŠÙßæ¿5>ûÍGma€·ŸÈ +ºÊ¯|ÐG45AmtÃ‡ÇØ?ô[Þö›L ÿ ¼öp¶¸²'[~ckÑäi¦†¿cÛî 7¦âv«¸"[|le¶üò»o²ý½ÝT»Öü?ðU¼ìy¢¨–n`|²¾÷OÖ<¤ãP1lIEND®B`‚djview4-4.10.5/src/images/splash.png000066400000000000000000000405411264256014000172150ustar00rootroot00000000000000‰PNG  IHDRÈñËGÐPLTE½½ÿ½µÿcckµµ÷µ­÷ƽ÷îRRñéÕ{”­RuˆJ9çý½Æœœÿœ”ÿÎÞç””÷ùµµ²VU”Œ÷¥œ÷Œ„凜÷BBZýú÷ÑEEÎÖÖ!9kÞ¡š½½÷Æçïçïÿ½µ÷BççÿàÞ×Ò¯¥îkksk÷UUUkœ½æœ½Ö¤“Ç„{÷ñðîkcïþþþÿ›Î÷ö÷Œ­Æœœ÷úöæÆÎÿœ”÷ÆÆÿwXµ999ïéå”Œï”ÆÞ”„滋””œœ¶GG,|¦Z”ÆäÞçÿÕȾÖï÷ Š¼…~²""¸ï÷ÿ¥­½Îª !!!ïïÿïçÿض­çï÷¶{s÷É™‘¥¥ÿÌüúñÜÔËskïscïãȾm¬Î„{ïîíí„sï3™ÎÖÿcsŒÎÎÿªªª¥ÎçÎÆÿÀjjÈÉÄÆÆ÷ãçåÖpoè558‹·1ZŒ)d„“™þþü÷ÿÿÞç÷cZïJBç÷÷ÿcRŽ÷ïÿï÷÷­­ÿ­¥ÿ[‚—{s便÷{kïV~’s­ÖÁÀ¹ÕÈÐŒ{ïrrrÖÞÿÖÖÿÖÎÿíßÐÎÎ÷çÞÿÎÆ÷)sš¿JJZRï„„÷åÝßRJçÿÿÿR(¥÷ñàkZïýýýRBçÿ÷ÿJ{­&\y÷÷÷cRç•Ãܵµÿµ­ÿ9kœ­­÷p”§ýššÆ½ÿ·µ®­¥÷çççÊ×ÛøöñãããÎ ÞÞÿÞÖÿµÖç””ÿÇÇÇŒŒ÷>•Á¥œÿŒ„÷ZR粬¥ZJçµÆÖ÷ïØ%â³ >IDATxÚí}cÓVž'l-CÇÀ➥iÂÆ3\{Û—`N{i—¶t»ÛNÝ„ …HYÅsÍL'nèv¦eÂ\eφ´Jl~Èj7nÜ6J“È,¹«¸?í¾ß';±'% O'_‚l˲ôÞû¼ïï÷c×Íj)Úõ¤ °Cõ´H‹Ñ -F;€´íÒb´H‹Ñ -F;€´íÒb´H‹‘Í€ á›']±¿T²I’&à.— æ¤`n–m“½€ä¢¾h…$ þü¿Ã6Oö"ùEÉ@ň\$ œ*2;´)Ù H0Z4ŠÅ¢‘ñ†QÌø2Ÿ/ã«a›(‘hÒç9éIW¼®ÜOº5d+ ’O™V¥˜.*†¯FÑ@dÈ_ž¾hßÏš>Ë®|î&(;¼Ÿ?á’¬“€¥O³élz¦á?â“F”Šp°ÊüÊÿ‡ïœÁ €@p@Ž%äë“Z†Iì$×—ŽÇY¤Êk<[‹HA*N#0}(Ä~`.A[´*H‘{‹ÅL´eD¨€HFÖëtz½,@oάN'~Œ¬?„ `¹dd~æûަælµ$Ÿ‘É\‚Π•4þ·Hù®büpd+ E'å âYÖÁ²”wÉB»ÃG8p«Ľ¬7 -’ÎN}ѾÌÖLRµ£'@ÜÛ {ƒRFQ^Íé4v 88O+ðßðý F§ÙåUÞ£(ªàQX]g•¿aGâ”C‰³½#,E±U`•Þ¸2íÌ*†ôItSD$t^:ÃW„7ÐlQˌޠ{‚ÀKÒwk $T0p CY€z4ëȦ£ñã„lDòeu:žŽ÷ê€D:>BÁ'§NS#:;¢Óú{^x…³tÒéDh¼ÎbA>ÙÌÞ‚;fAëxÔÈ{”éÃà3¦³é  º˜ ZD¯˜6¢[·j0 ŠҩiVw¦PB}$ý^\×߮;w@r}>/ÍhGœæ¸$M÷ê4×KÑ×qŽæX ôµÎq_ã»,ë6]L+Ðñ›uÏ`Ô7­ëýu(éMz"‘Ýœ^`DQÅd&ÅÐj^x§¬iwþ€˜WùÃ3 U4¢[4,¨ã=(—‚&{iî§ŽõÒ4°H«hñ,‰pº—‹àë×4¶#¼qê”#‰xv7œõêp…“b{u G<›.‚ ÚØŒÑ¢âŒˆ²èᎨª<Í{J¦¦‰¢ær¹%ÍuÝ ïòÍ­º\Ú*DŠf•ÍûzΧ_ë†J2 ÃíŽ0Lä”î€2;²[IοL@¢F‘‚2:‹ÇSÜnŽav‡ ÊN§fІÞÍ0w"S¢ƒŽ0œW§¼­{G¼Îì´/êkäÐHÞ¯õT¾œ%4í€zÙezò]…Œ—P H ˆ+¥ŸâX_t³2¢Nrr1ÉÉrŒ¹#Ê@´.FhÊ "°%´ˆm€@çShQ$ ?%›;Q¤BbŒXc1šå˜è`dY§c1† ÑÞG{{)°Å cCÿŒ*,ÍzÊ€ƒÛt¹Ü ¾è‚FŸå])# ‰ÕË«ˆ»Œgi1Âú65™¤LVñr§ÄdI ²žxAðÐ2,‚ÎH+°ˆm€@çáb11ÆéØñbSØô4J1™)ˆ©”îáS¼¬‹Ï%SÐ=™S»Qr±zr¢NŽÖuP)š¦h¯hº,@5T·–XÕ\šG­¢y'¹ ÿ\ãîpV¥c½¸) F6ÛËMÉàËf9Zh•bÀ"Šò©oâI£a# Að G"|JNEt9Åó‚L‰½YËû ';‚ ¸Iw—ohšÙåQS"§O§Ó-Á"v’‘Ï2„ zà ¨‚‡WUU %=˜C\ˆãËùr9_RËå²¢9¸(•H"§8šû7]¬ý`)ñˆ®u¾º:¯åYÐ눇+!ãq`uU@J«ä*W~ s¬± ‡H}i´0 tÁ3­Ÿr^ÚéÌ[A‹Øˆ/눤T`UM$j^Í—Q ä•×¼i‚…¯7¬3*/§dQŒpI0·Àq®í A_šåD4!­òvýLóÓ&qd£ÍV'Pœ’U³ö—Õj0øÁôÍaúM ÚÇZv2aÄuF@&0ñŸY¾a‚TÀ3yS<°c^ÆV$À &BJœÝ&W}Íù@‡ˆË®í’¦Néq_Ó·0 žÈçµú_ð±S\á¡ ’‘R°’%ž©}>Œ]€D/-"@ÿ¯òÔ÷2àaDÖéš¾­•Í|@àcLä§ GœÓµ,$€¨ÛÄUNÌjHß4x„Y¨c—™H¡áëŒ?œÈÊIU2 ˜ÀÐqô»"?< Ø~\ʬbàªixè@ ü`n˜µß܆•Ê €ÐªµŽú'ªÚC¢PÛá†R¤M éÔ9QN4"ÈLDwÄ•N~³f ŒÜ´‰â÷µ `cé¡yóiP@M ð!V«ÌD€M §œY£F­÷M³\ ,ß(È—·LžÑ³M]C ô Š©AbN€‡š-öÕ˜û¼2F£±©£¾Ÿ‘D ¦? p 2FÆ02¶É,Û°*Z9Vk­%b »eŒaAàS€D[¿ÉPj¡V-ÖÈpI¡BŒœ"¾[ ¬6UE@ËˆŽ‰÷¾¬Õ=G[×î7Rœ3“kZÈ,E3)Õ¬û‰Áê¥â`õâ ŒÏÌTÉ'ö56µ”A…K+½U4ÒJ«òF1®{oL®£ñ¸æ.ó%`Æ×xÙôÀÕÝ^߯’Œ‘zJ$L ‘Àñj A ±HaÄ©d¢`ðÓ>L´+iCIg‹0@±ÙrFVI;,g³Î¸âeÓv¹†6¥¤ VׯÄÅQft]aáu°^Ž‹è”ã…´ F=´†>ò¡€ ¢àXzä*ªXL¨7ï-›Új‚DyℊxuLGû´ºM€|~6›dÖ9äz%QFŽ$HgqÀ‰3›¦te9FŒÑª•ØÐˆ16î)ç6D³J]½¢iE‰Ã¯P‡‚™F –©Ñ×AÉG‰ùîëü¬%²*€hIzc…>Ãö2|¹µïBcp•@Úk ÄŽƒ†vL;€›uhjŠêÍêý=£~XcÐ`ãN¸¢×‹¬ï (òÙ¤Dì ø²:íqQ꘥€~ RÀYQ€Y4—Ò^:ˆz ¢Ô¹ë(×Üæ 5âôt­2–ÒÔ4¥'i G#8:åÑ)­­z4 $8m¼¢Ô1O…€x8jƒÙ#ùâìt×”z"ððÒwâ¤KÀÁ…hbšÖ{Y`æ÷t¾¬ïüÁ å„ïhÖ‹_â¥TÞÙ¥Õm‹e¥uƽÆ!höþ6A’ÞiˆÞg£O+¬ˆ@\™¡Tbv–È5v9Ï8tG]n) Â#‚.Èn\ùÝ!úcœ·.JoPŒÌ^OWbÀs£Ê!.¹I• °Ìcè¥ÑBã`öæi‡î4ƒtɉ ŠŽãvSÇÅYímFAÅ:à;: ¿ôr481ø3Å&­n# b—åÉÑåY%™VSì%zÁ¼W”iLÆ,Ké\„ÆîœX­d705¶+Û[ëòJF¯÷^ÜB> ŠW2Mžûº¨²U•Yò¬®9†8ØõmÈѧÁ²à hÄ1_õ¬ÞÐTÙÑ‹f.¹:—ý)¡¸HäXê4˜ë»ÛËé¯ÖßÊçwŠŒæØÍvpY»´º€¤ê#XV|¢,²8ðp_àb( «sÌÆ@®6.G¨ìš‘ M½1¢å#Î: "}jÓ4é¾úæ|þ4/8JEPZÆ,tåŸ,Çb1YŒ4tþ¨ƒ«DÄ0@1ņ²É̲ II MÚz´"U§¶I$>d€…OqL“f„Ö©‰ÓN8¹òÆ&"ïÕ7ä7¼ÜTc/Ðò2CSi£jJ(˜Y¶þÈ Ï§R¼XßnJ,8w‹‰ u›‚'ö¢7D }¹`5¯”¤ž(0IÖÛ4V¯©"í\3³$ôÂ7JÔkωtÄlò`—Ï5¤€$ÀM÷®{E:…iLþUUAÔ”c )žPŠpðàCgZ ¢®6„§ëzN#x™´³Ð Ëy™[7i&]œk4g&¼r3@L½¾}qá7H¬x…5iƒ@ia º: ¯&z¦ŽÙ$VäI‚‡çá/eá’⊭H.£'êÆXJ]㓲õóh_1ÍrüúEk¿ÉóõÆÚÓ\~ãǹb£ùd` ²ªÔ×ï©ë Á>–7®ÉƒW¸¦A ªVIø—Ë7HB0¡ë}Œ ‚þ 4¯FŠöؽ¶bèÂé€d|Ž–Z%1MÐ7XÁ 2ă+³•Ñ;eÌi¸78Yë—N·eHßè"càJ«<8’‘éFÃÀ8¿F®ñÖcÁé éºòù¨HJ+#Šx«· ¤ÀÆÊúÖÇû8Õ¥Ê8 cÀ³*ddÞldJ§È„B"áFùàè±Ç3´6„Ž¡–°ò!žÉ‡hr|£9Ê=íýCÀeºeµ„Žá¸}‰'È»×/ö9³x¯ò*Þ88TŽS6x|ñ”f– |ãÝž ôåÈ&[w‘¢GÄúŽw àFþÔºÞEš­ÍŠ $ ³àœßá5fºðçeù¹\Nˆ`@¶¹9Ñ“dâ­Å!àwyÜMò!É&€àdDÊSZˇðîR\¦§¦î¾Ÿj7 Ø…7e2˜Tc7d:rÊ”à)áÐ^I•\Zi°;Uƒ’²Iš.! ^<.×õUÌƒÔ mˆÒwiGK–IèÇ\]u ®©†ØzÚÁƒçÑÊn³–Iå<^{ÛÆöF©óy£.’©¦¹»¢*T°ÂªIbQÆ]Z¬F ù8VM2˜ô?TkTióRÒSyÓSÆ$²’GÓZ—ìRk=‘¨“ó$Æ| ‰F_O˜œÇÃ*µc±¢´¬a rËXÕLÕüä¦TîÀ³œ¦ñåYŽnP5!¶ÕÑUw“|H¾ 7' 6å1kÂï¨fJY¿!1Y ž|ƒ®®´PÌünr(áðÙøCÍ[Ó|,€¯ë•;ºÌ$G;3µ³I¢tÙEqAŠ¡Y¤ÁŽ(:à×e2‚  ¤¿ º†çZqw“|Hžj&Zs>'ô«šUaº&,q1M‘’šÅ!«¥I®fÜ¢‹yxL å$*½öF´ÖTC$÷Ò: ð’®ä={\uÉ{šäCÊM FÍʇ¡Î5TÒH53Dn¸Ä&€ãyB´•C\âzIi.¥Y€¸Ç«\”Ð)vº>“Ô\¬Ë*¿ŠåG@„@2TÝc«HIo1@&ô¼»&‚âÍ“mj|HNqÕÅwUó!¤G¢ðJ5€0˜°¨ÒÅ[iVïhÄ\Sê¤Ã’–R‹5ÏcòØÎ¥ð“ÜÁÆëG¸IºÅ!„ßH> 4âÓñ115òÄTÐ[LdIºé©Í‡$¬|ˆÉ65σJHp]ñã]$‚Æ–šÕ"ÑãÖ\ê ‘qXSM;¢7MÖvBuª€hk†o0ꈙ•¦ÃÇXfoŠ7Œ“G‘…âꪖŸ’iÄ]ÿ˜Õ®qÞ]n5@rIs¶.â!¾øæ€Ü4ˆS“r{JÙšÖa=«Ö·äƼǃW‰MëIYyx,ñ1])TM©êµ9-\®>F®\cŠlãˆÃœ…ª+¿&«®D# ÂÚcx|ŒYòxTW«L6D±*ñ¶ùåéÚ Èúo´Z@¦´&wlˆ©¬EåªW#eÅò†¢%}à+½ñ"ÑiP[>µþ1ÖÅ­HNw5£ïdÃå5ñIlv…Ü|`;Û,)¢Ui‚ÚËÔŽRåÝì‘MiBtkyê›Ôe3@‚ñ‡$ÖìŠTsmš«ÚÈ¾ÐÆH¾–j2±çq±§Ÿ ’÷Q‘7y¼³ÙÅ8/Xd62PyŠÝ8fý¯`”mˆùݲÉã3ÍÒTeŠXQ¹x“ä™ÊÅ3Á‡ªÄ@òÍ®jA@ê'†T"MÉùª2¿á7ùÇP’7L5AÙ$Êeæ‹£‡ŒM•tµöäÛ˲>-5©„kÝÒ¨Jm HcÙZ `ÒJI$fI¶ÁWÉ`›æ€H¾ôì8©™'’ï"sž5yµÎ‰ˆåYîZµò"ÚÀͬ,x~šX ¥.ô4…’•I‘`³O·&UÃ÷²µNJI0™fƒ i´KbåqVŠ¥Ä5¨~Ã\û6ßU²n\–õÖÊ‡Ü :J过xL[¸VgÄ«+g›\+I+¢×¬uaìUsJà"t­ ¡šÎ(…±î.+/b’Lmf]ºÀûÜÉ‹¸ø8Ȭ B‰ä®ò*:¯ª[þƒáÒMg¶ú8’Bæ=ÂlýÜàoa#3\Ür€äØÆ=žB‹YYÁÒ^â‰p$08å À[ecÇ‘¢Ñ,‡¡ÅñÕ7n[LîzÙmjbMfZº³ŠN3Fñ5wÂ¥zÈèÍÉQ¦«2O„Œ*M•°{x}ÒÍ\歹xÜä ã Íæ’.²z‡[%ÃhŒgÜ¥Ö ƒ’Á“’ç­ñÝGÀŒÕb~ˆD‘h/öK("¶ÆTaƒ§ÄalDèr'LÌdÍ¢oìQÕÿp™L Q&…BF¶——Z&!”¿Ù%`˜ªyW^`ŠQ0éªQÆ‘C+»³}Mî¡kØ ²D™´0³£kBôP|Et“‰(-ftf¢õI–«AYmuœ´"Fçn8r8‡ 2Á#oàS˜Õ¬¸6UÃsYÔè>†„'IJD\Ë‹ônTÍD4ò¾ËÄaße²Mj$“3þ€êeXF€ô6›Ë.Ñ™ÈCÒ“x%†=ÓQ+‹ÌÝÌIÑLvmÞY†ˆh«qwËbE{-@ò "Õqr¸ú-‡k,ëSµ€@Ày®ÄgqI‰Ô²i½}œY™'bBb¯u’!.³V⥈<Ý Ø5@Èã<@„4N¤#» à(&Å9»¼»`ÏZBvçC<–ÈZ›°¡q¸ÐO"kôF}}¾(NSh٬̯¯,€µP¹¼¬×’á,‘%»*—pòæ©kIçå’%²ˆyaå<i_d}" AÉ=ÅzµéÄiºfI.ò8ÌŒðY_†Ìm$U0¯X¤´–ÑçlKjw ûó8G¶"àhœ­y‰Lgú.á²ðé¬s„“M"¨ ÆHMÕNëÈp$#AÂù¸ˆŸÅ!ŽÍQ8‘ –à­¼IX” lZµ€æðu¢Ô.³yóEé¼P-¹%²0³#gâ%kцh´˜NïF^#ù´ÿ‚JÝÊè„Q[ì^ÛFüLW‰IÉÆqž²{`œLØÐÄŒ’Æñþ†57 ÅÉR½†ÌbFuƒóDøñ®’vƒÓéÚ1*†ˆÆÁ­¬¼ÊnÓŽôQ¼S&æEVÂÂÔ ´Vy@•Cxw"Ö|5”((»exÜ*‡¸VÇ=ÊtºˆøŠ†/£(wÌ*‡\ •ŒÎxȦ9T¶âÓÕR%mé‹ñUN‹a“Z³Yà “ì³qeÄAÑ´C·ÚK›% óy0óaÊŽÞÚÅ5.E‰&<’}Ï.b6C;ádøULMÔäEÌ«>?Å5àÞÝÖ(2p Ë'õÑf=ƒÓê Sep•tЀbcɉr*ølqDl¹˜¯ ™¬TÖ鬮5žuzY–Òiú”Ø×ȸΈž®¤!†AÞr›Ï“Ò´ i !|Ìl¸žÜDðù@·m\’‹ÑYÖÚeŽq§C­ýrí9ú¥Ö$£7 ¹AAqåñ*QlA§¹ˆ˜Úp±–ˆUkûŒp76ÞÎä6Ÿ\Ê\ßðƒD“B JsT}!1¯m¸Z¤)\Ä»Tª€üÆÅpòºÑZ€MG¿ã̪@­N¨ä" Îo¼N•½fžúÍÏG¸&Üñc{×)êÜ8¨¾é2B›)¢ ÝdE( צaÑYÖËât¶.íÆ†«ºa‹#ò=OG@3‹¦uëÈ*Žæ8†‰ñýð2Y$‰ªÍIï5DÙIÑ妓E˔ݤ3:#l`K Wo¢(;”C×¹)Íe–7*Ö¼[Ô“°YÓ)FØ ³4ùGë¢éHLÓʉ "WÕíY¢É>@(¾AVª“ pv$gM‘dD9%äM×åÚ‹?p©V§Q³TžÿiƒøÇ‹\z‹í‰ú‘íÔd4¹$…=•RË%5åáB„Ái”·)ÍT¶†óÅÏÐF‰aºÂ•˜-YÈŒ“d_ ÑÖdV=2ÅLEô— $Ê®r51«ž™yÆ-FtVé«éýo¤½¡.K~$ˆÉ—f.uËé®ÒtÜ®f5]Q}¼!³UäR|[›«§"‘åUOm>Ä…+sŠDt¯ÓA”Ð}ªQª7n\…âIU(=DB ²àF÷aÜ]"ƒßxfw$&‹Œîeb1æÑ9µl^÷ «pó<'àÜÂ;z„£”ºµ”£ˬ§+A¦l¤Ü—4ÌÂmħPIŽ,ö‹é ëØbX¦®U¡Ë}ÃÅl é%–uN^%ùY+â–ÝPj:Né^ ™ý­d.™J‘Q•䯗»VyZi1@Œ‘Wɇ¨nÍ%{°VÃ0¹$Ï3ºþ¿EAàB5•Lh)wiµ²†Ì•ó¡Â§{_­Í;£ -˜˜.=«Õ)]]·e½¥8´PMWð%â'Ê•P/ðoz3³ ˜aÁgMåóœ îh%’ÐÔ.ê…Sd;…$[H ò”£K#QºåI¢Á¸î¸[ÓxC”ê`ŸU7½A.ã#]VóÀãêøu’ iZ¢Týè—”ňÄrÀ­™r¾„3D¸y&nÏBåöéÊ»´P ²Ú޵ŸŠ!)äóù@Ž!ÙÔÌUkU 2á†)è±TŒ£Ò©Ô­¦—‹Ž€ßM’!düs¿r§<޾-‹AqôªV]ÈÊ‹Tç aêUnó†ó9iV *¨Õ|ˆV–uÙ‰ÅDŠŘ')¯ð¦¦r ³\^MSäÌ<÷^ksÀíïLÑÊе¡ÛT¹¬† àPbÕÔ8¾ºjO£]6ß äU¹0#lœÍëÖ•ÎEߣSI†ÔŠEØ­zb®è¤“¨Ëj!1By P|óŸûœúâ=ž²¦­%¨Ê©dªpJ– à-E"ôî”Y„ÐÑ<¥|~t=ÒZôÅõ‚ê@.—Õ®¸ï.›(\5!„+^—Aj¸ n¿¢i.o&’)ï0 GdzÎt½ –¢i€¯ÄWG@T·Ì±[ÍÐF³™mJYÏ‹ÁIü-&”û²Ôn–‰É´'…Ï[]Ê”“‚îIÉ¢#"BçÁy¼r>‘JBRÝUí¢Õ”®Ø³’¿}ù,E ªÊ•TRÒ|^äòy5$”¡Ë¦©åq ølIÓò¡„fš<­æI&%s\Ö:;’.Ö÷00˜hÞ$–Œ5eW^8v«0wP2دiU«BÆB dšÎlï:È—f½ÞÈ”H• ¸VÆÒ–BšKÉŒ×7áÈÆ@¢ª2É€Ê œ' BŒ²i-eûöQXV±ÀÈ4‡ë3!8xB)1‰SºË>)ònNÍ'T1É )ÎÁq» àrQÓFãÂë’a°S%k¯Dëš@«üÔ±eÌ(è›á„üekݬϸ5„¢Âÿaz‹Ÿ ŽŠ‹T>ÉçËy'€»Ð0SÐ1Æ$ãà°tq¶àÁÅPBÏË:ÍÅmÚ Ñ¾œºád§R|Š£ I ` ¤THOº…J@%\I—>`’1Ð’úî^–Nꬳøjãî§R&ÞK°ÜnäLWÝn×zØ4÷DPW%2L¯Ëí±–&H‘ÉŠ«žžÙœÁrQ\pñ¿÷~͉P™–q¹.ù¡åeŽrP`Szœrè‘$U ÅT*½OŽÅ¦ »‹ö¤ClœŽ`8¹˜H6‘S¸¸8Y„çcä˜Â5Ap r¾Y‹q¸B›ÍN;EHE–7„AòÐ0[ÆŒ‚}i'ͬÇO"f€ŠnH1ë¥0=%ÆR¤ÄdM ”;%’ƒ|¥XÖZbly\¾‰·iÑEûÊù²4Ù ,FÚZŒ‘Å‹pS*\tJ&(‰•E¿8 ÚQ¬366ì×UXNn áiy™f·âE¸‘›d54 /‰([íÔͤqy5ÚŠ¹Å !,xÄõ˜D(2Ø›uR²ZÖ”ˆÏáÊY m×bã6n›§è¦–¦àVŒ¼Ná«De-6¹ƒ$²Å&›â.mB·¸^µuÕ%_Œ!²RÙåê:2diÜ4CˆÅ¿ãÇÀ",ÉÙ@]¦p,ä‚”Õ‡"dçè?qÃEå*Õ%«ÊéöNìD*:¸HÂr“U æa ÄÀ h@õâiܸ±×‘C6d‹.«1d+á€;òÒ OVVÂõzˆ¸! [ÉÀœúÖ’>5ÒqZ: #2Õã îüœ¥kºù¾WOœ/ž$9Ìü´òŸ¼Ô&D ÇuLù°^€C)6ÛwPÊ@»nØaGSc4•îÛbËDš|ªÒ!p¹Ê-þ8£¤ãVÞŸ«æ ¬Ü)yÁÁÆÓE#«“ºÑ!r$’×i“N·`4]ÀÆ&iƒ$½’Ö—Äf¤tA#®(ÅKµ;VÖ­‚z%{P5Ž7PQ©o£À»ÃT€N“?8$+Çôwtã Ȭ"ŠQÀjp(º,(B41?¼€‡´Tc õ¬={w‹Î°¸Îq<î…&Osc+@£³$ÕFÅ)½€›±¥qu¯s:Ï‚¬êë‹NÔ´’ CN£¾ih–BeM¹J>d¶ |0Îkl]÷œÏ ›×ã‘"nmw‚˜Á„¸ó»é\ô¬aÓ^–òf³^’“¢Hù¡ZN¯¸Kl4§âÙ8Ar’GÚ¶ýØmÝO=NQN%Wâdëô4‹{gÓŸ:)à‡´Bö·Ç5ýNgø*¸9„$Õï'™ÁíÞ@å:⥓%k92†ÚÍwý_YL‚ˆÛºY­­ÓÞ°6VˆF @Åçû7üx½‹ðq~š†z5dz¸)ÔÈã¶%P`_|dÄ™þŸ¸_|Zñ¦CµZ›Ñ4´;ô®8¸Wiè¦Ð'¡³9§g<[üÔÈ:É[\Éݰ6q"»ÔcêS²ø¥’õ:{91…›(ÈO%¢•8žð¿µç}e‹…>_ßCí˜N¸wª(:Y\„jÚá`€˜îStý¹`€¾•eЩ¼ØÙâñL‹mWAH*"¸ãCÖ BÃpfÓ™l– €rLC'÷ R|¯ú¢dǃ\ý– Rß«E0+³Å¸·àDëÇ7”«ù-•dzãÙÌöÄ5>ÂÚZêa®Î倩ŒtFÁz8½içˆâ„wqTÈ9Ü+¥ˆ›Ïàæð…ÓëUâÙVÛòȪ˫ÙlGø©òûU%=í›NOCEP¦ûpbЙÅhî,„>m„ô’¡P ûˆ€Üœ,2KEPÎ#cmuæ#Ú· “&ÈR›l™#E eCxŽéŸ7ëó!&|1’.Ú¦@›S§åH¨ä ;AÇúÙ,ã«Ê< °Q ³ù¦•"b6 pÙeôÚ nñ‡V ßG6ž‹N(,Í:©Ö×¹nòûhQéMFD9ÙÅ ¥PÂÔjó!šËôè\Œ³ï{—í µ.zÔ%s‰°5Ù¬RnÉ—‰Œ€‡ ²‡ÏÆØmä¦Å`’ L€‹aíT$}„;z}g;‚[f°tŒ+ÁÌ'’ry &2;›ÿw„sbÛs‚É`Ò‡5š¨±‚p lê>kÏÕ(Ùísû»LoJöBШP0Gh¼œˆàŸ3`\%\—]‚Ûý·•|NÜ1=¡wèS}ÄgŸ|Ø’r9i½25¥¬T9¨º®m6–Ý€­]¶ƒD…$Ÿ;YL¥„ÊâVõc{µ#F­K-ÆP2†Q¼¤( n4m\2|g1›ýãg›­ H% :11}#:!MHŸ?ü›þ…PK‚d-Úü«àŠZjY@þZi£@ZŒvi1Ú¤Åh£@ZŒvi1Ú¤Åh£@ZŒvi1Ú¤Åh£@ZŒvi1Ú¤Åh ¿û¾èI×ô/„vi1ڤŨÕiûHmOº™~8z4@._Z:~üøÈÞÿ†4ó×3øä;i«Ð…uZªÐHpÆäG>但¾“C6r¡‚üoÛÄvÚ¶5æ ‡0±Æˆb²-y¤âÕÌýU Ò¶¥%?!ÐK€ÇÒò 8Œäöß>~áøñðpx1ìŸÿ¾ wü·Ã‡wÌåÂÏttt<3÷ãǤ) Þ`Ñ݃‹‹þÅkôÍâààÌíãßÀۃãÛ@äQJ7<¶264448×ÑÞ>6ÖÞÞßó¤Ûë{§¦€,ýúƒ ½|ìÁààÜÁ—«Ÿ?x¡sròLxù…>8}dpa²óáÕÈ#.Ø¿ÒÝ>³äjß7Öæêà`øÇoÿ6äÁéÏNFèôË&G¿yù³ þlr`øõŸ}öᛓ/Þ Ÿ€ôŒu¯t,õœÛ·Ò1ØÞ>ÓÓ?6ó¤ÛkS 殜½råñEêf€œþìã{û_ú ^ .ŒºGèòåèÂÂàü~áÅû÷'ç:«FÀüÌÞÛ6n_éŸÛ×Þ¿876Öß±§#ü¤Û}’.üõŸŽ;väÈÁùÇ»Óæ€<Ý99zï‹Ó§?>4¹09 Œ±°ðÍ€CçäÂâ±Ó§¿Ø?:¹¸8ì_ Ï_¹²4’mø¸½€gÚdžÃcÝíýÃCcí++í-+²rg/ûxpòt‰ý‹“ƒàõýÉÉѹÛÇídèâÀcåÌ0è’îî‹ýá6ôد êiïýìÙ7$é³g_{î¹çî9räÁãlä½% ÿªäñÁ ¹FœþìÏoŽ.|Y8 óÛÎ…3ÿrúô;ïƒ$Û{û‚½€´ï;¿¯cø™•óç»ÛÏøI=çOÜ"t´U,.é¹³ÒG7?ú(zöµ»w¡o¾ðåÓ½³lÈ2äôg/-Ü¥þ4òà‹Ï>ûâÍ…|öáK“@`/‡„;Ú÷u…ýcçσùë·jé¿uëÒþVWl&ÿrŸüæqÄÖCprÚäYÞø H0È\•Cî 6+õ64{çÃíçÛûç;†ÉÉá['®:thn¸%œÄàÙç^{ Ì+ ³È!ÿöÒÇ/o€œþ° Èý…ÑE´w,ov.4pÈ‹ ƒK¶+õî}=ÁA0³ÎŒ­ìk÷Wñ·õ\éqëhÛÍà7ð²HTʉ«ÁÜQÔ+Á9ü ò,¸ß]>Ó~hl¨ý"xûK¹™±••sÃícó`Tw<>“={å ‹EÎ^º„¦Ö@dÿ#Þ{k+ë.jï{“û ÷ %x÷¸È‹Å/^­2h3 3+çW†znæÆöuÌû;ú-!…€ÌÝúå øâÁ­_ýæÖ/‘öç†á͉E<‡ttþ(y=± swûXÇ:ÖßÞ³rmìç‹+í]÷Øcú @Ͻvé¬E—^+ë.ZY¨×?~·Óf@ÀEp ZüÃ/-‘€Œ†‰xüý’ÎÿC.‰€Àg› v¹ MÙŸCdõ¹* ~ȉ¹£GWÛ®ÂñÖ29'n ýå­£'ÿbÿʹeÿÐÊØò¢¿­cߨÜâ0¤Ó@6–Z.yðàÈÓ,d~ùÐòpÏûËï“`­õÀ\[[[.÷QÓ…Œ7çÓÀ oN®+õðÒû/cLåûIüÃÓ§?øì…ïùöóûú{‚aèàå­NYï9z´g£=þa€âÄp8âÖ­ƒäÜò‰_Þšƒÿû­o†V:æápn>ô·_‚¶ÛHðOþáxõñoÿòÂË_|ñÅŸÿüïO-’KÞúöí§N¾]!|âð'•'ï=< VèêÃ?¼M_ÈÒ<ÿeçÂý…3Ë1Æõá—p5Y¶"å|ûLpi {mÃåz–r5€´ŠýmóÀ-\xn±ÈU?6dÌßÓ6·ol€@†{ìài½£àRAéÊk¥þñS‡H¯úý®]»žýÕ³'ßÚµëÛ“o=?|¨sÞ€ÀÙmÒöþþI¤{‡®X˜üæƒÏÖY$_Œ"C ûß?´ÿÞ¡Éåý“÷–Q„Ù H%–²{l±Ž·ƒÁ`- à˜@ó¡íOœøåQ"²NÀyÄâjr@.Ž vË Œ eìñ¹r÷¹KgA¡[{ú ¯~÷î¯ZäØÓ ÃÏCÓûÒòòKßî:yèÞ¯ž:yò“ÅC pö÷¿Zð?$ ¿»àÏu ÉôÍô× ., /wvšœ„óáðÞð2\r®=ƒ€ømdq¬cn¬»ûÜ<0Èž¹ íVÇ!GQQÜŽ•qbÞRê'æ6²ÒÞÞuß¹yH÷ÊÊÊãréî§g£ˆÇGðï³—ž»û§yDÖŸÿõ_ÿî?¿‰¬³üÖ®“Ðö ºÞÞõ<Âsòí]/a»ïúöjÓ[n’1 wŽNVhÔè’Èò°êëÎpç™å¹3 H¬ûƒsa{ µwwíYÕno?×ÞnPµ€–o â{xׯ ºn-÷ld¬³3|ÕDÖÕÁþÇD:û†TYáWW'\rð Ø½o>ýå³û—v};yr×SÃ7õ-2÷ÖÛûŸBx¶ Èï–ü¤Ñ;;çüTɇƒ“`eu.}µg†&;çààÑ3ƒƒ{oßn³00ÇJ;ôâþÜLûÏáC{}ÓÕ2¿åQ$@·+VÖÑy¢CÐ «rn~>:Äo2¾½ëä'»~?¿m@Ö1i»0l)à†™Ãû*xì{@º<óÌá±±¯†æ@§,Í<óÌW‡Ç3g÷Éûgƒ£ƒ$*¿-@ ÕzP‡`kýç°¬ÔpÉœ¥¹+â‰xæè’€×~bÕ²dØÑÅ\•‹ǃíûVÚÇWöT9ñ8­Ž½ð ÿö§¿¿ ô÷ÿ†EtB@býûßýçg—o¢ˆÚõí·ß‚Iå6y~þ©]'ïD EÖ¡mÒ¶¦ÚæA¥ v.ûÛf:Î!~¥{lSˆƒK_]üçk¿Y¹øLx²sïžW°á^¹¸·sa0ÜñÊŤÒ^P4£··§Cr+ 3rheak¡ÇNh‘Å£€?:wôÄÑ«$N\m>jëÙŸö“=†[fÆú±k×®…{ϵ·w€7œƒÓ ÈÍȬ+o\!šäÒsÀÀOƒ¼¢ñWoïz¬ž§@f! 7ÿíÛ/=ø<¿ü€ÔS®mÉ6ïâè$4öÅî8³€Ñęï¬ô_œé¸xxqù«*÷´wN.÷·ÿü™¯ºÿ¡ͯѹmÒ?6D@,ü ÝÛAÅŸï>WUíóÃs@ÃþÅåaÿòy¿¸ØÌùÉ9ο¸8Œ—,b¸÷fÏpO0سˆŸçƒ=pÞß3ìÏÝl^Ê=6 lÇTº¥:Py}üî¿þÝóPÌOÞ~ëWpÕþ·@—»ë“›Ë¿Gð­“oÝ{‘ÕÖL¿pNéè¾vfòþ‹ ÑŸ¹ØÝ>7 šdÏJØ?SÕ/ÿã\çÌž×—ž9|ígþñÿpÛ ÁðÌ<žú^´÷]ëêÛwþbuÐI0Gl‹ªoÑS¶ÎÝ Zç+Ûü úÈOÐ<ÅóÖ(Høô¸€Ü<øà‹Pw#úüé?~÷Ù“¿Å À¡{÷°õÜ›¼u'¾¹rµóž|Ón>”ôøR£ »tü¶yÐÿÕ+ÿt:þ‹÷á-°Cxtarùð¾Ÿû¡'wÿó?#"׆¿ZºØ>vx/3Ç·iöæ0w c°7ˆlÈŸëYš;·¯»Ã¾A9"õ@é<Þ-¯{øãÁ]UøàÁ7¼ùæ›/ýþ“gŸÝÌÅù®U$7ç¥ùÆ|ÓÒíã–ö>sqßFN&Gý æ÷í‡kO÷ëËá•}c?ÿùØ ‚tø•=;΀Ï5Ø9´=¥^¡ž±óç_oѵBFæ†;öµÛ7 ¨§šš<@rß|ùñÇð÷…EäßA£Ÿ<ô¨7ÜÖü `rÍ\Ü÷Ë ¨ÀKô?Œü°ghPë\^¹88:‰Nݵ0|q ¬­Á™™9p ‹l»hó?ï>ÑésK¤îsí+ö ”›?x•Ðòc&©‚—Þܬq·2ÔöÍ7Ÿþí»Ï?ûæ#ßu[€´]¸MÝ>‡;¡ã/.­¹‰Ý¯weô«WºÿÓâWh§>¼çâ¾~`¦Ñ¹mù!/ý|w?ê’}{:ú‡zÀß7d ÁÊàþÇ^žYzð“ýÉ?&ôÇŸ€‹þwo|éÑc2Ûyâ•‹{ÐÃØî µ†ˆ1ÈÂdÇʾsƒŒ²üGäÅ_ ¤nǾóíþÜâÊy4Ýfóý-1²¡žr‹Gž¶èË/ß}÷ÙgO~yÈîqY›Ò3{ÖX¹øUxtèpõãoF'; W¿zåÚàBçPžֹðâýÉ™G$‡ß±žžsûΟïFŽiE@nbLë·ï"=õÔ³O½{ï±Ê¸=@¾ÚTÅ }æÅÑ™vbëîûOàÿ-îiš\X>ÜÝÃâÏ­ Ó¹ð/ÞÚÛö(£NzúÁÐêï™Ã'ýóè)ö·ÌpÅ:Ê]ÙÿÛwòü³O}òÛýþÇ»ÕöDÖй×_ý7×þ‰´õÊÌ‹/N†‡~síÚoúÏ€}»ÜÑ1xÿ~xìŸàË ᙎß\ûÍëshuî}‚A“Žnÿ>×ÿ‹¡á6`û†Z ÜüâûË‹þÇæàíq¸!WÏœùŹޱk+ÿ0óâýû‡æ''Ï€¿qap°^É<3^>3yfÈËÛ‹öÖÔÒߨ·wÌÌÍ cxÞF+«Ui›€tZI«ÑÎpx¨£óEhx+ŒnÉ`ÿ É#v’H}8|ÈúÞï}$³)7×1LŽœGEÒªÓì£í²ä·2»àî^%¿3<¼<:zæÌ™ÎðíÛáÎAøö*úƒ3·oïí<ß v.ÿ? ÷>Zùæç:Ú+±E`Ž–Ïû½Ñöi[òûýþð"€2Š1ùÑ9¿x±s9ÆD•”áð^Lïbºêv8¼ŒgnÃÛG$Ø6 n§…G÷Ø_ë¤Ï-ßðöÒÒÒ…ùyÿ2pÊœ '®ãôõãÇ/\hà jB`mÖß‘Ä,VW[–EÝ4é;?†,Ij¹ÓÁá¡30<y dçLÌBà2€Â*ÀË£÷Ô8w7Í¥ÒmpÔ‘Èi„Ò™UaQX, ˆ‚@ZË35vöŽu,ÄDÎDtJÊ`nz «÷E\º ¼ûk ËŒ„˜fh6ËD(Ìb,N]yÕUØmò €cEò¦ÉX( ™ ›ëy£Nƒ|ªë`fR#™¼`¹> Ä4 ±p!×Ï,…ÐtÍ0891ÅÙéÊ].ÎϙőE‡,ãeTIB‘$¢™,½CgèèîAÓ 2ŸöC& n$¢^Žaó–ë@¶Ø†"€YàäÔ SÁölíaG«ŸíæƒÈ¢ˆ"I+£¼â“ÓZŽíÍMôž‡ÀðK¿¼¤“×NZŽ_´2ŬVÀ&Š«]NY©*lhöSæ°ãe–I Ó$«ë¨²„*KØDÓ,ŒDð762‹³x¬ <%ˆA<´ÓDȪBñH^(¤uý°*IqE’¸¾©Û:ÚpÈ2ã‘(ádŠ–šêÕ=¯JY&’Ͳ4ÐÏúz‡áìi( ´¦Æó˜fHY«Ÿ,\ÀðRh¤©Ô(öX‘$r†Á¹à"Ûü´TVNg°‰"ª´Òª7O £®í"opð5H§ ´ ÂK`Sd<¥%V©cÀ’5jÅò_ðç[wLH‚ÐëQYB7MgçÙÕÖÌúj/m•åØm2³‰ä ðâ2§?ã–M8ô+â’† ³ÓPçèÜØˆMqZX´VW `¾}~♎Š2l¢HF×q«*µn×êŠIB3 †—šÒÞ½U–WúÏC…–‚+¬ª¦f‰ëwv!ˆËùÚÅâW\ÇŸ¾ðläÞG½I„–œn7M¼.'`,¥Âé`[] %ªŠÓ®ò@ÏFž<òYÕÙ ,ÌCS ø°µvÐ~㎊P…w™SŸ\d@>¯zN7ö—ÛU½DUó¡ËË8ª*Ië:‡Ç&ÑM¯ÃN2•†ÀX¿ &Ç ÎPSG]•—m-ʾwÿÊÊ}€órÍ+In÷íKw¶6m5 }‰ª²Î[Aky)Š$ñÊp€J—“_ÜØƒ*IÌê&#…OûAË¿j}TµµÓÓìçŽ6?w·49ó7Ýìû¬ïãSDÃ!ëüÜ ðÖÞoO/‡T»¸ %nÜŠ »$1O’7 ¾¿©·,c (’¹DÂà­†ª„5 ´ÖÕ²±¶šÆ7åªÂ·nÚyÛã¿ÿ.PØ® lîzÎ.Ig²Œ]’pÊ2ª,q!eïÆN†Cê{‚Œn¬ÜŽ;n_´w"øÛhm¨g[c=ݵU´–zðÚUÖ••8|뮟ìýסѺÖgAWË„…]þPô¹]·™ I¢€$ /…¹«¥‘Þ™ › ·ÃÁ¿ÎÍBpšÛðùýôøÙÝTÏúÊrjvIDEIdgÚM™ÍÛKOLN29–¯’CŒgN½j ”) .YÆc³!Š+°UᎵ­üîÐa_|ú>„¶µ8×Ô³±¡žõl¯­¢ÉíÂm“QD‘`&Kß²ñóú¢/}Ò_I,Ò ”]5}à¾ùƒòþ®öÛóæÊÁ%‹"§–Âdò:¿}êi8ò.ØíÖ¶k¤¦²‚Κ*:*Ê(WI$œÓ8±bßàÐØ«ï:ÁËÏŸ&¼Î`ÿ9ëX¶þ ý¢LX´ýCçþô³ë»{\6¹Ù£*üñég@U©üö^¢±8N‡_•—-M t×ÕÌçyéìùÄÞ|ç=ã—Ç87<ŽaD­» d«¡D¸†‡‰ú«NÜûÐuûâZ^}clŠéx‚þ©âé ~o%Mehº‘:953;ø÷}Ð{ä,¦±®àE l‰§­HVÌ„\ €8_›~jkuåÞùtF<\¢6H<—#•Ó2}ÑÓ‘Wö0üÙy­(¸`+€\"|Õ“ð*­Ð÷Íw´ud}÷æÙDŠ×‡G¦Þû­c£ýòÅì{o÷œÆ4.ë 6m¤.¿/5Úµ¿ U ¢ü7OÜ9;¼†7ÿ™  ]fª˜e4­:ÿפ—|œÚ€rÀ x¬².[)§˜tÍ/3¡ð^DzU `X_Z¸øý$Ì$pÒßIEND®B`‚djview4-4.10.5/src/qdjview.cpp000066400000000000000000004373471264256014000161430ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #else # define HAVE_STRING_H 1 # define HAVE_STRERROR 1 # ifndef WIN32 # define HAVE_UNISTD_H 1 # endif #endif #if HAVE_STRING_H # include #endif #if HAVE_UNISTD_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= 0x40200 # include #endif #if QT_VERSION >= 0x50000 # include #endif #include "qdjvu.h" #include "qdjvunet.h" #include "qdjvuwidget.h" #include "qdjview.h" #include "qdjviewprefs.h" #include "qdjviewdialogs.h" #include "qdjviewsidebar.h" // ---------------------------------------- // UTILITIES typedef QList > QueryItems; static QueryItems urlQueryItems(const QUrl &url, bool fullydecoded=false) { #if QT_VERSION >= 0x50000 if (fullydecoded) return QUrlQuery(url).queryItems(QUrl::FullyDecoded); return QUrlQuery(url).queryItems(); #else Q_UNUSED(fullydecoded); return url.queryItems(); #endif } static void addQueryItem(QueryItems &items, const QString &k, const QString &v) { items.append(qMakePair(k,v)); } static bool hasQueryItem(const QueryItems &items, QString key, bool afterDjvuOpts=true) { key = key.toLower(); QPair pair; foreach(pair, items) if (pair.first.toLower() == "djvuopts") afterDjvuOpts = true; else if (afterDjvuOpts && pair.first.toLower() == key) return true; return false; } static void urlSetQueryItems(QUrl &url, const QueryItems &items) { #if QT_VERSION >= 0x50000 QUrlQuery qitems; qitems.setQueryItems(items); url.setQuery(qitems); #else url.setQueryItems(items); #endif } static void growPageCombo(QComboBox *p, QString contents = QString()) { QFontMetrics metrics(p->font()); QSize csize = metrics.size(Qt::TextSingleLine, contents); QStyleOptionComboBox options; options.initFrom(p); options.editable = true; QSize osize = p->style()->sizeFromContents(QStyle::CT_ComboBox,&options,csize,p); p->setMinimumWidth(qMax(p->minimumWidth(), osize.width())); } // ---------------------------------------- // QDJVIEW /*! \class QDjView \brief The main viewer interface. Class \a QDjView defines the djvu viewer graphical user interface. It is composed of a main window with menubar, toolbar, statusbar and a dockable sidebar. The center is occupied by a \a QDjVuWidget. */ // ---------------------------------------- // FILL USER INTERFACE COMPONENTS void QDjView::fillPageCombo(QComboBox *pageCombo) { pageCombo->clear(); int n = documentPages.size(); for (int j=0; jaddItem(name, QVariant(j)); } } void QDjView::fillZoomCombo(QComboBox *zoomCombo) { zoomCombo->clear(); zoomCombo->addItem(tr("FitWidth","zoomCombo"), QDjVuWidget::ZOOM_FITWIDTH); zoomCombo->addItem(tr("FitPage","zoomCombo"), QDjVuWidget::ZOOM_FITPAGE); zoomCombo->addItem(tr("Stretch","zoomCombo"), QDjVuWidget::ZOOM_STRETCH); zoomCombo->addItem(tr("1:1","zoomCombo"), QDjVuWidget::ZOOM_ONE2ONE); zoomCombo->addItem(tr("300%","zoomCombo"), 300); zoomCombo->addItem(tr("200%","zoomCombo"), 200); zoomCombo->addItem(tr("150%","zoomCombo"), 150); zoomCombo->addItem(tr("100%","zoomCombo"), 100); zoomCombo->addItem(tr("75%","zoomCombo"), 75); zoomCombo->addItem(tr("50%","zoomCombo"), 50); } void QDjView::fillModeCombo(QComboBox *modeCombo) { modeCombo->clear(); modeCombo->addItem(tr("Color","modeCombo"), QDjVuWidget::DISPLAY_COLOR); modeCombo->addItem(tr("Stencil","modeCombo"), QDjVuWidget::DISPLAY_STENCIL); modeCombo->addItem(tr("Foreground","modeCombo"), QDjVuWidget::DISPLAY_FG); modeCombo->addItem(tr("Background","modeCombo"), QDjVuWidget::DISPLAY_BG); modeCombo->addItem(tr("Hidden Text","modeCombo"), QDjVuWidget::DISPLAY_TEXT); } void QDjView::fillToolBar(QToolBar *toolBar) { // Hide toolbar bool wasHidden = toolBar->isHidden(); toolBar->hide(); toolBar->clear(); // Hide combo boxes modeCombo->hide(); pageCombo->hide(); zoomCombo->hide(); // Use options to compose toolbar if (viewerMode >= STANDALONE) { if (tools & QDjViewPrefs::TOOL_NEW) toolBar->addAction(actionNew); if (tools & QDjViewPrefs::TOOL_OPEN) toolBar->addAction(actionOpen); } if (tools & QDjViewPrefs::TOOL_SAVE) { toolBar->addAction(actionSave); } if (tools & QDjViewPrefs::TOOL_PRINT) { toolBar->addAction(actionPrint); } if (tools & QDjViewPrefs::TOOL_FIND) { toolBar->addAction(actionFind); } if (tools & QDjViewPrefs::TOOL_SELECT) { toolBar->addAction(actionSelect); } if (tools & QDjViewPrefs::TOOL_LAYOUT) { toolBar->addAction(actionLayoutContinuous); toolBar->addAction(actionLayoutSideBySide); } if ((tools & QDjViewPrefs::TOOL_MODECOMBO) || (tools & QDjViewPrefs::TOOL_MODEBUTTONS) ) { modeCombo->show(); toolBar->addWidget(modeCombo); } if (tools & QDjViewPrefs::TOOL_ZOOMCOMBO) { zoomCombo->show(); toolBar->addWidget(zoomCombo); } if (tools & QDjViewPrefs::TOOL_ZOOMBUTTONS) { toolBar->addAction(actionZoomIn); toolBar->addAction(actionZoomOut); } if (tools & QDjViewPrefs::TOOL_ROTATE) { toolBar->addAction(actionRotateRight); toolBar->addAction(actionRotateLeft); } if (tools & QDjViewPrefs::TOOL_PAGECOMBO) { pageCombo->show(); toolBar->addWidget(pageCombo); } if (tools & QDjViewPrefs::TOOL_FIRSTLAST) { toolBar->addAction(actionNavFirst); } if (tools & QDjViewPrefs::TOOL_PREVNEXT) { toolBar->addAction(actionNavPrev); toolBar->addAction(actionNavNext); } if (tools & QDjViewPrefs::TOOL_FIRSTLAST) { toolBar->addAction(actionNavLast); } if (tools & QDjViewPrefs::TOOL_BACKFORW) { toolBar->addAction(actionBack); toolBar->addAction(actionForw); } if (tools & QDjViewPrefs::TOOL_WHATSTHIS) { toolBar->addAction(actionWhatsThis); } // Allowed areas Qt::ToolBarAreas areas = 0; if (tools & QDjViewPrefs::TOOLBAR_TOP) areas |= Qt::TopToolBarArea; if (tools & QDjViewPrefs::TOOLBAR_BOTTOM) areas |= Qt::BottomToolBarArea; if (!areas) areas = Qt::TopToolBarArea | Qt::BottomToolBarArea; toolBar->setAllowedAreas(areas); if (! (toolBarArea(toolBar) & areas)) { removeToolBar(toolBar); if (areas & Qt::TopToolBarArea) addToolBar(Qt::TopToolBarArea, toolBar); else addToolBar(Qt::BottomToolBarArea, toolBar); } // Done toolBar->setVisible(!wasHidden); toolsCached = tools; } // ---------------------------------------- // ACTIONS QAction * QDjView::makeAction(QString text) { QAction *action = new QAction(text, this); allActions.append(action); return action; } QAction * QDjView::makeAction(QString text, Qt::ShortcutContext scontext) { QAction *action = new QAction(text, widget); allActions.append(action); action->setShortcutContext(scontext); return action; } QAction * QDjView::makeAction(QString text, bool value) { QAction *action = new QAction(text, this); allActions.append(action); action->setCheckable(true); action->setChecked(value); return action; } static inline QAction * operator<<(QAction *action, QIcon icon) { action->setIcon(icon); return action; } static inline QAction * operator<<(QAction *action, QActionGroup &group) { action->setActionGroup(&group); return action; } static inline QAction * operator<<(QAction *action, QKeySequence shortcut) { QList shortcuts = action->shortcuts(); shortcuts.prepend(shortcut); action->setShortcuts(shortcuts); return action; } static inline QAction * operator<<(QAction *action, QString string) { if (action->text().isEmpty()) action->setText(string); else if (action->statusTip().isEmpty()) action->setStatusTip(string); else if (action->whatsThis().isEmpty()) action->setWhatsThis(string); return action; } struct Trigger { QObject *object; const char *slot; Trigger(QObject *object, const char *slot) : object(object), slot(slot) { } }; static inline QAction * operator<<(QAction *action, Trigger trigger) { QObject::connect(action, SIGNAL(triggered(bool)), trigger.object, trigger.slot); return action; } static inline QAction * operator<<(QAction *action, QVariant variant) { action->setData(variant); return action; } void QDjView::createActions() { // Create action groups zoomActionGroup = new QActionGroup(this); modeActionGroup = new QActionGroup(this); rotationActionGroup = new QActionGroup(this); // Create all actions actionNew = makeAction(tr("&New", "File|")) << QKeySequence(tr("Ctrl+N", "File|New")) << QIcon(":/images/icon_new.png") << tr("Create a new DjView window.") << Trigger(this, SLOT(performNew())); actionOpen = makeAction(tr("&Open", "File|")) << QKeySequence(tr("Ctrl+O", "File|Open")) << QIcon(":/images/icon_open.png") << tr("Open a DjVu document.") << Trigger(this, SLOT(performOpen())); actionOpenLocation = makeAction(tr("Open &Location...", "File|")) << tr("Open a remote DjVu document.") << QIcon(":/images/icon_web.png") << Trigger(this, SLOT(performOpenLocation())); actionClose = makeAction(tr("&Close", "File|")) << QKeySequence(tr("Ctrl+W", "File|Close")) << QIcon(":/images/icon_close.png") << tr("Close this window.") << Trigger(this, SLOT(close())); actionQuit = makeAction(tr("&Quit", "File|")) << QKeySequence(tr("Ctrl+Q", "File|Quit")) << QIcon(":/images/icon_quit.png") << tr("Close all windows and quit the application.") << Trigger(QCoreApplication::instance(), SLOT(closeAllWindows())); actionSave = makeAction(tr("Save &as...", "File|")) << QKeySequence(tr("Ctrl+S", "File|SaveAs")) << QIcon(":/images/icon_save.png") << tr("Save the DjVu document.") << Trigger(this, SLOT(saveAs())); actionExport = makeAction(tr("&Export as...", "File|")) << QKeySequence(tr("Ctrl+E", "File|ExportAs")) << QIcon(":/images/icon_save.png") << tr("Export DjVu page or document to other formats.") << Trigger(this, SLOT(exportAs())); actionPrint = makeAction(tr("&Print...", "File|")) << QKeySequence(tr("Ctrl+P", "File|Print")) << QIcon(":/images/icon_print.png") << tr("Print the DjVu document.") << Trigger(this, SLOT(print())); actionFind = makeAction(tr("&Find...", "Edit|")) << QKeySequence(tr("Ctrl+F", "Edit|Find")) << QIcon(":/images/icon_find.png") << tr("Find text in the document.") << Trigger(this, SLOT(showFind())); actionFindNext = makeAction(tr("Find &Next", "Edit|")) << QKeySequence(tr("F3", "Edit|Find Next")) << tr("Find next occurence of search text in the document.") << Trigger(findWidget, SLOT(findNext())); actionFindPrev = makeAction(tr("Find &Previous", "Edit|")) << QKeySequence(tr("Shift+F3", "Edit|Find Previous")) << tr("Find previous occurence of search text in the document.") << Trigger(findWidget, SLOT(findPrev())); actionSelect = makeAction(tr("&Select", "Edit|"), false) << QKeySequence(tr("F2", "Edit|Select")) << QIcon(":/images/icon_select.png") << tr("Select a rectangle in the document.") << Trigger(this, SLOT(performSelect(bool))); actionZoomIn = makeAction(tr("Zoom &In", "Zoom|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_zoomin.png") << tr("Increase the magnification.") << QKeySequence("+") << Trigger(widget, SLOT(zoomIn())); actionZoomOut = makeAction(tr("Zoom &Out", "Zoom|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_zoomout.png") << tr("Decrease the magnification.") << QKeySequence("-") << Trigger(widget, SLOT(zoomOut())); actionZoomFitWidth = makeAction(tr("Fit &Width", "Zoom|"), false) << tr("Set magnification to fit page width.") << QVariant(QDjVuWidget::ZOOM_FITWIDTH) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoomFitPage = makeAction(tr("Fit &Page", "Zoom|"), false) << tr("Set magnification to fit page.") << QVariant(QDjVuWidget::ZOOM_FITPAGE) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoomOneToOne = makeAction(tr("One &to one", "Zoom|"), false) << tr("Set full resolution magnification.") << QVariant(QDjVuWidget::ZOOM_ONE2ONE) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom300 = makeAction(tr("&300%", "Zoom|"), false) << tr("Magnify 300%") << QVariant(300) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom200 = makeAction(tr("&200%", "Zoom|"), false) << tr("Magnify 20%") << QVariant(200) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom150 = makeAction(tr("&150%", "Zoom|"), false) << tr("Magnify 150%") << QVariant(200) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom100 = makeAction(tr("&100%", "Zoom|"), false) << tr("Magnify 100%") << QVariant(100) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom75 = makeAction(tr("&75%", "Zoom|"), false) << tr("Magnify 75%") << QVariant(75) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionZoom50 = makeAction(tr("&50%", "Zoom|"), false) << tr("Magnify 50%") << QVariant(50) << Trigger(this, SLOT(performZoom())) << *zoomActionGroup; actionNavFirst = makeAction(tr("&First Page", "Go|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_first.png") << tr("Jump to first document page.") << QKeySequence("Ctrl+Home") << Trigger(widget, SLOT(firstPage())) << Trigger(this, SLOT(updateActionsLater())); actionNavNext = makeAction(tr("&Next Page", "Go|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_next.png") << tr("Jump to next document page.") << QKeySequence("PgDown") << Trigger(widget, SLOT(nextPage())) << Trigger(this, SLOT(updateActionsLater())); actionNavPrev = makeAction(tr("&Previous Page", "Go|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_prev.png") << tr("Jump to previous document page.") << QKeySequence("PgUp") << Trigger(widget, SLOT(prevPage())) << Trigger(this, SLOT(updateActionsLater())); actionNavLast = makeAction(tr("&Last Page", "Go|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_last.png") << tr("Jump to last document page.") << QKeySequence("Ctrl+End") << Trigger(widget, SLOT(lastPage())) << Trigger(this, SLOT(updateActionsLater())); actionBack = makeAction(tr("&Backward", "Go|")) << QIcon(":/images/icon_back.png") << tr("Backward in history.") << QKeySequence("Alt+Left") << Trigger(this, SLOT(performUndo())) << Trigger(this, SLOT(updateActionsLater())); actionForw = makeAction(tr("&Forward", "Go|")) << QIcon(":/images/icon_forw.png") << tr("Forward in history.") << QKeySequence("Alt+Right") << Trigger(this, SLOT(performRedo())) << Trigger(this, SLOT(updateActionsLater())); actionRotateLeft = makeAction(tr("Rotate &Left", "Rotate|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_rotateleft.png") << tr("Rotate page image counter-clockwise.") << QKeySequence("[") << Trigger(widget, SLOT(rotateLeft())) << Trigger(this, SLOT(updateActionsLater())); actionRotateRight = makeAction(tr("Rotate &Right", "Rotate|"), Qt::WidgetWithChildrenShortcut) << QIcon(":/images/icon_rotateright.png") << tr("Rotate page image clockwise.") << QKeySequence("]") << Trigger(widget, SLOT(rotateRight())) << Trigger(this, SLOT(updateActionsLater())); actionRotate0 = makeAction(trUtf8("Rotate &0\302\260", "Rotate|"), false) << tr("Set natural page orientation.") << QVariant(0) << Trigger(this, SLOT(performRotation())) << *rotationActionGroup; actionRotate90 = makeAction(trUtf8("Rotate &90\302\260", "Rotate|"), false) << tr("Turn page on its left side.") << QVariant(1) << Trigger(this, SLOT(performRotation())) << *rotationActionGroup; actionRotate180 = makeAction(trUtf8("Rotate &180\302\260", "Rotate|"), false) << tr("Turn page upside-down.") << QVariant(2) << Trigger(this, SLOT(performRotation())) << *rotationActionGroup; actionRotate270 = makeAction(trUtf8("Rotate &270\302\260", "Rotate|"), false) << tr("Turn page on its right side.") << QVariant(3) << Trigger(this, SLOT(performRotation())) << *rotationActionGroup; actionInformation = makeAction(tr("&Information...", "Edit|")) << QKeySequence(tr("Ctrl+I", "Edit|Information")) << tr("Show information about the document encoding and structure.") << Trigger(this, SLOT(performInformation())); actionMetadata = makeAction(tr("&Metadata...", "Edit|")) #ifndef Q_OS_DARWIN << QKeySequence(tr("Ctrl+M", "Edit|Metadata")) #endif << tr("Show the document and page meta data.") << Trigger(this, SLOT(performMetadata())); actionWhatsThis = QWhatsThis::createAction(this); actionAbout = makeAction(tr("&About DjView...")) #ifndef Q_OS_DARWIN << QIcon(":/images/djview.png") #endif << tr("Show information about this program.") << Trigger(this, SLOT(performAbout())); actionDisplayColor = makeAction(tr("&Color", "Display|"), false) << tr("Display everything.") << Trigger(widget, SLOT(displayModeColor())) << Trigger(this, SLOT(updateActionsLater())) << *modeActionGroup; actionDisplayBW = makeAction(tr("&Stencil", "Display|"), false) << tr("Only display the document bitonal stencil.") << Trigger(widget, SLOT(displayModeStencil())) << Trigger(this, SLOT(updateActionsLater())) << *modeActionGroup; actionDisplayForeground = makeAction(tr("&Foreground", "Display|"), false) << tr("Only display the foreground layer.") << Trigger(widget, SLOT(displayModeForeground())) << Trigger(this, SLOT(updateActionsLater())) << *modeActionGroup; actionDisplayBackground = makeAction(tr("&Background", "Display|"), false) << tr("Only display the background layer.") << Trigger(widget, SLOT(displayModeBackground())) << Trigger(this, SLOT(updateActionsLater())) << *modeActionGroup; actionDisplayHiddenText = makeAction(tr("&Hidden Text", "Display|"), false) << tr("Overlay a representation of the hidden text layer.") << Trigger(widget, SLOT(displayModeText())) << Trigger(this, SLOT(updateActionsLater())) << *modeActionGroup; actionInvertLuminance = makeAction(tr("I&nvert Luminance", "View|"), true) << tr("Invert image luminance while preserving hue.") << Trigger(widget, SLOT(setInvertLuminance(bool))) << Trigger(this, SLOT(updateActionsLater())); actionPreferences = makeAction(tr("Prefere&nces...", "Settings|")) << QIcon(":/images/icon_prefs.png") << tr("Show the preferences dialog.") << Trigger(this, SLOT(performPreferences())); actionViewSideBar = makeAction(tr("Show &Sidebar", "Settings|"), true) << QKeySequence(tr("F9", "Settings|Show sidebar")) #ifdef Q_OS_DARWIN << QKeySequence(tr("Ctrl+F9", "Settings|Show sidebar")) #endif << tr("Show/hide the side bar.") << Trigger(this, SLOT(showSideBar(bool))); actionViewToolBar = toolBar->toggleViewAction() << tr("Show &Toolbar", "Settings|") << QKeySequence(tr("F10", "Settings|Show toolbar")) #ifdef Q_OS_DARWIN << QKeySequence(tr("Ctrl+F10", "Settings|Show toolbar")) #endif << tr("Show/hide the standard tool bar.") << Trigger(this, SLOT(updateActionsLater())); actionViewStatusBar = makeAction(tr("Show Stat&usbar", "Settings|"), true) << tr("Show/hide the status bar.") << Trigger(statusBar,SLOT(setVisible(bool))) << Trigger(this, SLOT(updateActionsLater())); actionViewFullScreen = makeAction(tr("&Full Screen","View|"), false) << QKeySequence(tr("F11","View|FullScreen")) #ifdef Q_OS_DARWIN << QKeySequence(tr("Ctrl+F11","View|FullScreen")) #endif << QIcon(":/images/icon_fullscreen.png") << tr("Toggle full screen mode.") << Trigger(this, SLOT(performViewFullScreen(bool))); actionViewSlideShow = makeAction(tr("&Slide Show","View|"), false) << QKeySequence(tr("Shift+F11","View|Slideshow")) << QIcon(":/images/icon_slideshow.png") << tr("Toggle slide show mode.") << Trigger(this, SLOT(performViewSlideShow(bool))); actionLayoutContinuous = makeAction(tr("&Continuous", "Layout|"), false) << QIcon(":/images/icon_continuous.png") << QKeySequence(tr("F4", "Layout|Continuous")) << tr("Toggle continuous layout mode.") << Trigger(widget, SLOT(setContinuous(bool))) << Trigger(this, SLOT(updateActionsLater())); actionLayoutSideBySide = makeAction(tr("Side &by Side", "Layout|"), false) << QIcon(":/images/icon_sidebyside.png") << QKeySequence(tr("F5", "Layout|SideBySide")) << tr("Toggle side-by-side layout mode.") << Trigger(widget, SLOT(setSideBySide(bool))) << Trigger(this, SLOT(updateActionsLater())); actionLayoutCoverPage = makeAction(tr("Co&ver Page", "Layout|"), false) #ifdef Q_OS_DARWIN << QIcon(":/images/icon_coverpage.png") #endif << QKeySequence(tr("F6", "Layout|CoverPage")) << tr("Show the cover page alone in side-by-side mode.") << Trigger(widget, SLOT(setCoverPage(bool))) << Trigger(this, SLOT(updateActionsLater())); actionLayoutRightToLeft = makeAction(tr("&Right to Left", "Layout|"), false) #ifdef Q_OS_DARWIN << QIcon(":/images/icon_righttoleft.png") #endif << QKeySequence(tr("Ctrl+Shift+F6", "Layout|RightToLeft")) << QKeySequence(tr("Shift+F6", "Layout|RightToLeft")) << tr("Show pages right-to-left in side-by-side mode.") << Trigger(widget, SLOT(setRightToLeft(bool))) << Trigger(this, SLOT(updateActionsLater())); actionCopyUrl = makeAction(tr("Copy &URL", "Edit|")) << tr("Save an URL for the current page into the clipboard.") << QKeySequence(tr("Ctrl+C", "Edit|CopyURL")) << Trigger(this, SLOT(performCopyUrl())); actionCopyOutline = makeAction(tr("Copy &Outline", "Edit|")) << tr("Save the djvused code for the outline into the clipboard.") << Trigger(this, SLOT(performCopyOutline())); actionCopyAnnotation = makeAction(tr("Copy &Annotations", "Edit|")) << tr("Save the djvused code for the page annotations into the clipboard.") << Trigger(this, SLOT(performCopyAnnotation())); actionAbout->setMenuRole(QAction::AboutRole); actionQuit->setMenuRole(QAction::QuitRole); actionPreferences->setMenuRole(QAction::PreferencesRole); } void QDjView::createMenus() { // Layout main menu QMenu *fileMenu = menuBar->addMenu(tr("&File", "File|")); if (viewerMode >= STANDALONE) { fileMenu->addAction(actionNew); fileMenu->addAction(actionOpen); fileMenu->addAction(actionOpenLocation); recentMenu = fileMenu->addMenu(tr("Open &Recent")); recentMenu->menuAction()->setIcon(QIcon(":/images/icon_open.png")); connect(recentMenu, SIGNAL(aboutToShow()), this, SLOT(fillRecent())); fileMenu->addSeparator(); } fileMenu->addAction(actionSave); fileMenu->addAction(actionExport); fileMenu->addAction(actionPrint); if (viewerMode >= STANDALONE) { fileMenu->addSeparator(); fileMenu->addAction(actionClose); fileMenu->addAction(actionQuit); } QMenu *editMenu = menuBar->addMenu(tr("&Edit", "Edit|")); editMenu->addAction(actionSelect); editMenu->addAction(actionCopyUrl); editMenu->addAction(actionCopyOutline); editMenu->addAction(actionCopyAnnotation); editMenu->addSeparator(); editMenu->addAction(actionFind); editMenu->addAction(actionFindNext); editMenu->addAction(actionFindPrev); QMenu *viewMenu = menuBar->addMenu(tr("&View", "View|")); QMenu *zoomMenu = viewMenu->addMenu(tr("&Zoom","View|Zoom")); zoomMenu->addAction(actionZoomIn); zoomMenu->addAction(actionZoomOut); zoomMenu->addSeparator(); zoomMenu->addAction(actionZoomOneToOne); zoomMenu->addAction(actionZoomFitWidth); zoomMenu->addAction(actionZoomFitPage); zoomMenu->addSeparator(); zoomMenu->addAction(actionZoom300); zoomMenu->addAction(actionZoom200); zoomMenu->addAction(actionZoom150); zoomMenu->addAction(actionZoom100); zoomMenu->addAction(actionZoom75); zoomMenu->addAction(actionZoom50); QMenu *rotationMenu = viewMenu->addMenu(tr("&Rotate","View|Rotate")); rotationMenu->addAction(actionRotateLeft); rotationMenu->addAction(actionRotateRight); rotationMenu->addSeparator(); rotationMenu->addAction(actionRotate0); rotationMenu->addAction(actionRotate90); rotationMenu->addAction(actionRotate180); rotationMenu->addAction(actionRotate270); QMenu *modeMenu = viewMenu->addMenu(tr("&Display","View|Display")); modeMenu->addAction(actionDisplayColor); modeMenu->addAction(actionDisplayBW); modeMenu->addAction(actionDisplayForeground); modeMenu->addAction(actionDisplayBackground); modeMenu->addAction(actionDisplayHiddenText); viewMenu->addSeparator(); viewMenu->addAction(actionLayoutContinuous); viewMenu->addAction(actionLayoutSideBySide); viewMenu->addAction(actionLayoutCoverPage); viewMenu->addAction(actionLayoutRightToLeft); viewMenu->addSeparator(); viewMenu->addAction(actionInvertLuminance); viewMenu->addSeparator(); viewMenu->addAction(actionInformation); viewMenu->addAction(actionMetadata); if (viewerMode >= STANDALONE) viewMenu->addSeparator(); if (viewerMode >= STANDALONE) viewMenu->addAction(actionViewFullScreen); if (viewerMode >= STANDALONE) viewMenu->addAction(actionViewSlideShow); QMenu *gotoMenu = menuBar->addMenu(tr("&Go", "Go|")); gotoMenu->addAction(actionNavFirst); gotoMenu->addAction(actionNavPrev); gotoMenu->addAction(actionNavNext); gotoMenu->addAction(actionNavLast); gotoMenu->addSeparator(); gotoMenu->addAction(actionBack); gotoMenu->addAction(actionForw); QMenu *settingsMenu = menuBar->addMenu(tr("&Settings", "Settings|")); settingsMenu->addAction(actionViewSideBar); settingsMenu->addAction(actionViewToolBar); settingsMenu->addAction(actionViewStatusBar); settingsMenu->addSeparator(); settingsMenu->addAction(actionPreferences); QMenu *helpMenu = menuBar->addMenu(tr("&Help", "Help|")); helpMenu->addAction(actionWhatsThis); helpMenu->addSeparator(); helpMenu->addAction(actionAbout); // Layout context menu gotoMenu = contextMenu->addMenu(tr("&Go", "Go|")); gotoMenu->addAction(actionNavFirst); gotoMenu->addAction(actionNavPrev); gotoMenu->addAction(actionNavNext); gotoMenu->addAction(actionNavLast); zoomMenu = contextMenu->addMenu(tr("&Zoom","View|Zoom")); zoomMenu->addAction(actionZoomIn); zoomMenu->addAction(actionZoomOut); zoomMenu->addSeparator(); zoomMenu->addAction(actionZoomOneToOne); zoomMenu->addAction(actionZoomFitWidth); zoomMenu->addAction(actionZoomFitPage); zoomMenu->addSeparator(); zoomMenu->addAction(actionZoom300); zoomMenu->addAction(actionZoom200); zoomMenu->addAction(actionZoom150); zoomMenu->addAction(actionZoom100); zoomMenu->addAction(actionZoom75); zoomMenu->addAction(actionZoom50); rotationMenu = contextMenu->addMenu(tr("&Rotate","View|Rotate")); rotationMenu->addAction(actionRotateLeft); rotationMenu->addAction(actionRotateRight); rotationMenu->addSeparator(); rotationMenu->addAction(actionRotate0); rotationMenu->addAction(actionRotate90); rotationMenu->addAction(actionRotate180); rotationMenu->addAction(actionRotate270); modeMenu = contextMenu->addMenu(tr("&Display","View|Display")); modeMenu->addAction(actionDisplayColor); modeMenu->addAction(actionDisplayBW); modeMenu->addAction(actionDisplayForeground); modeMenu->addAction(actionDisplayBackground); modeMenu->addAction(actionDisplayHiddenText); contextMenu->addSeparator(); contextMenu->addAction(actionLayoutContinuous); contextMenu->addAction(actionLayoutSideBySide); contextMenu->addAction(actionLayoutCoverPage); contextMenu->addSeparator(); contextMenu->addAction(actionFind); contextMenu->addAction(actionInformation); contextMenu->addAction(actionMetadata); contextMenu->addSeparator(); contextMenu->addAction(actionSave); contextMenu->addAction(actionExport); contextMenu->addAction(actionPrint); contextMenu->addSeparator(); contextMenu->addAction(actionViewSideBar); contextMenu->addAction(actionViewToolBar); contextMenu->addAction(actionViewFullScreen); contextMenu->addAction(actionViewSlideShow); contextMenu->addSeparator(); contextMenu->addAction(actionPreferences); contextMenu->addSeparator(); contextMenu->addAction(actionWhatsThis); contextMenu->addAction(actionAbout); } /*! Update graphical interface components. This is called whenever something changes using function \a QDjView::updateActionsLater(). It updates the all gui compnents. */ void QDjView::updateActions() { // Rebuild toolbar if necessary if (tools != toolsCached) fillToolBar(toolBar); // Enable all actions foreach(QObject *object, allActions) if (QAction *action = qobject_cast(object)) action->setEnabled(true); // Some actions are explicitly disabled actionSave->setEnabled(savingAllowed || prefs->restrictOverride); actionExport->setEnabled(savingAllowed || prefs->restrictOverride); actionPrint->setEnabled(printingAllowed || prefs->restrictOverride); // Some actions are only available in standalone mode actionNew->setVisible(viewerMode >= STANDALONE); actionOpen->setVisible(viewerMode >= STANDALONE); actionOpenLocation->setVisible(viewerMode >= STANDALONE); actionClose->setVisible(viewerMode >= STANDALONE); actionQuit->setVisible(viewerMode >= STANDALONE); actionViewFullScreen->setVisible(viewerMode >= STANDALONE); actionViewSlideShow->setVisible(viewerMode >= STANDALONE); setAcceptDrops(viewerMode >= STANDALONE); // Zoom combo and actions int zoom = widget->zoom(); actionZoomIn->setEnabled(zoom < QDjVuWidget::ZOOM_MAX); actionZoomOut->setEnabled(zoom < 0 || zoom > QDjVuWidget::ZOOM_MIN); actionZoomFitPage->setChecked(zoom == QDjVuWidget::ZOOM_FITPAGE); actionZoomFitWidth->setChecked(zoom == QDjVuWidget::ZOOM_FITWIDTH); actionZoomOneToOne->setChecked(zoom == QDjVuWidget::ZOOM_ONE2ONE); actionZoom300->setChecked(zoom == 300); actionZoom200->setChecked(zoom == 200); actionZoom150->setChecked(zoom == 150); actionZoom100->setChecked(zoom == 100); actionZoom75->setChecked(zoom == 75); actionZoom50->setChecked(zoom == 50); zoomCombo->setEnabled(!!document); int zoomIndex = zoomCombo->findData(QVariant(zoom)); zoomCombo->clearEditText(); zoomCombo->setCurrentIndex(zoomIndex); if (zoomIndex < 0 && zoom >= QDjVuWidget::ZOOM_MIN && zoom <= QDjVuWidget::ZOOM_MAX) zoomCombo->setEditText(QString("%1%").arg(zoom)); else if (zoomIndex >= 0) zoomCombo->setEditText(zoomCombo->itemText(zoomIndex)); // Mode combo and actions QDjVuWidget::DisplayMode mode = widget->displayMode(); actionDisplayColor->setChecked(mode == QDjVuWidget::DISPLAY_COLOR); actionDisplayBW->setChecked(mode == QDjVuWidget::DISPLAY_STENCIL); actionDisplayBackground->setChecked(mode == QDjVuWidget::DISPLAY_BG); actionDisplayForeground->setChecked(mode == QDjVuWidget::DISPLAY_FG); actionDisplayHiddenText->setChecked(mode == QDjVuWidget::DISPLAY_TEXT); modeCombo->setCurrentIndex(modeCombo->findData(QVariant(mode))); modeCombo->setEnabled(!!document); // Image inversion actionInvertLuminance->setChecked(widget->invertLuminance()); // Rotations int rotation = widget->rotation(); actionRotate0->setChecked(rotation == 0); actionRotate90->setChecked(rotation == 1); actionRotate180->setChecked(rotation == 2); actionRotate270->setChecked(rotation == 3); // Page combo and actions int pagenum = documentPages.size(); int pageno = widget->page(); pageCombo->clearEditText(); pageCombo->setCurrentIndex(pageCombo->findData(QVariant(pageno))); if (pageno >= 0 && pagenum > 0 && !pageCombo->hasFocus()) { QString sNumber = QString("%1 / %2").arg(pageno+1).arg(pagenum); QString sName = pageName(pageno,true); growPageCombo(pageCombo, sNumber); pageCombo->setEditText((sName.isEmpty()) ? sNumber : sName); pageCombo->lineEdit()->setCursorPosition(0); } pageCombo->setEnabled(pagenum > 0); actionNavFirst->setEnabled(pagenum>0 && pageno>0); actionNavPrev->setEnabled(pagenum>0 && pageno>0); actionNavNext->setEnabled(pagenum>0 && pagenosetEnabled(pagenum>0 && pagenosetChecked(widget->continuous()); actionLayoutSideBySide->setChecked(widget->sideBySide()); actionLayoutCoverPage->setEnabled(widget->sideBySide()); actionLayoutCoverPage->setChecked(widget->coverPage()); actionLayoutRightToLeft->setEnabled(widget->sideBySide()); actionLayoutRightToLeft->setChecked(widget->rightToLeft()); // UndoRedo undoTimer->stop(); undoTimer->start(250); actionBack->setEnabled(undoList.size() > 0); actionForw->setEnabled(redoList.size() > 0); // Misc textLabel->setVisible(prefs->showTextLabel); textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored); actionCopyOutline->setVisible(prefs->advancedFeatures); actionCopyAnnotation->setVisible(prefs->advancedFeatures); actionCopyUrl->setEnabled(pagenum > 0); actionCopyOutline->setEnabled(pagenum > 0); actionCopyAnnotation->setEnabled(pagenum > 0); actionViewSideBar->setChecked(hiddenSideBarTabs() == 0); actionViewSlideShow->setChecked(viewerMode == STANDALONE_SLIDESHOW); actionViewFullScreen->setChecked(viewerMode == STANDALONE_FULLSCREEN); // Disable almost everything when document==0 if (! document) { foreach(QObject *object, allActions) if (QAction *action = qobject_cast(object)) if (action != actionNew && action != actionOpen && action != actionOpenLocation && action != actionClose && action != actionQuit && action != actionPreferences && action != actionViewToolBar && action != actionViewStatusBar && action != actionViewSideBar && action != actionViewFullScreen && action != actionWhatsThis && action != actionAbout ) action->setEnabled(false); } // Finished updateActionsScheduled = false; // Reset slide show timeout slideShowTimeout(true); // Notify plugin if (viewerMode < STANDALONE) emit pluginOnChange(); } // ---------------------------------------- // WHATSTHIS HELP void QDjView::createWhatsThis() { #define HELP(x,y) { QString s(x); Help h(s); h y; } struct Help { QString s; Help(QString s) : s(s) { } Help& operator>>(QWidget *w) { w->setWhatsThis(s); return *this; } Help& operator>>(QAction *a) { a->setWhatsThis(s); return *this; } }; QString mc, ms, ml; #ifdef Q_OS_DARWIN mc = tr("Control Left Mouse Button"); #else mc = tr("Right Mouse Button"); #endif ms = prefs->modifiersToString(prefs->modifiersForSelect); ms = ms.replace("+"," "); ml = prefs->modifiersToString(prefs->modifiersForLens); ml = ml.replace("+"," "); HELP(tr("Selecting a rectangle.
" "Once a rectangular area is selected, a popup menu " "lets you copy the corresponding text or image. " "Instead of using this tool, you can also hold %1 " "and use the Left Mouse Button." "").arg(ms), >> actionSelect ); HELP(tr("Zooming.
" "Choose a zoom level for viewing the document. " "Zoom level 100% displays the document for a 100 dpi screen. " "Zoom levels Fit Page and Fit Width ensure " "that the full page or the page width fit in the window. " ""), >> actionZoomIn >> actionZoomOut >> actionZoomFitPage >> actionZoomFitWidth >> actionZoom300 >> actionZoom200 >> actionZoom150 >> actionZoom75 >> actionZoom50 >> zoomCombo ); HELP(tr("Rotating the pages.
" "Choose to display pages in portrait or landscape mode. " "You can also turn them upside down."), >> actionRotateLeft >> actionRotateRight >> actionRotate0 >> actionRotate90 >> actionRotate180 >> actionRotate270 ); HELP(tr("Display mode.
" "DjVu images compose a background layer and a foreground layer " "using a stencil. The display mode specifies with layers " "should be displayed."), >> actionDisplayColor >> actionDisplayBW >> actionDisplayForeground >> actionDisplayBackground >> modeCombo ); HELP(tr("Navigating the document.
" "The page selector lets you jump to any page by name " "and can be activated at any time by pressing Ctrl+G. " "The navigation buttons jump to the first page, the previous " "page, the next page, or the last page. "), >> actionNavFirst >> actionNavPrev >> actionNavNext >> actionNavLast >> pageCombo ); HELP(tr("Document and page information.
" "Display a dialog window for viewing " "encoding information pertaining to the document " "or to a specific page."), >> actionInformation ); HELP(tr("Document and page metadata.
" "Display a dialog window for viewing metadata " "pertaining to the document " "or to a specific page."), >> actionMetadata ); HELP(tr("Continuous layout.
" "Display all the document pages arranged vertically " "inside the scrollable document viewing area."), >> actionLayoutContinuous ); HELP(tr("Side by side layout.
" "Display pairs of pages side by side " "inside the scrollable document viewing area."), >> actionLayoutSideBySide ); HELP(tr("Page information.
" "Display information about the page located under the cursor: " "the sequential page number, the page size in pixels, " "and the page resolution in dots per inch. "), >> pageLabel ); HELP(tr("Cursor information.
" "Display the position of the mouse cursor " "expressed in page coordinates. "), >> mouseLabel ); HELP(tr("Document viewing area.
" "This is the main display area for the DjVu document.

    " "
  • Arrows and page keys to navigate the document.
  • " "
  • Space and BackSpace to read the document.
  • " "
  • Keys + - [ ] " "to zoom or rotate the document.
  • " "
  • Left Mouse Button for panning and selecting links.
  • " "
  • %3 for displaying the contextual menu.
  • " "
  • %1 Left Mouse Button for selecting text or images.
  • " "
  • %2 for popping the magnification lens.
  • " "
").arg(ms).arg(ml).arg(mc), >> widget ); HELP(tr("Document viewing area.
" "This is the main display area for the DjVu document. " "But you must first open a DjVu document to see anything." ""), >> splash ); #undef HELP } // ---------------------------------------- // APPLY PREFERENCES QDjViewPrefs::Saved * QDjView::getSavedConfig(ViewerMode mode) { if (mode == STANDALONE_FULLSCREEN) return &fsSavedFullScreen; else if (mode == STANDALONE_SLIDESHOW) return &fsSavedSlideShow; return &fsSavedNormal; } QDjViewPrefs::Saved * QDjView::getSavedPrefs(void) { if (viewerMode==EMBEDDED_PLUGIN) return &prefs->forEmbeddedPlugin; else if (viewerMode==FULLPAGE_PLUGIN) return &prefs->forFullPagePlugin; else if (viewerMode==STANDALONE_FULLSCREEN) return &prefs->forFullScreen; else if (viewerMode==STANDALONE_SLIDESHOW) return &prefs->forSlideShow; return &prefs->forStandalone; } void QDjView::enableContextMenu(bool enable) { QMenu *oldContextMenu = widget->contextMenu(); if (!enable || oldContextMenu != contextMenu) { // remove context menu widget->setContextMenu(0); // disable shortcuts if (oldContextMenu) foreach(QAction *action, widget->actions()) widget->removeAction(action); } if (enable && oldContextMenu != contextMenu) { // setup context menu widget->setContextMenu(contextMenu); // enable shortcuts if (contextMenu) { // all explicit shortcuts in context menu widget->addAction(contextMenu->menuAction()); // things that do not have a context menu entry widget->addAction(actionFindNext); widget->addAction(actionFindPrev); } } } void QDjView::enableScrollBars(bool enable) { Qt::ScrollBarPolicy policy = Qt::ScrollBarAlwaysOff; if (enable) policy = Qt::ScrollBarAsNeeded; widget->setHorizontalScrollBarPolicy(policy); widget->setVerticalScrollBarPolicy(policy); } void QDjView::applyOptions(bool remember) { menuBar->setVisible(options & QDjViewPrefs::SHOW_MENUBAR); toolBar->setVisible(options & QDjViewPrefs::SHOW_TOOLBAR); statusBar->setVisible(options & QDjViewPrefs::SHOW_STATUSBAR); enableScrollBars(options & QDjViewPrefs::SHOW_SCROLLBARS); widget->setDisplayFrame(options & QDjViewPrefs::SHOW_FRAME); widget->setDisplayMapAreas(options & QDjViewPrefs::SHOW_MAPAREAS); widget->setContinuous(options & QDjViewPrefs::LAYOUT_CONTINUOUS); widget->setSideBySide(options & QDjViewPrefs::LAYOUT_SIDEBYSIDE); widget->setCoverPage(options & QDjViewPrefs::LAYOUT_COVERPAGE); widget->setRightToLeft(options & QDjViewPrefs::LAYOUT_RIGHTTOLEFT); widget->enableMouse(options & QDjViewPrefs::HANDLE_MOUSE); widget->enableKeyboard(options & QDjViewPrefs::HANDLE_KEYBOARD); widget->enableHyperlink(options & QDjViewPrefs::HANDLE_LINKS); enableContextMenu(options & QDjViewPrefs::HANDLE_CONTEXTMENU); if (!remember) showSideBar(options & QDjViewPrefs::SHOW_SIDEBAR); } void QDjView::updateOptions(void) { options = 0; if (! menuBar->isHidden()) options |= QDjViewPrefs::SHOW_MENUBAR; if (! toolBar->isHidden()) options |= QDjViewPrefs::SHOW_TOOLBAR; if (! statusBar->isHidden()) options |= QDjViewPrefs::SHOW_STATUSBAR; if (! hiddenSideBarTabs()) options |= QDjViewPrefs::SHOW_SIDEBAR; if (widget->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff) options |= QDjViewPrefs::SHOW_SCROLLBARS; if (widget->displayFrame()) options |= QDjViewPrefs::SHOW_FRAME; if (widget->displayMapAreas()) options |= QDjViewPrefs::SHOW_MAPAREAS; if (widget->continuous()) options |= QDjViewPrefs::LAYOUT_CONTINUOUS; if (widget->sideBySide()) options |= QDjViewPrefs::LAYOUT_SIDEBYSIDE; if (widget->coverPage()) options |= QDjViewPrefs::LAYOUT_COVERPAGE; if (widget->rightToLeft()) options |= QDjViewPrefs::LAYOUT_RIGHTTOLEFT; if (widget->mouseEnabled()) options |= QDjViewPrefs::HANDLE_MOUSE; if (widget->keyboardEnabled()) options |= QDjViewPrefs::HANDLE_KEYBOARD; if (widget->hyperlinkEnabled()) options |= QDjViewPrefs::HANDLE_LINKS; if (widget->contextMenu()) options |= QDjViewPrefs::HANDLE_CONTEXTMENU; } void QDjView::applySaved(Saved *saved) { // default dock geometry tabifyDockWidget(thumbnailDock, outlineDock); tabifyDockWidget(thumbnailDock, findDock); thumbnailDock->raise(); // main saved states options = saved->options; if (saved->state.size() > 0) restoreState(saved->state); applyOptions(saved->remember); widget->setZoom(saved->zoom); } static const Qt::WindowStates unusualWindowStates = (Qt::WindowMinimized|Qt::WindowMaximized|Qt::WindowFullScreen); void QDjView::updateSaved(Saved *saved) { updateOptions(); if (saved->remember) { // main saved states saved->zoom = widget->zoom(); saved->state = saveState(); saved->options = options; // avoid confusing options in standalone mode if (saved == &prefs->forStandalone && !(saved->options & QDjViewPrefs::HANDLE_CONTEXTMENU) && !(saved->options & QDjViewPrefs::SHOW_MENUBAR) ) saved->options |= (QDjViewPrefs::SHOW_MENUBAR | QDjViewPrefs::SHOW_SCROLLBARS | QDjViewPrefs::SHOW_STATUSBAR | QDjViewPrefs::SHOW_FRAME | QDjViewPrefs::HANDLE_CONTEXTMENU ); // main window size in standalone mode if (saved == &prefs->forStandalone) { Qt::WindowStates wstate = windowState(); prefs->windowMaximized = false; if (wstate & Qt::WindowMaximized) prefs->windowMaximized = true; else if (! (wstate & unusualWindowStates)) prefs->windowSize = size(); } // non-saved saved->nsBorderBrush = widget->borderBrush(); saved->nsBorderSize = widget->borderSize(); } } void QDjView::applyPreferences(void) { // Saved preferences applySaved(getSavedPrefs()); // Other preferences QDjVuNetDocument::setProxy(prefs->proxyUrl); djvuContext.setCacheSize(prefs->cacheSize); widget->setPixelCacheSize(prefs->pixelCacheSize); widget->setModifiersForLens(prefs->modifiersForLens); widget->setModifiersForSelect(prefs->modifiersForSelect); widget->setModifiersForLinks(prefs->modifiersForLinks); widget->setGamma(prefs->gamma); widget->setWhite(prefs->white); widget->setScreenDpi(prefs->resolution ? prefs->resolution : physicalDpiY()); widget->setLensSize(prefs->lensSize); widget->setLensPower(prefs->lensPower); widget->enableAnimation(prefs->enableAnimations); widget->setInvertLuminance(prefs->invertLuminance); widget->setMouseWheelZoom(prefs->mouseWheelZoom); // Thumbnail preferences thumbnailWidget->setSize(prefs->thumbnailSize); thumbnailWidget->setSmart(prefs->thumbnailSmart); // Search preferences findWidget->setWordOnly(prefs->searchWordsOnly); findWidget->setCaseSensitive(prefs->searchCaseSensitive); // Too risky: findWidget->setRegExpMode(prefs->searchRegExpMode); // Special preferences for embedded plugins if (viewerMode == EMBEDDED_PLUGIN) setMinimumSize(QSize(8,8)); // Preload mode change prefs. fsSavedNormal = prefs->forStandalone; fsSavedFullScreen = prefs->forFullScreen; fsSavedSlideShow = prefs->forSlideShow; } void QDjView::updatePreferences(void) { updateSaved(getSavedPrefs()); prefs->thumbnailSize = thumbnailWidget->size(); prefs->thumbnailSmart = thumbnailWidget->smart(); prefs->searchWordsOnly = findWidget->wordOnly(); prefs->searchCaseSensitive = findWidget->caseSensitive(); prefs->searchRegExpMode = findWidget->regExpMode(); } void QDjView::preferencesChanged(void) { applyPreferences(); createWhatsThis(); updateActions(); } // ---------------------------------------- // SESSION MANAGEMENT void QDjView::saveSession(QSettings *s) { Saved saved; updateSaved(&saved); s->setValue("name", objectName()); s->setValue("options", prefs->optionsToString(saved.options)); s->setValue("state", saved.state); s->setValue("tools", prefs->toolsToString(tools)); s->setValue("documentUrl", getDecoratedUrl().toString()); } void QDjView::restoreSession(QSettings *s) { QUrl du = QUrl(s->value("documentUrl").toString()); Tools tools = this->tools; Saved saved; updateSaved(&saved); if (s->contains("options")) saved.options = prefs->stringToOptions(s->value("options").toString()); if (s->contains("zoom")) // compat saved.zoom = s->value("zoom").toInt(); if (s->contains("state")) saved.state = s->value("state").toByteArray(); if (s->contains("tools")) tools = prefs->stringToTools(s->value("tools").toString()); if (s->contains("name")) setObjectName(s->value("name").toString()); applySaved(&saved); updateActionsLater(); if (du.isValid()) open(du); if (document && s->contains("pageNo")) // compat goToPage(s->value("pageNo", 0).toInt()); } // ---------------------------------------- // QDJVIEW ARGUMENTS static bool string_is_on(QString val) { QString v = val.toLower(); return v == "yes" || v == "on" || v == "true" || v == "1"; } static bool string_is_off(QString val) { QString v = val.toLower(); return v == "no" || v == "off" || v == "false" || v == "0"; } static QString get_boolean(bool b) { return QString(b ? "yes" : "no"); } static bool parse_boolean(QString key, QString val, QList &errors, bool &answer) { answer = false; if (string_is_off(val)) return true; answer = true; if (string_is_on(val) || val.isNull()) return true; errors << QDjView::tr("Option '%1' requires boolean argument.").arg(key); return false; } static void illegal_value(QString key, QString value, QList &errors) { errors << QDjView::tr("Illegal value '%2' for option '%1'.") .arg(key).arg(value); } static bool parse_position(QString value, double &x, double &y) { bool okay0, okay1; QStringList val = value.split(","); if (val.size() == 2) { x = val[0].toDouble(&okay0); y = val[1].toDouble(&okay1); return okay0 && okay1; } return false; } static bool parse_highlight(QString value, int &x, int &y, int &w, int &h, QColor &color) { bool okay0, okay1, okay2, okay3; QStringList val = value.split(","); if (val.size() < 4) return false; x = val[0].toInt(&okay0); y = val[1].toInt(&okay1); w = val[2].toInt(&okay2); h = val[3].toInt(&okay3); if (! (okay0 && okay1 && okay2 && okay3)) return false; if (val.size() < 5) return true; QString c = val[4]; if (c[0] != '#') c = "#" + c; color.setNamedColor(c); if (! color.isValid()) return false; if (val.size() <= 5) return true; return false; } template static inline void set_reset(QFlags &x, bool plus, bool minus, T y) { if (plus) x |= y; else if (minus) x &= ~y; } void QDjView::parseToolBarOption(QString option, QStringList &errors) { QString str = option.toLower(); int len = str.size(); bool wantselect = false; bool wantmode = false; bool minus = false; bool plus = false; int npos = 0; while (npos < len) { int pos = npos; npos = str.indexOf(QRegExp("[-+,]"), pos); if (npos < 0) npos = len; QString key = str.mid(pos, npos-pos).trimmed(); if (string_is_off(key) && !plus && !minus) options &= ~QDjViewPrefs::SHOW_TOOLBAR; else if (string_is_on(key) && !plus && !minus) options |= QDjViewPrefs::SHOW_TOOLBAR; else if (key=="bottom" && !plus && !minus) { options |= QDjViewPrefs::SHOW_TOOLBAR; tools &= ~QDjViewPrefs::TOOLBAR_TOP; } else if (key=="top" && !plus && !minus) { options |= QDjViewPrefs::SHOW_TOOLBAR; tools &= ~QDjViewPrefs::TOOLBAR_BOTTOM; } else if (key=="auto" && !plus && !minus) tools |= QDjViewPrefs::TOOLBAR_AUTOHIDE; else if (key=="always" && !plus && !minus) { options |= QDjViewPrefs::SHOW_TOOLBAR; tools &= ~QDjViewPrefs::TOOLBAR_AUTOHIDE; } else if (key.contains(QRegExp("^(fore|back|color|bw)(_button)?$"))) wantmode |= plus; else if (key=="pan" || key=="zoomsel" || key=="textsel") wantselect |= plus; else if (key=="modecombo") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_MODECOMBO); else if (key=="rescombo" || key=="zoomcombo") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_ZOOMCOMBO); else if (key=="zoom") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_ZOOMBUTTONS); else if (key=="rotate") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_ROTATE); else if (key=="search" || key=="find") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_FIND); else if (key=="print") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_PRINT); else if (key=="save") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_SAVE); else if (key=="pagecombo") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_PAGECOMBO); else if (key=="backforw") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_BACKFORW); else if (key=="prevnext" || key=="prevnextpage") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_PREVNEXT); else if (key=="firstlast" || key=="firstlastpage") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_FIRSTLAST); // lizards else if (key=="doublepage") // lizards! set_reset(tools, plus, minus, QDjViewPrefs::TOOL_LAYOUT); else if (key=="calibrate" || key=="ruler" || key=="lizard") errors << tr("Toolbar option '%1' is not implemented.").arg(key); // djview4 else if (key=="select") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_SELECT); else if (key=="new") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_NEW); else if (key=="open") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_OPEN); else if (key=="layout") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_LAYOUT); else if (key=="help") set_reset(tools, plus, minus, QDjViewPrefs::TOOL_WHATSTHIS); else if (key!="") errors << tr("Toolbar option '%1' is not recognized.").arg(key); // handle + or - if (npos < len) { Tools base = QDjViewPrefs::TOOLBAR_AUTOHIDE | QDjViewPrefs::TOOLBAR_TOP | QDjViewPrefs::TOOLBAR_BOTTOM; if (str[npos] == '-') { if (!minus && !plus) tools |= (prefs->tools & ~base); plus = false; minus = true; } else if (str[npos] == '+') { if (!minus && !plus) tools &= base; minus = false; plus = true; } npos += 1; } } if (wantmode) tools |= QDjViewPrefs::TOOL_MODECOMBO; if (wantselect) tools |= QDjViewPrefs::TOOL_SELECT; } /*! Parse a qdjview option described by a pair \a key, \a value. Such options can be provided on the command line or passed with the document URL as pseudo-CGI arguments. Return a list of error strings. */ QStringList QDjView::parseArgument(QString key, QString value) { bool okay; QStringList errors; key = key.toLower(); if (key == "fullscreen" || key == "fs") { if (viewerMode < STANDALONE) errors << tr("Option '%1' requires a standalone viewer.").arg(key); if (parse_boolean(key, value, errors, okay)) setViewerMode(okay ? STANDALONE_FULLSCREEN : STANDALONE); } else if (key == "slideshow") { if (viewerMode < STANDALONE) errors << tr("Option '%1' requires a standalone viewer.").arg(key); int delay = value.toInt(&okay); if (okay && delay < 0) okay = false; if (okay || parse_boolean(key, value, errors, okay)) setViewerMode(okay ? STANDALONE_SLIDESHOW : STANDALONE); if (delay > 0) setSlideShowDelay(delay); } else if (key == "toolbar") { parseToolBarOption(value, errors); toolBar->setVisible(options & QDjViewPrefs::SHOW_TOOLBAR); } else if (key == "page") { pendingPage = value; performPendingLater(); } else if (key == "pageno") { pendingPage = QString("$%1").arg(value.toInt()); performPendingLater(); } else if (key == "cache") { // see QDjVuDocument::setUrl(...) parse_boolean(key, value, errors, okay); } else if (key == "passive" || key == "passivestretch") { if (parse_boolean(key, value, errors, okay) && okay) { enableScrollBars(false); enableContextMenu(false); menuBar->setVisible(false); statusBar->setVisible(false); thumbnailDock->setVisible(false); outlineDock->setVisible(false); findDock->setVisible(false); toolBar->setVisible(false); if (key == "passive") widget->setZoom(QDjVuWidget::ZOOM_FITPAGE); else widget->setZoom(QDjVuWidget::ZOOM_STRETCH); widget->setContinuous(false); widget->setSideBySide(false); widget->enableKeyboard(false); widget->enableMouse(false); } } else if (key == "scrollbars") { if (parse_boolean(key, value, errors, okay)) enableScrollBars(okay); } else if (key == "menubar") // new for djview4 { if (parse_boolean(key, value, errors, okay)) menuBar->setVisible(okay); } else if (key == "sidebar" || // new for djview4 key == "navpane" ) // lizards { showSideBar(value, errors); } else if (key == "statusbar") // new for djview4 { if (parse_boolean(key, value, errors, okay)) statusBar->setVisible(okay); } else if (key == "continuous") // new for djview4 { if (parse_boolean(key, value, errors, okay)) widget->setContinuous(okay); } else if (key == "side_by_side" || key == "sidebyside") // new for djview4 { if (parse_boolean(key, value, errors, okay)) widget->setSideBySide(okay); } else if (key == "firstpagealone" || key == "first_page_alone" || key == "cover_page" || key == "coverpage") // new for djview4 { if (parse_boolean(key, value, errors, okay)) widget->setCoverPage(okay); } else if (key == "right_to_left" || key == "righttoleft") // new for djview4 { if (parse_boolean(key, value, errors, okay)) widget->setRightToLeft(okay); } else if (key == "layout") // lizards { bool layout = false; bool continuous = false; bool sidebyside = false; foreach (QString s, value.split(",")) { if (s == "single") layout = true, continuous = sidebyside = false; else if (s == "double") layout = sidebyside = true; else if (s == "continuous") layout = continuous = true; else if (s == "ltor") widget->setRightToLeft(false); else if (s == "rtol") widget->setRightToLeft(true); else if (s == "cover") widget->setCoverPage(true); else if (s == "nocover") widget->setCoverPage(false); else if (s == "gap") widget->setSeparatorSize(12); else if (s == "nogap") widget->setSeparatorSize(0); } if (layout) { widget->setContinuous(continuous); widget->setSideBySide(sidebyside); } } else if (key == "frame") { if (parse_boolean(key, value, errors, okay)) widget->setDisplayFrame(okay); } else if (key == "background") { QColor color; color.setNamedColor((value[0] == '#') ? value : "#" + value); if (color.isValid()) { QBrush brush = QBrush(color); widget->setBorderBrush(brush); fsSavedNormal.nsBorderBrush = brush; fsSavedFullScreen.nsBorderBrush = brush; fsSavedSlideShow.nsBorderBrush = brush; } else illegal_value(key, value, errors); } else if (key == "menu") { if (parse_boolean(key, value, errors, okay)) enableContextMenu(okay); } else if (key == "keyboard") { if (parse_boolean(key, value, errors, okay)) widget->enableKeyboard(okay); } else if (key == "mouse") { if (parse_boolean(key, value, errors, okay)) widget->enableMouse(okay); } else if (key == "links") { if (parse_boolean(key, value, errors, okay)) widget->enableHyperlink(okay); } else if (key == "zoom") { int z = value.toInt(&okay); QString val = value.toLower(); if (val == "one2one") widget->setZoom(QDjVuWidget::ZOOM_ONE2ONE); else if (val == "width" || val == "fitwidth") widget->setZoom(QDjVuWidget::ZOOM_FITWIDTH); else if (val == "page" || val == "fitpage") widget->setZoom(QDjVuWidget::ZOOM_FITPAGE); else if (val == "stretch") widget->setZoom(QDjVuWidget::ZOOM_STRETCH); else if (okay && z >= QDjVuWidget::ZOOM_MIN && z <= QDjVuWidget::ZOOM_MAX) widget->setZoom(z); else illegal_value(key, value, errors); } else if (key == "mode") { QString val = value.toLower(); if (val == "color") widget->setDisplayMode(QDjVuWidget::DISPLAY_COLOR); else if (val == "bw" || val == "mask" || val == "stencil") widget->setDisplayMode(QDjVuWidget::DISPLAY_STENCIL); else if (val == "fore" || val == "foreground" || val == "fg") widget->setDisplayMode(QDjVuWidget::DISPLAY_FG); else if (val == "back" || val == "background" || val == "bg") widget->setDisplayMode(QDjVuWidget::DISPLAY_BG); else if (val == "text" || val == "hiddentext") widget->setDisplayMode(QDjVuWidget::DISPLAY_TEXT); else illegal_value(key, value, errors); } else if (key == "hor_align" || key == "halign") { QString val = value.toLower(); if (val == "left") widget->setHorizAlign(QDjVuWidget::ALIGN_LEFT); else if (val == "center") widget->setHorizAlign(QDjVuWidget::ALIGN_CENTER); else if (val == "right") widget->setHorizAlign(QDjVuWidget::ALIGN_RIGHT); else illegal_value(key, value, errors); } else if (key == "ver_align" || key == "valign") { QString val = value.toLower(); if (val == "top") widget->setVertAlign(QDjVuWidget::ALIGN_TOP); else if (val == "center") widget->setVertAlign(QDjVuWidget::ALIGN_CENTER); else if (val == "bottom") widget->setVertAlign(QDjVuWidget::ALIGN_BOTTOM); else illegal_value(key, value, errors); } else if (key == "highlight") { int x,y,w,h; QColor color; if (value.isEmpty()) widget->clearHighlights(widget->page()); else if (parse_highlight(value, x, y, w, h, color)) pendingHilite << StringPair(pendingPage, value); else illegal_value(key, value, errors); performPendingLater(); } else if (key == "rotate") { if (value == "0") widget->setRotation(0); else if (value == "90") widget->setRotation(1); else if (value == "180") widget->setRotation(2); else if (value == "270") widget->setRotation(3); else illegal_value(key, value, errors); } else if (key == "print") { if (parse_boolean(key, value, errors, okay)) printingAllowed = okay; } else if (key == "save") { if (parse_boolean(key, value, errors, okay)) savingAllowed = okay; } else if (key == "notoolbar" || key == "noscrollbars" || key == "nomenu" ) { QString msg = tr("Deprecated option '%1'").arg(key); qWarning("%s",(const char*)msg.toLocal8Bit()); if (key == "notoolbar" && value.isNull()) toolBar->setVisible(false); else if (key == "noscrollbars" && value.isNull()) enableScrollBars(false); else if (key == "nomenu" && value.isNull()) enableContextMenu(false); } else if (key == "thumbnails") { QStringList junk; if (! showSideBar(value+",thumbnails", junk)) illegal_value(key, value, errors); } else if (key == "outline") { QStringList junk; if (! showSideBar(value+",outline", junk)) illegal_value(key, value, errors); } else if (key == "find") // new for djview4 { if (findWidget) { findWidget->setText(QString::null); findWidget->setRegExpMode(false); findWidget->setWordOnly(true); findWidget->setCaseSensitive(false); } pendingFind = value; if (! value.isEmpty()) performPendingLater(); } else if (key == "showposition") { double x=0, y=0; pendingPosition.clear(); if (! parse_position(value, x, y)) illegal_value(key, value, errors); else { pendingPosition << x << y; performPendingLater(); } } else if (key == "logo" || key == "textsel" || key == "search") { QString msg = tr("Option '%1' is not implemented.").arg(key); qWarning("%s",(const char*)msg.toLocal8Bit()); } else { errors << tr("Option '%1' is not recognized.").arg(key); } updateActionsLater(); return errors; } /*! Parse a \a QDjView option expressed a a string \a key=value. This is very useful for processing command line options. */ QStringList QDjView::parseArgument(QString keyEqualValue) { int n = keyEqualValue.indexOf("="); if (n < 0) return parseArgument(keyEqualValue, QString()); else return parseArgument(keyEqualValue.left(n), keyEqualValue.mid(n+1)); } /*! Parse the \a QDjView options passed via the CGI query arguments of \a url. This is called by \a QDjView::open(QDjVuDocument, QUrl). */ void QDjView::parseDjVuCgiArguments(QUrl url) { QStringList errors; // parse bool djvuopts = false; QPair pair; foreach(pair, urlQueryItems(url, true)) { if (pair.first.toLower() == "djvuopts") djvuopts = true; else if (djvuopts) errors << parseArgument(pair.first, pair.second); } // warning for errors if (djvuopts && errors.size() > 0) foreach(QString error, errors) qWarning("%s",(const char*)error.toLocal8Bit()); } /*! Return a copy of the url without the CGI query arguments corresponding to DjVu options. */ QUrl QDjView::removeDjVuCgiArguments(QUrl url) { QList > args; bool djvuopts = false; QPair pair; foreach(pair, urlQueryItems(url)) { if (pair.first.toLower() == "djvuopts") djvuopts = true; else if (!djvuopts) args << pair; } QUrl newurl = url; urlSetQueryItems(newurl, args); return newurl; } /*! Returns the most adequate value that could be passed to \a parseArgument for the specified \a key. */ QString QDjView::getArgument(QString key) { key = key.toLower(); if (key == "pages") // readonly return QString::number(pageNum()); else if (key == "page") return pageName(widget->page()); else if (key == "pageno") return QString::number(widget->page()+1); else if (key == "fullscreen" || key == "fs") return get_boolean(viewerMode == STANDALONE_FULLSCREEN); else if (key == "slideshow") return get_boolean(viewerMode == STANDALONE_SLIDESHOW); else if (key == "scrollbars") return get_boolean(widget->horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff ); else if (key == "menubar") return get_boolean(menuBar->isVisibleTo(this)); else if (key == "statusbar") return get_boolean(statusBar->isVisibleTo(this)); else if (key == "continuous") return get_boolean(widget->continuous()); else if (key == "side_by_side" || key == "sidebyside") return get_boolean(widget->sideBySide()); else if (key == "coverpage" || key == "firstpagealone" || key == "first_page_alone" ) return get_boolean(widget->coverPage()); else if (key == "righttoleft" || key == "right_to_left") return get_boolean(widget->rightToLeft()); else if (key == "frame") return get_boolean(widget->displayFrame()); else if (key == "keyboard") return get_boolean(widget->keyboardEnabled()); else if (key == "mouse") return get_boolean(widget->mouseEnabled()); else if (key == "links") return get_boolean(widget->hyperlinkEnabled()); else if (key == "menu") return get_boolean(widget->contextMenu() != 0); else if (key == "rotate") return QString::number(widget->rotation() * 90); else if (key == "print") return get_boolean(printingAllowed); else if (key == "save") return get_boolean(savingAllowed); else if (key == "background") { QBrush brush = widget->borderBrush(); if (brush.style() == Qt::SolidPattern) return brush.color().name(); } else if (key == "layout") { QStringList l; if (widget->sideBySide()) l << QString("double"); if (widget->continuous()) l << QString("continuous"); if (l.isEmpty()) l << QString("single"); l << QString(widget->rightToLeft() ? "rtol" : "ltor"); l << QString(widget->coverPage() ? "cover" : "nocover"); l << QString(widget->separatorSize() ? "gap" : "nogap"); return l.join(","); } else if (key == "zoom") { int z = widget->zoom(); if (z == QDjVuWidget::ZOOM_ONE2ONE) return QString("one2one"); else if (z == QDjVuWidget::ZOOM_FITWIDTH) return QString("width"); else if (z == QDjVuWidget::ZOOM_FITPAGE) return QString("page"); else if (z == QDjVuWidget::ZOOM_STRETCH) return QString("stretch"); else if (z >= QDjVuWidget::ZOOM_MIN && z <= QDjVuWidget::ZOOM_MAX) return QString::number(z); } else if (key == "mode") { QDjVuWidget::DisplayMode m = widget->displayMode(); if (m == QDjVuWidget::DISPLAY_COLOR) return QString("color"); else if (m == QDjVuWidget::DISPLAY_STENCIL) return QString("bw"); else if (m == QDjVuWidget::DISPLAY_FG) return QString("fore"); else if (m == QDjVuWidget::DISPLAY_BG) return QString("back"); else if (m == QDjVuWidget::DISPLAY_TEXT) return QString("text"); } else if (key == "hor_align" || key == "halign") { QDjVuWidget::Align a = widget->horizAlign(); if (a == QDjVuWidget::ALIGN_LEFT) return QString("left"); else if (a == QDjVuWidget::ALIGN_CENTER) return QString("center"); else if (a == QDjVuWidget::ALIGN_RIGHT) return QString("right"); } else if (key == "ver_align" || key == "valign") { QDjVuWidget::Align a = widget->vertAlign(); if (a == QDjVuWidget::ALIGN_TOP) return QString("top"); else if (a == QDjVuWidget::ALIGN_CENTER) return QString("center"); else if (a == QDjVuWidget::ALIGN_BOTTOM) return QString("bottom"); } else if (key == "showposition") { QPoint center = widget->rect().center(); QDjVuWidget::Position pos = widget->positionWithClosestAnchor(center); double ha = pos.hAnchor / 100.0; double va = pos.vAnchor / 100.0; return QString("%1,%2").arg(ha).arg(va); } else if (key == "passive" || key == "passivestretch") { if (widget->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff && !menuBar->isVisibleTo(this) && !statusBar->isVisibleTo(this) && !thumbnailDock->isVisibleTo(this) && !outlineDock->isVisibleTo(this) && !findDock->isVisibleTo(this) && !toolBar->isVisibleTo(this) && !widget->continuous() && !widget->sideBySide() && !widget->keyboardEnabled() && !widget->mouseEnabled() && widget->contextMenu() == 0 ) { int z = widget->zoom(); if (key == "passive" && z == QDjVuWidget::ZOOM_FITPAGE) return QString("yes"); if (key == "passivestretch" && z == QDjVuWidget::ZOOM_STRETCH) return QString("yes"); } return QString("no"); } else if (key == "sidebar") { // without position QStringList what; if (thumbnailDock->isVisibleTo(this)) what << "thumbnails"; if (outlineDock->isVisibleTo(this)) what << "outline"; if (findDock->isVisibleTo(this)) what << "find"; if (what.size() > 0) return QString("yes,") + what.join(","); else return QString("no"); } else if (key == "toolbar") { // Currently without toolbar content return get_boolean(toolBar->isVisibleTo(this)); } else if (key == "highlight") { // Currently not working return QString(); } return QString(); } // ---------------------------------------- // QDJVIEW /*! \enum QDjView::ViewerMode The viewer mode is selected at creation time. Mode \a STANDALONE corresponds to a standalone program. Modes \a FULLPAGE_PLUGIN and \a EMBEDDED_PLUGIN correspond to a netscape plugin. */ QDjView::~QDjView() { closeDocument(); } /*! Construct a \a QDjView object using the specified djvu context and viewer mode. */ QDjView::QDjView(QDjVuContext &context, ViewerMode mode, QWidget *parent) : QMainWindow(parent), viewerMode(mode < STANDALONE ? mode : STANDALONE), djvuContext(context), document(0), hasNumericalPageTitle(true), updateActionsScheduled(false), performPendingScheduled(false), printingAllowed(true), savingAllowed(true) { // Main window setup setWindowTitle(tr("DjView")); setWindowIcon(QIcon(":/images/djview.png")); #ifndef Q_OS_DARWIN if (QApplication::windowIcon().isNull()) QApplication::setWindowIcon(windowIcon()); #endif // Determine unique object name if (mode >= STANDALONE) { QWidgetList wl = QApplication::topLevelWidgets(); static int num = 0; QString name; while(name.isEmpty()) { name = QString("djview%1").arg(num++); foreach(QWidget *w, wl) if (w->objectName() == name) name = QString::null; } setObjectName(name); } // Basic preferences prefs = QDjViewPrefs::instance(); options = QDjViewPrefs::defaultOptions; tools = prefs->tools; toolsCached = 0; // Create dialogs errorDialog = new QDjViewErrorDialog(this); infoDialog = 0; metaDialog = 0; // Try using GLWidget? bool useOpenGL = prefs->openGLAccel; QString envOpenGL = QString::fromLocal8Bit(::getenv("DJVIEW_OPENGL")); useOpenGL |= string_is_on(envOpenGL); useOpenGL &= !string_is_off(envOpenGL); if (viewerMode < STANDALONE) useOpenGL = false; // GLWidget/XEmbed has focus issues // Create djvu widget QWidget *central = new QWidget(this); widget = new QDjVuWidget(useOpenGL, central); widget->setFrameShape(QFrame::NoFrame); if (viewerMode >= STANDALONE) widget->setFrameShadow(QFrame::Sunken); widget->viewport()->installEventFilter(this); connect(widget, SIGNAL(errorCondition(int)), this, SLOT(errorCondition(int))); connect(widget, SIGNAL(error(QString,QString,int)), errorDialog, SLOT(error(QString,QString,int))); connect(widget, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int))); connect(widget, SIGNAL(info(QString)), this, SLOT(info(QString))); connect(widget, SIGNAL(layoutChanged()), this, SLOT(updateActionsLater())); connect(widget, SIGNAL(pageChanged(int)), this, SLOT(updateActionsLater())); connect(widget, SIGNAL(pointerPosition(const Position&,const PageInfo&)), this, SLOT(pointerPosition(const Position&,const PageInfo&))); connect(widget, SIGNAL(pointerEnter(const Position&,miniexp_t)), this, SLOT(pointerEnter(const Position&,miniexp_t))); connect(widget, SIGNAL(pointerLeave(const Position&,miniexp_t)), this, SLOT(pointerLeave(const Position&,miniexp_t))); connect(widget, SIGNAL(pointerClick(const Position&,miniexp_t)), this, SLOT(pointerClick(const Position&,miniexp_t))); connect(widget, SIGNAL(pointerSelect(const QPoint&,const QRect&)), this, SLOT(pointerSelect(const QPoint&,const QRect&))); // Create splash screen splash = new QLabel(central); splash->setFrameShadow(QFrame::Sunken); splash->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); splash->setPixmap(QPixmap(":/images/splash.png")); QPalette palette = splash->palette(); palette.setColor(QPalette::Background, Qt::white); splash->setPalette(palette); splash->setAutoFillBackground(true); // Create central layout layout = new QStackedLayout(central); layout->addWidget(widget); layout->addWidget(splash); layout->setCurrentWidget(splash); setCentralWidget(central); // Create context menu contextMenu = new QMenu(this); recentMenu = 0; // Create menubar menuBar = new QMenuBar(this); setMenuBar(menuBar); // Create statusbar statusBar = new QStatusBar(this); QFont font = QApplication::font(); font.setPointSize((font.pointSize() * 3 + 3) / 4); QFontMetrics metric(font); textLabelTimer = new QTimer(this); textLabelTimer->setSingleShot(true); connect(textLabelTimer,SIGNAL(timeout()),this,SLOT(updateTextLabel())); textLabel = new QLabel(statusBar); textLabel->setFont(font); textLabel->setAutoFillBackground(true); textLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); textLabel->setFrameStyle(QFrame::Panel); textLabel->setFrameShadow(QFrame::Sunken); textLabel->setMinimumWidth(metric.width("M")*48); statusBar->addWidget(textLabel, 1); pageLabel = new QLabel(statusBar); pageLabel->setFont(font); pageLabel->setTextFormat(Qt::PlainText); pageLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); pageLabel->setFrameStyle(QFrame::Panel); pageLabel->setFrameShadow(QFrame::Sunken); pageLabel->setMinimumWidth(metric.width(" P88/888 8888x8888 888dpi ")); statusBar->addPermanentWidget(pageLabel); mouseLabel = new QLabel(statusBar); mouseLabel->setFont(font); mouseLabel->setTextFormat(Qt::PlainText); mouseLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); mouseLabel->setFrameStyle(QFrame::Panel); mouseLabel->setFrameShadow(QFrame::Sunken); mouseLabel->setMinimumWidth(metric.width(" x=888 y=888 ")); statusBar->addPermanentWidget(mouseLabel); setStatusBar(statusBar); // Create toolbar toolBar = new QToolBar(this); toolBar->setObjectName("toolbar"); toolBar->setAllowedAreas(Qt::TopToolBarArea|Qt::BottomToolBarArea); addToolBar(toolBar); // Create mode combo box modeCombo = new QComboBox(toolBar); fillModeCombo(modeCombo); connect(modeCombo, SIGNAL(activated(int)), this, SLOT(modeComboActivated(int)) ); connect(modeCombo, SIGNAL(activated(int)), this, SLOT(updateActionsLater()) ); // Create zoom combo box zoomCombo = new QComboBox(toolBar); zoomCombo->setEditable(true); zoomCombo->setInsertPolicy(QComboBox::NoInsert); fillZoomCombo(zoomCombo); connect(zoomCombo, SIGNAL(activated(int)), this, SLOT(zoomComboActivated(int)) ); connect(zoomCombo->lineEdit(), SIGNAL(editingFinished()), this, SLOT(zoomComboEdited()) ); // Create page combo box pageCombo = new QComboBox(toolBar); pageCombo->setEditable(true); pageCombo->setInsertPolicy(QComboBox::NoInsert); pageCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents); pageCombo->installEventFilter(this); connect(pageCombo, SIGNAL(activated(int)), this, SLOT(pageComboActivated(int))); connect(pageCombo->lineEdit(), SIGNAL(editingFinished()), this, SLOT(pageComboEdited()) ); // Create sidebar thumbnailWidget = new QDjViewThumbnails(this); thumbnailDock = new QDockWidget(this); thumbnailDock->setObjectName("thumbnailDock"); thumbnailDock->setWindowTitle(tr("Thumbnails")); thumbnailDock->setWidget(thumbnailWidget); thumbnailDock->installEventFilter(this); addDockWidget(Qt::LeftDockWidgetArea, thumbnailDock); outlineWidget = new QDjViewOutline(this); outlineDock = new QDockWidget(this); outlineDock->setObjectName("outlineDock"); outlineDock->setWindowTitle(tr("Outline")); outlineDock->setWidget(outlineWidget); outlineDock->installEventFilter(this); addDockWidget(Qt::LeftDockWidgetArea, outlineDock); findWidget = new QDjViewFind(this); findDock = new QDockWidget(this); findDock->setObjectName("findDock"); findDock->setWindowTitle(tr("Find")); findDock->setWidget(findWidget); findDock->installEventFilter(this); addDockWidget(Qt::LeftDockWidgetArea, findDock); // Create escape shortcut for sidebar shortcutEscape = new QShortcut(QKeySequence("Esc"), this); connect(shortcutEscape, SIGNAL(activated()), this, SLOT(performEscape())); // Create escape shortcut for activating page dialog shortcutGoPage = new QShortcut(QKeySequence("Ctrl+G"), this); connect(shortcutGoPage, SIGNAL(activated()), this, SLOT(performGoPage())); // Create MacOS shortcut for minimizing current window #ifdef Q_OS_DARWIN QShortcut *shortcutMinimize = new QShortcut(QKeySequence("Ctrl+M"),this); connect(shortcutMinimize, SIGNAL(activated()), this, SLOT(showMinimized())); #endif // Create misc timers undoTimer = new QTimer(this); undoTimer->setSingleShot(true); connect(undoTimer,SIGNAL(timeout()), this, SLOT(saveUndoData())); slideShowTimer = new QTimer(this); slideShowTimer->setSingleShot(true); connect(slideShowTimer, SIGNAL(timeout()), this, SLOT(slideShowTimeout())); // Actions createActions(); createMenus(); createWhatsThis(); enableContextMenu(true); // Remember geometry and fix viewerMode if (mode >= STANDALONE) if (! (prefs->windowSize.isNull())) resize(prefs->windowSize); if (mode >= STANDALONE) if (prefs->windowMaximized) setWindowState(Qt::WindowMaximized); if (mode > STANDALONE) setViewerMode(mode); // Preferences connect(prefs, SIGNAL(updated()), this, SLOT(preferencesChanged())); applyPreferences(); updateActions(); // Options set so far have default priority widget->reduceOptionsToPriority(QDjVuWidget::PRIORITY_DEFAULT); } void QDjView::closeDocument() { // remember recent document QDjVuDocument *doc = document; if (doc && viewerMode >= STANDALONE) { if (documentPages.size() > 0) addRecent(getDecoratedUrl()); } // clear undo data here.clear(); undoList.clear(); redoList.clear(); // kill one-shot timers undoTimer->stop(); textLabelTimer->stop(); // close document layout->setCurrentWidget(splash); if (doc) { doc->ref(); disconnect(doc, 0, this, 0); disconnect(doc, 0, errorDialog, 0); printingAllowed = true; savingAllowed = true; } widget->setDocument(0); documentPages.clear(); documentFileName.clear(); hasNumericalPageTitle = true; documentUrl.clear(); documentModified = QDateTime(); document = 0; if (doc) { emit documentClosed(doc); doc->deref(); } } /*! Open a document represented by a \a QDjVuDocument object. */ void QDjView::open(QDjVuDocument *doc, QUrl url) { closeDocument(); document = doc; if (url.isValid()) documentUrl = url; connect(doc,SIGNAL(destroyed(void)), this, SLOT(closeDocument(void))); connect(doc,SIGNAL(docinfo(void)), this, SLOT(docinfo(void))); widget->setDocument(document); disconnect(document, 0, errorDialog, 0); layout->setCurrentWidget(widget); updateActions(); docinfo(); if (doc) emit documentOpened(doc); // process url options if (url.isValid()) parseDjVuCgiArguments(url); widget->reduceOptionsToPriority(QDjVuWidget::PRIORITY_CGI); // set focus widget->setFocus(); // set title setWindowTitle(QString("%1[*] - ").arg(getShortFileName()) + tr("DjView")); #if QT_VERSION > 0x40400 setWindowFilePath(url.toLocalFile()); #endif } /*! Open the djvu document stored in file \a filename. */ bool QDjView::open(QString filename) { closeDocument(); QDjVuDocument *doc = new QDjVuDocument(true); connect(doc, SIGNAL(error(QString,QString,int)), errorDialog, SLOT(error(QString,QString,int))); doc->setFileName(&djvuContext, filename); if (!doc->isValid()) { delete doc; addToErrorDialog(tr("Cannot open file '%1'.").arg(filename)); raiseErrorDialog(QMessageBox::Critical, tr("Opening DjVu file")); return false; } QFileInfo fileinfo(filename); QUrl url = QUrl::fromLocalFile(fileinfo.absoluteFilePath()); open(doc, url); documentFileName = filename; documentModified = QFileInfo(filename).lastModified(); restoreRecentDocument(url); return true; } /*! Open the djvu document available at url \a url. Only the \a http: and \a file: protocols are supported. */ bool QDjView::open(QUrl url) { closeDocument(); QDjVuNetDocument *doc = new QDjVuNetDocument(true); connect(doc, SIGNAL(error(QString,QString,int)), errorDialog, SLOT(error(QString,QString,int))); connect(doc, SIGNAL(authRequired(QString,QString&,QString&)), this, SLOT(authRequired(QString,QString&,QString&)) ); connect(doc, SIGNAL(sslWhiteList(QString,bool&)), this, SLOT(sslWhiteList(QString,bool&)) ); QUrl docurl = removeDjVuCgiArguments(url); doc->setUrl(&djvuContext, docurl); if (!doc->isValid()) { delete doc; addToErrorDialog(tr("Cannot open URL '%1'.").arg(url.toString())); raiseErrorDialog(QMessageBox::Critical, tr("Opening DjVu document")); return false; } open(doc, url); return true; } void QDjView::sslWhiteList(QString why, bool &okay) { #if QT_VERSION >= 0x50000 QString ewhy = why.toHtmlEscaped(); #else QString ewhy = Qt::escape(why); #endif if (QMessageBox::question(this, tr("Certificate validation error - DjView", "dialog caption"), tr(" %1 Do you want to continue anyway? ").arg(ewhy), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) okay = true; else closeDocument(); } void QDjView::authRequired(QString why, QString &user, QString &pass) { QDjViewAuthDialog *dialog = new QDjViewAuthDialog(this); dialog->setInfo(why); dialog->setUser(user); dialog->setPass(pass); int result = dialog->exec(); user = dialog->user(); pass = dialog->pass(); if (result != QDialog::Accepted) closeDocument(); } /*! Reload the document afresh. */ void QDjView::reloadDocument() { QDjVuDocument *doc = document; QUrl url = getDecoratedUrl(); if (doc && viewerMode >= STANDALONE && url.isValid()) { closeDocument(); ddjvu_cache_clear(djvuContext); // Opening files more efficiently QFileInfo file = url.toLocalFile(); if (file.exists()) { open(file.absoluteFilePath()); parseDjVuCgiArguments(url); return; } // Opening the url could do it all in fact. open(url); } } void QDjView::maybeReloadDocument() { QDjVuDocument *doc = document; if (doc && !documentModified.isNull() && !documentFileName.isNull()) { QFileInfo info(documentFileName); if (info.exists() && info.lastModified() > documentModified) QTimer::singleShot(0, this, SLOT(reloadDocument())); } } /*! Jump to the page numbered \a pageno. */ void QDjView::goToPage(int pageno) { int pagenum = documentPages.size(); if (!pagenum || !document) { pendingPage = QString("$%1").arg(pageno+1); } else { if (pageno>=0 && pagenosetPage(pageno); } else { QString msg = tr("Cannot find page numbered: %1").arg(pageno+1); qWarning("%s",(const char*)msg.toLocal8Bit()); } updateActionsLater(); } } /*! Jump to the page named \a name. Names starting with the "#" character are interpreted using the same rules as hyperlinks. In particular, names of the form \a "#+n" and \a "#-n" express relative displacement from the current page or the page specified by argument \a from. */ void QDjView::goToPage(QString name, int from) { int pagenum = documentPages.size(); if (!pagenum || !document) { pendingPage = name; } else { int pageno = pageNumber(name, from); if (pageno >= 0 && pageno < pagenum) { widget->setPage(pageno); } else { QString msg = tr("Cannot find page named: %1").arg(name); qWarning("%s",(const char*)msg.toLocal8Bit()); } updateActionsLater(); } } /* Jump to the page named \a pagename and tries to position the specified point in the center of the window. Arguments \a px and \a py must be in range 0 to 1 indicating a fraction of the page width or height. */ void QDjView::goToPosition(QString name, double px, double py) { int pagenum = documentPages.size(); if (!pagenum || !document) { pendingPosition.clear(); pendingPosition << px << py; if (! name.isEmpty()) pendingPage = name; } else { int pageno = (name.isEmpty()) ? widget->page() : pageNumber(name); if (pageno < 0 || pageno >= pagenum) { QString msg = tr("Cannot find page named: %1").arg(name); qWarning("%s",(const char*)msg.toLocal8Bit()); } else { QDjVuWidget::Position pos; pos.pageNo = pageno; pos.inPage = false; pos.posView = QPoint(0,0); pos.posPage = QPoint(0,0); pos.hAnchor = qBound(0, (int)(px*100), 100); pos.vAnchor = qBound(0, (int)(py*100), 100); widget->setPosition(pos, widget->rect().center()); } updateActionsLater(); } } /*! Add a message to the error dialog. */ void QDjView::addToErrorDialog(QString message) { errorDialog->error(message, __FILE__, __LINE__); } /*! Show the error dialog. */ void QDjView::raiseErrorDialog(QMessageBox::Icon icon, QString caption) { errorDialog->prepare(icon, caption); errorDialog->show(); errorDialog->raise(); errorDialog->activateWindow(); } /*! Show the error dialog and wait until the user clicks "OK". */ int QDjView::execErrorDialog(QMessageBox::Icon icon, QString caption) { errorDialog->prepare(icon, caption); return errorDialog->exec(); } /*! Set the content of the page box in the status bar. */ void QDjView::setPageLabelText(QString s) { QLabel *m = pageLabel; m->setText(s); m->setMinimumWidth(qMax(m->minimumWidth(), m->sizeHint().width())); } /*! Set the content of the mouse box in the status bar. */ void QDjView::setMouseLabelText(QString s) { QLabel *m = mouseLabel; m->setText(s); m->setMinimumWidth(qMax(m->minimumWidth(), m->sizeHint().width())); } /*! Display transient message in the status bar. This also emits signal \a pluginStatusMessage to mirror the message in the browser status bar. */ void QDjView::statusMessage(QString message) { if (message.isEmpty()) statusBar->clearMessage(); else statusBar->showMessage(message); emit pluginStatusMessage(message); } /*! Returns a bitmask of the visible sidebar tabs. */ int QDjView::visibleSideBarTabs() { int tabs = 0; if (! thumbnailDock->isHidden()) tabs |= 1; if (! outlineDock->isHidden()) tabs |= 2; if (! findDock->isHidden()) tabs |= 4; return tabs; } /*! Returns a bitmask of the hidden sidebar tabs. */ int QDjView::hiddenSideBarTabs() { int tabs = 0; if (thumbnailDock->isHidden()) tabs |= 1; if (outlineDock->isHidden()) tabs |= 2; if (findDock->isHidden()) tabs |= 4; return tabs; } /*! Change the position and the visibility of the sidebars specified by bitmask \a tabs. */ bool QDjView::showSideBar(Qt::DockWidgetAreas areas, int tabs) { QList allDocks; allDocks << thumbnailDock << outlineDock << findDock; // find first tab in desired area QDockWidget *first = 0; foreach(QDockWidget *w, allDocks) if (!first && !w->isHidden() && !w->isFloating()) if (dockWidgetArea(w) & areas) first = w; // find relevant docks QList docks; if (tabs & 1) docks << thumbnailDock; if (tabs & 2) docks << outlineDock; if (tabs & 4) docks << findDock; // hide all foreach(QDockWidget *w, docks) w->hide(); if (areas) { Qt::DockWidgetArea area = Qt::LeftDockWidgetArea; if (areas & Qt::LeftDockWidgetArea) area = Qt::LeftDockWidgetArea; else if (areas & Qt::RightDockWidgetArea) area = Qt::RightDockWidgetArea; else if (areas & Qt::TopDockWidgetArea) area = Qt::TopDockWidgetArea; else if (areas & Qt::BottomDockWidgetArea) area = Qt::BottomDockWidgetArea; foreach(QDockWidget *w, docks) { w->show(); if (w->isFloating()) w->setFloating(false); if (! (areas & dockWidgetArea(w))) { removeDockWidget(w); addDockWidget(area, w); if (first) tabifyDockWidget(first, w); else first = w; } w->show(); w->raise(); } } // Okay return true; } /*! Change the position and composition of the sidebar. String \a args contains comma separated keywords: \a left, \a right, \a top, \a bottom, \a yes, or \a no, \a outline, \a bookmarks, \a thumbnails, \a search, etc. Error messages are added to string list \a errors. */ bool QDjView::showSideBar(QString args, QStringList &errors) { bool yes = true; bool ret = true; int tabs = 0; Qt::DockWidgetAreas areas = 0; QString arg; foreach(arg, args.split(",", QString::SkipEmptyParts)) { arg = arg.toLower(); if (arg == "no" || arg == "false") yes = false; else if (arg == "left") areas |= Qt::LeftDockWidgetArea; else if (arg == "right") areas |= Qt::RightDockWidgetArea; else if (arg == "top") areas |= Qt::TopDockWidgetArea; else if (arg == "bottom") areas |= Qt::BottomDockWidgetArea; else if (arg == "thumbnails" || arg == "thumbnail") tabs |= 1; else if (arg == "outline" || arg == "bookmarks") tabs |= 2; else if (arg == "search" || arg == "find") tabs |= 4; else if (arg != "yes" && arg != "true") { errors << tr("Unrecognized sidebar options '%1'.").arg(arg); ret = false; } } if (!tabs) tabs = ~0; if (yes && !areas) areas = Qt::AllDockWidgetAreas; if (showSideBar(areas, tabs)) return ret; return false; } /*! Overloaded version of \a showSideBar for convenience. This version makes great efforts to show docks with the exact layout they had before being hidden. */ bool QDjView::showSideBar(bool show) { if (! show) { // save everything about dock geometry savedDockState = saveState(); } else if (savedDockState.size() > 0) { // hack toolbar name to avoid restoring its state QString savedToolBarName = toolBar->objectName(); toolBar->setObjectName(QString::null); restoreState(savedDockState); toolBar->setObjectName(savedToolBarName); savedDockState.clear(); } // set visibility thumbnailDock->setVisible(show); outlineDock->setVisible(show); findDock->setVisible(show); if (! show) widget->setFocus(Qt::OtherFocusReason); return true; } /*! Pops up find sidebar */ void QDjView::showFind() { if (! actionViewSideBar->isChecked()) actionViewSideBar->activate(QAction::Trigger); findDock->show(); findDock->raise(); findWidget->selectAll(); findWidget->takeFocus(Qt::ShortcutFocusReason); } bool QDjView::warnAboutPrintingRestrictions() { if (prefs->restrictOverride && !printingAllowed) if (QMessageBox::warning(this, tr("Print - DjView", "dialog caption"), tr(" This file was served with " "printing restrictions. " "Do you want to print it anyway?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes ) return false; return true; } bool QDjView::warnAboutSavingRestrictions() { if (prefs->restrictOverride && !savingAllowed) if (QMessageBox::warning(this, tr("Save - DjView", "dialog caption"), tr(" This file was served with " "saving restrictions. " "Do you want to save it anyway?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes ) return false; return true; } /*! Pops up a print dialog */ void QDjView::print() { QDjViewPrintDialog *pd = printDialog; if (! pd) { printDialog = pd = new QDjViewPrintDialog(this); pd->setAttribute(Qt::WA_DeleteOnClose); pd->setWindowTitle(tr("Print - DjView", "dialog caption")); } if (warnAboutPrintingRestrictions()) { pd->show(); pd->raise(); } } /*! Pops up a save dialog */ void QDjView::saveAs() { QDjViewSaveDialog *sd = saveDialog; if (! sd) { saveDialog = sd = new QDjViewSaveDialog(this); sd->setAttribute(Qt::WA_DeleteOnClose); sd->setWindowTitle(tr("Save - DjView", "dialog caption")); } if (warnAboutSavingRestrictions()) { sd->show(); sd->raise(); } } /*! Pops up export dialog */ void QDjView::exportAs() { QDjViewExportDialog *sd = exportDialog; if (! sd) { exportDialog = sd = new QDjViewExportDialog(this); sd->setAttribute(Qt::WA_DeleteOnClose); sd->setWindowTitle(tr("Export - DjView", "dialog caption")); } if (warnAboutSavingRestrictions()) { sd->show(); sd->raise(); } } /*! Start searching string \a find. String might be terminated with a slash followed by letters "w" (words only), "W" (not words only), "c" (case sensitive), or "C" (case insentitive). */ void QDjView::find(QString find) { if (! find.isEmpty()) { QRegExp options("/[wWcCrR]*$"); if (find.contains(options)) { for (int i=find.lastIndexOf("/"); isetCaseSensitive(true); else if (c == 'C') findWidget->setCaseSensitive(false); else if (c == 'w') findWidget->setWordOnly(true); else if (c == 'W') findWidget->setWordOnly(false); else if (c == 'r') findWidget->setRegExpMode(true); else if (c == 'R') findWidget->setRegExpMode(false); } find = find.remove(options); } findWidget->setText(find); } findWidget->findNext(); } // ----------------------------------- // UTILITIES /*! \fn QDjView::getDjVuWidget() Return the \a QDjVuWidget object managed by this window. */ /*! \fn QDjView::getErrorDialog() Return the error dialog for this window. */ /*! \fn QDjView::getDocument() Return the currently displayed \a QDjVuDocument. */ /*! \fn QDjView::getDocumentFileName() Return the filename of the currently displayed \a QDjVuDocument. */ /*! \fn QDjView::getDocumentUrl() Return the url of the currently displayed \a QDjVuDocument. */ /*! \fn QDjView::getViewerMode Return the current viewer mode. */ /*! Return an url that encodes the current view and page. */ QUrl QDjView::getDecoratedUrl() { QUrl url = removeDjVuCgiArguments(documentUrl); QPoint center = widget->rect().center(); QDjVuWidget::Position pos = widget->positionWithClosestAnchor(center); int pageNo = pos.pageNo; if (url.isValid() && pageNo>=0 && pageNo &dp = documentPages; QString pagestr = QString("%1").arg(pageNo+1); if (hasNumericalPageTitle && pageNorotation(); if (rotation) addQueryItem(items, "rotate", QString::number(90 * rotation)); QString zoom = getArgument("zoom"); if (zoom.isEmpty()) zoom = QString::number(widget->zoomFactor()); addQueryItem(items, "zoom", zoom); double ha = pos.hAnchor / 100.0; double va = pos.vAnchor / 100.0; addQueryItem(items, "showposition", QString("%1,%2").arg(ha).arg(va)); urlSetQueryItems(url, items); } return url; } /*! Return the base name of the current file. */ QString QDjView::getShortFileName() { if (! documentFileName.isEmpty()) return QFileInfo(documentFileName).fileName(); else if (! documentUrl.isEmpty()) return documentUrl.path().section('/', -1); return QString(); } /*! Return the number of pages in the document. This function returns zero when called before fully decoding the document header. */ int QDjView::pageNum(void) { return documentPages.size(); } /*! Return a name for page \a pageno. */ QString QDjView::pageName(int pageno, bool titleonly) { // obtain page title if (pageno>=0 && pagenopage(); if (from < pagenum && name.contains(QRegExp("^[-+$]\\d+$")) ) { int num = name.mid(1).toInt(); if (name[0]=='+') num = from + 1 + num; else if (name[0]=='-') num = from + 1 - num; return qBound(1, num, pagenum) - 1; } // Then search a matching page title starting // from the current page and wrapping around for (int i=from; iwidget; other->setAttribute(Qt::WA_DeleteOnClose); // copy window geometry if (! (windowState() & unusualWindowStates)) { other->resize( size() ); other->toolBar->setVisible(!toolBar->isHidden()); other->statusBar->setVisible(!statusBar->isHidden()); other->restoreState(saveState()); } // copy essential properties otherWidget->setDisplayMode( widget->displayMode() ); otherWidget->setContinuous( widget->continuous() ); otherWidget->setSideBySide( widget->sideBySide() ); otherWidget->setCoverPage( widget->coverPage() ); otherWidget->setRotation( widget->rotation() ); otherWidget->setZoom( widget->zoom() ); // copy document if (document && openDocument) { other->open(document); other->documentFileName = documentFileName; other->documentUrl = documentUrl; // copy position bool saved = otherWidget->animationEnabled(); otherWidget->enableAnimation(false); otherWidget->setPosition( widget->position() ); otherWidget->enableAnimation(saved); } return other; } /*! Save \a text info the specified file. When argument \a filename is omitted, a file dialog is presented to the user. */ bool QDjView::saveTextFile(QString text, QString filename) { // obtain filename if (filename.isEmpty()) { QString filters; filters += tr("Text files", "save filter")+" (*.txt);;"; filters += tr("All files", "save filter") + " (*)"; QString caption = tr("Save Text - DjView", "dialog caption"); filename = QFileDialog::getSaveFileName(this, caption, "", filters); if (filename.isEmpty()) return false; } // open file errno = 0; QFile file(filename); if (! file.open(QIODevice::WriteOnly|QIODevice::Truncate)) { QString message = file.errorString(); #if HAVE_STRERROR if (file.error() == QFile::OpenError && errno > 0) message = strerror(errno); #endif QMessageBox::critical(this, tr("Error - DjView", "dialog caption"), tr("Cannot write file '%1'.\n%2.") .arg(QFileInfo(filename).fileName()) .arg(message) ); file.remove(); return false; } // save text in current locale encoding QTextStream(&file) << text; return true; } /*! Save \a image info the specified file using a format derived from the filename suffix. When argument \a filename is omitted, a file dialog is presented to the user. */ bool QDjView::saveImageFile(QImage image, QString filename) { // obtain filename with suitable suffix if (filename.isEmpty()) { QString filters; QList formats = QImageWriter::supportedImageFormats(); foreach(QByteArray format, formats) filters += tr("%1 files (*.%2);;", "save image filter") .arg(QString(format).toUpper()) .arg(QString(format).toLower()); filters += tr("All files", "save filter") + " (*)"; QString caption = tr("Save Image - DjView", "dialog caption"); filename = QFileInfo(getShortFileName()).baseName(); if (formats.size()) filename += "." + QString(formats[0]); filename = QFileDialog::getSaveFileName(this, caption, filename, filters); if (filename.isEmpty()) return false; } // suffix QString suffix = QFileInfo(filename).suffix(); if (suffix.isEmpty()) { QMessageBox::critical(this, tr("Error - DjView", "dialog caption"), tr("Cannot determine file format.\n" "Filename '%1' has no suffix.") .arg(QFileInfo(filename).fileName()) ); return false; } // write errno = 0; QFile file(filename); QImageWriter writer(&file, suffix.toLatin1()); if (! writer.write(image)) { QString message = file.errorString(); if (writer.error() == QImageWriter::UnsupportedFormatError) message = tr("Image format %1 not supported.").arg(suffix.toUpper()); #if HAVE_STRERROR else if (file.error() == QFile::OpenError && errno > 0) message = strerror(errno); #endif QMessageBox::critical(this, tr("Error - DjView", "dialog caption"), tr("Cannot write file '%1'.\n%2.") .arg(QFileInfo(filename).fileName()) .arg(message) ); file.remove(); return false; } return true; } /*! Start the preferred browser on \a url. */ bool QDjView::startBrowser(QUrl url) { // Determine browsers to try QStringList browsers; #ifdef Q_OS_DARWIN browsers << "open"; #endif #ifdef Q_OS_WIN32 # if QT_VERSION < 0x40200 browsers << "firefox.exe"; browsers << "iexplore.exe"; # endif #endif #ifdef Q_OS_UNIX browsers << "x-www-browser" << "firefox" << "konqueror"; const char *varBrowser = ::getenv("BROWSER"); if (varBrowser && varBrowser[0]) browsers = QFile::decodeName(varBrowser).split(":") + browsers; browsers << "sensible-browser"; const char *varPath = ::getenv("PATH"); QStringList path; if (varPath && varPath[0]) path = QFile::decodeName(varPath).split(":"); path << "."; #endif if (! prefs->browserProgram.isEmpty()) browsers.prepend(prefs->browserProgram); // Try them QStringList args(url.toEncoded()); foreach (QString browser, browsers) { #ifdef Q_OS_UNIX int i; for (i=0; i= path.size()) continue; #endif if (QProcess::startDetached(browser, args)) return true; } // fallback #if QT_VERSION >= 0x40200 return QDesktopServices::openUrl(url); #else return false; #endif } /*! \fn QDjView::documentClosed(QDjVuDocument *doc) This signal is emitted when clearing the current document. Argument \a doc is the previous document. */ /*! \fn QDjView::documentOpened(QDjVuDocument *doc) This signal is emitted when opening a new document \a doc. */ /*! \fn QDjView::documentReady(QDjVuDocument *doc) This signal is emitted when the document structure for the current document \a doc is known. */ /*! \fn QDjView::pluginStatusMessage(QString message = QString()) This signal is emitted when a message is displayed in the status bar. This is useful for plugins because the message must be replicated in the browser status bar. */ /*! \fn QDjView::pluginGetUrl(QUrl url, QString target) This signal is emitted when the user clicks an external hyperlink while the viewer is in plugin mode. */ // ----------------------------------- // OVERRIDES void QDjView::closeEvent(QCloseEvent *event) { // Close document. closeDocument(); // Save options. // after closing the document in order to // avoid saving document defined settings. updatePreferences(); prefs->saveRemembered(); // continue closing the window event->accept(); } void QDjView::dragEnterEvent(QDragEnterEvent *event) { if (viewerMode >= STANDALONE) { const QMimeData *data = event->mimeData(); if (data->hasUrls() && data->urls().size()==1) event->accept(); } } void QDjView::dragMoveEvent(QDragMoveEvent *event) { #ifdef Q_OS_WIN QMainWindow::dragMoveEvent(event); #else QRect rect = centralWidget()->geometry(); if (event->answerRect().intersects(rect)) event->accept(rect); else event->ignore(); #endif } void QDjView::dropEvent(QDropEvent *event) { if (viewerMode >= STANDALONE) { const QMimeData *data = event->mimeData(); if (data->hasUrls() && data->urls().size()==1) if (open(data->urls()[0])) { event->setDropAction(Qt::CopyAction); event->accept(); } } } bool QDjView::eventFilter(QObject *watched, QEvent *event) { switch(event->type()) { case QEvent::Show: case QEvent::Hide: if (qobject_cast(watched)) updateActionsLater(); break; case QEvent::Leave: if ((watched == widget->viewport()) || (qobject_cast(watched)) ) { mouseLabel->clear(); textLabel->clear(); statusMessage(); return false; } break; case QEvent::Enter: if ((watched == widget->viewport()) || (qobject_cast(watched)) ) maybeReloadDocument(); break; case QEvent::StatusTip: if (qobject_cast(watched)) return QApplication::sendEvent(this, event); break; case QEvent::FocusIn: if (watched == pageCombo) if (widget && documentPages.size()) pageCombo->setEditText(pageName(widget->page())); break; default: break; } return false; } // ----------------------------------- // PROTECTED SIGNALS void QDjView::info(QString message) { if (! message.contains(QRegExp("^\\[\\d+"))) statusBar->showMessage(message, 2000); qWarning("INFO: %s", (const char*)message.toLocal8Bit()); } void QDjView::error(QString message, QString filename, int lineno) { // just for calling qWarning filename = filename.section("/", -1); if (filename.isEmpty()) qWarning("ERROR: %s", (const char*)message.toLocal8Bit()); else qWarning("ERROR (%s:%d): %s", (const char*)filename.toLocal8Bit(), lineno, (const char*)message.toLocal8Bit() ); } void QDjView::errorCondition(int pageno) { QString message; if (pageno >= 0) message = tr("Cannot decode page %1.").arg(pageno+1); else message = tr("Cannot decode document."); addToErrorDialog(message); raiseErrorDialog(QMessageBox::Warning, tr("Decoding DjVu document")); } void QDjView::docinfo() { if (document && documentPages.size()==0 && ddjvu_document_decoding_status(*document)==DDJVU_JOB_OK) { // Obtain information about pages. int n = ddjvu_document_get_pagenum(*document); int m = ddjvu_document_get_filenum(*document); for (int i=0; i0) { bool saved = widget->animationEnabled(); widget->enableAnimation(false); performPending(); widget->enableAnimation(saved); updateActionsLater(); emit documentReady(document); } } /*! Set options that could not be set before fully decoding the document header. For instance, calling \a QDjView::goToPage before decoding the djvu document header simply stores the page number in a well known variable. Function \a performPending peforms the page change as soon as the document information is available. */ void QDjView::performPending() { if (! documentPages.isEmpty()) { if (! pendingPosition.isEmpty()) { if (pendingPosition.size() == 2) goToPosition(pendingPage, pendingPosition[0], pendingPosition[1]); pendingPosition.clear(); pendingPage.clear(); } if (! pendingPage.isNull()) { goToPage(pendingPage); pendingPage.clear(); } if (pendingHilite.size() > 0) { StringPair pair; foreach(pair, pendingHilite) { int x, y, w, h; QColor color = Qt::blue; int pageno = widget->page(); if (! pair.first.isEmpty()) pageno = pageNumber(pair.first); if (pageno < pageNum() && pageno >= 0 && parse_highlight(pair.second, x, y, w, h, color) && w > 0 && h > 0 ) { color.setAlpha(96); widget->addHighlight(pageno, x, y, w, h, color); } } pendingHilite.clear(); } if (pendingFind.size() > 0) { find(pendingFind); pendingFind.clear(); } } performPendingScheduled = false; } /*! Schedule a call to \a QDjView::performPending(). */ void QDjView::performPendingLater() { if (! performPendingScheduled) { performPendingScheduled = true; QTimer::singleShot(0, this, SLOT(performPending())); } } void QDjView::pointerPosition(const Position &pos, const PageInfo &info) { // setup page label QString p = ""; QString m = ""; if (pos.pageNo >= 0) { p = tr(" P%1/%2 %3x%4 %5dpi ") .arg(pos.pageNo+1).arg(documentPages.size()) .arg(info.width).arg(info.height).arg(info.dpi); } if (pos.inPage || !info.segment.isEmpty()) { if (info.segment.isEmpty()) m = tr(" x=%1 y=%2 ") .arg(pos.posPage.x()) .arg(pos.posPage.y()); else m = tr(" %3x%4+%1+%2 ") .arg(info.segment.left()) .arg(info.segment.top()) .arg(info.segment.width()) .arg(info.segment.height()); } setPageLabelText(p); setMouseLabelText(m); if (textLabel->isVisibleTo(this)) { textLabelRect = info.selected; textLabelTimer->start(25); } } void QDjView::updateTextLabel() { textLabel->clear(); textLabel->setWordWrap(false); textLabel->setTextFormat(Qt::PlainText); if (document && textLabel->isVisibleTo(this)) { QString text; QFontMetrics m(textLabel->font()); QString lb = QString::fromUtf8(" \302\253 "); QString rb = QString::fromUtf8(" \302\273 "); int w = textLabel->width() - 2 * textLabel->frameWidth() - m.width(lb + rb + "MM"); if (! textLabelRect.isEmpty()) { text = widget->getTextForRect(textLabelRect); text = text.replace(QRegExp("\\s+"), " "); text = m.elidedText(text, Qt::ElideMiddle, w); } else { QString results[3]; if (widget->getTextForPointer(results)) { results[0] = results[0].simplified(); results[1] = results[1].simplified(); results[2] = results[2].simplified(); if (results[0].size() || results[2].size()) results[1] = " [" + results[1] + "] "; int r1 = m.width(results[1]); int r2 = m.width(results[2]); int r0 = qMax(0, qMax( (w-r1)/2, (w-r1-r2) )); text = m.elidedText(results[0], Qt::ElideLeft, r0) + results[1]; text = m.elidedText(text+results[2], Qt::ElideRight, w); } } text = text.trimmed(); if (text.size()) textLabel->setText(lb + text + rb); } } void QDjView::pointerEnter(const Position&, miniexp_t) { // Display information message about hyperlink QString link = widget->linkUrl(); if (link.isEmpty()) return; QString target = widget->linkTarget(); if (target=="_self" || target=="_page") target.clear(); QString message; if (link.startsWith("#") && link.contains(QRegExp("^#[-+]\\d+$")) ) { int n = link.mid(2).toInt(); if (link[1]=='+') message = (n==1) ? tr("Go: 1 page forward.") : tr("Go: %n pages forward.", 0, n); else message = (n==1) ? tr("Go: 1 page backward.") : tr("Go: %n pages backward.", 0, n); } else if (link.startsWith("#$")) message = tr("Go: page %1.").arg(link.mid(2)); else if (link.startsWith("#")) message = tr("Go: page %1.").arg(link.mid(1)); else message = tr("Go: %1").arg(link); if (!target.isEmpty()) message = message + tr(" (in other window.)"); statusMessage(message); } void QDjView::pointerLeave(const Position&, miniexp_t) { statusMessage(); } void QDjView::pointerClick(const Position &pos, miniexp_t) { goToLink(widget->linkUrl(), widget->linkTarget(), pos.pageNo); } void QDjView::goToLink(QString link, QString target, int fromPage) { bool inPlace = target.isEmpty() || target=="_self" || target=="_page"; QUrl url = documentUrl; // Internal link if (link.startsWith("#")) { QString name = link.mid(1); if (inPlace) { goToPage(name, fromPage); return; } if (viewerMode >= STANDALONE) { QDjView *other = copyWindow(); other->goToPage(name, fromPage); other->show(); return; } // Construct url url = removeDjVuCgiArguments(url); QueryItems items = urlQueryItems(url); addQueryItem(items, "djvuopts", QString::null); int pageno = pageNumber(name, fromPage); if (pageno>=0 && pageno<=documentPages.size()) addQueryItem(items, "page", QString::fromUtf8(documentPages[pageno].id)); urlSetQueryItems(url, items); } else if (link.startsWith("?")) { if (inPlace) { foreach(QString opt, link.mid(1).split("&")) parseArgument(opt); return; } if (viewerMode >= STANDALONE) { QDjView *other = copyWindow(); foreach(QString opt, link.mid(1).split("&")) other->parseArgument(opt); other->show(); return; } // Construct url QUrl linkUrl = QUrl::fromEncoded("file://d/d" + link.toUtf8()); url = removeDjVuCgiArguments(url); QueryItems items = urlQueryItems(url); addQueryItem(items, "djvuopts", ""); QPair pair; foreach(pair, urlQueryItems(linkUrl)) addQueryItem(items, pair.first, pair.second); urlSetQueryItems(url, items); } else { // Decode url QUrl linkUrl = QUrl::fromEncoded(link.toUtf8()); // Resolve url QueryItems empty; urlSetQueryItems(url, empty); url = url.resolved(linkUrl); urlSetQueryItems(url, urlQueryItems(linkUrl)); } // Check url if (! url.isValid() || url.isRelative()) { QString msg = tr("Cannot resolve link '%1'").arg(link); qWarning("%s", (const char*)msg.toLocal8Bit()); return; } // Signal browser if (viewerMode < STANDALONE) { emit pluginGetUrl(url, target); return; } // Standalone can open djvu documents QFileInfo file = url.toLocalFile(); QString suffix = file.suffix().toLower(); if (file.exists() && (suffix=="djvu" || suffix=="djv")) { if (inPlace) open(url); else { QDjView *other = copyWindow(); other->open(url); other->show(); } return; } // Open a browser if (! startBrowser(url)) { QString msg = tr("Cannot spawn a browser for url '%1'").arg(link); qWarning("%s",(const char*)msg.toLocal8Bit()); } } void QDjView::pointerSelect(const QPoint &pointerPos, const QRect &rect) { // Collect text QString text=widget->getTextForRect(rect); int l = text.size(); int w = rect.width(); int h = rect.height(); QString s = tr("%n characters", 0, l); if (QApplication::clipboard()->supportsSelection()) QApplication::clipboard()->setText(text, QClipboard::Selection); // Prepare menu QMenu *menu = new QMenu(this); QAction *copyText = menu->addAction(tr("Copy text (%1)").arg(s)); QAction *saveText = menu->addAction(tr("Save text as...")); copyText->setEnabled(l>0); saveText->setEnabled(l>0); copyText->setStatusTip(tr("Copy text into the clipboard.")); saveText->setStatusTip(tr("Save text into a file.")); menu->addSeparator(); QString copyImageString = tr("Copy image (%1x%2 pixels)").arg(w).arg(h); QAction *copyImage = menu->addAction(copyImageString); QAction *saveImage = menu->addAction(tr("Save image as...")); copyImage->setStatusTip(tr("Copy image into the clipboard.")); saveImage->setStatusTip(tr("Save image into a file.")); menu->addSeparator(); QAction *zoom = menu->addAction(tr("Zoom to rectangle")); zoom->setStatusTip(tr("Zoom the selection to fit the window.")); QAction *copyUrl = 0; QAction *copyMaparea = 0; if (prefs->advancedFeatures) { menu->addSeparator(); copyUrl = menu->addAction(tr("Copy URL")); copyUrl->setStatusTip(tr("Save into the clipboard an URL that " "highlights the selection.")); copyMaparea = menu->addAction(tr("Copy Maparea")); copyMaparea->setStatusTip(tr("Save into the clipboard a maparea " "annotation expression for program " "djvused.")); } // Make sure that status tips work (hack) menu->installEventFilter(this); // Execute menu QAction *action = menu->exec(pointerPos-QPoint(5,5), copyText); if (action == zoom) widget->zoomRect(rect); else if (action == copyText) QApplication::clipboard()->setText(text); else if (action == saveText) saveTextFile(text); else if (action == copyImage) QApplication::clipboard()->setImage(widget->getImageForRect(rect)); else if (action == saveImage) saveImageFile(widget->getImageForRect(rect)); else if (action && action == copyMaparea) { Position pos = widget->position(pointerPos); QRect seg = widget->getSegmentForRect(rect, pos.pageNo); if (! rect.isEmpty()) { QString s = QString("(maparea \"url\"\n" " \"comment\"\n" " (rect %1 %2 %3 %4))") .arg(seg.left()).arg(seg.top()) .arg(seg.width()).arg(seg.height()); QApplication::clipboard()->setText(s); } } else if (action && action == copyUrl) { QUrl url = getDecoratedUrl(); Position pos = widget->position(pointerPos); QRect seg = widget->getSegmentForRect(rect, pos.pageNo); if (url.isValid() && pos.pageNo>=0 && pos.pageNo &dp = documentPages; if (! hasQueryItem(items, "page", false)) if (pos.pageNo>=0 && pos.pageNosetText(url.toString()); } } // Cancel select mode. updateActionsLater(); if (actionSelect->isChecked()) { actionSelect->setChecked(false); performSelect(false); } } /*! Schedule a call to \a QDjView::updateActions(). */ void QDjView::updateActionsLater() { if (! updateActionsScheduled) { updateActionsScheduled = true; QTimer::singleShot(0, this, SLOT(updateActions())); } } void QDjView::modeComboActivated(int index) { int mode = modeCombo->itemData(index).toInt(); widget->setDisplayMode((QDjVuWidget::DisplayMode)mode); widget->setFocus(); } void QDjView::zoomComboActivated(int index) { int zoom = zoomCombo->itemData(index).toInt(); widget->setZoom(zoom); updateActionsLater(); widget->setFocus(); } void QDjView::zoomComboEdited(void) { bool okay; QString text = zoomCombo->lineEdit()->text(); int zoom = text.replace(QRegExp("\\s*%?$"),"").trimmed().toInt(&okay); if (okay && zoom>0) widget->setZoom(zoom); updateActionsLater(); if (okay) widget->setFocus(); } void QDjView::pageComboActivated(int index) { goToPage(pageCombo->itemData(index).toInt()); updateActionsLater(); widget->setFocus(); } void QDjView::pageComboEdited(void) { QString data = pageCombo->lineEdit()->text().trimmed(); int pagenum = documentPages.size(); QRegExp pattern = QRegExp(QString("\\s*(\\d+)\\s*/\\s*%1\\s*").arg(pagenum)); if (pattern.exactMatch(data)) goToPage(qMax(0, pattern.cap(1).toInt() - 1)); else goToPage(data); updateActionsLater(); widget->setFocus(); } // ----------------------------------- // SIGNALS IMPLEMENTING ACTIONS void QDjView::performAbout(void) { QStringList version; #if DDJVUAPI_VERSION >= 20 version << QString(ddjvu_get_version_string()); #endif #ifdef QT_VERSION version << QString("Qt-%1").arg(qVersion()); #endif QString versioninfo = ""; if (version.size() > 0) versioninfo = "(" + version.join(", ") + ")"; QString html = trUtf8("" "

DjVuLibre DjView %1

%2" "

" "Viewer for DjVu documents
" "%3
" "Copyright \302\251 2006-- L\303\251on Bottou." "

" "

" "This program is free software. " "You can redistribute or modify it under the terms of the " "GNU General Public License as published " "by the Free Software Foundation. " "This program is distributed without any warranty. " "See the GNU General Public License for more details." "

" "") .arg(QDjViewPrefs::versionString()) .arg(versioninfo) .arg("http://djvu.sourceforge.net"); QMessageBox::about(this, tr("About DjView"), html); } void QDjView::performNew(void) { if (viewerMode < STANDALONE) return; QDjView *other = copyWindow(false); other->show(); } void QDjView::performOpen(void) { if (viewerMode < STANDALONE) return; QString filters; filters += tr("DjVu files") + " (*.djvu *.djv);;"; filters += tr("All files") + " (*)"; QString caption = tr("Open - DjView", "dialog caption"); QString dirname = QDir::currentPath(); QDir dir = QFileInfo(documentFileName).absoluteDir(); if (dir.exists() && !documentFileName.isEmpty()) dirname = dir.absolutePath(); QString fname; fname = QFileDialog::getOpenFileName(this, caption, dirname, filters); if (! fname.isEmpty()) open(fname); } void QDjView::performOpenLocation(void) { if (viewerMode < STANDALONE) return; QString caption = tr("Open Location - DjView", "dialog caption"); QString label = tr("Enter the URL of a DjVu document:"); QString text = "http://"; bool ok; QUrl url = QInputDialog::getText(this, caption, label, QLineEdit::Normal, text, &ok); if (ok && url.isValid()) open(url); } void QDjView::performInformation(void) { if (! documentPages.size()) return; if (! infoDialog) infoDialog = new QDjViewInfoDialog(this); infoDialog->setWindowTitle(tr("Information - DjView", "dialog caption")); infoDialog->setPage(widget->page()); infoDialog->refresh(); infoDialog->raise(); infoDialog->show(); } void QDjView::performMetadata(void) { if (! documentPages.size()) return; if (! metaDialog) metaDialog = new QDjViewMetaDialog(this); metaDialog->setWindowTitle(tr("Metadata - DjView", "dialog caption")); metaDialog->setPage(widget->page()); metaDialog->refresh(); metaDialog->raise(); metaDialog->show(); } void QDjView::performPreferences(void) { updatePreferences(); QDjViewPrefsDialog *dialog = QDjViewPrefsDialog::instance(); dialog->load(this); dialog->show(); dialog->raise(); } void QDjView::performRotation(void) { QAction *action = qobject_cast(sender()); int rotation = action->data().toInt(); widget->setRotation(rotation); } void QDjView::performZoom(void) { QAction *action = qobject_cast(sender()); int zoom = action->data().toInt(); widget->setZoom(zoom); } void QDjView::performSelect(bool checked) { if (checked) widget->setModifiersForSelect(Qt::NoModifier); else widget->setModifiersForSelect(prefs->modifiersForSelect); } bool QDjView::setViewerMode(ViewerMode mode) { Saved *savedPrefs; Saved *savedConfig; if (viewerMode == mode) return true; if (viewerMode < STANDALONE || mode < STANDALONE) return false; savedPrefs = getSavedPrefs(); savedConfig = getSavedConfig(viewerMode); savedConfig->remember = true; updateSaved(savedConfig); updateSaved(savedPrefs); Qt::WindowStates wstate = windowState(); wstate &= ~unusualWindowStates; if (mode > STANDALONE) wstate |= Qt::WindowFullScreen; if (mode > STANDALONE) setUnifiedTitleAndToolBarOnMac(false); savedConfig = getSavedConfig(mode); setWindowState(wstate); applySaved(savedConfig); widget->setBorderBrush(savedConfig->nsBorderBrush); widget->setBorderSize(savedConfig->nsBorderSize); viewerMode = mode; // slideshow delay if (mode == STANDALONE_SLIDESHOW) setSlideShowDelay(prefs->slideShowDelay); // make sure checkboxes are set right. updateActionsLater(); return true; } void QDjView::setSlideShowDelay(int delay) { slideShowCounter = 0; slideShowDelay = delay; slideShowTimeout(true); } void QDjView::slideShowTimeout(bool reset) { double ratio = 0; bool ssmode = (viewerMode == STANDALONE_SLIDESHOW) && (slideShowDelay>0); bool active = ssmode && (widget->page() < pageNum()-1); bool newpage = (slideShowCounter >= slideShowDelay-1); slideShowCounter = (reset||newpage||!active) ? 0 : slideShowCounter+1; if (newpage && active) widget->nextPage(); if (active) ratio = 1.0 - (double)slideShowCounter / slideShowDelay; widget->setHourGlassRatio(ratio); slideShowTimer->stop(); if (ssmode) slideShowTimer->start(1000); } void QDjView::performViewFullScreen(bool checked) { if (checked) setViewerMode(STANDALONE_FULLSCREEN); else setViewerMode(STANDALONE); } void QDjView::performViewSlideShow(bool checked) { if (checked) setViewerMode(STANDALONE_SLIDESHOW); else setViewerMode(STANDALONE); } void QDjView::performEscape() { if (actionViewSideBar->isChecked()) actionViewSideBar->activate(QAction::Trigger); else if (viewerMode > STANDALONE && widget->keyboardEnabled()) setViewerMode(STANDALONE); } void QDjView::performGoPage() { if (toolBar->isVisibleTo(this) || widget->keyboardEnabled()) if (toolsCached & QDjViewPrefs::TOOL_PAGECOMBO) { toolBar->show(); pageCombo->setFocus(); QTimer::singleShot(0, pageCombo->lineEdit(), SLOT(selectAll())); } } void QDjView::restoreRecentDocument(QUrl url) { url.setPassword(QString::null); QUrl cleanUrl = removeDjVuCgiArguments(url); QString prefix = cleanUrl.toString(QUrl::RemoveQuery); foreach (QString recent, prefs->recentFiles) if (recent.startsWith(prefix)) { QUrl recentUrl = recent; QUrl cleanRecentUrl = removeDjVuCgiArguments(recentUrl); if (cleanUrl == cleanRecentUrl) { parseDjVuCgiArguments(recentUrl); return; } } } void QDjView::addRecent(QUrl url) { prefs->loadRecent(); // never remember passwords url.setPassword(QString::null); // remove matching entries QUrl cleanUrl = removeDjVuCgiArguments(url); QString prefix = cleanUrl.toString(QUrl::RemoveQuery); QStringList::iterator it = prefs->recentFiles.begin(); while (it != prefs->recentFiles.end()) { if (it->startsWith(prefix) && cleanUrl == removeDjVuCgiArguments(QUrl(*it))) it = prefs->recentFiles.erase(it); else ++it; } // add new url (max 50) QString name = url.toString(); prefs->recentFiles.prepend(name); while(prefs->recentFiles.size() > 50) prefs->recentFiles.pop_back(); // save prefs->saveRecent(); } void QDjView::fillRecent() { if (recentMenu) { recentMenu->clear(); prefs->loadRecent(); int n = qMin(prefs->recentFiles.size(), 8); for (int i=0; irecentFiles[i]; QString base = url.path().section("/",-1); QString name = url.toLocalFile(); if (name.isEmpty()) name = removeDjVuCgiArguments(url).toString(); QFont defaultFont; QFontMetrics metrics(defaultFont); name = metrics.elidedText(name, Qt::ElideMiddle, 400); name = QString("%1 [%2]").arg(base).arg(name); QAction *action = recentMenu->addAction(name); action->setData(url); connect(action,SIGNAL(triggered()), this, SLOT(openRecent())); } recentMenu->addSeparator(); } QAction *action = recentMenu->addAction(tr("&Clear History")); connect(action, SIGNAL(triggered()), this, SLOT(clearRecent())); } void QDjView::openRecent() { QAction *action = qobject_cast(sender()); if (action && viewerMode >= STANDALONE) { QUrl url = action->data().toUrl(); QFileInfo file = url.toLocalFile(); if (file.exists()) open(file.absoluteFilePath()); else open(url); } } void QDjView::clearRecent() { prefs->recentFiles.clear(); prefs->saveRecent(); } QDjView::UndoRedo::UndoRedo() : valid(false) { } void QDjView::UndoRedo::clear() { valid = false; } void QDjView::UndoRedo::set(QDjView *djview) { QDjVuWidget *djvu = djview->getDjVuWidget(); rotation = djvu->rotation(); zoom = djvu->zoom(); hotSpot = djvu->hotSpot(); position = djvu->position(hotSpot); valid = true; } void QDjView::UndoRedo::apply(QDjView *djview) { if (valid) { QDjVuWidget *djvu = djview->getDjVuWidget(); djvu->setZoom(zoom); djvu->setRotation(rotation); djvu->setPosition(position, hotSpot); } } bool QDjView::UndoRedo::changed(const QDjVuWidget *djvu) const { if (valid) { if (zoom != djvu->zoom() || rotation != djvu->rotation()) return true; Position curpos = djvu->position(hotSpot); if (curpos.pageNo != position.pageNo || curpos.inPage != position.inPage) return true; if (curpos.inPage) return (curpos.posPage != position.posPage); else return (curpos.posView != position.posView); } return false; } void QDjView::saveUndoData() { if (QApplication::mouseButtons() == Qt::NoButton && widget->pageSizeKnown(widget->page()) ) { if (here.changed(widget)) { undoList.prepend(here); while (undoList.size() > 1024) undoList.removeLast(); redoList.clear(); } here.set(this); actionBack->setEnabled(undoList.size() > 0); actionForw->setEnabled(redoList.size() > 0); } else { undoTimer->stop(); undoTimer->start(250); } } void QDjView::performUndo() { if (undoList.size() > 0) { UndoRedo target = undoList.takeFirst(); UndoRedo saved; saved.set(this); target.apply(this); here.clear(); redoList.prepend(saved); } } void QDjView::performRedo() { if (redoList.size() > 0) { UndoRedo target = redoList.takeFirst(); UndoRedo saved; saved.set(this); target.apply(this); here.clear(); undoList.prepend(saved); } } void QDjView::performCopyUrl() { QUrl url = getDecoratedUrl(); if (url.isValid()) QApplication::clipboard()->setText(url.toString()); } #if DDJVUAPI_VERSION < 21 static QByteArray *qstring_puts_data = 0; static int qstring_puts(const char *s) { if (qstring_puts_data) (*qstring_puts_data) += s; return strlen(s); } static QString miniexp_to_string(miniexp_t expr, int width=40, bool octal=false) { QByteArray buffer; qstring_puts_data = &buffer; int (*saved_puts)(const char*) = minilisp_puts; int saved_print_7bits = minilisp_print_7bits; minilisp_puts = qstring_puts; minilisp_print_7bits = (octal) ? 1 : 0; miniexp_pprint(expr, width); minilisp_print_7bits = saved_print_7bits; minilisp_puts = saved_puts; return QString::fromUtf8(buffer.data()); } #else static int qstring_puts(miniexp_io_t *io, const char *s) { QByteArray *bap = (QByteArray*)io->data[1]; if (bap) *bap += s; return strlen(s); } static QString miniexp_to_string(miniexp_t expr, int width=40, bool octal=false) { QByteArray buffer; miniexp_io_t io; miniexp_io_init(&io); io.fputs = qstring_puts; io.data[1] = (void*)&buffer; #ifdef miniexp_io_print7bits static int flags = miniexp_io_print7bits; io.p_flags = (octal) ? &flags : 0; #else static int flags = 1; io.p_print7bits = (octal) ? &flags : 0; #endif miniexp_pprint_r(&io, expr, width); return QString::fromUtf8(buffer.data()); } #endif void QDjView::performCopyOutline() { if (document) { QString s; minivar_t expr = document->getDocumentOutline(); if (miniexp_consp(expr)) s += QString("# This is the existing outline.\n"); else { s += QString("# This is an outline template with all pages.\n"); expr = miniexp_cons(miniexp_symbol("bookmarks"),miniexp_nil); for (int i=0; isetText(s); } } void QDjView::performCopyAnnotation() { int pageNo = widget->page(); if (document && pageNo>=0 && pageNogetPageAnnotations(pageNo); if (expr == miniexp_nil || expr == miniexp_dummy) s += QString("# There were no annotations for page %1.\n"); else s += QString("# These are the annotation for page %1.\n"); s += QString("# Edit this file and store it with command:\n" "# $ djvused foo.djvu -f thisfile -s\n" "# Tip: select an area in djview4 and use 'copy maparea'.\n" "# The following line is the djvused command to set\n" "# the annotation and the rest are the annotations\n" "select %2; set-ant\n\n"); s = s.arg(pageNo+1).arg(pageNo+1); while (miniexp_consp(expr)) { s += miniexp_to_string(miniexp_car(expr)); expr = miniexp_cdr(expr); } // copy to clipboard QApplication::clipboard()->setText(s); } } /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjview.h000066400000000000000000000304371264256014000155750ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEW_H #define QDJVIEW_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "qdjvu.h" #include "qdjvuwidget.h" #include "qdjviewprefs.h" #include "qdjviewdialogs.h" class QAction; class QActionGroup; class QBoxLayout; class QCloseEvent; class QComboBox; class QDockWidget; class QDjViewOutline; class QDjViewThumbnails; class QDjViewFind; class QDragEnterEvent; class QDragMoveEvent; class QDropEvent; class QFileDialog; class QFileSystemWatcher; class QLabel; class QMenu; class QMenuBar; class QShortcut; class QSettings; class QStackedLayout; class QStatusBar; class QStringList; class QTimer; class QTabWidget; class QToolBar; #if DDJVUAPI_VERSION < 18 # error "DDJVUAPI_VERSION>=18 is required !" #endif #if QT_VERSION < 0x40200 # error "QT_VERSION>=0x40200 is required !" #endif class QDjView : public QMainWindow { Q_OBJECT public: enum ViewerMode { EMBEDDED_PLUGIN = 0, FULLPAGE_PLUGIN = 1, STANDALONE = 2, STANDALONE_FULLSCREEN = 3, STANDALONE_SLIDESHOW = 4 }; QDjView(QDjVuContext &context, ViewerMode mode=STANDALONE, QWidget *parent=0); ~QDjView(); QDjVuContext &getDjVuContext() { return djvuContext; } QDjVuWidget *getDjVuWidget() { return widget; } QDjViewErrorDialog *getErrorDialog() { return errorDialog; } QDjVuDocument *getDocument() { return document; } QString getDocumentFileName() { return documentFileName; } QUrl getDocumentUrl() { return documentUrl; } QUrl getDecoratedUrl(); QString getShortFileName(); ViewerMode getViewerMode() { return viewerMode; } QString getArgument(QString key); QStringList parseArgument(QString key, QString val); QStringList parseArgument(QString keyEqualVal); void parseDjVuCgiArguments(QUrl url); static QUrl removeDjVuCgiArguments(QUrl url); int pageNum(void); QString pageName(int pageno, bool titleonly=false); int pageNumber(QString name, int from = -1); QDjView *copyWindow(bool openDocument=true); int visibleSideBarTabs(); int hiddenSideBarTabs(); bool saveTextFile(QString text, QString filename=QString()); bool saveImageFile(QImage image, QString filename=QString()); bool startBrowser(QUrl url); void fillZoomCombo(QComboBox *zoomCombo); void fillModeCombo(QComboBox *modeCombo); void fillPageCombo(QComboBox *pageCombo); public slots: bool open(QString filename); bool open(QUrl url); void open(QDjVuDocument *document, QUrl url = QUrl()); void closeDocument(); void reloadDocument(); void goToPage(int pageno); void goToPage(QString name, int from=-1); void goToPosition(QString pagename, double px, double py); void goToLink(QString link, QString target=QString(), int from=-1); void addToErrorDialog(QString message); void raiseErrorDialog(QMessageBox::Icon icon, QString caption=QString()); int execErrorDialog (QMessageBox::Icon icon, QString caption=QString()); void setPageLabelText(QString s = QString()); void setMouseLabelText(QString s = QString()); void statusMessage(QString s = QString()); bool showSideBar(Qt::DockWidgetAreas areas, int tabs); bool showSideBar(QString args, QStringList &errors); bool showSideBar(bool); void showFind(void); void print(void); void saveAs(void); void exportAs(void); void find(QString find = QString()); void saveSession(QSettings *s); void restoreSession(QSettings *s); bool setViewerMode(ViewerMode); void setSlideShowDelay(int delay); signals: void documentClosed(QDjVuDocument *doc); void documentOpened(QDjVuDocument *doc); void documentReady(QDjVuDocument *doc); void pluginStatusMessage(QString message = QString()); void pluginGetUrl(QUrl url, QString target); void pluginOnChange(); protected: typedef QDjVuWidget::Position Position; typedef QDjVuWidget::PageInfo PageInfo; typedef QDjViewPrefs::Options Options; typedef QDjViewPrefs::Tools Tools; typedef QDjViewPrefs::Saved Saved; void fillToolBar(QToolBar *toolBar); QAction *makeAction(QString text); QAction *makeAction(QString text, Qt::ShortcutContext sc); QAction *makeAction(QString text, bool value); void createActions(void); void createMenus(void); void createWhatsThis(void); Saved *getSavedPrefs(void); Saved *getSavedConfig(ViewerMode mode); void enableContextMenu(bool); void enableScrollBars(bool); void applyOptions(bool remember=true); void updateOptions(void); void applySaved(Saved *saved); void updateSaved(Saved *saved); void applyPreferences(void); void updatePreferences(void); void parseToolBarOption(QString option, QStringList &errors); bool warnAboutPrintingRestrictions(); bool warnAboutSavingRestrictions(); void restoreRecentDocument(QUrl); virtual bool eventFilter(QObject *watched, QEvent *event); virtual void closeEvent(QCloseEvent *event); virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dragMoveEvent(QDragMoveEvent *event); virtual void dropEvent(QDropEvent *event); protected slots: void info(QString); void error(QString, QString, int); void errorCondition(int); void docinfo(); void docinfoExtra(); void performPending(); void performPendingLater(); void pointerPosition(const Position &pos, const PageInfo &page); void pointerEnter(const Position &pos, miniexp_t maparea); void pointerLeave(const Position &pos, miniexp_t maparea); void pointerClick(const Position &pos, miniexp_t maparea); void pointerSelect(const QPoint &pointerPos, const QRect &rect); void updateActions(void); void updateActionsLater(void); void updateTextLabel(void); void modeComboActivated(int); void zoomComboActivated(int); void zoomComboEdited(void); void pageComboActivated(int); void pageComboEdited(void); void preferencesChanged(void); void performAbout(void); void performNew(void); void performOpen(void); void performOpenLocation(void); void performInformation(void); void performMetadata(void); void performPreferences(void); void performRotation(void); void performZoom(void); void performSelect(bool); void performViewFullScreen(bool); void performViewSlideShow(bool); void performEscape(); void performGoPage(); void addRecent(QUrl); void fillRecent(); void openRecent(); void clearRecent(); void performUndo(); void performRedo(); void saveUndoData(); void performCopyUrl(); void performCopyOutline(); void performCopyAnnotation(); void maybeReloadDocument(); void sslWhiteList(QString why, bool &okay); void authRequired(QString why, QString &user, QString &pass); void slideShowTimeout(bool reset=false); protected: // mode ViewerMode viewerMode; // preferences QDjViewPrefs *prefs; Options options; Tools tools; Tools toolsCached; // dialogs QPointer errorDialog; QPointer infoDialog; QPointer metaDialog; QPointer saveDialog; QPointer exportDialog; QPointer printDialog; // widgets QLabel *splash; QDjVuWidget *widget; QStackedLayout *layout; QMenu *contextMenu; QMenu *recentMenu; QMenuBar *menuBar; QStatusBar *statusBar; QLabel *pageLabel; QLabel *mouseLabel; QLabel *textLabel; QToolBar *toolBar; QComboBox *modeCombo; QComboBox *zoomCombo; QComboBox *pageCombo; QDjViewOutline *outlineWidget; QDockWidget *outlineDock; QDjViewThumbnails *thumbnailWidget; QDockWidget *thumbnailDock; QDjViewFind *findWidget; QDockWidget *findDock; // document data QDjVuContext &djvuContext; QDjVuDocument *document; QString documentFileName; QUrl documentUrl; QList documentPages; QDateTime documentModified; bool hasNumericalPageTitle; // delayed settings typedef QPair StringPair; QString pendingPage; QList pendingPosition; QList pendingHilite; QString pendingFind; // delayed updates bool updateActionsScheduled; bool performPendingScheduled; QTimer *textLabelTimer; QRect textLabelRect; // action lists QActionGroup *zoomActionGroup; QActionGroup *modeActionGroup; QActionGroup *rotationActionGroup; // all actions QObjectList allActions; QAction *actionNew; QAction *actionOpen; QAction *actionOpenLocation; QAction *actionClose; QAction *actionQuit; QAction *actionSave; QAction *actionExport; QAction *actionPrint; QAction *actionFind; QAction *actionFindNext; QAction *actionFindPrev; QAction *actionSelect; QAction *actionZoomIn; QAction *actionZoomOut; QAction *actionZoomFitWidth; QAction *actionZoomFitPage; QAction *actionZoomOneToOne; QAction *actionZoom300; QAction *actionZoom200; QAction *actionZoom150; QAction *actionZoom100; QAction *actionZoom75; QAction *actionZoom50; QAction *actionNavFirst; QAction *actionNavNext; QAction *actionNavPrev; QAction *actionNavLast; QAction *actionBack; QAction *actionForw; QAction *actionRotateLeft; QAction *actionRotateRight; QAction *actionRotate0; QAction *actionRotate90; QAction *actionRotate180; QAction *actionRotate270; QAction *actionInformation; QAction *actionMetadata; QAction *actionAbout; QAction *actionWhatsThis; QAction *actionDisplayColor; QAction *actionDisplayBW; QAction *actionDisplayForeground; QAction *actionDisplayBackground; QAction *actionDisplayHiddenText; QAction *actionInvertLuminance; QAction *actionPreferences; QAction *actionViewToolBar; QAction *actionViewSideBar; QAction *actionViewStatusBar; QAction *actionViewFullScreen; QAction *actionViewSlideShow; QAction *actionLayoutContinuous; QAction *actionLayoutSideBySide; QAction *actionLayoutCoverPage; QAction *actionLayoutRightToLeft; QShortcut *shortcutEscape; QShortcut *shortcutGoPage; QAction *actionCopyUrl; QAction *actionCopyOutline; QAction *actionCopyAnnotation; // permission bool printingAllowed; bool savingAllowed; // mode changes Saved fsSavedNormal; Saved fsSavedFullScreen; Saved fsSavedSlideShow; QByteArray savedDockState; QTimer *slideShowTimer; int slideShowDelay; int slideShowCounter; // undo/redo class UndoRedo { public: UndoRedo(); void clear(); void set(QDjView *djview); void apply(QDjView *djview); bool changed(const QDjVuWidget *widget) const; protected: bool valid; QPoint hotSpot; QDjVuWidget::Position position; int rotation; int zoom; }; UndoRedo here; QTimer *undoTimer; QList undoList; QList redoList; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjview.qrc000066400000000000000000000026401264256014000161260ustar00rootroot00000000000000 images/splash.png images/djview.png images/icon_back.png images/icon_close.png images/icon_continuous.png images/icon_djvu.png images/icon_down.png images/icon_empty.png images/icon_erase.png images/icon_export.png images/icon_find.png images/icon_first.png images/icon_forw.png images/icon_fullscreen.png images/icon_last.png images/icon_new.png images/icon_next.png images/icon_open.png images/icon_prefs.png images/icon_prev.png images/icon_print.png images/icon_quit.png images/icon_rotateleft.png images/icon_rotateright.png images/icon_save.png images/icon_select.png images/icon_sidebar.png images/icon_sidebyside.png images/icon_slideshow.png images/icon_up.png images/icon_web.png images/icon_zoomin.png images/icon_zoomout.png images/text_pushpin.png djview4-4.10.5/src/qdjviewauthdialog.ui000066400000000000000000000057171264256014000200300ustar00rootroot00000000000000 QDjViewAuthDialog 0 0 318 157 Dialog Qt::Vertical 20 3 300 0 Password: QLineEdit::Password User: Qt::Vertical 20 3 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() QDjViewAuthDialog accept() 248 254 157 274 buttonBox rejected() QDjViewAuthDialog reject() 316 260 286 274 djview4-4.10.5/src/qdjviewdialogs.cpp000066400000000000000000001543561264256014000175020ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #else # define HAVE_STRING_H 1 # define HAVE_SYS_TYPES_H 1 # define HAVE_STRERROR 1 # ifndef WIN32 # define HAVE_UNISTD_H 1 # endif #endif #include #include #include #include #include #include #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_STRING_H # include #endif #if HAVE_UNISTD_H # include #endif #if HAVE_TIFF # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qdjview.h" #include "qdjviewprefs.h" #include "qdjviewdialogs.h" #include "qdjviewexporters.h" #include "qdjvuwidget.h" #include "qdjvu.h" // ======================================= // QDJVIEWERRORDIALOG // ======================================= #include "ui_qdjviewerrordialog.h" struct QDjViewErrorDialog::Private { Ui::QDjViewErrorDialog ui; QList messages; void compose(); }; QDjViewErrorDialog::~QDjViewErrorDialog() { delete d; } QDjViewErrorDialog::QDjViewErrorDialog(QWidget *parent) : QDialog(parent), d(new Private) { d->ui.setupUi(this); d->ui.textEdit->viewport()->setBackgroundRole(QPalette::Background); setWindowTitle(tr("DjView Error")); } void QDjViewErrorDialog::compose() { QString html; for (int i=0; imessages.size(); i++) html = "
  • " + d->messages[i] + "
  • " + html; d->ui.textEdit->setHtml("
      " + html + "
    "); QScrollBar *scrollBar = d->ui.textEdit->verticalScrollBar(); scrollBar->setValue(scrollBar->maximum()); } void QDjViewErrorDialog::error(QString msg, QString, int) { // Remove [1-nnnnn] prefix from djvulibre-3.5 if (msg.startsWith("[")) msg = msg.replace(QRegExp("^\\[\\d*-?\\d*\\]\\s*") , ""); #if QT_VERSION >= 0x50000 msg = msg.toHtmlEscaped(); #else msg = Qt::escape(msg); #endif // Ignore empty and duplicate messages if (msg.isEmpty()) return; if (!d->messages.isEmpty() && msg == d->messages[0]) return; // Add message d->messages.prepend(msg); while (d->messages.size() >= 16) d->messages.removeLast(); compose(); } void QDjViewErrorDialog::prepare(QMessageBox::Icon icon, QString caption) { if (icon != QMessageBox::NoIcon) d->ui.iconLabel->setPixmap(QMessageBox::standardIcon(icon)); if (caption.isEmpty()) caption = tr("Error - DjView", "dialog caption"); setWindowTitle(caption); } void QDjViewErrorDialog::done(int result) { emit closing(); d->messages.clear(); QDialog::done(result); } // ======================================= // QDJVIEWAUTHDIALOG // ======================================= #include "ui_qdjviewauthdialog.h" struct QDjViewAuthDialog::Private { Ui_QDjViewAuthDialog ui; }; QDjViewAuthDialog::~QDjViewAuthDialog() { delete d; } QDjViewAuthDialog::QDjViewAuthDialog(QWidget *parent) : QDialog(parent), d(new Private) { d->ui.setupUi(this); setWindowTitle(tr("Authentication required - DjView")); } QString QDjViewAuthDialog::user() const { return d->ui.userLineEdit->text(); } QString QDjViewAuthDialog::pass() const { return d->ui.passLineEdit->text(); } void QDjViewAuthDialog::setInfo(QString why) { #if QT_VERSION >= 0x50000 QString ewhy = why.toHtmlEscaped(); #else QString ewhy = Qt::escape(why); #endif QString txt = QString("%1").arg(ewhy); d->ui.whyLabel->setText(txt); } void QDjViewAuthDialog::setUser(QString user) { d->ui.userLineEdit->setText(user); } void QDjViewAuthDialog::setPass(QString pass) { d->ui.passLineEdit->setText(pass); } // ======================================= // QDJVIEWINFODIALOG // ======================================= #include "ui_qdjviewinfodialog.h" struct QDjViewInfoDialog::Private { Ui::QDjViewInfoDialog ui; QDjView *djview; QDjVuDocument *document; QList files; int fileno; int pageno; bool done; }; QDjViewInfoDialog::~QDjViewInfoDialog() { delete d; } QDjViewInfoDialog::QDjViewInfoDialog(QDjView *parent) : QDialog(parent), d(new Private) { d->djview = parent; d->document = 0; d->fileno = 0; d->pageno = -1; d->done = false; d->ui.setupUi(this); QDjViewPrefs *prefs = QDjViewPrefs::instance(); int index = prefs->infoDialogTab; if (index >= 0 && index < d->ui.tabWidget->count()) d->ui.tabWidget->setCurrentIndex(index); QFont font = d->ui.fileText->font(); font.setFixedPitch(true); font.setFamily("monospace"); font.setPointSize((font.pointSize() * 5 + 5) / 6); d->ui.fileText->setFont(font); d->ui.fileText->viewport()->setBackgroundRole(QPalette::Background); QStringList labels; d->ui.docTable->setColumnCount(6); labels << tr("File #") << tr("File Name") << tr("File Size") << tr("File Type") << tr("Page #") << tr("Page Title"); d->ui.docTable->setHorizontalHeaderLabels(labels); d->ui.docTable->verticalHeader()->hide(); d->ui.docTable->horizontalHeader()->setHighlightSections(false); d->ui.docTable->horizontalHeader()->setStretchLastSection(true); connect(d->djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear())); connect(d->djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh())); connect(d->djview->getDjVuWidget(), SIGNAL(pageChanged(int)), this, SLOT(setPage(int))); connect(d->ui.nextButton, SIGNAL(clicked()), this, SLOT(nextFile()) ); connect(d->ui.jumpButton, SIGNAL(clicked()), this, SLOT(jumpToSelectedPage()) ); connect(d->ui.fileCombo, SIGNAL(activated(int)), this, SLOT(setFile(int)) ); connect(d->ui.prevButton, SIGNAL(clicked()), this, SLOT(prevFile()) ); connect(d->ui.docTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(setFile(int)) ); connect(d->ui.docTable, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(jumpToSelectedPage()) ); d->ui.fileCombo->setEnabled(false); d->ui.jumpButton->setEnabled(false); d->ui.prevButton->setEnabled(false); d->ui.nextButton->setEnabled(false); // what's this QWidget *wd = d->ui.tabDocument; wd->setWhatsThis(tr("Document information
    " "This panel shows information about the document and " "its component files. Select a component file " "to display detailled information in the File " "tab. Double click a component file to show " "the corresponding page in the main window. " "")); QWidget *wf = d->ui.tabFile; wf->setWhatsThis(tr("File and page information
    " "This panel shows the structure of the DjVu data " "corresponding to the component file or the page " "selected in the Document tab. " "The arrow buttons jump to the previous or next " "component file.")); } void QDjViewInfoDialog::refresh() { // document known if (! d->document) { QDjVuDocument *doc; doc = d->djview->getDjVuWidget()->document(); if (! doc) return; d->document = doc; connect(doc, SIGNAL(pageinfo()), this, SLOT(refresh()) ); } // document ready if (! d->files.size()) { QDjVuDocument *doc = d->document; if (ddjvu_document_decoding_status(*doc) != DDJVU_JOB_OK) return; int filenum = ddjvu_document_get_filenum(*doc); for (int i=0; ifiles << info; } fillFileCombo(); fillDocLabel(); fillDocTable(); if (d->pageno >= 0) setPage(d->pageno); else if (d->fileno >= 0) setFile(d->fileno); d->ui.fileCombo->setEnabled(true); d->done = false; } // file ready if (! d->done) { QDjVuDocument *doc = d->document; ddjvu_fileinfo_t &info = d->files[d->fileno]; d->done = true; // file dump QString dump = tr("Waiting for data..."); char *s = ddjvu_document_get_filedump(*doc, d->fileno); if (! s) d->done = false; else { dump = QString::fromUtf8(s); free(s); } d->ui.fileText->setPlainText(dump); d->ui.prevButton->setEnabled(d->fileno - 1 >= 0); d->ui.nextButton->setEnabled(d->fileno + 1 < d->files.size()); d->ui.jumpButton->setEnabled(info.type == 'P'); d->ui.fileCombo->setCurrentIndex(d->fileno); QTableWidget *table = d->ui.docTable; int rows = table->rowCount(); int cols = table->columnCount(); QTableWidgetSelectionRange all(0,0,rows-1,cols-1); table->setRangeSelected(all, false); table->selectRow(d->fileno); } } void QDjViewInfoDialog::setPage(int pageno) { if (d->document && d->files.size()) { int i; for (i=0; ifiles.size(); i++) if (d->files[i].pageno == pageno && d->files[i].type == 'P' ) break; if (i < d->files.size()) setFile(i); } else { d->fileno = -1; d->pageno = pageno; } } void QDjViewInfoDialog::setFile(int fileno) { if (d->document && d->files.size()) { if (fileno >= 0 && fileno < d->files.size() && fileno != d->fileno ) { d->fileno = fileno; d->pageno = d->files[fileno].pageno; d->done = false; refresh(); } } else { d->pageno = -1; d->fileno = fileno; } } void QDjViewInfoDialog::prevFile() { if (d->document && d->files.size()) if (d->fileno - 1 >= 0) setFile(d->fileno - 1); } void QDjViewInfoDialog::nextFile() { if (d->document && d->files.size()) if (d->fileno + 1 < d->files.size()) setFile(d->fileno + 1); } void QDjViewInfoDialog::jumpToSelectedPage() { if (d->document && d->files.size()) { ddjvu_fileinfo_t &info = d->files[d->fileno]; if (info.type == 'P') d->djview->goToPage(info.pageno); } } void QDjViewInfoDialog::clear() { hide(); if (d->document) disconnect(d->document, 0, this, 0); d->files.clear(); d->document = 0; QDjViewPrefs *prefs = QDjViewPrefs::instance(); prefs->infoDialogTab = d->ui.tabWidget->currentIndex(); } void QDjViewInfoDialog::fillFileCombo() { QComboBox *fileCombo = d->ui.fileCombo; fileCombo->clear(); for (int fileno=0; filenofiles.size(); fileno++) { ddjvu_fileinfo_t &info = d->files[fileno]; QString msg; if (info.type == 'P') { if (info.title && info.name && strcmp(info.title, info.name)) msg = trUtf8("Page #%1 - \302\253 %2 \302\273") // << .. >> .arg(info.pageno + 1).arg(QString::fromUtf8(info.title)); else msg = tr("Page #%1").arg(info.pageno + 1); } else if (info.type == 'T') msg = tr("Thumbnails"); else if (info.type == 'S') msg = tr("Shared annotations"); else msg = tr("Shared data"); fileCombo->addItem(tr("File #%1 - ").arg(fileno+1) + msg); } } void QDjViewInfoDialog::fillDocLabel() { if (d->document && d->files.size()) { QStringList msg; QDjVuDocument *doc = d->document; ddjvu_document_type_t docType = ddjvu_document_get_type(*doc); if (docType == DDJVU_DOCTYPE_SINGLEPAGE) msg << tr("Single DjVu page"); else { if (docType == DDJVU_DOCTYPE_BUNDLED) msg << tr("Bundled DjVu document"); else if (docType == DDJVU_DOCTYPE_INDIRECT) msg << tr("Indirect DjVu document"); else if (docType == DDJVU_DOCTYPE_OLD_BUNDLED) msg << tr("Obsolete bundled DjVu document"); else if (docType == DDJVU_DOCTYPE_OLD_INDEXED) msg << tr("Obsolete indexed DjVu document"); int pagenum = ddjvu_document_get_pagenum(*doc); int filenum = ddjvu_document_get_filenum(*doc); msg << ((filenum==1) ? tr("1 file") : tr("%n files", 0, filenum)); msg << ((pagenum==1) ? tr("1 page") : tr("%n pages", 0, pagenum)); } d->ui.docLabel->setText(msg.join(" - ")); } } void QDjViewInfoDialog::fillDocTable() { int filenum = d->files.size(); QTableWidget *table = d->ui.docTable; table->setRowCount(filenum); table->setSortingEnabled(false); for (int i=0; iresizeColumnsToContents(); table->resizeRowsToContents(); table->horizontalHeader()->setStretchLastSection(true); } void QDjViewInfoDialog::fillDocRow(int i) { ddjvu_fileinfo_t &info = d->files[i]; QTableWidget *table = d->ui.docTable; QTableWidgetItem *numItem = new QTableWidgetItem(); numItem->setText(QString("%1 ").arg(i+1,5)); numItem->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); numItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 0, numItem); QTableWidgetItem *nameItem = new QTableWidgetItem(); QString name = (info.name) ? QString::fromUtf8(info.name) : tr("n/a"); nameItem->setText(QString(" %1 ").arg(name)); nameItem->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); nameItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 1, nameItem); QTableWidgetItem *sizeItem = new QTableWidgetItem(); sizeItem->setText((info.size>0) ? QString(" %1 ").arg(info.size) : tr("n/a")); sizeItem->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); sizeItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 2, sizeItem); QTableWidgetItem *typeItem = new QTableWidgetItem(); if (info.type == 'P') typeItem->setText(tr(" Page ")); else if (info.type == 'T') typeItem->setText(tr(" Thumbnails ")); else typeItem->setText(tr(" Shared ")); typeItem->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); typeItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 3, typeItem); QTableWidgetItem *pnumItem = new QTableWidgetItem(); if (info.type == 'P') pnumItem->setText(QString(" %1 ").arg(info.pageno+1)); pnumItem->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); pnumItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 4, pnumItem); QTableWidgetItem *titleItem = new QTableWidgetItem(); if (info.type == 'P') { QString title = d->djview->pageName(info.pageno, true); titleItem->setText(QString(" %1 ").arg(title)); } titleItem->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); titleItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(i, 5, titleItem); } // ======================================= // QDJVIEWMETADIALOG // ======================================= #include "ui_qdjviewmetadialog.h" struct QDjViewMetaDialog::Private { Ui::QDjViewMetaDialog ui; QDjView *djview; QDjVuDocument *document; int pageno; minivar_t docAnno; minivar_t pageAnno; }; QDjViewMetaDialog::~QDjViewMetaDialog() { delete d; } QDjViewMetaDialog::QDjViewMetaDialog(QDjView *parent) : QDialog(parent), d(new Private) { d->djview = parent; d->document = 0; d->pageno = 0; d->docAnno = miniexp_dummy; d->pageAnno = miniexp_dummy; d->ui.setupUi(this); // get preferences QDjViewPrefs *prefs = QDjViewPrefs::instance(); int index = prefs->metaDialogTab; if (index >= 0 && index < d->ui.tabWidget->count()) d->ui.tabWidget->setCurrentIndex(index); // make ctrl+c work new QShortcut(QKeySequence(tr("Ctrl+C","copy")), this, SLOT(copy())); // tweaks QStringList labels; labels << tr(" Key ") << tr(" Value "); d->ui.docTable->setColumnCount(2); d->ui.docTable->setHorizontalHeaderLabels(labels); d->ui.docTable->horizontalHeader()->setHighlightSections(false); d->ui.docTable->horizontalHeader()->setStretchLastSection(true); #if QT_VERSION >= 0x50000 d->ui.docTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); #else d->ui.docTable->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); #endif d->ui.docTable->verticalHeader()->hide(); d->ui.pageTable->setColumnCount(2); d->ui.pageTable->setHorizontalHeaderLabels(labels); d->ui.pageTable->horizontalHeader()->setHighlightSections(false); d->ui.pageTable->horizontalHeader()->setStretchLastSection(true); #if QT_VERSION >= 0x50000 d->ui.pageTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); #else d->ui.pageTable->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); #endif d->ui.pageTable->verticalHeader()->hide(); d->ui.pageCombo->setEnabled(false); d->ui.jumpButton->setEnabled(false); d->ui.prevButton->setEnabled(false); d->ui.nextButton->setEnabled(false); // connections connect(d->djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear()) ); connect(d->djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh())); connect(d->djview->getDjVuWidget(), SIGNAL(pageChanged(int)), this, SLOT(setPage(int)) ); connect(d->ui.jumpButton, SIGNAL(clicked()), this, SLOT(jumpToSelectedPage()) ); connect(d->ui.pageCombo, SIGNAL(activated(int)), this, SLOT(setPage(int)) ); connect(d->ui.prevButton, SIGNAL(clicked()), this, SLOT(prevPage()) ); connect(d->ui.nextButton, SIGNAL(clicked()), this, SLOT(nextPage()) ); connect(d->ui.pageCombo, SIGNAL(activated(int)), this, SLOT(setPage(int)) ); // what's this QWidget *wd = d->ui.docTab; wd->setWhatsThis(tr("Document metadata
    " "This panel displays metadata pertaining " "to the document, such as author, title, " "references, etc. " "This information can be saved into the document " "with program djvused: use the commands " "create-shared-ant and set-meta." "")); QWidget *wp = d->ui.pageTab; wp->setWhatsThis(tr("Page metadata
    " "This panel displays metadata pertaining " "to a specific page. " "Page specific metadata override document metadata. " "This information can be saved into the document " "with program djvused: use command " "select to select the page and command " "set-meta to specify the metadata entries." "")); } static QMap metadataFromAnnotations(miniexp_t p) { QMap m; miniexp_t s_metadata = miniexp_symbol("metadata"); while (miniexp_consp(p)) { if (miniexp_caar(p) == s_metadata) { miniexp_t q = miniexp_cdar(p); while (miniexp_consp(q)) { miniexp_t a = miniexp_car(q); q = miniexp_cdr(q); if (miniexp_consp(a) && miniexp_symbolp(miniexp_car(a)) && miniexp_stringp(miniexp_cadr(a)) ) { QString k; k = QString::fromUtf8(miniexp_to_name(miniexp_car(a))); m[k] = QString::fromUtf8(miniexp_to_str(miniexp_cadr(a))); } } } p = miniexp_cdr(p); } return m; } static void metadataSubtract(QMap &from, QMap m) { QMap::const_iterator i = m.constBegin(); for( ; i != m.constEnd(); i++) if (from.contains(i.key()) && from[i.key()] == i.value()) from.remove(i.key()); } static void metadataFill(QTableWidget *table, QMap m) { QList keys; QMap::const_iterator i = m.constBegin(); for( ; i != m.constEnd(); i++) keys << i.key(); qSort(keys.begin(), keys.end()); int nkeys = keys.size(); table->setRowCount(nkeys); table->setSortingEnabled(false); for(int j = 0; j < nkeys; j++) { QTableWidgetItem *kitem = new QTableWidgetItem(keys[j]); QTableWidgetItem *vitem = new QTableWidgetItem(m[keys[j]]); kitem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); vitem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); table->setItem(j, 0, kitem); table->setItem(j, 1, vitem); } table->resizeColumnToContents(0); } void QDjViewMetaDialog::refresh() { // new document? if (! d->document) { QDjVuDocument *doc; doc = d->djview->getDjVuWidget()->document(); if (! doc) return; d->document = doc; connect(doc, SIGNAL(pageinfo()), this, SLOT(refresh()) ); } // document ready if (! d->ui.pageCombo->count()) { if (! d->djview->pageNum()) return; d->djview->fillPageCombo(d->ui.pageCombo); d->ui.pageCombo->setEnabled(true); d->ui.jumpButton->setEnabled(true); } // document annotations known if (d->docAnno == miniexp_dummy) { d->docAnno = d->document->getDocumentAnnotations(); if (d->docAnno != miniexp_dummy) { QMap docMeta = metadataFromAnnotations(d->docAnno); metadataFill(d->ui.docTable, docMeta); } } // page annotations if (d->ui.pageCombo->count() > 0) { d->pageno = qBound(0, d->pageno, d->djview->pageNum()-1); d->ui.prevButton->setEnabled(d->pageno-1 >= 0); d->ui.nextButton->setEnabled(d->pageno+1 < d->djview->pageNum()); d->ui.pageCombo->setCurrentIndex(d->pageno); if (d->document && d->pageAnno == miniexp_dummy) { d->pageAnno = d->document->getPageAnnotations(d->pageno); if (d->pageAnno != miniexp_dummy) { QMap docMeta = metadataFromAnnotations(d->docAnno); QMap pageMeta = metadataFromAnnotations(d->pageAnno); metadataSubtract(pageMeta, docMeta); metadataFill(d->ui.pageTable, pageMeta); } } } } void QDjViewMetaDialog::prevPage() { setPage(qMax(d->pageno - 1, 0)); } void QDjViewMetaDialog::nextPage() { setPage(qMin(d->pageno + 1, d->djview->pageNum() - 1)); } void QDjViewMetaDialog::setPage(int pageno) { if (d->document && pageno != d->pageno) { d->pageno = pageno; d->pageAnno = miniexp_dummy; d->ui.pageTable->setRowCount(0); refresh(); } } void QDjViewMetaDialog::jumpToSelectedPage() { if (d->document && d->pageno >= 0 && d->pageno < d->djview->pageNum() ) d->djview->goToPage(d->pageno); } void QDjViewMetaDialog::clear() { hide(); if (d->document) disconnect(d->document, 0, this, 0); d->document = 0; d->pageno = 0; d->docAnno = miniexp_dummy; d->pageAnno = miniexp_dummy; d->ui.pageCombo->clear(); d->ui.pageCombo->setEnabled(false); d->ui.docTable->setRowCount(0); d->ui.pageTable->setRowCount(0); d->ui.jumpButton->setEnabled(false); QDjViewPrefs *prefs = QDjViewPrefs::instance(); prefs->infoDialogTab = d->ui.tabWidget->currentIndex(); } void QDjViewMetaDialog::copy() { QTableWidget *table = d->ui.pageTable; if (d->ui.tabWidget->currentWidget() == d->ui.docTab) table = d->ui.docTable; QList selected = table->selectedItems(); if (selected.size() == 1) QApplication::clipboard()->setText(selected[0]->text()); } // ======================================= // QDJVIEWSAVEDIALOG // ======================================= #include "ui_qdjviewsavedialog.h" struct QDjViewSaveDialog::Private { QDjView *djview; QDjVuDocument *document; Ui::QDjViewSaveDialog ui; QDjViewExporter *exporter; bool stopping; }; QDjViewSaveDialog::~QDjViewSaveDialog() { delete d; } QDjViewSaveDialog::QDjViewSaveDialog(QDjView *djview) : QDialog(djview), d(0) { d = new QDjViewSaveDialog::Private; d->djview = djview; d->document = 0; d->stopping = false; d->exporter = 0; d->ui.setupUi(this); setAttribute(Qt::WA_GroupLeader, true); connect(d->ui.okButton, SIGNAL(clicked()), this, SLOT(start())); connect(d->ui.stopButton, SIGNAL(clicked()), this, SLOT(stop())); connect(d->ui.browseButton, SIGNAL(clicked()), this, SLOT(browse())); connect(d->ui.formatCombo, SIGNAL(activated(int)), this, SLOT(refresh())); connect(d->ui.fileNameEdit, SIGNAL(textChanged(QString)), this, SLOT(refresh())); connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear())); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh())); setWhatsThis(tr("Saving.
    " "You can save the whole document or a page range. " "The bundled format creates a single file. " "The indirect format creates multiple files " "suitable for web serving.")); refresh(); } void QDjViewSaveDialog::refresh() { bool nodoc = !d->document; if (nodoc && d->djview->pageNum() > 0) { nodoc = false; d->document = d->djview->getDocument(); QString fname = d->djview->getDocumentFileName(); if (fname.isEmpty()) fname = d->djview->getShortFileName(); else fname = QFileInfo(fname).absoluteFilePath(); d->ui.fileNameEdit->setText(fname); d->djview->fillPageCombo(d->ui.fromPageCombo); d->ui.fromPageCombo->setCurrentIndex(0); d->djview->fillPageCombo(d->ui.toPageCombo); d->ui.toPageCombo->setCurrentIndex(d->djview->pageNum()-1); } bool notxt = d->ui.fileNameEdit->text().isEmpty(); bool nojob = true; bool nofmt = true; QDjViewExporter *exporter = d->exporter; QString exporterName = "DJVU/BUNDLED"; if (d->ui.formatCombo->currentIndex() > 0) exporterName = "DJVU/INDIRECT"; if (exporter && exporter->status() <= DDJVU_JOB_STARTED && exporter->name() != exporterName ) { exporter->saveProperties(); delete exporter; exporter = d->exporter = 0; } if (! exporter) { exporter = QDjViewExporter::create(this, d->djview, exporterName); if (exporter) { exporter->loadProperties(); connect(exporter, SIGNAL(progress(int)), this, SLOT(progress(int))); d->exporter = exporter; } } if (exporter) { nofmt = false; if (exporter->status() >= DDJVU_JOB_STARTED) nojob = false; } d->ui.destinationGroupBox->setEnabled(nojob && !nodoc); d->ui.saveGroupBox->setEnabled(nojob && !nodoc && !nofmt); d->ui.formatCombo->setEnabled(nojob && !nodoc && !nofmt); d->ui.okButton->setEnabled(nojob && !nodoc && !notxt && !nofmt); d->ui.cancelButton->setEnabled(nojob); d->ui.stopButton->setEnabled(!nojob); d->ui.stackedWidget->setCurrentIndex(nojob ? 0 : 1); } void QDjViewSaveDialog::clear() { d->stopping = true; reject(); } void QDjViewSaveDialog::start() { QString fname = d->ui.fileNameEdit->text(); QFileInfo info(fname); if (info.exists()) { QString docname = d->djview->getDocumentFileName(); if (info == QFileInfo(docname) && ! docname.isEmpty()) { QMessageBox::critical(this, tr("Error - DjView", "dialog caption"), tr("Overwriting the current file " "is not allowed!" ) ); return; } if ( QMessageBox::question(this, tr("Question - DjView", "dialog caption"), tr("A file with this name already exists.\n" "Do you want to replace it?"), tr("&Replace"), tr("&Cancel") )) return; } QDjViewExporter *exporter = d->exporter; if (exporter) { int lastPage = d->djview->pageNum()-1; int curPage = d->djview->getDjVuWidget()->page(); int fromPage = d->ui.fromPageCombo->currentIndex(); int toPage = d->ui.toPageCombo->currentIndex(); if (d->ui.currentPageButton->isChecked()) exporter->setFromTo(curPage, curPage); else if (d->ui.pageRangeButton->isChecked()) exporter->setFromTo(fromPage, toPage); else exporter->setFromTo(0, lastPage); // ignition! exporter->save(fname); } refresh(); } void QDjViewSaveDialog::progress(int percent) { ddjvu_status_t jobstatus = DDJVU_JOB_NOTSTARTED; QDjViewExporter *exporter = d->exporter; if (exporter) jobstatus = exporter->status(); d->ui.progressBar->setValue(percent); switch(jobstatus) { case DDJVU_JOB_OK: QTimer::singleShot(0, this, SLOT(accept())); break; case DDJVU_JOB_FAILED: exporter->error(tr("This operation has failed."), __FILE__, __LINE__); break; case DDJVU_JOB_STOPPED: exporter->error(tr("This operation has been interrupted."), __FILE__, __LINE__); break; default: break; } } void QDjViewSaveDialog::stop() { QDjViewExporter *exporter = d->exporter; if (exporter && exporter->status() == DDJVU_JOB_STARTED) { exporter->stop(); d->ui.stopButton->setEnabled(false); d->stopping = true; } } void QDjViewSaveDialog::browse() { QString fname = d->ui.fileNameEdit->text(); QStringList info = QDjViewExporter::info("DJVU/BUNDLED"); QString filters = tr("All files", "save filter") + " (*)"; QString suffix; if (info.size() > 3) filters = info[3] + ";;" + filters; if (info.size() > 1) suffix = info[1]; fname = QFileDialog::getSaveFileName(this, tr("Save - DjView", "dialog caption"), fname, filters, 0, QFileDialog::DontConfirmOverwrite); if (! fname.isEmpty()) { QFileInfo finfo(fname); if (finfo.suffix().isEmpty() && !suffix.isEmpty()) fname = QFileInfo(finfo.dir(), finfo.completeBaseName() + "." + suffix).filePath(); d->ui.fileNameEdit->setText(fname); } } void QDjViewSaveDialog::done(int reason) { setEnabled(false); QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status()==DDJVU_JOB_STARTED) { stop(); return; } if (exporter) exporter->saveProperties(); delete exporter; d->exporter = 0; QDialog::done(reason); } void QDjViewSaveDialog::closeEvent(QCloseEvent *event) { QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status()==DDJVU_JOB_STARTED) { stop(); event->ignore(); return; } if (exporter) exporter->saveProperties(); delete exporter; d->exporter = 0; event->accept(); QDialog::closeEvent(event); } // ======================================= // QDJVIEWEXPORTDIALOG // ======================================= #include "ui_qdjviewexportdialog.h" struct QDjViewExportDialog::Private { QDjView *djview; QDjVuDocument *document; Ui::QDjViewExportDialog ui; bool stopping; QDjViewExporter *exporter; QStringList exporterNames; }; QDjViewExportDialog::~QDjViewExportDialog() { delete d; } QDjViewExportDialog::QDjViewExportDialog(QDjView *djview) : QDialog(djview), d(0) { d = new QDjViewExportDialog::Private; d->djview = djview; d->document = 0; d->stopping = false; d->exporter = 0; d->ui.setupUi(this); setAttribute(Qt::WA_GroupLeader, true); connect(d->ui.okButton, SIGNAL(clicked()), this, SLOT(start())); connect(d->ui.stopButton, SIGNAL(clicked()), this, SLOT(stop())); connect(d->ui.browseButton, SIGNAL(clicked()), this, SLOT(browse())); connect(d->ui.formatCombo, SIGNAL(activated(int)), this, SLOT(refresh())); connect(d->ui.resetButton, SIGNAL(clicked()), this, SLOT(reset())); connect(d->ui.fileNameEdit, SIGNAL(textChanged(QString)), this, SLOT(refresh())); connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear())); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh())); setWhatsThis(tr("Saving.
    " "You can save the whole document or a page range " "under a variety of formats. Selecting certain " "formats creates additional dialog pages for " "specifying format options.")); foreach (QString name, QDjViewExporter::names()) if (!name.startsWith("DJVU") && !name.startsWith("PRN")) { QStringList info = QDjViewExporter::info(name); if (info.size() > 2) { d->exporterNames << name; d->ui.formatCombo->addItem(info[2], QVariant(name)); } } d->ui.formatCombo->setCurrentIndex(0); refresh(); } void QDjViewExportDialog::refresh() { bool nodoc = !d->document; if (nodoc && d->djview->pageNum() > 0) { nodoc = false; d->document = d->djview->getDocument(); QString fname = d->djview->getDocumentFileName(); if (fname.isEmpty()) fname = d->djview->getShortFileName(); else fname = QFileInfo(fname).absoluteFilePath(); d->ui.fileNameEdit->setText(fname); d->djview->fillPageCombo(d->ui.fromPageCombo); d->ui.fromPageCombo->setCurrentIndex(0); d->djview->fillPageCombo(d->ui.toPageCombo); d->ui.toPageCombo->setCurrentIndex(d->djview->pageNum()-1); } bool notxt = d->ui.fileNameEdit->text().isEmpty(); bool nojob = true; bool nofmt = true; bool noopt = true; QDjViewExporter *exporter = d->exporter; int formatIndex = d->ui.formatCombo->currentIndex(); QString formatName = d->ui.formatCombo->itemData(formatIndex).toString(); if (exporter && exporter->status() <= DDJVU_JOB_STARTED && exporter->name() != formatName ) { exporter->saveProperties(); delete exporter; exporter = d->exporter = 0; } if (! exporter) { exporter = QDjViewExporter::create(this, d->djview, formatName); if (exporter) { exporter->loadProperties(); connect(exporter, SIGNAL(progress(int)), this, SLOT(progress(int))); d->exporter = exporter; // update tabs while (d->ui.tabWidget->count() > 1) d->ui.tabWidget->removeTab(1); QWidget *w; for (int i=0; ipropertyPages(); i++) if ((w = exporter->propertyPage(i))) d->ui.tabWidget->addTab(w, w->objectName()); // update fname QString fname = d->ui.fileNameEdit->text(); QStringList info = QDjViewExporter::info(formatName); if (info.size() > 1) { QString suffix = info[1]; QFileInfo finfo(fname); if (!finfo.suffix().isEmpty() && !suffix.isEmpty()) fname = QFileInfo(finfo.dir(), finfo.completeBaseName() + "." + suffix).filePath(); d->ui.fileNameEdit->setText(fname); } // update exportgroupbox disconnect(d->ui.fromPageCombo, 0, d->ui.toPageCombo, 0); d->ui.documentButton->setEnabled(true); d->ui.toPageCombo->setEnabled(true); d->ui.toLabel->setEnabled(true); if (exporter->exportOnePageOnly()) { connect(d->ui.fromPageCombo, SIGNAL(activated(int)), d->ui.toPageCombo, SLOT(setCurrentIndex(int))); d->ui.toPageCombo->setEnabled(false); d->ui.toLabel->setEnabled(false); d->ui.documentButton->setEnabled(false); if (d->ui.documentButton->isChecked()) d->ui.currentPageButton->setChecked(true); int page = d->ui.fromPageCombo->currentIndex(); d->ui.toPageCombo->setCurrentIndex(page); } } } if (exporter) { nofmt = false; if (exporter->status() >= DDJVU_JOB_STARTED) nojob = false; if (exporter->propertyPages() > 0) noopt = false; QWidget *w = 0; for (int i=0; ipropertyPages(); i++) if ((w = exporter->propertyPage(i))) w->setEnabled(nojob); } d->ui.destinationGroupBox->setEnabled(nojob && !nodoc); d->ui.saveGroupBox->setEnabled(nojob && !nodoc && !nofmt); d->ui.resetButton->setEnabled(nojob && !nodoc && !noopt); d->ui.okButton->setEnabled(nojob && !nodoc && !notxt && !nofmt); d->ui.cancelButton->setEnabled(nojob); d->ui.stopButton->setEnabled(!nojob); d->ui.stackedWidget->setCurrentIndex(nojob ? 0 : 1); } void QDjViewExportDialog::clear() { d->stopping = true; reject(); } void QDjViewExportDialog::reset() { QDjViewExporter *exporter = d->exporter; if (exporter) exporter->resetProperties(); refresh(); } void QDjViewExportDialog::start() { QString fname = d->ui.fileNameEdit->text(); QFileInfo info(fname); if (info.exists()) { QString docname = d->djview->getDocumentFileName(); if (info == QFileInfo(docname) && ! docname.isEmpty()) { QMessageBox::critical(this, tr("Error - DjView", "dialog caption"), tr("Overwriting the current file " "is not allowed!" ) ); return; } if ( QMessageBox::question(this, tr("Question - DjView", "dialog caption"), tr("A file with this name already exists.\n" "Do you want to replace it?"), tr("&Replace"), tr("&Cancel") )) return; } QDjViewExporter *exporter = d->exporter; if (exporter) { int lastPage = d->djview->pageNum()-1; int curPage = d->djview->getDjVuWidget()->page(); int fromPage = d->ui.fromPageCombo->currentIndex(); int toPage = d->ui.toPageCombo->currentIndex(); if (d->ui.currentPageButton->isChecked()) exporter->setFromTo(curPage, curPage); else if (d->ui.pageRangeButton->isChecked()) exporter->setFromTo(fromPage, toPage); else exporter->setFromTo(0, lastPage); // ignition! exporter->save(fname); } refresh(); } void QDjViewExportDialog::progress(int percent) { QDjViewExporter *exporter = d->exporter; ddjvu_status_t jobstatus = DDJVU_JOB_NOTSTARTED; if (exporter) jobstatus = exporter->status(); d->ui.progressBar->setValue(percent); switch(jobstatus) { case DDJVU_JOB_OK: QTimer::singleShot(0, this, SLOT(accept())); break; case DDJVU_JOB_FAILED: exporter->error(tr("This operation has failed."), __FILE__, __LINE__); break; case DDJVU_JOB_STOPPED: exporter->error(tr("This operation has been interrupted."), __FILE__, __LINE__); break; default: break; } } void QDjViewExportDialog::stop() { QDjViewExporter *exporter = d->exporter; if (exporter && exporter->status() == DDJVU_JOB_STARTED) { exporter->stop(); d->ui.stopButton->setEnabled(false); d->stopping = true; } } void QDjViewExportDialog::browse() { QString fname = d->ui.fileNameEdit->text(); QDjViewExporter *exporter = d->exporter; QString format = (exporter) ? exporter->name() : QString::null; QStringList info = QDjViewExporter::info(format); QString filters = tr("All files", "save filter") + " (*)"; QString suffix; if (info.size() > 3) filters = info[3] + ";;" + filters; if (info.size() > 1) suffix = info[1]; fname = QFileDialog::getSaveFileName(this, tr("Export - DjView", "dialog caption"), fname, filters, 0, QFileDialog::DontConfirmOverwrite); if (! fname.isEmpty()) { QFileInfo finfo(fname); if (finfo.suffix().isEmpty() && !suffix.isEmpty()) fname = QFileInfo(finfo.dir(), finfo.completeBaseName() + "." + suffix).filePath(); d->ui.fileNameEdit->setText(fname); } } void QDjViewExportDialog::done(int reason) { setEnabled(false); QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status()==DDJVU_JOB_STARTED) { stop(); return; } if (exporter) exporter->saveProperties(); delete exporter; d->exporter = 0; QDialog::done(reason); } void QDjViewExportDialog::closeEvent(QCloseEvent *event) { QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status()==DDJVU_JOB_STARTED) { stop(); event->ignore(); return; } if (exporter) exporter->saveProperties(); delete exporter; d->exporter = 0; event->accept(); QDialog::closeEvent(event); } // ======================================= // QDJVIEWPRINTDIALOG // ======================================= #include "ui_qdjviewprintdialog.h" struct QDjViewPrintDialog::Private { QDjView *djview; QDjVuDocument *document; Ui::QDjViewPrintDialog ui; QDjViewExporter *exporter; QString groupname; QPrinter *printer; bool stopping; }; QDjViewPrintDialog::~QDjViewPrintDialog() { if (d && d->printer) delete d->printer; if (d) delete d; } QDjViewPrintDialog::QDjViewPrintDialog(QDjView *djview) : QDialog(djview), d(0) { d = new QDjViewPrintDialog::Private; d->djview = djview; d->document = 0; d->stopping = false; d->exporter = 0; d->printer = new QPrinter(QPrinter::HighResolution); d->ui.setupUi(this); setAttribute(Qt::WA_GroupLeader, true); connect(d->ui.okButton, SIGNAL(clicked()), this, SLOT(start())); connect(d->ui.stopButton, SIGNAL(clicked()), this, SLOT(stop())); connect(d->ui.resetButton, SIGNAL(clicked()), this, SLOT(reset())); connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear())); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh())); connect(d->ui.printToFileCheckBox, SIGNAL(clicked()), this, SLOT(refresh())); connect(d->ui.fileNameEdit, SIGNAL(textChanged(QString)), this, SLOT(refresh())); connect(d->ui.printerButton, SIGNAL(clicked()), this, SLOT(choose())); connect(d->ui.browseButton, SIGNAL(clicked()), this, SLOT(browse())); setWhatsThis(tr("Printing.
    " "You can print the whole document or a page range. " "Use the Choose button to select a print " "destination and specify printer options. Additional " "dialog tabs might appear to specify conversion " "options.")); // Load preferences d->ui.printerLabel->setText(QString::null); d->ui.fileNameEdit->setText("print.ps"); QDjViewPrefs *prefs = QDjViewPrefs::instance(); QString printerName = prefs->printerName; QString printFile = prefs->printFile; if (! printFile.isEmpty()) { d->ui.printToFileCheckBox->setChecked(true); d->ui.fileNameEdit->setText(printFile); printerName = QString::null; } else if (! printerName.isEmpty()) { d->ui.printToFileCheckBox->setChecked(false); d->ui.printerLabel->setText(prefs->printerName); d->printer->setPrinterName(printerName); } else { printFile = "print.ps"; d->ui.printToFileCheckBox->setChecked(true); d->ui.fileNameEdit->setText(printFile); } d->printer->setCollateCopies(prefs->printCollate); if (prefs->printReverse) d->printer->setPageOrder(QPrinter::LastPageFirst); else d->printer->setPageOrder(QPrinter::FirstPageFirst); // Create exporter #ifdef Q_OS_WIN if (! d->exporter) d->exporter = QDjViewExporter::create(this, d->djview, "PRN"); #endif if (! d->exporter) d->exporter = QDjViewExporter::create(this, d->djview, "PS"); if (! d->exporter) d->exporter = QDjViewExporter::create(this, d->djview, "PRN"); if (d->exporter) { QDjViewExporter *exporter = d->exporter; exporter->loadProperties("Print-" + d->exporter->name()); // setup exporter property pages QWidget *w; for (int i=0; ipropertyPages(); i++) if ((w = exporter->propertyPage(i))) d->ui.tabWidget->addTab(w, w->objectName()); // setup exporter connections connect(exporter, SIGNAL(progress(int)), this, SLOT(progress(int))); } // Refresh Ui refresh(); } void QDjViewPrintDialog::refresh() { bool nodoc = !d->document; if (nodoc && d->djview->pageNum() > 0) { nodoc = false; d->document = d->djview->getDocument(); d->djview->fillPageCombo(d->ui.fromPageCombo); d->ui.fromPageCombo->setCurrentIndex(0); d->djview->fillPageCombo(d->ui.toPageCombo); d->ui.toPageCombo->setCurrentIndex(d->djview->pageNum()-1); } bool tofile = d->ui.printToFileCheckBox->isChecked(); bool noexp = !d->exporter; bool nojob = true; bool notxt = true; if (tofile) { notxt = d->ui.fileNameEdit->text().isEmpty(); } else if (d->printer) { QString pName = d->printer->printerName(); notxt = pName.isEmpty(); d->ui.printerLabel->setText(pName); if (notxt) d->ui.printerLabel->setText(tr("(invalid printer)")); } if (d->exporter) { noexp = false; if (d->exporter->status() >= DDJVU_JOB_STARTED) nojob = false; QWidget *w = 0; for (int i=0; iexporter->propertyPages(); i++) if ((w = d->exporter->propertyPage(i))) w->setEnabled(nojob); } d->ui.pageFile->setEnabled(tofile); d->ui.pagePrinter->setEnabled(!tofile); d->ui.destStackedWidget->setCurrentIndex(tofile ? 0 : 1); d->ui.destinationGroupBox->setEnabled(nojob && !noexp); d->ui.printGroupBox->setEnabled(nojob && !nodoc && !noexp); d->ui.resetButton->setEnabled(!noexp && nojob && !nodoc); d->ui.okButton->setEnabled(nojob && !nodoc && !notxt && !noexp); d->ui.cancelButton->setEnabled(nojob); d->ui.stopButton->setEnabled(!nojob); d->ui.stackedWidget->setCurrentIndex(nojob ? 0 : 1); } void QDjViewPrintDialog::browse() { QString fname = d->ui.fileNameEdit->text(); QDjViewExporter *exporter = d->exporter; QString format = (exporter) ? exporter->name() : QString::null; QStringList info = QDjViewExporter::info(format); QString filters = tr("All files", "save filter") + " (*)"; QString suffix; if (info.size() > 3) filters = info[3] + ";;" + filters; if (info.size() > 1) suffix = info[1]; fname = QFileDialog::getSaveFileName(this, tr("Print To File - DjView", "dialog caption"), fname, filters, 0, 0); if (! fname.isEmpty()) { QFileInfo finfo(fname); if (finfo.suffix().isEmpty() && !suffix.isEmpty()) fname = QFileInfo(finfo.dir(), finfo.completeBaseName() + "." + suffix).filePath(); d->ui.fileNameEdit->setText(fname); } } void QDjViewPrintDialog::choose() { if (d->exporter) { d->exporter->savePrintSetup(d->printer); QPrintDialog *dialog = new QPrintDialog(d->printer, this); // options QPrintDialog::PrintDialogOptions options = dialog->enabledOptions(); options |= QPrintDialog::PrintCollateCopies; options &= ~QPrintDialog::PrintToFile; options &= ~QPrintDialog::PrintSelection; dialog->setEnabledOptions(options); // copy page spec int pagenum = d->djview->pageNum(); int curpage = d->djview->getDjVuWidget()->page(); int frompage = d->ui.fromPageCombo->currentIndex(); int topage = d->ui.toPageCombo->currentIndex(); dialog->setMinMax(1, pagenum); dialog->setFromTo(1, pagenum); dialog->setPrintRange(QPrintDialog::PageRange); if (d->ui.currentPageButton->isChecked()) dialog->setFromTo(curpage+1, curpage+1); else if (d->ui.pageRangeButton->isChecked()) dialog->setFromTo(frompage+1, topage+1); else dialog->setPrintRange(QPrintDialog::AllPages); // exec if (dialog->exec() == QDialog::Accepted) { d->exporter->loadPrintSetup(d->printer, dialog); // copy page spec back frompage = qBound(0, dialog->fromPage()-1, pagenum-1); topage = qBound(0, dialog->toPage()-1, pagenum-1); if (dialog->printRange() == QPrintDialog::AllPages) { d->ui.documentButton->setChecked(true); d->ui.fromPageCombo->setCurrentIndex(0); d->ui.toPageCombo->setCurrentIndex(pagenum-1); } else { d->ui.fromPageCombo->setCurrentIndex(frompage); d->ui.toPageCombo->setCurrentIndex(topage); if (frompage == curpage && topage == curpage) d->ui.currentPageButton->setChecked(true); else d->ui.pageRangeButton->setChecked(true); } } delete dialog; } refresh(); } void QDjViewPrintDialog::clear() { d->stopping = true; reject(); } void QDjViewPrintDialog::reset() { QDjViewExporter *exporter = d->exporter; if (exporter) exporter->resetProperties(); refresh(); } void QDjViewPrintDialog::start() { // start conversion QDjViewExporter *exporter = d->exporter; if (exporter) { int lastPage = d->djview->pageNum()-1; int curPage = d->djview->getDjVuWidget()->page(); int fromPage = d->ui.fromPageCombo->currentIndex(); int toPage = d->ui.toPageCombo->currentIndex(); if (d->ui.currentPageButton->isChecked()) exporter->setFromTo(curPage, curPage); else if (d->ui.pageRangeButton->isChecked()) exporter->setFromTo(fromPage, toPage); else exporter->setFromTo(0, lastPage); // ignition! if (d->ui.printToFileCheckBox->isChecked()) { QString fname = d->ui.fileNameEdit->text(); QFileInfo info(fname); if (info.exists() && QMessageBox::question(this, tr("Question - DjView", "dialog caption"), tr("A file with this name already exists.\n" "Do you want to replace it?"), tr("&Replace"), tr("&Cancel") )) return; // save preferences QDjViewPrefs *prefs = QDjViewPrefs::instance(); prefs->printerName = QString::null; prefs->printFile = fname; // print to file exporter->save(fname); } else { QPrinter *printer = d->printer; // save preferences QDjViewPrefs *prefs = QDjViewPrefs::instance(); prefs->printFile = QString::null; prefs->printerName = printer->printerName(); // print exporter->print(d->printer); } } // refresh ui refresh(); } void QDjViewPrintDialog::progress(int percent) { ddjvu_status_t jobstatus = DDJVU_JOB_NOTSTARTED; QDjViewExporter *exporter = d->exporter; if (exporter) jobstatus = exporter->status(); d->ui.progressBar->setValue(percent); switch(jobstatus) { case DDJVU_JOB_OK: QTimer::singleShot(0, this, SLOT(accept())); break; case DDJVU_JOB_FAILED: exporter->error(tr("This operation has failed."), __FILE__, __LINE__); break; case DDJVU_JOB_STOPPED: exporter->error(tr("This operation has been interrupted."), __FILE__, __LINE__); break; default: break; } } void QDjViewPrintDialog::stop() { QDjViewExporter *exporter = d->exporter; if (exporter && exporter->status() == DDJVU_JOB_STARTED) { exporter->stop(); d->ui.stopButton->setEnabled(false); d->stopping = true; } } void QDjViewPrintDialog::done(int reason) { setEnabled(false); QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status()==DDJVU_JOB_STARTED ) { stop(); return; } if (exporter) exporter->saveProperties("Printer-" + exporter->name()); delete exporter; d->exporter = 0; QDialog::done(reason); } void QDjViewPrintDialog::closeEvent(QCloseEvent *event) { QDjViewExporter *exporter = d->exporter; if (!d->stopping && exporter && exporter->status() == DDJVU_JOB_STARTED) { stop(); event->ignore(); return; } if (exporter) exporter->saveProperties("Printer-" + exporter->name()); delete exporter; d->exporter = 0; event->accept(); QDialog::closeEvent(event); } /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewdialogs.h000066400000000000000000000104701264256014000171330ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEWDIALOGS_H #define QDJVIEWDIALOGS_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include class QCloseEvent; class QComboBox; class QDjView; class QDjViewExporter; class QDjVuDocument; class QDjVuJob; class QProgressBar; class QPushButton; class QRadioButton; // ----------- QDJVIEWERRORDIALOG class QDjViewErrorDialog : public QDialog { Q_OBJECT public: ~QDjViewErrorDialog(); QDjViewErrorDialog(QWidget *parent); void prepare(QMessageBox::Icon icon, QString caption); public slots: void error(QString message, QString filename, int lineno); virtual void done(int); signals: void closing(); private: void compose(void); struct Private; Private *d; }; // ----------- QDJVIEWAUTHDIALOG class QDjViewAuthDialog : public QDialog { Q_OBJECT public: ~QDjViewAuthDialog(); QDjViewAuthDialog(QWidget *parent); QString user() const; QString pass() const; public slots: void setInfo(QString why); void setUser(QString user); void setPass(QString pass); private: struct Private; Private *d; }; // ----------- QDJVIEWINFODIALOG class QDjViewInfoDialog : public QDialog { Q_OBJECT public: ~QDjViewInfoDialog(); QDjViewInfoDialog(QDjView *parent); public slots: void clear(); void refresh(); void setPage(int pageno); void setFile(int fileno); protected slots: void prevFile(); void nextFile(); void jumpToSelectedPage(); private: void fillFileCombo(); void fillDocLabel(); void fillDocTable(); void fillDocRow(int); struct Private; Private *d; }; // ----------- QDJVIEWMETADIALOG class QDjViewMetaDialog : public QDialog { Q_OBJECT public: ~QDjViewMetaDialog(); QDjViewMetaDialog(QDjView *parent); public slots: void clear(); void refresh(); void prevPage(); void nextPage(); void setPage(int pageno); protected slots: void jumpToSelectedPage(); void copy(); private: struct Private; Private *d; }; // ----------- QDJVIEWSAVEDIALOG class QDjViewSaveDialog : public QDialog { Q_OBJECT public: QDjViewSaveDialog(QDjView *djview); ~QDjViewSaveDialog(); protected slots: void refresh(); void clear(); void start(); void progress(int); void stop(); void browse(); virtual void done(int); protected: virtual void closeEvent(QCloseEvent *event); struct Private; Private *d; }; // ----------- QDJVIEWEXPORTDIALOG class QDjViewExportDialog : public QDialog { Q_OBJECT public: QDjViewExportDialog(QDjView *djview); ~QDjViewExportDialog(); protected slots: void refresh(); void clear(); void start(); void progress(int); void stop(); void browse(); void reset(); virtual void done(int); protected: virtual void closeEvent(QCloseEvent *event); struct Private; Private *d; }; // ----------- QDJVIEWPRINTDIALOG class QDjViewPrintDialog : public QDialog { Q_OBJECT public: QDjViewPrintDialog(QDjView *djview); ~QDjViewPrintDialog(); protected slots: void refresh(); void clear(); void choose(); void browse(); void start(); void progress(int); void stop(); void reset(); virtual void done(int); protected: virtual void closeEvent(QCloseEvent *event); struct Private; Private *d; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewerrordialog.ui000066400000000000000000000067271264256014000202220ustar00rootroot00000000000000 QDjViewErrorDialog 0 0 662 150 DjView Error 6 9 6 0 Qt::Horizontal QSizePolicy::Fixed 16 20 28 28 Qt::AlignCenter Qt::NoFocus QFrame::NoFrame QFrame::Plain Qt::ScrollBarAsNeeded true 6 0 Qt::Horizontal 40 20 &Ok true Qt::Horizontal 40 20 okButton clicked() QDjViewErrorDialog accept() 280 122 386 115 djview4-4.10.5/src/qdjviewexportdialog.ui000066400000000000000000000230531264256014000204010ustar00rootroot00000000000000 QDjViewExportDialog 0 0 427 335 Dialog 9 6 Export 9 6 Export 9 6 &Document true C&urrent page 0 6 &Pages to Qt::AlignCenter Qt::Horizontal QSizePolicy::MinimumExpanding 40 10 Destination 9 6 0 6 Format: 3 0 1 0 280 0 0 6 :/images/icon_open.png 3 3 0 0 0 9 6 &Defaults false Qt::Horizontal QSizePolicy::MinimumExpanding 150 20 &Ok true true false &Cancel false 9 6 Qt::Horizontal Stop false fromPageCombo activated(int) pageRangeButton click() 158 163 76 158 toPageCombo activated(int) pageRangeButton click() 248 155 44 154 cancelButton clicked() QDjViewExportDialog reject() 375 342 443 367 djview4-4.10.5/src/qdjviewexporters.cpp000066400000000000000000001746331264256014000201130ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #else # define HAVE_STRING_H 1 # define HAVE_SYS_TYPES_H 1 # define HAVE_STRERROR 1 # ifndef WIN32 # define HAVE_SYS_WAIT_H 1 # define HAVE_WAITPID 1 # define HAVE_UNISTD_H 1 # endif #endif #include #include #include #include #include #include #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_WAIT_H # include #endif #if HAVE_STRING_H # include #endif #if HAVE_UNISTD_H # include #endif #if HAVE_TIFF # include # include # include # include "tiff2pdf.h" #endif #ifdef WIN32 # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qdjview.h" #include "qdjviewprefs.h" #include "qdjviewdialogs.h" #include "qdjviewexporters.h" #include "qdjvuwidget.h" #include "qdjvu.h" #ifdef WIN32 # define wdup(fh) _dup(fh) #else # define wdup(fh) (fh) #endif // ---------------------------------------- // FACTORY typedef QDjViewExporter* (*exporter_creator_t)(QDialog*,QDjView*,QString); static QStringList exporterNames; static QMap exporterInfo; static QMap exporterCreators; static void addExporterData(QString name, QString suffix, QString lname, QString filter, exporter_creator_t creator) { QStringList info; info << name << suffix << lname << filter; exporterNames << name; exporterInfo[name] = info; exporterCreators[name] = creator; } static void createExporterData(); QDjViewExporter * QDjViewExporter::create(QDialog *dialog, QDjView *djview, QString name) { if (exporterNames.isEmpty()) createExporterData(); if (exporterCreators.contains(name)) return (*exporterCreators[name])(dialog, djview, name); return 0; } QStringList QDjViewExporter::names() { if (exporterNames.isEmpty()) createExporterData(); return exporterNames; } QStringList QDjViewExporter::info(QString name) { if (exporterNames.isEmpty()) createExporterData(); if (exporterInfo.contains(name)) return exporterInfo[name]; return QStringList(); } // ---------------------------------------- // QDJVIEWEXPORTER QDjViewExporter::~QDjViewExporter() { } bool QDjViewExporter::exportOnePageOnly() { return false; } void QDjViewExporter::resetProperties() { // reset all properties to default values } void QDjViewExporter::loadProperties(QString) { // fill properties from settings keyed by string } void QDjViewExporter::saveProperties(QString) { // save properties into settings keyed by string } bool QDjViewExporter::loadPrintSetup(QPrinter*, QPrintDialog*) { // fill properties using printer and print dialog data return false; } bool QDjViewExporter::savePrintSetup(QPrinter*) { // save properties into printer settings return false; } int QDjViewExporter::propertyPages() { return 0; } QWidget* QDjViewExporter::propertyPage(int) { return 0; } void QDjViewExporter::setFromTo(int fp, int tp) { fromPage = fp; toPage = tp; } void QDjViewExporter::setErrorCaption(QString caption) { errorCaption = caption; } ddjvu_status_t QDjViewExporter::status() { return DDJVU_JOB_NOTSTARTED; } QString QDjViewExporter::name() { return exporterName; } bool QDjViewExporter::print(QPrinter *) { qWarning("QDjViewExporter does not support printing."); return false; } void QDjViewExporter::stop() { } void QDjViewExporter::error(QString message, QString filename, int lineno) { if (! errorDialog) { errorDialog = new QDjViewErrorDialog(parent); errorDialog->prepare(QMessageBox::Critical, errorCaption); connect(errorDialog, SIGNAL(closing()), parent, SLOT(reject())); errorDialog->setWindowModality(Qt::WindowModal); } errorDialog->error(message, filename, lineno); errorDialog->show(); } QDjViewExporter::QDjViewExporter(QDialog *parent, QDjView *djview, QString name) : parent(parent), djview(djview), errorDialog(0), exporterName(name), fromPage(0), toPage(-1) { } // ---------------------------------------- // QDJVIEWDJVUEXPORTER class QDjViewDjVuExporter : public QDjViewExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: ~QDjViewDjVuExporter(); QDjViewDjVuExporter(QDialog *parent, QDjView *djview, QString name, bool indirect); virtual bool save(QString fileName); virtual void stop(); virtual ddjvu_status_t status(); protected: QFile file; QDjVuJob *job; FILE *output; bool indirect; bool failed; }; QDjViewExporter* QDjViewDjVuExporter::create(QDialog *parent, QDjView *djview, QString name) { if (name == "DJVU/BUNDLED") return new QDjViewDjVuExporter(parent, djview, name, false); if (name == "DJVU/INDIRECT") return new QDjViewDjVuExporter(parent, djview, name, true); return 0; } void QDjViewDjVuExporter::setup() { addExporterData("DJVU/BUNDLED", "djvu", tr("DjVu Bundled Document"), tr("DjVu Files (*.djvu *.djv)"), QDjViewDjVuExporter::create); addExporterData("DJVU/INDIRECT", "djvu", tr("DjVu Indirect Document"), tr("DjVu Files (*.djvu *.djv)"), QDjViewDjVuExporter::create); } QDjViewDjVuExporter::QDjViewDjVuExporter(QDialog *parent, QDjView *djview, QString name, bool indirect) : QDjViewExporter(parent, djview, name), job(0), output(0), indirect(indirect), failed(false) { } QDjViewDjVuExporter::~QDjViewDjVuExporter() { QIODevice::OpenMode mode = file.openMode(); ddjvu_status_t st = status(); if (st == DDJVU_JOB_STARTED) if (job) ddjvu_job_stop(*job); if (output) ::fclose(output); output = 0; if (file.openMode()) file.close(); if (st != DDJVU_JOB_OK) if (mode & (QIODevice::WriteOnly|QIODevice::Append)) file.remove(); if (djview) ddjvu_cache_clear(djview->getDjVuContext()); } bool QDjViewDjVuExporter::save(QString fname) { QDjVuDocument *document = djview->getDocument(); int pagenum = djview->pageNum(); if (output || document==0 || pagenum <= 0 || fname.isEmpty()) return false; QFileInfo info(fname); QDir::Filters filters = QDir::AllEntries|QDir::NoDotAndDotDot; if (indirect && !info.dir().entryList(filters).isEmpty() && QMessageBox::question(parent, tr("Question - DjView", "dialog caption"), tr(" This file belongs to a non empty " "directory. Saving an indirect document " "creates many files in this directory. " "Do you want to continue and risk " "overwriting files in this directory?" ""), tr("Con&tinue"), tr("&Cancel") ) ) return false; toPage = qBound(0, toPage, pagenum-1); fromPage = qBound(0, fromPage, pagenum-1); QByteArray pagespec; if (fromPage == toPage && pagenum > 1) pagespec.append(QString("--pages=%1").arg(fromPage+1)); else if (fromPage != 0 || toPage != pagenum - 1) pagespec.append(QString("--pages=%1-%2").arg(fromPage+1).arg(toPage+1)); QByteArray namespec; if (indirect) namespec = "--indirect=" + fname.toUtf8(); int argc = 0; const char *argv[2]; if (! namespec.isEmpty()) argv[argc++] = namespec.data(); if (! pagespec.isEmpty()) argv[argc++] = pagespec.data(); file.setFileName(fname); file.remove(); if (file.open(QIODevice::WriteOnly)) output = ::fdopen(wdup(file.handle()), "wb"); if (! output) { failed = true; QString message = tr("Unknown error."); if (! file.errorString().isEmpty()) message = tr("System error: %1.").arg(file.errorString()); error(message, __FILE__, __LINE__); return false; } ddjvu_job_t *pjob; pjob = ddjvu_document_save(*document, output, argc, argv); if (! pjob) { failed = true; // error messages went to the document connect(document, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int)) ); qApp->sendEvent(&djview->getDjVuContext(), new QEvent(QEvent::User)); disconnect(document, 0, this, 0); // main error message QString message = tr("Save job creation failed!"); error(message, __FILE__, __LINE__); return false; } job = new QDjVuJob(pjob, this); connect(job, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int)) ); connect(job, SIGNAL(progress(int)), this, SIGNAL(progress(int)) ); emit progress(0); return true; } void QDjViewDjVuExporter::stop() { if (job && status() == DDJVU_JOB_STARTED) ddjvu_job_stop(*job); } ddjvu_status_t QDjViewDjVuExporter::status() { if (job) return ddjvu_job_status(*job); else if (failed) return DDJVU_JOB_FAILED; else return DDJVU_JOB_NOTSTARTED; } // ---------------------------------------- // QDJVIEWPSEXPORTER #include "ui_qdjviewexportps1.h" #include "ui_qdjviewexportps2.h" #include "ui_qdjviewexportps3.h" class QDjViewPSExporter : public QDjViewExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: ~QDjViewPSExporter(); QDjViewPSExporter(QDialog *parent, QDjView *djview, QString name, bool eps); virtual bool exportOnePageOnly(); virtual void resetProperties(); virtual void loadProperties(QString group); virtual void saveProperties(QString group); virtual bool loadPrintSetup(QPrinter *printer, QPrintDialog *dialog); virtual bool savePrintSetup(QPrinter *printer); virtual int propertyPages(); virtual QWidget* propertyPage(int num); virtual bool save(QString fileName); virtual bool print(QPrinter *printer); virtual ddjvu_status_t status(); virtual void stop(); public slots: void refresh(); protected: bool start(); void openFile(); void closeFile(); protected: QFile file; QDjVuJob *job; FILE *output; int outputfd; int copies; bool collate; bool lastfirst; bool duplex; bool failed; bool encapsulated; QPrinter *printer; QPointer page1; QPointer page2; QPointer page3; Ui::QDjViewExportPS1 ui1; Ui::QDjViewExportPS2 ui2; Ui::QDjViewExportPS3 ui3; }; QDjViewExporter* QDjViewPSExporter::create(QDialog *parent, QDjView *djview, QString name) { if (name == "PS") return new QDjViewPSExporter(parent, djview, name, false); if (name == "EPS") return new QDjViewPSExporter(parent, djview, name, true); return 0; } void QDjViewPSExporter::setup() { addExporterData("PS", "ps", tr("PostScript"), tr("PostScript Files (*.ps *.eps)"), QDjViewPSExporter::create); addExporterData("EPS", "eps", tr("Encapsulated PostScript"), tr("PostScript Files (*.ps *.eps)"), QDjViewPSExporter::create); } QDjViewPSExporter::~QDjViewPSExporter() { // cleanup output QIODevice::OpenMode mode = file.openMode(); ddjvu_status_t st = status(); if (st == DDJVU_JOB_STARTED) if (job) ddjvu_job_stop(*job); closeFile(); if (st != DDJVU_JOB_OK) if (mode & (QIODevice::WriteOnly|QIODevice::Append)) file.remove(); // delete property pages delete page1; delete page2; delete page3; } QDjViewPSExporter::QDjViewPSExporter(QDialog *parent, QDjView *djview, QString name, bool eps) : QDjViewExporter(parent, djview, name), job(0), output(0), outputfd(-1), copies(1), collate(true), lastfirst(false), duplex(false), failed(false), encapsulated(eps), printer(0) { // create pages page1 = new QWidget(); page2 = new QWidget(); page3 = new QWidget(); ui1.setupUi(page1); ui2.setupUi(page2); ui3.setupUi(page3); page1->setObjectName(tr("PostScript","tab caption")); page2->setObjectName(tr("Position","tab caption")); page3->setObjectName(tr("Booklet","tab caption")); resetProperties(); // connect stuff connect(ui2.autoOrientCheckBox, SIGNAL(clicked()), this, SLOT(refresh()) ); connect(ui3.bookletCheckBox, SIGNAL(clicked()), this, SLOT(refresh()) ); connect(ui2.zoomSpinBox, SIGNAL(valueChanged(int)), ui2.zoomButton, SLOT(click()) ); // whatsthis page1->setWhatsThis(tr("PostScript options.
    " "Option Color enables color printing. " "Document pages can be decorated with frame " "and crop marks. " "PostScript language level 1 is only useful " "with very old printers. Level 2 works with most " "printers. Level 3 print color document faster " "on recent printers.") ); page2->setWhatsThis(tr("Position and scaling.
    " "Option Scale to fit accommodates " "whatever paper size your printer uses. " "Zoom factor 100% reproduces the initial " "document size. Orientation Automatic " "chooses portrait or landscape on a page per " "page basis.") ); page3->setWhatsThis(tr("Producing booklets.
    " "The booklet mode prints the selected " "pages as sheets suitable for folding one or several " "booklets. Several booklets might be produced when " "a maximum number of sheets per booklet is " "specified. You can either use a duplex printer or " "print rectos and versos separately.

    " "Shifting rectos and versos is useful " "with poorly aligned duplex printers. " "The center margins determine how much " "space is left between the pages to fold the " "sheets. This space slowly increases from the " "inner sheet to the outer sheet." "") ); // adjust ui refresh(); } bool QDjViewPSExporter::exportOnePageOnly() { return encapsulated; } void QDjViewPSExporter::resetProperties() { ui1.colorButton->setChecked(true); ui1.frameCheckBox->setChecked(false); ui1.cropMarksCheckBox->setChecked(false); ui1.levelSpinBox->setValue(3); ui2.autoOrientCheckBox->setChecked(true); ui2.scaleToFitButton->setChecked(true); ui2.zoomSpinBox->setValue(100); ui3.bookletCheckBox->setChecked(false); ui3.sheetsSpinBox->setValue(0); ui3.rectoVersoCombo->setCurrentIndex(0); ui3.rectoVersoShiftSpinBox->setValue(0); ui3.centerMarginSpinBox->setValue(18); ui3.centerIncreaseSpinBox->setValue(40); refresh(); } void QDjViewPSExporter::loadProperties(QString group) { // load settings (ui1) QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); bool color = s.value("color", true).toBool(); ui1.colorButton->setChecked(color); ui1.grayScaleButton->setChecked(!color); ui1.frameCheckBox->setChecked(s.value("frame", false).toBool()); ui1.cropMarksCheckBox->setChecked(s.value("cropMarks", false).toBool()); int level = s.value("psLevel", 3).toInt(); ui1.levelSpinBox->setValue(qBound(1,level,3)); // load settings (ui2) ui2.autoOrientCheckBox->setChecked(s.value("autoOrient", true).toBool()); bool landscape = s.value("landscape",false).toBool(); ui2.portraitButton->setChecked(!landscape); ui2.landscapeButton->setChecked(landscape); int zoom = s.value("zoom",0).toInt(); ui2.scaleToFitButton->setChecked(zoom == 0); ui2.zoomButton->setChecked(zoom!=0); ui2.zoomSpinBox->setValue(zoom ? qBound(25,zoom,2400) : 100); // load settings (ui3) ui3.bookletCheckBox->setChecked(s.value("booklet", false).toBool()); ui3.sheetsSpinBox->setValue(s.value("bookletSheets", 0).toInt()); int rectoVerso = qBound(0, s.value("bookletRectoVerso",0).toInt(), 2); ui3.rectoVersoCombo->setCurrentIndex(rectoVerso); int rectoVersoShift = qBound(-72, s.value("bookletShift",0).toInt(), 72); ui3.rectoVersoShiftSpinBox->setValue(rectoVersoShift); int centerMargin = qBound(0, s.value("bookletCenter", 18).toInt(), 144); ui3.centerMarginSpinBox->setValue(centerMargin); int centerIncrease = qBound(0, s.value("bookletCenterAdd", 40).toInt(), 200); ui3.centerIncreaseSpinBox->setValue(centerIncrease); } void QDjViewPSExporter::saveProperties(QString group) { // save properties QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); s.setValue("color", ui1.colorButton->isChecked()); s.setValue("frame", ui1.frameCheckBox->isChecked()); s.setValue("cropMarks", ui1.cropMarksCheckBox->isChecked()); s.setValue("psLevel", ui1.levelSpinBox->value()); s.setValue("autoOrient", ui2.autoOrientCheckBox->isChecked()); s.setValue("landscape", ui2.landscapeButton->isChecked()); int zoom = ui2.zoomSpinBox->value(); s.setValue("zoom", QVariant(ui2.zoomButton->isChecked() ? zoom : 0)); s.setValue("booklet", ui3.bookletCheckBox->isChecked()); s.setValue("bookletSheets", ui3.sheetsSpinBox->value()); s.setValue("bookletRectoVerso", ui3.rectoVersoCombo->currentIndex()); s.setValue("bookletShift", ui3.rectoVersoShiftSpinBox->value()); s.setValue("bookletCenter", ui3.centerMarginSpinBox->value()); s.setValue("bookletCenterAdd", ui3.centerIncreaseSpinBox->value()); } bool QDjViewPSExporter::loadPrintSetup(QPrinter *printer, QPrintDialog *dialog) { bool grayscale = (printer->colorMode() == QPrinter::GrayScale); bool landscape = (printer->orientation() == QPrinter::Landscape); ui1.grayScaleButton->setChecked(grayscale); ui1.colorButton->setChecked(!grayscale); ui2.landscapeButton->setChecked(landscape); ui2.portraitButton->setChecked(!landscape); // BEGIN HACK // // Directly steal settings from print dialog. copies = 1; collate = true; lastfirst = false; #if QT_VERSION >= 0x50000 QSpinBox* lcop = dialog->findChild("copies"); QCheckBox* lcol = dialog->findChild("collate"); QCheckBox* lplf = dialog->findChild("reverse"); #elif QT_VERSION >= 0x40400 QSpinBox* lcop = qFindChild(dialog, "copies"); QCheckBox* lcol = qFindChild(dialog, "collate"); QCheckBox* lplf = qFindChild(dialog, "reverse"); #else QSpinBox* lcop = qFindChild(dialog, "sbNumCopies"); QCheckBox* lcol = qFindChild(dialog, "chbCollate"); QCheckBox* lplf = qFindChild(dialog, "chbPrintLastFirst"); #endif if (lcop) copies = qMax(1, lcop->value()); if (lcol) collate = lcol->isChecked(); if (lplf) lastfirst = lplf->isChecked(); // END HACK // return true; } bool QDjViewPSExporter::savePrintSetup(QPrinter *printer) { bool g = ui1.grayScaleButton->isChecked(); bool l = ui2.landscapeButton->isChecked(); printer->setColorMode(g ? QPrinter::GrayScale : QPrinter::Color); printer->setOrientation(l ? QPrinter::Landscape : QPrinter::Portrait); return true; } int QDjViewPSExporter::propertyPages() { return (encapsulated) ? 1 : 3; } QWidget* QDjViewPSExporter::propertyPage(int n) { if (n == 0) return page1; else if (n == 1) return page2; else if (n == 2) return page3; return 0; } void QDjViewPSExporter::refresh() { if (encapsulated) { ui1.cropMarksCheckBox->setEnabled(false); ui1.cropMarksCheckBox->setChecked(false); } bool autoOrient = ui2.autoOrientCheckBox->isChecked(); ui2.portraitButton->setEnabled(!autoOrient); ui2.landscapeButton->setEnabled(!autoOrient); bool booklet = ui3.bookletCheckBox->isChecked(); ui3.bookletGroupBox->setEnabled(booklet); bool nojob = (status() < DDJVU_JOB_STARTED); page1->setEnabled(nojob); page2->setEnabled(nojob && !encapsulated); page3->setEnabled(nojob && !encapsulated); } void QDjViewPSExporter::openFile() { if (printer) { file.close(); if (! printer->outputFileName().isEmpty()) file.setFileName(printer->outputFileName()); } if (! file.fileName().isEmpty()) { file.remove(); if (file.open(QIODevice::WriteOnly)) output = ::fdopen(wdup(file.handle()), "wb"); } else if (printer) { QString printerName = printer->printerName(); // disable sigpipe #ifdef SIGPIPE # ifndef HAVE_SIGACTION # ifdef SA_RESTART # define HAVE_SIGACTION 1 # endif # endif # if HAVE_SIGACTION sigset_t mask; struct sigaction act; sigemptyset(&mask); sigaddset(&mask, SIGPIPE); sigprocmask(SIG_BLOCK, &mask, 0); sigaction(SIGPIPE, 0, &act); act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, 0); # else signal(SIGPIPE, SIG_IGN); # endif #endif // Arguments for lp/lpr QVector lpargs; QVector lprargs; lpargs << "lp"; lprargs << "lpr"; QByteArray pname = printerName.toLocal8Bit(); if (! pname.isEmpty()) { lpargs << "-d"; lpargs << pname.data(); lprargs << "-P"; lprargs << pname.data(); } // Arguments for cups. bool cups = false; QList cargs; QPrintEngine *engine = printer->printEngine(); # define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00) # define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03) QVariant cPageSize = engine->property(PPK_CupsStringPageSize); QVariant cOptions = engine->property(PPK_CupsOptions); if (! cPageSize.toString().isEmpty()) { cups = true; cargs << "-o" << "media=" + cPageSize.toString().toLocal8Bit(); } QStringList options = cOptions.toStringList(); if (! options.isEmpty()) { cups = true; QStringList::const_iterator it = options.constBegin(); while (it != options.constEnd()) { cargs << "-o"; cargs << (*it).toLocal8Bit() + "=" + (*(it+1)).toLocal8Bit(); it += 2; } } QByteArray bCopies = QByteArray::number(copies); if (cups) { if (collate) cargs << "-o" << "Collate=True"; if (lastfirst) cargs << "-o" << "outputorder=reverse"; lastfirst = false; if (duplex) cargs << "-o" << "sides=two-sided-long-edge"; // add cups option for number of copies if (copies > 1) { lprargs << "-#" << bCopies.data(); lpargs << "-n" << bCopies.data(); } // add remaining cups options for(int i=0; i= 0 && fork() == 0) { // try lp and lpr (void)execvp("lpr", (char**)lprargs.data()); (void)execv("/bin/lpr", (char**)lprargs.data()); (void)execv("/usr/bin/lpr", (char**)lprargs.data()); (void)execvp("lp", (char**)lpargs.data()); (void)execv("/bin/lp", (char**)lpargs.data()); (void)execv("/usr/bin/lp", (char**)lpargs.data()); } // exit without running destructors (void)execlp("true", "true", (char *)0); (void)execl("/bin/true", "true", (char *)0); (void)execl("/usr/bin/true", "true", (char *)0); ::_exit(0); ::exit(0); } ::close(fds[0]); outputfd = fds[1]; output = fdopen(outputfd, "wb"); if (pid >= 0) { # if HAVE_WAITPID ::waitpid(pid, 0, 0); # else ::wait(0); # endif } else closeFile(); } #endif } } void QDjViewPSExporter::closeFile() { if (output) ::fclose(output); if (outputfd >= 0) ::close(outputfd); if (file.openMode()) file.close(); output = 0; outputfd = -1; printer = 0; } bool QDjViewPSExporter::save(QString fname) { if (output) return false; printer = 0; file.close(); file.setFileName(fname); return start(); } bool QDjViewPSExporter::print(QPrinter *qprinter) { if (output) return false; printer = qprinter; file.close(); file.setFileName(QString::null); QDjViewPrefs *prefs = QDjViewPrefs::instance(); prefs->printReverse = lastfirst; prefs->printCollate = collate; return start(); } bool QDjViewPSExporter::start() { QDjViewPrefs *prefs = QDjViewPrefs::instance(); QDjVuDocument *document = djview->getDocument(); int pagenum = djview->pageNum(); if (document==0 || pagenum <= 0) return false; int tpg = qBound(0, toPage, pagenum-1); int fpg = qBound(0, fromPage, pagenum-1); openFile(); if (! output) return false; // prepare arguments QList args; if (copies > 1) args << QString("--copies=%1").arg(copies).toLocal8Bit(); if (fromPage == toPage && pagenum > 1) args << QString("--pages=%1").arg(fpg+1).toLocal8Bit(); else if (fromPage != 0 || toPage != pagenum - 1) args << QString("--pages=%1-%2").arg(fpg+1).arg(tpg+1).toLocal8Bit(); if (! ui2.autoOrientCheckBox->isChecked()) { if (ui2.portraitButton->isChecked()) args << QByteArray("--orientation=portrait"); else if (ui2.landscapeButton->isChecked()) args << QByteArray("--orientation=landscape"); } if (ui2.zoomButton->isChecked()) args << QString("--zoom=%1").arg(ui2.zoomSpinBox->value()).toLocal8Bit(); if (ui1.frameCheckBox->isChecked()) args << QByteArray("--frame=yes"); if (ui1.cropMarksCheckBox->isChecked()) args << QByteArray("--cropmarks=yes"); if (ui1.levelSpinBox) args << QString("--level=%1").arg(ui1.levelSpinBox->value()).toLocal8Bit(); if (ui1.grayScaleButton->isChecked()) args << QByteArray("--color=no"); if (prefs && prefs->printerGamma != 0.0) { double gamma = qBound(0.3, prefs->printerGamma, 5.0); args << QByteArray("--colormatch=no"); args << QString("--gamma=%1").arg(gamma).toLocal8Bit(); } if (ui3.bookletCheckBox->isChecked()) { int bMode = ui3.rectoVersoCombo->currentIndex(); if (bMode == 1) args << QByteArray("--booklet=recto"); else if (bMode == 2) args << QByteArray("--booklet=verso"); else args << QByteArray("--booklet=yes"); int bMax = ui3.sheetsSpinBox->value(); if (bMax > 0) args << QString("--bookletmax=%1").arg(bMax).toLocal8Bit(); int bAlign = ui3.rectoVersoShiftSpinBox->value(); args << QString("--bookletalign=%1").arg(bAlign).toLocal8Bit(); int bCenter = ui3.centerMarginSpinBox->value(); int bIncr = ui3.centerIncreaseSpinBox->value() * 10; args << QString("--bookletfold=%1+%2") .arg(bCenter).arg(bIncr).toLocal8Bit(); } if (encapsulated) args << QByteArray("--format=eps"); QDjVuWidget::DisplayMode displayMode; displayMode = djview->getDjVuWidget()->displayMode(); if (displayMode == QDjVuWidget::DISPLAY_STENCIL) args << QByteArray("--mode=black"); else if (displayMode == QDjVuWidget::DISPLAY_BG) args << QByteArray("--mode=background"); else if (displayMode == QDjVuWidget::DISPLAY_FG) args << QByteArray("--mode=foreground"); // convert arguments int argc = args.count(); QVector argv(argc); for (int i=0; isendEvent(&djview->getDjVuContext(), new QEvent(QEvent::User)); disconnect(document, 0, this, 0); // main error message QString message = tr("Save job creation failed!"); error(message, __FILE__, __LINE__); return false; } job = new QDjVuJob(pjob, this); connect(job, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int)) ); connect(job, SIGNAL(progress(int)), this, SIGNAL(progress(int)) ); emit progress(0); refresh(); return true; } void QDjViewPSExporter::stop() { if (job && status() == DDJVU_JOB_STARTED) ddjvu_job_stop(*job); } ddjvu_status_t QDjViewPSExporter::status() { if (job) return ddjvu_job_status(*job); else if (failed) return DDJVU_JOB_FAILED; else return DDJVU_JOB_NOTSTARTED; } // ---------------------------------------- // QDJVIEWPAGEEXPORTER class QDjViewPageExporter : public QDjViewExporter { Q_OBJECT public: ~QDjViewPageExporter(); QDjViewPageExporter(QDialog *parent, QDjView *djview, QString name); virtual ddjvu_status_t status() { return curStatus; } public slots: virtual bool start(); virtual void stop(); virtual void error(QString message, QString filename, int lineno); protected slots: void checkPage(); protected: virtual void openFile() {} virtual void closeFile() {} virtual void doFinal() {} virtual void doPage() = 0; ddjvu_status_t curStatus; QDjVuPage *curPage; int curProgress; }; QDjViewPageExporter::~QDjViewPageExporter() { curStatus = DDJVU_JOB_NOTSTARTED; closeFile(); } QDjViewPageExporter::QDjViewPageExporter(QDialog *parent, QDjView *djview, QString name) : QDjViewExporter(parent, djview, name), curStatus(DDJVU_JOB_NOTSTARTED), curPage(0), curProgress(0) { } bool QDjViewPageExporter::start() { if (curStatus != DDJVU_JOB_STARTED) { curStatus = DDJVU_JOB_STARTED; openFile(); checkPage(); } if (curStatus <= DDJVU_JOB_OK) return true; return false; } void QDjViewPageExporter::stop() { if (curStatus == DDJVU_JOB_STARTED) curStatus = DDJVU_JOB_STOPPED; if (curPage) if (ddjvu_page_decoding_status(*curPage) == DDJVU_JOB_STARTED) ddjvu_job_stop(ddjvu_page_job(*curPage)); emit progress(curProgress); } void QDjViewPageExporter::error(QString message, QString filename, int lineno) { if (curStatus == DDJVU_JOB_STARTED) curStatus = DDJVU_JOB_FAILED; QDjViewExporter::error(message, filename, lineno); } void QDjViewPageExporter::checkPage() { QDjVuDocument *document = djview->getDocument(); int pagenum = djview->pageNum(); if (document==0 || pagenum <= 0) return; ddjvu_status_t pageStatus = DDJVU_JOB_NOTSTARTED; if (curPage) pageStatus = ddjvu_page_decoding_status(*curPage); if (pageStatus > DDJVU_JOB_OK) { curStatus = pageStatus; emit progress(curProgress); disconnect(curPage, 0, this, 0); delete curPage; curPage = 0; closeFile(); return; } int tpg = qBound(0, toPage, pagenum-1); int fpg = qBound(0, fromPage, pagenum-1); int nextPage = fpg; if (pageStatus == DDJVU_JOB_OK) { nextPage = curPage->pageNo() + 1; doPage(); curProgress = 100 * (nextPage - fpg) / (1 + tpg - fpg); disconnect(curPage, 0, this, 0); delete curPage; curPage = 0; if (curStatus < DDJVU_JOB_OK && nextPage > tpg) { curStatus = DDJVU_JOB_OK; doFinal(); } emit progress(curProgress); if (curStatus >= DDJVU_JOB_OK) closeFile(); } if (curStatus == DDJVU_JOB_STARTED && !curPage) { curPage = new QDjVuPage(document, nextPage, this); connect(curPage, SIGNAL(pageinfo()), this, SLOT(checkPage())); connect(curPage, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int)) ); if (ddjvu_page_decoding_done(*curPage)) QTimer::singleShot(0, this, SLOT(checkPage())); } } // ---------------------------------------- // QDJVIEWTIFFEXPORTER #include "ui_qdjviewexporttiff.h" class QDjViewTiffExporter : public QDjViewPageExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: ~QDjViewTiffExporter(); QDjViewTiffExporter(QDialog *parent, QDjView *djview, QString name); virtual void resetProperties(); virtual void loadProperties(QString group); virtual void saveProperties(QString group); virtual int propertyPages(); virtual QWidget* propertyPage(int num); virtual bool save(QString fileName); protected: virtual void closeFile(); virtual void doPage(); protected: void checkTiffSupport(); Ui::QDjViewExportTiff ui; QPointer page; QFile file; #if HAVE_TIFF TIFF *tiff; #else FILE *tiff; #endif }; QDjViewExporter* QDjViewTiffExporter::create(QDialog *parent, QDjView *djview, QString name) { if (name == "TIFF") return new QDjViewTiffExporter(parent, djview, name); return 0; } void QDjViewTiffExporter::setup() { addExporterData("TIFF", "tiff", tr("TIFF Document"), tr("TIFF Files (*.tiff *.tif)"), QDjViewTiffExporter::create); } QDjViewTiffExporter::~QDjViewTiffExporter() { closeFile(); delete page; } QDjViewTiffExporter::QDjViewTiffExporter(QDialog *parent, QDjView *djview, QString name) : QDjViewPageExporter(parent, djview, name), tiff(0) { page = new QWidget(); ui.setupUi(page); page->setObjectName(tr("TIFF Options", "tab caption")); resetProperties(); page->setWhatsThis(tr("TIFF options.
    " "The resolution box specifies an upper " "limit for the resolution of the TIFF images. " "Forcing bitonal G4 compression " "encodes all pages in black and white " "using the CCITT Group 4 compression. " "Allowing JPEG compression uses lossy JPEG " "for all non bitonal or subsampled images. " "Otherwise, allowing deflate compression " "produces more compact (but less portable) files " "than the default packbits compression." "") ); } void QDjViewTiffExporter::checkTiffSupport() { #ifdef CCITT_SUPPORT ui.bitonalCheckBox->setEnabled(true); #else ui.bitonalCheckBox->setEnabled(false); #endif #ifdef JPEG_SUPPORT ui.jpegCheckBox->setEnabled(true); ui.jpegSpinBox->setEnabled(true); #else ui.jpegCheckBox->setEnabled(false); ui.jpegSpinBox->setEnabled(false); #endif #ifdef ZIP_SUPPORT ui.deflateCheckBox->setEnabled(true); #else ui.deflateCheckBox->setEnabled(false); #endif } void QDjViewTiffExporter::resetProperties() { ui.dpiSpinBox->setValue(600); ui.bitonalCheckBox->setChecked(false); ui.jpegCheckBox->setChecked(true); ui.jpegSpinBox->setValue(75); ui.deflateCheckBox->setChecked(true); checkTiffSupport(); } void QDjViewTiffExporter::loadProperties(QString group) { QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); ui.dpiSpinBox->setValue(s.value("dpi", 600).toInt()); ui.bitonalCheckBox->setChecked(s.value("bitonal", false).toBool()); ui.jpegCheckBox->setChecked(s.value("jpeg", true).toBool()); ui.jpegSpinBox->setValue(s.value("jpegQuality", 75).toInt()); ui.deflateCheckBox->setChecked(s.value("deflate", true).toBool()); checkTiffSupport(); } void QDjViewTiffExporter::saveProperties(QString group) { QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); s.setValue("dpi", ui.dpiSpinBox->value()); s.setValue("bitonal", ui.bitonalCheckBox->isChecked()); s.setValue("jpeg", ui.jpegCheckBox->isChecked()); s.setValue("jpegQuality", ui.jpegSpinBox->value()); s.setValue("deflate", ui.deflateCheckBox->isChecked()); } int QDjViewTiffExporter::propertyPages() { return 1; } QWidget* QDjViewTiffExporter::propertyPage(int num) { if (num == 0) return page; return 0; } #if HAVE_TIFF static QDjViewTiffExporter *tiffExporter; static void tiffHandler(const char *, const char *fmt, va_list ap) { QString message; message.vsprintf(fmt, ap); tiffExporter->error(message, __FILE__, __LINE__); } #endif void QDjViewTiffExporter::closeFile() { #if HAVE_TIFF tiffExporter = this; TIFFSetErrorHandler(tiffHandler); TIFFSetWarningHandler(0); if (tiff) TIFFClose(tiff); #endif tiff = 0; QIODevice::OpenMode mode = file.openMode(); file.close(); if (curStatus > DDJVU_JOB_OK) if (mode & (QIODevice::WriteOnly|QIODevice::Append)) file.remove(); } bool QDjViewTiffExporter::save(QString fname) { if (file.openMode()) return false; file.setFileName(fname); return start(); } void QDjViewTiffExporter::doPage() { ddjvu_format_t *fmt = 0; char *image = 0; QString message; #if HAVE_TIFF tiffExporter = this; TIFFSetErrorHandler(tiffHandler); TIFFSetWarningHandler(0); QDjVuPage *page = curPage; // open file or write directory if (tiff) TIFFWriteDirectory(tiff); else if (file.open(QIODevice::ReadWrite)) tiff = TIFFFdOpen(wdup(file.handle()), file.fileName().toLocal8Bit().data(),"w"); if (!tiff) message = tr("Cannot open output file."); else { // determine rectangle ddjvu_rect_t rect; int imgdpi = ddjvu_page_get_resolution(*page); int dpi = qMin(imgdpi, ui.dpiSpinBox->value()); rect.x = rect.y = 0; rect.w = ( ddjvu_page_get_width(*page) * dpi + imgdpi/2 ) / imgdpi; rect.h = ( ddjvu_page_get_height(*page) * dpi + imgdpi/2 ) / imgdpi; // determine mode ddjvu_render_mode_t mode = DDJVU_RENDER_COLOR; QDjVuWidget::DisplayMode displayMode; displayMode = djview->getDjVuWidget()->displayMode(); if (ui.bitonalCheckBox->isChecked()) mode = DDJVU_RENDER_BLACK; else if (displayMode == QDjVuWidget::DISPLAY_STENCIL) mode = DDJVU_RENDER_BLACK; else if (displayMode == QDjVuWidget::DISPLAY_BG) mode = DDJVU_RENDER_BACKGROUND; else if (displayMode == QDjVuWidget::DISPLAY_FG) mode = DDJVU_RENDER_FOREGROUND; // determine format and compression ddjvu_page_type_t type = ddjvu_page_get_type(*page); ddjvu_format_style_t style = DDJVU_FORMAT_RGB24; int compression = COMPRESSION_NONE; if (ui.bitonalCheckBox->isChecked()) style = DDJVU_FORMAT_MSBTOLSB; else if (mode==DDJVU_RENDER_BLACK || type==DDJVU_PAGETYPE_BITONAL) style = (dpi == imgdpi) ? DDJVU_FORMAT_MSBTOLSB : DDJVU_FORMAT_GREY8; #ifdef CCITT_SUPPORT if (style == DDJVU_FORMAT_MSBTOLSB && TIFFFindCODEC(COMPRESSION_CCITT_T6)) compression = COMPRESSION_CCITT_T6; #endif #ifdef JPEG_SUPPORT else if (ui.jpegCheckBox->isChecked() && style != DDJVU_FORMAT_MSBTOLSB && TIFFFindCODEC(COMPRESSION_JPEG)) compression = COMPRESSION_JPEG; #endif #ifdef ZIP_SUPPORT else if (ui.deflateCheckBox->isChecked() && style != DDJVU_FORMAT_MSBTOLSB && TIFFFindCODEC(COMPRESSION_DEFLATE)) compression = COMPRESSION_DEFLATE; #endif #ifdef PACKBITS_SUPPORT else if (TIFFFindCODEC(COMPRESSION_PACKBITS)) compression = COMPRESSION_PACKBITS; #endif fmt = ddjvu_format_create(style, 0, 0); ddjvu_format_set_row_order(fmt, 1); ddjvu_format_set_gamma(fmt, 2.2); // set parameters int quality = ui.jpegSpinBox->value(); TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, (uint32)rect.w); TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, (uint32)rect.h); TIFFSetField(tiff, TIFFTAG_XRESOLUTION, (float)(dpi)); TIFFSetField(tiff, TIFFTAG_YRESOLUTION, (float)(dpi)); TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); #ifdef CCITT_SUPPORT if (compression != COMPRESSION_CCITT_T6) #endif #ifdef JPEG_SUPPORT if (compression != COMPRESSION_JPEG) #endif #ifdef ZIP_SUPPORT if (compression != COMPRESSION_DEFLATE) #endif TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, (uint32)64); if (style == DDJVU_FORMAT_MSBTOLSB) { TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, (uint16)1); TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16)1); TIFFSetField(tiff, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression); TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); } else { TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, (uint16)8); TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression); #ifdef JPEG_SUPPORT if (compression == COMPRESSION_JPEG) TIFFSetField(tiff, TIFFTAG_JPEGQUALITY, quality); #endif if (style == DDJVU_FORMAT_GREY8) { TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16)1); TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); } else { TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16)3); TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression); #ifdef JPEG_SUPPORT if (compression == COMPRESSION_JPEG) { TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); TIFFSetField(tiff, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); } else #endif TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); } } // render and save char white = (char)0xff; int rowsize = rect.w * 3; if (style == DDJVU_FORMAT_MSBTOLSB) { white = 0x00; rowsize = (rect.w + 7) / 8; } else if (style == DDJVU_FORMAT_GREY8) rowsize = rect.w; if (! (image = (char*)malloc(rowsize * rect.h))) message = tr("Out of memory."); else if (rowsize != TIFFScanlineSize(tiff)) message = tr("Internal error."); else { char *s = image; ddjvu_rect_t *r = ▭ if (! ddjvu_page_render(*page, mode, r, r, fmt, rowsize, image)) memset(image, white, rowsize * rect.h); for (int i=0; i<(int)rect.h; i++, s+=rowsize) TIFFWriteScanline(tiff, s, i, 0); } } #else message = tr("TIFF export has not been compiled."); #endif if (! message.isEmpty()) error(message, __FILE__, __LINE__); if (fmt) ddjvu_format_release(fmt); if (image) free(image); } // ---------------------------------------- // QDJVIEWPDFEXPORTER class QDjViewPdfExporter : public QDjViewTiffExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: QDjViewPdfExporter(QDialog *parent, QDjView *djview, QString name); virtual bool save(QString fileName); protected: virtual void doFinal(); protected: QTemporaryFile tempFile; QFile pdfFile; }; QDjViewExporter* QDjViewPdfExporter::create(QDialog *parent, QDjView *djview, QString name) { if (name == "PDF") return new QDjViewPdfExporter(parent, djview, name); return 0; } void QDjViewPdfExporter::setup() { addExporterData("PDF", "pdf", tr("PDF Document"), tr("PDF Files (*.pdf)"), QDjViewPdfExporter::create); } QDjViewPdfExporter::QDjViewPdfExporter(QDialog *parent, QDjView *djview, QString name) : QDjViewTiffExporter(parent, djview, name) { page->setObjectName(tr("PDF Options", "tab caption")); page->setWhatsThis(tr("PDF options.
    " "These options control the characteristics of " "the images embedded in the exported PDF files. " "The resolution box limits their maximal resolution. " "Forcing bitonal G4 compression " "encodes all pages in black and white " "using the CCITT Group 4 compression. " "Allowing JPEG compression uses lossy JPEG " "for all non bitonal or subsampled images. " "Otherwise, allowing deflate compression " "produces more compact files. " "") ); } void QDjViewPdfExporter::doFinal() { QString message; // close tiff #if HAVE_TIFF2PDF tiffExporter = this; TIFFSetErrorHandler(tiffHandler); TIFFSetWarningHandler(0); if (tiff) TIFFClose(tiff); tiff = 0; // open files TIFF *input = 0; FILE *output = 0; QByteArray inameArray = file.fileName().toLocal8Bit(); QByteArray onameArray = pdfFile.fileName().toLocal8Bit(); file.close(); if (file.open(QIODevice::ReadOnly)) input = TIFFFdOpen(wdup(file.handle()), inameArray.data(), "r"); if (pdfFile.open(QIODevice::WriteOnly)) output = ::fdopen(wdup(pdfFile.handle()),"wb"); if (input && output) { const char *argv[3]; argv[0] = "tiff2pdf"; argv[1] = "-o"; argv[2] = onameArray.data(); if (tiff2pdf(input, output, 3, argv) != EXIT_SUCCESS) message = tr("Error while creating pdf file."); } else if (! output) { message = tr("Unable to create output file."); if (! pdfFile.errorString().isEmpty()) message = tr("System error: %1.").arg(pdfFile.errorString()); } else message = tr("Unable to reopen temporary file."); // close all if (input) TIFFClose(input); if (output) fclose(output); if (file.openMode()) file.close(); if (pdfFile.openMode()) pdfFile.close(); if (tempFile.openMode()) tempFile.close(); if (tempFile.exists()) tempFile.remove(); #else message = tr("PDF export was not compiled."); #endif if (!message.isEmpty()) { curStatus = DDJVU_JOB_FAILED; error(message, __FILE__, __LINE__); } } bool QDjViewPdfExporter::save(QString fname) { if (file.openMode() || tempFile.openMode() || pdfFile.openMode()) return false; pdfFile.setFileName(fname); tempFile.setFileTemplate(fname); if (tempFile.open()) { file.setFileName(tempFile.fileName()); tempFile.close(); return start(); } // prepare error message QString message = tr("Unable to create temporary file."); if (! tempFile.errorString().isEmpty()) message = tr("System error: %1.").arg(tempFile.errorString()); error(message, __FILE__, __LINE__); return false; } // ---------------------------------------- // QDJVIEWIMGEXPORTER class QDjViewImgExporter : public QDjViewPageExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: QDjViewImgExporter(QDialog *parent, QDjView *djview, QString name, QByteArray format); virtual bool exportOnePageOnly(); virtual bool save(QString fname); protected: virtual void doPage(); QString fileName; QByteArray format; }; QDjViewExporter* QDjViewImgExporter::create(QDialog *parent, QDjView *djview, QString name) { QByteArray format = name.toLocal8Bit(); QList formats = QImageWriter::supportedImageFormats(); if (formats.contains(format)) return new QDjViewImgExporter(parent, djview, name, format); return 0; } void QDjViewImgExporter::setup() { QByteArray format; QList formats = QImageWriter::supportedImageFormats(); foreach(format, formats) { QString name = QString::fromLocal8Bit(format); QString uname = name.toUpper(); QString suffix = name.toLower(); addExporterData(name, suffix, tr("%1 Image", "JPG Image").arg(uname), tr("%1 Files (*.%2)", "JPG Files").arg(uname).arg(suffix), QDjViewImgExporter::create); } } QDjViewImgExporter::QDjViewImgExporter(QDialog *parent, QDjView *djview, QString name, QByteArray format) : QDjViewPageExporter(parent, djview, name), format(format) { } bool QDjViewImgExporter::exportOnePageOnly() { return true; } bool QDjViewImgExporter::save(QString fname) { fileName = fname; return start(); } void QDjViewImgExporter::doPage() { QDjVuPage *page = curPage; // determine rectangle ddjvu_rect_t rect; int imgdpi = ddjvu_page_get_resolution(*page); int dpi = imgdpi; // (TODO: add property page with resolution!) rect.x = rect.y = 0; rect.w = ( ddjvu_page_get_width(*page) * dpi + imgdpi/2 ) / imgdpi; rect.h = ( ddjvu_page_get_height(*page) * dpi + imgdpi/2 ) / imgdpi; // prepare format ddjvu_format_t *fmt = 0; #if DDJVUAPI_VERSION < 18 unsigned int masks[3] = { 0xff0000, 0xff00, 0xff }; fmt = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 3, masks); #else unsigned int masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; fmt = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 4, masks); #endif ddjvu_format_set_row_order(fmt, true); ddjvu_format_set_gamma(fmt, 2.2); // determine mode (TODO: add property page with mode!) ddjvu_render_mode_t mode = DDJVU_RENDER_COLOR; QDjVuWidget::DisplayMode displayMode; displayMode = djview->getDjVuWidget()->displayMode(); if (displayMode == QDjVuWidget::DISPLAY_STENCIL) mode = DDJVU_RENDER_BLACK; else if (displayMode == QDjVuWidget::DISPLAY_BG) mode = DDJVU_RENDER_BACKGROUND; else if (displayMode == QDjVuWidget::DISPLAY_FG) mode = DDJVU_RENDER_FOREGROUND; // compute image QString message; QImage img(rect.w, rect.h, QImage::Format_RGB32); if (! ddjvu_page_render(*page, mode, &rect, &rect, fmt, img.bytesPerLine(), (char*)img.bits() )) message = tr("Cannot render page."); else { QFile file(fileName); QImageWriter writer(&file, format); if (! writer.write(img)) { message = file.errorString(); file.remove(); if (writer.error() == QImageWriter::UnsupportedFormatError) message = tr("Image format %1 not supported.") .arg(QString::fromLocal8Bit(format).toUpper()); #if HAVE_STRERROR if (file.error() == QFile::OpenError && errno > 0) message = strerror(errno); #endif } } if (! message.isEmpty()) error(message, __FILE__, __LINE__); if (fmt) ddjvu_format_release(fmt); } // ---------------------------------------- // QDJVIEWPRNEXPORTER #include "ui_qdjviewexportprn.h" class QDjViewPrnExporter : public QDjViewPageExporter { Q_OBJECT public: static QDjViewExporter *create(QDialog*, QDjView*, QString); static void setup(); public: ~QDjViewPrnExporter(); QDjViewPrnExporter(QDialog *parent, QDjView *djview, QString name); virtual void resetProperties(); virtual void loadProperties(QString group); virtual void saveProperties(QString group); virtual bool loadPrintSetup(QPrinter *printer, QPrintDialog *dialog); virtual bool savePrintSetup(QPrinter *printer); virtual int propertyPages(); virtual QWidget* propertyPage(int num); virtual bool save(QString fileName); virtual bool print(QPrinter *printer); protected: virtual void closeFile(); virtual void doPage(); protected: Ui::QDjViewExportPrn ui; QPointer page; QPrinter *printer; QPainter *painter; QString fileName; }; QDjViewExporter* QDjViewPrnExporter::create(QDialog *parent, QDjView *djview, QString name) { if (name == "PRN") return new QDjViewPrnExporter(parent, djview, name); return 0; } void QDjViewPrnExporter::setup() { addExporterData("PRN", "prn", tr("Printer data"), tr("PRN Files (*.prn)"), QDjViewPrnExporter::create); } QDjViewPrnExporter::~QDjViewPrnExporter() { closeFile(); delete page; } QDjViewPrnExporter::QDjViewPrnExporter(QDialog *parent, QDjView *djview, QString name) : QDjViewPageExporter(parent, djview, name), printer(0), painter(0) { page = new QWidget(); ui.setupUi(page); page->setObjectName(tr("Printing Options", "tab caption")); resetProperties(); page->setWhatsThis(tr("Printing options.
    " "Option Color enables color printing. " "Document pages can be decorated with a frame. " "Option Scale to fit accommodates " "whatever paper size your printer uses. " "Zoom factor 100% reproduces the initial " "document size. Orientation Automatic " "chooses portrait or landscape on a page per " "page basis.") ); } void QDjViewPrnExporter::resetProperties() { ui.colorButton->setChecked(true); ui.frameCheckBox->setChecked(false); ui.cropMarksCheckBox->setChecked(false); ui.autoOrientCheckBox->setChecked(true); ui.scaleToFitButton->setChecked(true); ui.zoomSpinBox->setValue(100); } void QDjViewPrnExporter::loadProperties(QString group) { QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); bool color = s.value("color", true).toBool(); ui.colorButton->setChecked(color); ui.grayScaleButton->setChecked(!color); ui.frameCheckBox->setChecked(s.value("frame", false).toBool()); ui.cropMarksCheckBox->setChecked(false); ui.autoOrientCheckBox->setChecked(s.value("autoOrient", true).toBool()); bool landscape = s.value("landscape",false).toBool(); ui.portraitButton->setChecked(!landscape); ui.landscapeButton->setChecked(landscape); int zoom = s.value("zoom",0).toInt(); ui.scaleToFitButton->setChecked(zoom == 0); ui.zoomButton->setChecked(zoom!=0); ui.zoomSpinBox->setValue(zoom ? qBound(25,zoom,2400) : 100); } void QDjViewPrnExporter::saveProperties(QString group) { QSettings s; if (group.isEmpty()) group = "Export-" + name(); s.beginGroup(group); s.setValue("color", ui.colorButton->isChecked()); s.setValue("frame", ui.frameCheckBox->isChecked()); s.setValue("autoOrient", ui.autoOrientCheckBox->isChecked()); s.setValue("landscape", ui.landscapeButton->isChecked()); int zoom = ui.zoomSpinBox->value(); s.setValue("zoom", QVariant(ui.zoomButton->isChecked() ? zoom : 0)); } bool QDjViewPrnExporter::loadPrintSetup(QPrinter *printer, QPrintDialog *) { bool grayscale = (printer->colorMode() == QPrinter::GrayScale); bool landscape = (printer->orientation() == QPrinter::Landscape); ui.grayScaleButton->setChecked(grayscale); ui.colorButton->setChecked(!grayscale); ui.landscapeButton->setChecked(landscape); ui.portraitButton->setChecked(!landscape); return true; } bool QDjViewPrnExporter::savePrintSetup(QPrinter *printer) { bool grayscale = ui.grayScaleButton->isChecked(); bool landscape = ui.landscapeButton->isChecked(); printer->setColorMode(grayscale ? QPrinter::GrayScale : QPrinter::Color); printer->setOrientation(landscape ? QPrinter::Landscape : QPrinter::Portrait); return true; } int QDjViewPrnExporter::propertyPages() { return 1; } QWidget* QDjViewPrnExporter::propertyPage(int num) { if (num == 0) return page; return 0; } bool QDjViewPrnExporter::save(QString fileName) { closeFile(); this->fileName = fileName; printer = new QPrinter(QPrinter::HighResolution); printer->setOutputFileName(fileName); #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) printer->setOutputFormat(QPrinter::PdfFormat); #endif return start(); } bool QDjViewPrnExporter::print(QPrinter *printer) { closeFile(); this->printer = printer; return start(); } void QDjViewPrnExporter::closeFile() { if (painter) delete painter; painter = 0; if (printer && !fileName.isEmpty()) delete printer; printer = 0; if (curStatus > DDJVU_JOB_OK && !fileName.isEmpty()) ::remove(QFile::encodeName(fileName).data()); fileName = QString(); } void QDjViewPrnExporter::doPage() { QDjVuPage *page = curPage; // determine zoom factor and rectangles ddjvu_rect_t rect; rect.x = rect.y = 0; rect.w = ddjvu_page_get_width(*page); rect.h = ddjvu_page_get_height(*page); QRect pageRect = printer->pageRect(); bool landscape = false; int prndpi = printer->resolution(); int imgdpi = ddjvu_page_get_resolution(*page); if (ui.autoOrientCheckBox->isChecked()) landscape = (rect.w > rect.h) ^ (pageRect.width() > pageRect.height()); else if (ui.landscapeButton->isChecked()) landscape = true; int printW = (landscape) ? pageRect.height() : pageRect.width(); int printH = (landscape) ? pageRect.width() : pageRect.height(); int targetW = (rect.w * prndpi + imgdpi/2 ) / imgdpi; int targetH = (rect.h * prndpi + imgdpi/2 ) / imgdpi; int zoom = 100; if (ui.zoomButton->isChecked()) zoom = qBound(25, ui.zoomSpinBox->value(), 2400); else if (ui.scaleToFitButton->isChecked()) zoom = qMin( printW * 100 / targetW, printH * 100 / targetH); targetW = targetW * zoom / 100; targetH = targetH * zoom / 100; int dpi = qMin(prndpi * zoom / 100, imgdpi); rect.w = ( rect.w * dpi + imgdpi/2 ) / imgdpi; rect.h = ( rect.h * dpi + imgdpi/2 ) / imgdpi; // create image QImage::Format imageFormat = QImage::Format_RGB32; if (ddjvu_page_get_type(*page) == DDJVU_PAGETYPE_BITONAL && dpi >= imgdpi) imageFormat = QImage::Format_Mono; else if (ui.grayScaleButton->isChecked()) imageFormat = QImage::Format_Indexed8; QImage img(rect.w, rect.h, imageFormat); // render bool rendered = false; ddjvu_format_t *fmt = 0; ddjvu_render_mode_t mode = DDJVU_RENDER_COLOR; QDjViewPrefs *prefs = QDjViewPrefs::instance(); if (imageFormat == QImage::Format_RGB32) { #if DDJVUAPI_VERSION < 18 unsigned int masks[3] = { 0xff0000, 0xff00, 0xff }; fmt = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 3, masks); #else unsigned int masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; fmt = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 4, masks); #endif if (prefs->printerGamma > 0) ddjvu_format_set_gamma(fmt, prefs->printerGamma); ddjvu_format_set_row_order(fmt, true); if (ddjvu_page_render(*page, mode, &rect, &rect, fmt, img.bytesPerLine(), (char*)img.bits() )) rendered = true; } else if (imageFormat == QImage::Format_Indexed8) { #if QT_VERSION >= 0x40600 img.setColorCount(256); #else img.setNumColors(256); #endif for (int i=0; i<256; i++) img.setColor(i, qRgb(i,i,i)); fmt = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, 0); if (prefs->printerGamma > 0) ddjvu_format_set_gamma(fmt, prefs->printerGamma); ddjvu_format_set_row_order(fmt, true); if (ddjvu_page_render(*page, mode, &rect, &rect, fmt, img.bytesPerLine(), (char*)img.bits() )) rendered = true; } else if (imageFormat == QImage::Format_Mono) { fmt = ddjvu_format_create(DDJVU_FORMAT_MSBTOLSB, 0, 0); ddjvu_format_set_row_order(fmt, true); if (ddjvu_page_render(*page, mode, &rect, &rect, fmt, img.bytesPerLine(), (char*)img.bits() )) rendered = true; if (rendered) img.invertPixels(); } // prepare painter if (! painter) painter = new QPainter(printer); else printer->newPage(); // prepare settings painter->save(); if (landscape) { painter->translate(QPoint(pageRect.width(),0)); painter->rotate(90); } painter->translate(qMax(0, (printW-targetW)/2), qMax(0, (printH-targetH)/2)); // print page QRect sourceRect(0,0,rect.w,rect.h); QRect targetRect(0,0,targetW,targetH); if (rendered) painter->drawImage(targetRect, img, sourceRect); QPen pen(Qt::black, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); painter->setPen(pen); painter->setBrush(Qt::NoBrush); if (ui.frameCheckBox->isChecked()) painter->drawRect(targetRect); // finish painter->restore(); if (! rendered) { QString pageName = djview->pageName(curPage->pageNo()); error(tr("Cannot render page %1.").arg(pageName), __FILE__, __LINE__); } if (fmt) ddjvu_format_release(fmt); fmt = 0; } // ---------------------------------------- // CREATEEXPORTERDATA static void createExporterData() { QDjViewDjVuExporter::setup(); #if HAVE_TIFF2PDF QDjViewPdfExporter::setup(); #endif #if HAVE_TIFF QDjViewTiffExporter::setup(); #endif QDjViewPSExporter::setup(); QDjViewImgExporter::setup(); QDjViewPrnExporter::setup(); } // ---------------------------------------- // MOC #include "qdjviewexporters.moc" /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewexporters.h000066400000000000000000000052101264256014000175400ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEWEXPORTERS_H #define QDJVIEWEXPORTERS_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include class QPrinter; class QPrintDialog; #include #include #include "qdjview.h" #include "qdjviewdialogs.h" // ----------- QDJVIEWEXPORTER class QDjViewExporter : public QObject { Q_OBJECT public: virtual ~QDjViewExporter(); virtual bool exportOnePageOnly(); virtual void setFromTo(int fromPage, int toPage); virtual void setErrorCaption(QString); virtual void resetProperties(); virtual void loadProperties(QString group=QString::null); virtual void saveProperties(QString group=QString::null); virtual bool loadPrintSetup(QPrinter *printer, QPrintDialog *dialog); virtual bool savePrintSetup(QPrinter *printer); virtual int propertyPages(); virtual QWidget* propertyPage(int num); virtual ddjvu_status_t status(); virtual QString name(); public slots: virtual bool save(QString fileName) = 0; virtual bool print(QPrinter *printer); virtual void stop(); virtual void error(QString, QString, int); signals: void progress(int i); protected: friend class QDjViewExporterFactory; QDjViewExporter(QDialog *parent, QDjView *djview, QString name); QDialog *parent; QDjView *djview; QDjViewErrorDialog *errorDialog; QString errorCaption; QString exporterName; int fromPage; int toPage; public: static QDjViewExporter *create(QDialog*, QDjView*, QString name); static QStringList names(); static QStringList info(QString name); }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewexportprn.ui000066400000000000000000000141121264256014000177350ustar00rootroot00000000000000 QDjViewExportPrn 0 0 350 255 Form Color 6 &Color true &GrayScale Marks 6 Print image &frame false Print crop &marks Scaling Scale to &fit the page true 6 &Zoom false % 25 2400 25 100 Orientation 6 Automatic true false &Portrait false &Landscape zoomButton toggled(bool) zoomSpinBox setEnabled(bool) 60 204 128 212 autoOrientCheckBox toggled(bool) portraitButton setDisabled(bool) 298 162 309 195 autoOrientCheckBox toggled(bool) landscapeButton setDisabled(bool) 255 155 264 222 djview4-4.10.5/src/qdjviewexportps1.ui000066400000000000000000000077301264256014000176510ustar00rootroot00000000000000 QDjViewExportPS1 0 0 323 202 Form 9 6 0 6 Color 9 6 &Color true &GrayScale Marks 9 6 Print image &frame Print crop &marks PostScript 9 6 Language Level 3 1 2 Qt::Horizontal 5 5 Qt::Vertical 1 1 djview4-4.10.5/src/qdjviewexportps2.ui000066400000000000000000000100471264256014000176450ustar00rootroot00000000000000 QDjViewExportPS2 0 0 344 157 Form 9 6 0 6 Scaling 9 6 Scale to &fit the page true 0 6 &Zoom % 2400 25 25 100 Orientation 9 6 Automatic true &Portrait &Landscape Qt::Vertical 20 0 djview4-4.10.5/src/qdjviewexportps3.ui000066400000000000000000000155501264256014000176520ustar00rootroot00000000000000 QDjViewExportPS3 0 0 417 230 Form 9 6 Print sheets suitable for folding a booklet. Advanced 9 6 0 6 Sheets per booklet: Unlimited at most 1000 Qt::Horizontal 5 5 0 6 Print 160 10 rectos and versos. rectos only. versos only. Qt::Horizontal 5 5 0 6 Shift rectos and versos by points. 72 -72 Qt::Horizontal 5 5 0 6 Center: points 144 18 plus /100 200 10 40 per page. Qt::Vertical 20 0 djview4-4.10.5/src/qdjviewexporttiff.ui000066400000000000000000000125221264256014000200710ustar00rootroot00000000000000 QDjViewExportTiff 0 0 355 248 Form 9 6 Resolution 9 6 Maximum image resolution dpi 9600 50 600 Qt::Horizontal 5 5 Compression 9 6 Force &bitonal G4 compression. Allow &lossy JPEG compression. true 0 6 Qt::Horizontal QSizePolicy::Fixed 40 5 JPEG &quality jpegSpinBox 100 50 75 Qt::Horizontal 5 5 Allow &deflate compression. true Qt::Vertical 305 16 bitonalCheckBox jpegCheckBox jpegSpinBox jpegCheckBox toggled(bool) jpegSpinBox setEnabled(bool) 94 80 194 115 djview4-4.10.5/src/qdjviewinfodialog.ui000066400000000000000000000151001264256014000200050ustar00rootroot00000000000000 QDjViewInfoDialog 0 0 600 320 Dialog 9 6 &Document 9 6 5 5 0 0 0 30 QFrame::Box QFrame::Raised Qt::PlainText Qt::AlignCenter Qt::ScrollBarAlwaysOff QAbstractItemView::NoEditTriggers QAbstractItemView::SelectRows true &File 9 6 0 6 File: :/images/icon_prev.png 1 0 1 0 :/images/icon_next.png Qt::Horizontal 40 20 &View Page QFrame::Box QFrame::Raised QTextEdit::NoWrap true 0 6 Qt::Horizontal 131 31 &Close true Qt::Horizontal 40 20 okButton clicked() QDjViewInfoDialog accept() 278 253 96 254 djview4-4.10.5/src/qdjviewmetadialog.ui000066400000000000000000000130421264256014000200030ustar00rootroot00000000000000 QDjViewMetaDialog 0 0 600 320 Dialog 9 6 &Document Metadata 9 6 QAbstractItemView::NoEditTriggers QAbstractItemView::SingleSelection true &Page Metadata 9 6 0 6 Page: :/images/icon_prev.png 1 0 1 0 :/images/icon_next.png Qt::Horizontal 40 20 &View Page QAbstractItemView::NoEditTriggers QAbstractItemView::SingleSelection true 0 6 Qt::Horizontal 131 31 &Close true Qt::Horizontal 40 20 okButton clicked() QDjViewMetaDialog accept() 278 253 96 254 djview4-4.10.5/src/qdjviewplugin.cpp000066400000000000000000001202701264256014000173420ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qdjvu.h" #include "qdjview.h" #include "qdjviewplugin.h" #include "djview.h" #include #include #include #include #include #include #include #include #include #if QT_VERSION < 0x50000 # if defined(Q_WS_X11) # include # include # define HAVE_QX11EMBED 1 # endif #endif #if QT_VERSION >= 0x50000 # include # include # define HAVE_QT5EMBED 1 #endif #if WITH_X11 # ifndef X_DISPLAY_MISSING # if QT_VERSION < 0x50000 # ifdef Q_WS_X11 # define HAVE_X11 1 # endif # endif # endif # if HAVE_X11 # include # include # include # undef FocusOut # undef FocusIn # undef KeyPress # undef KeyRelease # undef None # undef RevertToParent # undef GrayScale # undef CursorShape # endif #endif // ======================================== // STRUCTURES // ======================================== class QDjViewPlugin::Document : public QDjVuDocument { Q_OBJECT public: QDjViewPlugin::Instance * const instance; Document(QDjViewPlugin::Instance *instance); virtual void newstream(int streamid, QString name, QUrl url); }; class QDjViewPlugin::Forwarder : public QObject { Q_OBJECT public: QDjViewPlugin * const dispatcher; Forwarder(QDjViewPlugin *dispatcher); #if HAVE_X11 virtual bool eventFilter(QObject*, QEvent*); #endif public slots: void containerClosed(); void showStatus(QString message); void getUrl(QUrl url, QString target); void onChange(); void quit(); void dispatch(); void lastViewerClosed(); void continueExec(); }; // QDjViewPlugin, Stream and Instance cannot be QObjects // because subtle errors occur when one creates QObjects // before the QApplication. struct QDjViewPlugin::Stream { typedef QDjViewPlugin::Instance Instance; QUrl url; Instance *instance; int streamid; bool started; bool checked; bool closed; ~Stream(); Stream(int streamid, QUrl url, Instance *instance); }; struct QDjViewPlugin::Instance { QUrl url; QDjViewPlugin *dispatcher; QPointer document; QPointer shell; QPointer djview; QPointer containerwin; WId containerid; QStringList args; QByteArray saved; int savedformat; int onchange; QDjView::ViewerMode viewerMode; ~Instance(); Instance(QDjViewPlugin *dispatcher); void open(); void destroy(); void save(QDjVuWidget*); void restore(QDjVuWidget*); }; // ======================================== // WORKAROUND QT55 XEMBED BUG // ======================================== #if QT_VERSION >= 0x50500 /* && QT_VERSION < 0x50XXX */ # define WORKAROUND_QT55_XEMBED_BUG 1 #endif #if WORKAROUND_QT55_XEMBED_BUG struct my_xcb_configure_notify_event_t { quint8 response_type, pad0, pad1, pad2; quint32 pad3, window, pad4; quint16 x, y, width, height; }; class my_timer_object_t : public QObject { Q_OBJECT quint32 wid; quint16 w,h; public: my_timer_object_t(quint32, quint16, quint16); void timerEvent(QTimerEvent*); }; struct my_event_filter_t : public QAbstractNativeEventFilter { QMap instances; virtual bool nativeEventFilter(const QByteArray &type, void *msg, long*); }; static my_event_filter_t *my_event_filter() { static my_event_filter_t *filter = 0; if (! filter) filter = new my_event_filter_t; return filter; } my_timer_object_t::my_timer_object_t(quint32 wid, quint16 w, quint16 h) : wid(wid), w(w), h(h) { startTimer(1); } void my_timer_object_t::timerEvent(QTimerEvent *ev) { QDjViewPlugin::Instance *instance = my_event_filter()->instances.value(wid,0); if (instance && instance->shell) // test for resizing bug if (instance->shell->width() != w || instance->shell->height() != h ) instance->shell->resize((int)w, (int)h); killTimer(ev->timerId()); deleteLater(); wid = 0; } bool my_event_filter_t::nativeEventFilter(const QByteArray &type, void *msg, long*) { if (type == "xcb_generic_event_t") { my_xcb_configure_notify_event_t *ev = (my_xcb_configure_notify_event_t*)msg; if (ev->response_type == 22 && instances.contains(ev->window) ) new my_timer_object_t(ev->window, ev->width, ev->height); } return false; } #endif // ======================================== // FIXING TRANSIENT WINDOW PROPERTIES (QT4) // ======================================== #if HAVE_X11 static Atom wm_state; static Atom wm_client_leader; static Window x11ToplevelWindow(Display *dpy, Window start) { Window shell = 0; if (!dpy || !start) return 0; if (! wm_state) wm_state = XInternAtom(dpy, "WM_STATE", True); if (! wm_state) return 0; while (1) { int nprops; Atom *props = XListProperties(dpy, start, &nprops); if (props && nprops) { for(int i=0; iparentWidget(); Display *dpy = QX11Info::display(); if (dpy && parent && (widget->windowFlags() & Qt::Window)) { Window transient = 0; XGetTransientForHint(dpy, widget->winId(), &transient); if (transient) { Window group = 0; XWMHints *wmhints = XGetWMHints(dpy, widget->winId()); if (wmhints && (wmhints->flags & WindowGroupHint)) group = wmhints->window_group; Window ntransient = x11ToplevelWindow(dpy, parent->winId()); Window ngroup = 0; if (ntransient) { XWMHints *morehints = XGetWMHints(dpy, ntransient); if (morehints && (morehints->flags & WindowGroupHint)) ngroup = morehints->window_group; if (morehints) XFree(morehints); if (transient == group && ngroup) ntransient = ngroup; XSetTransientForHint(dpy, widget->winId(), ntransient); } if (ngroup) { wmhints->flags |= WindowGroupHint; wmhints->window_group = ngroup; XSetWMHints(dpy, widget->winId(), wmhints); if (! wm_client_leader) wm_client_leader = XInternAtom(dpy, "WM_CLIENT_LEADER", True); if (wm_client_leader) XChangeProperty(dpy, widget->winId(), wm_client_leader, XA_WINDOW, 32, PropModeReplace, (unsigned char*)&ngroup, 1); } if (wmhints) XFree(wmhints); } } } #endif // ======================================== // STREAM // ======================================== QDjViewPlugin::Stream::Stream(int streamid, QUrl url, Instance *instance) : url(url), instance(instance), streamid(streamid), started(false), checked(false), closed(false) { if (instance->dispatcher) instance->dispatcher->streamCreated(this); } QDjViewPlugin::Stream::~Stream() { if (instance->dispatcher) instance->dispatcher->streamDestroyed(this); } // ======================================== // DOCUMENT // ======================================== QDjViewPlugin::Document::Document(QDjViewPlugin::Instance *instance) : QDjVuDocument(true), instance(instance) { QUrl docurl = QDjView::removeDjVuCgiArguments(instance->url); setUrl(instance->dispatcher->context, docurl); } void QDjViewPlugin::Document::newstream(int streamid, QString, QUrl url) { if (streamid > 0) { new QDjViewPlugin::Stream(streamid, url, instance); QString message = tr("Requesting %1.").arg(url.toString()); instance->dispatcher->showStatus(instance, message); instance->dispatcher->getUrl(instance, url, QString()); } } // ======================================== // FORWARDER // ======================================== QDjViewPlugin::Forwarder::Forwarder(QDjViewPlugin *dispatcher) : QObject(), dispatcher(dispatcher) { // The purpose of the Forwarder is to redirect // certain signals towards the QDjViewPlugin // (which cannot be a QObject.) } void QDjViewPlugin::Forwarder::containerClosed() { #if HAVE_QT5EMBED QDjView *shell = qobject_cast(sender()); Instance *instance = dispatcher->findInstance(shell); if (instance && dispatcher->xembedFlag) instance->destroy(); #elif HAVE_QX11EMBED QX11EmbedWidget *shell = qobject_cast(sender()); Instance *instance = dispatcher->findInstance(shell); if (instance && dispatcher->xembedFlag) instance->destroy(); #endif } void QDjViewPlugin::Forwarder::showStatus(QString message) { QDjView *viewer = qobject_cast(sender()); Instance *instance = dispatcher->findInstance(viewer); if (instance) dispatcher->showStatus(instance, message); } void QDjViewPlugin::Forwarder::getUrl(QUrl url, QString target) { QDjView *viewer = qobject_cast(sender()); Instance *instance = dispatcher->findInstance(viewer); if (! target.size()) target = "_self"; if (instance) dispatcher->getUrl(instance, url, target); } void QDjViewPlugin::Forwarder::onChange() { QDjView *viewer = qobject_cast(sender()); Instance *instance = dispatcher->findInstance(viewer); if (instance) dispatcher->onChange(instance); } void QDjViewPlugin::Forwarder::quit() { dispatcher->quit(); } void QDjViewPlugin::Forwarder::dispatch() { dispatcher->dispatch(); } void QDjViewPlugin::Forwarder::lastViewerClosed() { dispatcher->lastViewerClosed(); } void QDjViewPlugin::Forwarder::continueExec() { dispatcher->continueExec(); } #if HAVE_X11 static bool x11EventFilter(void *message, long *) { // We define a low level handler because we need to make // the window active before calling the QX11EmbedWidget event filter. XEvent *event = reinterpret_cast(message); if (event->type == ButtonPress) { QWidget *w = QWidget::find(event->xbutton.window); if (w && w->window()->objectName() == "djvu_shell") { QApplication *app = (QApplication*)QCoreApplication::instance(); app->setActiveWindow(w->window()); } } return false; } #endif #if HAVE_X11 bool QDjViewPlugin::Forwarder::eventFilter(QObject *o, QEvent *e) { if (o->isWidgetType()) { QWidget *w = static_cast(o); switch( e->type() ) { // Try to fix transient windows properties. // - this does not work too well... case QEvent::Show: if (w->windowFlags() & Qt::Window) QApplication::postEvent(w, new QEvent(QEvent::User)); break; case QEvent::User: if (w->windowFlags() & Qt::Window) x11SetTransientForHint(w); break; default: break; } } // Keep processing return false; } #endif // ======================================== // INSTANCE // ======================================== QDjViewPlugin::Instance::~Instance() { destroy(); delete shell; delete djview; delete containerwin; if (document) document->deref(); document = 0; } QDjViewPlugin::Instance::Instance(QDjViewPlugin *parent) : url(), dispatcher(parent), document(0), shell(0), djview(0), containerid(0), onchange(0) { } void QDjViewPlugin::Instance::open() { if (!document && url.isValid()) { document = new QDjViewPlugin::Document(this); document->ref(); } if (document && djview && !djview->getDocument()) { djview->open(document, url); restore(djview->getDjVuWidget()); shell->show(); } } void QDjViewPlugin::Instance::destroy() { if (djview) { save(djview->getDjVuWidget()); djview->close(); djview = 0; } if (shell) { #if HAVE_QT5EMBED QWindow *window = shell->windowHandle(); if (window) { window->setVisible(false); window->setParent(0); # if WORKAROUND_QT55_XEMBED_BUG my_event_filter()->instances.remove((quint32)shell->winId()); # endif } #elif HAVE_X11 Display *dpy = QX11Info::display(); XUnmapWindow(dpy, shell->winId()); XReparentWindow(dpy, shell->winId(), QX11Info::appRootWindow(), 0,0); #endif shell->close(); dispatcher->registerForDeletion(shell); containerid = 0; shell = 0; } } void QDjViewPlugin::Instance::save(QDjVuWidget *widget) { if (widget) { int q[4]; // get info int zoom = widget->zoom(); int rotation = widget->rotation(); bool sideBySide = widget->sideBySide(); bool continuous = widget->continuous(); QDjVuWidget::DisplayMode mode = widget->displayMode(); QDjVuWidget::Position pos = widget->position(); // pack info into four bytes for compatibility. q[0] = 0; q[1] = pos.pageNo; q[2] = pos.posView.x(); q[3] = pos.posView.y(); q[0] |= (rotation & 0x3) << 12; if (zoom >= 0) q[0] = zoom & 0x7ff; else q[0] = 0x1000 - ((- zoom) & 0x7ff); if (sideBySide) q[0] |= 0x4000; if (continuous) q[0] |= 0x8000; q[0] |= (((int)mode) & 0xf) << 16; // make sure first two integers are positive. q[0] |= 0x40000000; q[1] |= 0x40000000; // store saved = QByteArray((const char*)q, sizeof(q)); } } void QDjViewPlugin::Instance::restore(QDjVuWidget *widget) { int q[4]; if (saved.size()==sizeof(q) && widget) { // unpack memcpy((void*)q, (const char*)saved, sizeof(q)); int zoom = q[0] & 0xfff; if (zoom & 0x800) zoom -= 0x1000; int rotation = (q[0] & 0x3000) >> 12; bool sideBySide = !! (q[0] & 0x4000); bool continuous = !! (q[0] & 0x8000); QDjVuWidget::DisplayMode mode = (QDjVuWidget::DisplayMode)((q[0] & 0xf0000) >> 16); QDjVuWidget::Position pos; pos.inPage = false; pos.pageNo = (q[1] & 0xfffffff); pos.posView.rx() = q[2]; pos.posView.ry() = q[3]; // apply widget->setZoom(zoom); widget->setRotation(rotation); widget->setSideBySide(sideBySide); widget->setContinuous(continuous); widget->setDisplayMode(mode); widget->setPosition(pos); } } // ======================================== // PROTOCOL // ======================================== enum { TYPE_INTEGER = 1, TYPE_DOUBLE = 2, TYPE_STRING = 3, TYPE_POINTER = 4, TYPE_ARRAY = 5 }; enum { CMD_SHUTDOWN = 0, CMD_NEW = 1, CMD_DETACH_WINDOW = 2, CMD_ATTACH_WINDOW = 3, CMD_RESIZE = 4, CMD_DESTROY = 5, CMD_PRINT = 6, CMD_NEW_STREAM = 7, CMD_WRITE = 8, CMD_DESTROY_STREAM = 9, CMD_SHOW_STATUS = 10, CMD_GET_URL = 11, CMD_GET_URL_NOTIFY = 12, CMD_URL_NOTIFY = 13, CMD_HANDSHAKE = 14, CMD_SET_DJVUOPT = 15, CMD_GET_DJVUOPT = 16, CMD_ON_CHANGE = 17, }; #define OK_STRING "OK" #define ERR_STRING "ERR" void QDjViewPlugin::write(int fd, const char *ptr, int size) { while(size>0) { errno = 0; int res = ::write(fd, ptr, size); if (res<0 && errno==EINTR) continue; if (res<=0) throw res; size -= res; ptr += res; } } void QDjViewPlugin::read(int fd, char *buffer, int size) { char *ptr = buffer; while(size>0) { errno = 0; int res = ::read(fd, ptr, size); if (res<0 && errno==EINTR) continue; if (res <= 0) throw res; size -= res; ptr += res; } } void QDjViewPlugin::writeString(int fd, QByteArray s) { int type = TYPE_STRING; int length = s.size(); write(fd, (const char*)&type, sizeof(type)); write(fd, (const char*)&length, sizeof(length)); write(fd, s.data(), length+1); } void QDjViewPlugin::writeString(int fd, QString x) { writeString(fd, x.toUtf8()); } void QDjViewPlugin::writeInteger(int fd, int x) { int type = TYPE_INTEGER; write(fd, (const char*)&type, sizeof(type)); write(fd, (const char*)&x, sizeof(x)); } void QDjViewPlugin::writeDouble(int fd, double x) { int type = TYPE_DOUBLE; write(fd, (const char*)&type, sizeof(type)); write(fd, (const char*)&x, sizeof(x)); } void QDjViewPlugin::writePointer(int fd, const void *x) { int type = TYPE_POINTER; write(fd, (const char*)&type, sizeof(type)); write(fd, (const char*)&x, sizeof(x)); } void QDjViewPlugin::writeArray(int fd, QByteArray s) { int type = TYPE_ARRAY; int length = s.size(); write(fd, (const char*)&type, sizeof(type)); write(fd, (const char*)&length, sizeof(length)); write(fd, s.data(), length); } QString QDjViewPlugin::readString(int fd) { int type, length; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_STRING) throw 1; read(fd, (char*)&length, sizeof(length)); if (length < 0) throw 2; QByteArray utf(length+1, 0); read(fd, utf.data(), length+1); return QString::fromUtf8(utf); } QByteArray QDjViewPlugin::readRawString(int fd) { int type, length; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_STRING) throw 1; read(fd, (char*)&length, sizeof(length)); if (length < 0) throw 2; QByteArray x(length+1, 0); read(fd, x.data(), length+1); x.truncate(length); return x; } int QDjViewPlugin::readInteger(int fd) { int type; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_INTEGER) throw 1; int x; read(fd, (char*)&x, sizeof(x)); return x; } double QDjViewPlugin::readDouble(int fd) { int type; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_DOUBLE) throw 1; double x; read(fd, (char*)&x, sizeof(x)); return x; } void* QDjViewPlugin::readPointer(int fd) { int type; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_POINTER) throw 1; void *x; read(fd, (char*)&x, sizeof(x)); return x; } QByteArray QDjViewPlugin::readArray(int fd) { int type, length; read(fd, (char*)&type, sizeof(type)); if (type != TYPE_ARRAY) throw 1; read(fd, (char*)&length, sizeof(length)); if (length < 0) throw 2; QByteArray x(length, 0); read(fd, x.data(), length); return x; } // ======================================== // COMMANDS // ======================================== void QDjViewPlugin::cmdNew() { // read arguments bool fullPage = !!readInteger(pipeRead); readString(pipeRead); // djvuDir (unused) int argc = readInteger(pipeRead); QStringList args; for (int i=0; i(argv)); application->setQuitOnLastWindowClosed(false); argc = 1; context = application->djvuContext(); forwarder = new Forwarder(this); #if HAVE_X11 application->setEventFilter(x11EventFilter); application->installEventFilter(forwarder); #endif #if WORKAROUND_QT55_XEMBED_BUG application->installNativeEventFilter(my_event_filter()); #endif QObject::connect(application, SIGNAL(lastWindowClosed()), forwarder, SLOT(lastViewerClosed())); notifier = new QSocketNotifier(pipeRead, QSocketNotifier::Read); QObject::connect(notifier, SIGNAL(activated(int)), forwarder, SLOT(dispatch())); timer = new QTimer(); timer->setSingleShot(true); timer->start(5*60*1000); QObject::connect(timer, SIGNAL(timeout()), forwarder, SLOT(quit())); #if HAVE_QX11EMBED || HAVE_QT5EMBED if (protocol.startsWith("XEMBED")) xembedFlag = true; #endif } // create djview object QWidget *shell = instance->shell; QDjView *djview = instance->djview; if (! shell) { #if HAVE_QT5EMBED if (xembedFlag) { djview = new QDjView(*context, instance->viewerMode, 0); djview->winId(); shell = djview; QObject::connect(shell, SIGNAL(destroyed()), forwarder, SLOT(containerClosed()) ); shell->setObjectName("djvu_shell"); QWindow *dwindow = djview->windowHandle(); QWindow *cwindow = QWindow::fromWinId(window); instance->containerwin = cwindow; dwindow->setParent(cwindow); # if WORKAROUND_QT55_XEMBED_BUG my_event_filter()->instances.insert((quint32)shell->winId(), instance); # endif } else #elif HAVE_QX11EMBED if (xembedFlag) { QX11EmbedWidget *embed = new QX11EmbedWidget(); shell = embed; QObject::connect(shell, SIGNAL(containerClosed()), forwarder, SLOT(containerClosed()) ); shell->setObjectName("djvu_shell"); shell->setGeometry(0, 0, width, height); djview = new QDjView(*context, instance->viewerMode, shell); djview->setWindowFlags(djview->windowFlags() & ~Qt::Window); djview->setAttribute(Qt::WA_DeleteOnClose, false); instance->containerid = window; embed->embedInto(window); } else #endif { shell = new QWidget(); shell->setObjectName("djvu_shell"); shell->setGeometry(0, 0, width, height); djview = new QDjView(*context, instance->viewerMode, shell); djview->setWindowFlags(djview->windowFlags() & ~Qt::Window); djview->setAttribute(Qt::WA_DeleteOnClose, false); #if HAVE_X11 instance->containerid = window; Display *dpy = QX11Info::display(); XReparentWindow(dpy, shell->winId(), (Window)window, 0,0); #elif HAVE_QT5EMBED shell->winId(); QWindow *dwindow = shell->windowHandle(); QWindow *cwindow = QWindow::fromWinId(window); instance->containerwin = cwindow; dwindow->setParent(cwindow); #else qWarning("djview: unable to embed the djview window."); #endif } if (shell && djview && shell != djview) { QLayout *layout = new QHBoxLayout(shell); layout->setMargin(0); layout->setSpacing(0); layout->addWidget(djview); } QObject::connect(djview, SIGNAL(pluginStatusMessage(QString)), forwarder, SLOT(showStatus(QString)) ); QObject::connect(djview, SIGNAL(pluginGetUrl(QUrl,QString)), forwarder, SLOT(getUrl(QUrl,QString)) ); QObject::connect(djview, SIGNAL(pluginOnChange()), forwarder, SLOT(onChange()) ); instance->shell = shell; instance->djview = djview; // apply arguments while (instance->args.size() > 0) djview->parseArgument(instance->args.takeFirst()); instance->args.clear(); } // map and reparent djview object instance->open(); writeString(pipeWrite, QByteArray(OK_STRING)); timer->stop(); } void QDjViewPlugin::cmdDetachWindow() { Instance *instance = (Instance*) readPointer(pipeRead); if (instances.contains(instance)) instance->destroy(); writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdResize() { Instance *instance = (Instance*) readPointer(pipeRead); int width = readInteger(pipeRead); int height = readInteger(pipeRead); if (instances.contains(instance) && width>0 && height>0) if (instance->shell && application) instance->shell->resize(width, height); writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdDestroy() { int savedformat = 0; QByteArray saved; Instance *instance = (Instance*) readPointer(pipeRead); if (instances.contains(instance)) { instance->destroy(); QList streamList = streams.toList(); foreach(Stream *stream, streamList) if (stream->instance == instance) delete(stream); savedformat = instance->savedformat; saved = instance->saved; delete instance; instances.remove(instance); } writeString(pipeWrite, QByteArray(OK_STRING)); if (savedformat == 1 || savedformat == 0) { int q[4]; q[0] = q[1] = q[2] = q[3] = 0; if (saved.size() == sizeof(q)) memcpy((void*)q, (const char*)saved, sizeof(q)); writeInteger(pipeWrite, q[0]); writeInteger(pipeWrite, q[1]); writeInteger(pipeWrite, q[2]); writeInteger(pipeWrite, q[3]); } else writeArray(pipeWrite, saved); } void QDjViewPlugin::cmdNewStream() { // read Instance *instance = (Instance*) readPointer(pipeRead); QUrl url = QUrl::fromEncoded(readRawString(pipeRead)); // check if (! url.isValid() ) { fprintf(stderr,"djview dispatcher: invalid url '%s'\n", (const char*) url.toEncoded()); writeString(pipeWrite, QByteArray(ERR_STRING)); return; } // proceed Stream *stream = 0; if (instances.contains(instance)) { // first stream if (! instance->url.isValid()) { instance->url = url; url = QDjView::removeDjVuCgiArguments(url); Stream *s = new QDjViewPlugin::Stream(0, url, instance); s->checked = true; instance->open(); } // search stream foreach(Stream *s, streams) if (!stream && !s->started) if (s->instance == instance && s->url == url) stream = s; } // mark if (stream) stream->started = true; // reply (null means discard stream) writeString(pipeWrite, QByteArray(OK_STRING)); writePointer(pipeWrite, (void*)stream); } void QDjViewPlugin::cmdWrite() { Stream *stream = (Stream*) readPointer(pipeRead); QByteArray data = readArray(pipeRead); // locate stream if (!streams.contains(stream) || stream->closed) { // -- null return value means that stream must be discarded. writeString(pipeWrite, QByteArray(OK_STRING)); writeInteger(pipeWrite, 0); return; } // check stream if (!stream->checked && data.size()>0) { stream->checked = true; // -- if the stream is not a djvu file, // this is probably a html error message. // But we need at least 8 bytes to check if (data.size() >= 8) { const char *cdata = (const char*)data; if (strncmp(cdata, "FORM", 4) && strncmp(cdata+4, "FORM", 4)) { getUrl(stream->instance, stream->url, QString("_self")); delete stream; writeString(pipeWrite, QByteArray(OK_STRING)); writeInteger(pipeWrite, 0); return; } } } // pass data Document *document = stream->instance->document; ddjvu_stream_write(*document, stream->streamid, data, data.size()); writeString(pipeWrite, QByteArray(OK_STRING)); writeInteger(pipeWrite, data.size()); } void QDjViewPlugin::cmdDestroyStream() { Stream *stream = (Stream*) readPointer(pipeRead); int okay = readInteger(pipeRead); if (streams.contains(stream)) { Document *document = stream->instance->document; if (document && !stream->closed) ddjvu_stream_close(*document, stream->streamid, !okay); stream->closed = true; showStatus(stream->instance, QString()); delete stream; } writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdUrlNotify() { QUrl url = QUrl::fromEncoded(readRawString(pipeRead)); readInteger(pipeRead); // notification code (unused) Stream *stream = 0; QList streamList = streams.toList(); foreach(stream, streamList) if (!stream->started && stream->url == url) delete stream; writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdPrint() { Instance *instance = (Instance*) readPointer(pipeRead); readInteger(pipeRead); // full mode (unused) if (instances.contains(instance)) if (instance->djview) QTimer::singleShot(0, instance->djview, SLOT(print())); writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdHandshake() { writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdSetDjVuOpt() { // protocol extension for plugin scripting Instance *instance = (Instance*) readPointer(pipeRead); QString key = readString(pipeRead); QString value = readString(pipeRead); // check instance if (!instances.contains(instance)) { fprintf(stderr, "djview dispatcher: bad instance\n"); writeString(pipeWrite, QByteArray(ERR_STRING)); return; } // return code writeString(pipeWrite, QByteArray(OK_STRING)); // apply options QStringList errors; if (instance->djview) errors = instance->djview->parseArgument(key, value); else instance->args += key + QString("=") + value; // print error messages if (errors.size() > 0) foreach(QString error, errors) qWarning("djvuopt: %s",(const char*)error.toLocal8Bit()); } void QDjViewPlugin::cmdGetDjVuOpt() { // protocol extension for plugin scripting. Instance *instance = (Instance*) readPointer(pipeRead); QString key = readString(pipeRead); // check instance. if (!instances.contains(instance)) { fprintf(stderr, "djview dispatcher: bad instance\n"); writeString(pipeWrite, QByteArray(ERR_STRING)); return; } // get argument. QString value; if (instance->djview) value = instance->djview->getArgument(key); writeString(pipeWrite, QByteArray(OK_STRING)); writeString(pipeWrite, value); } void QDjViewPlugin::cmdOnChange() { Instance *instance = (Instance*) readPointer(pipeRead); instance->onchange = readInteger(pipeRead); writeString(pipeWrite, QByteArray(OK_STRING)); } void QDjViewPlugin::cmdShutdown() { QList streamList = streams.toList(); QList instanceList = instances.toList(); foreach(Instance *s, instanceList) s->destroy(); foreach(Stream *s, streamList) delete(s); foreach(Instance *s, instanceList) delete(s); streams.clear(); instances.clear(); lastViewerClosed(); } // ======================================== // QDJVIEWPLUGIN // ======================================== static QDjViewPlugin *thePlugin; QDjViewPlugin::~QDjViewPlugin() { thePlugin = 0; QList streamList = streams.toList(); QList instanceList = instances.toList(); foreach(Stream *s, streamList) delete(s); foreach(Instance *s, instanceList) delete(s); delete forwarder; delete notifier; delete timer; delete application; } QDjViewPlugin::QDjViewPlugin(const char *progname) : progname(progname), context(0), timer(0), notifier(0), application(0), forwarder(0), xembedFlag(false), eventLoop(0), returnCode(0), quitFlag(false), pipeRead(3), pipeWrite(4), pipeRequest(5) { // Disable SIGPIPE #ifdef SIGPIPE # ifndef HAVE_SIGACTION # ifdef SA_RESTART # define HAVE_SIGACTION 1 # endif # endif # if HAVE_SIGACTION sigset_t mask; struct sigaction act; sigemptyset(&mask); sigaddset(&mask, SIGPIPE); sigprocmask(SIG_BLOCK, &mask, 0); sigaction(SIGPIPE, 0, &act); act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, 0); # else signal(SIGPIPE, SIG_IGN); # endif #endif // Set global dispatcher if (thePlugin) qWarning("Constructing multiple dispatchers"); thePlugin = this; } QDjViewPlugin * QDjViewPlugin::instance() { return thePlugin; } int QDjViewPlugin::exec() { #ifndef QT_NO_DEBUG const char *s = ::getenv("DJVIEW_DEBUG"); if (s && strcmp(s,"0")) { static int loop = 1; qWarning("QDjViewPlugin::exec() looping for gdb"); while (loop) sleep(1); } #endif returnCode = 0; quitFlag = false; qWarning("QDjViewPlugin::exec() begin"); try { // startup message announcing capabilities #if HAVE_QX11EMBED || HAVE_QT5EMBED const char *djviewName = "DJVIEW/4 SCRIPT XEMBED"; #else const char *djviewName = "DJVIEW/4 SCRIPT"; #endif writeString(pipeWrite, QByteArray(djviewName)); // dispatch until we get display while (!application && !quitFlag) dispatch(); // start application if (application && forwarder) { QTimer::singleShot(0, forwarder, SLOT(continueExec())); application->exec(); } } catch(int err) { reportError(err); returnCode = 10; } qWarning("QDjViewPlugin::exec() end code=%d", returnCode); return returnCode; } void QDjViewPlugin::continueExec() { try { // handle events in private loop while (!quitFlag) { QEventLoop loop; eventLoop = &loop; eventLoop->exec(); eventLoop = 0; // see registerForDeletion() QObjectList toDelete = pendingDelete; pendingDelete.clear(); foreach(QObject *o, toDelete) delete o; } } catch(int err) { reportError(err); returnCode = 10; } if (application) application->exit(returnCode); } void QDjViewPlugin::exit(int retcode) { returnCode = retcode; quitFlag = true; if (timer) timer->stop(); if (eventLoop) eventLoop->exit(retcode); else if (application) application->exit(retcode); } void QDjViewPlugin::quit() { this->exit(0); } void QDjViewPlugin::reportError(int err) { if (err < 0) perror("djview dispatcher"); else if (err > 0) fprintf(stderr, "djview dispatcher: protocol error (%d)\n", err); } void QDjViewPlugin::streamCreated(Stream *stream) { streams.insert(stream); } void QDjViewPlugin::streamDestroyed(Stream *stream) { if (streams.contains(stream)) { if (instances.contains(stream->instance)) { Document *document = stream->instance->document; if (document && !stream->closed) ddjvu_stream_close(*document, stream->streamid, true); } stream->closed = true; stream->started = stream->checked = false; streams.remove(stream); } } QDjViewPlugin::Instance* QDjViewPlugin::findInstance(QWidget *widget) { if (widget) foreach(Instance *instance, instances) if (widget == instance->djview || widget == instance->shell) return instance; return 0; } void QDjViewPlugin::getUrl(Instance *instance, QUrl url, QString target) { try { writeInteger(pipeRequest, CMD_GET_URL); writePointer(pipeRequest, (void*) instance); writeString(pipeRequest, url.toEncoded()); writeString(pipeRequest, target); } catch(int err) { reportError(err); exit(10); } } void QDjViewPlugin::onChange(Instance *instance) { try { if (!instance->onchange) return; writeInteger(pipeRequest, CMD_ON_CHANGE); writePointer(pipeRequest, (void*) instance); } catch(int err) { reportError(err); exit(10); } } void QDjViewPlugin::showStatus(Instance *instance, QString message) { try { message.replace(QRegExp("\\s"), " "); writeInteger(pipeRequest, CMD_SHOW_STATUS); writePointer(pipeRequest, (void*) instance); writeString(pipeRequest, message); } catch(int err) { reportError(err); exit(10); } } void QDjViewPlugin::dispatch() { try { int cmd = readInteger(pipeRead); switch (cmd) { case CMD_SHUTDOWN: cmdShutdown(); break; case CMD_NEW: cmdNew(); break; case CMD_DETACH_WINDOW: cmdDetachWindow(); break; case CMD_ATTACH_WINDOW: cmdAttachWindow(); break; case CMD_RESIZE: cmdResize(); break; case CMD_DESTROY: cmdDestroy(); break; case CMD_PRINT: cmdPrint(); break; case CMD_NEW_STREAM: cmdNewStream(); break; case CMD_WRITE: cmdWrite(); break; case CMD_DESTROY_STREAM: cmdDestroyStream(); break; case CMD_URL_NOTIFY: cmdUrlNotify(); break; case CMD_HANDSHAKE: cmdHandshake(); break; case CMD_SET_DJVUOPT: cmdSetDjVuOpt(); break; case CMD_GET_DJVUOPT: cmdGetDjVuOpt(); break; case CMD_ON_CHANGE: cmdOnChange(); break; default: throw 3; } } catch(int err) { reportError(err); exit(err ? 10 : 0); } } void QDjViewPlugin::lastViewerClosed() { if (timer) { timer->stop(); timer->start(5*60*1000); return; } exit(0); } void QDjViewPlugin::registerForDeletion(QObject *p) { // QObject::deleteLater() deletes when // returning to the current event loop. // Here we want deletions to happen when // returning to the main loop. // Otherwise Instance::destroy() might // delete window modal dialogs while // they are running. if (application) { pendingDelete.append(p); if (eventLoop) eventLoop->exit(0); return; } // Fallback p->deleteLater(); } // ---------------------------------------- // MOC #include "qdjviewplugin.moc" // ---------------------------------------- // END /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewplugin.h000066400000000000000000000067231264256014000170150ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEWPLUGIN_H #define QDJVIEWPLUGIN_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include "qdjvu.h" #include "qdjview.h" #include "djview.h" class QMutex; class QSocketNotifier; class QTimer; class QEventLoop; class QDjViewPlugin { public: ~QDjViewPlugin(); QDjViewPlugin(const char *progname); static QDjViewPlugin *instance(); int exec(); void exit(int retcode); void quit(); class Document; class Forwarder; struct Instance; struct Stream; private: void write(int fd, const char *buffer, int size); void read(int fd, char *buffer, int size); void writeString(int fd, QByteArray x); void writeString(int fd, QString x); void writeInteger(int fd, int x); void writeDouble(int fd, double x); void writePointer(int fd, const void *x); void writeArray(int fd, QByteArray x); QString readString(int fd); QByteArray readRawString(int fd); int readInteger(int fd); double readDouble(int fd); void * readPointer(int fd); QByteArray readArray(int fd); void cmdNew(); void cmdAttachWindow(); void cmdDetachWindow(); void cmdResize(); void cmdDestroy(); void cmdNewStream(); void cmdWrite(); void cmdDestroyStream(); void cmdUrlNotify(); void cmdPrint(); void cmdHandshake(); void cmdShutdown(); void cmdSetDjVuOpt(); void cmdGetDjVuOpt(); void cmdOnChange(); void reportError(int err); void streamCreated(Stream *s); void streamDestroyed(Stream *s); Instance *findInstance(QWidget *widget); void getUrl(Instance *instance, QUrl url, QString target); void showStatus(Instance *instance, QString message); void onChange(Instance *instance); void continueExec(); void dispatch(); void lastViewerClosed(); void registerForDeletion(QObject*); QByteArray progname; QDjVuContext *context; QTimer *timer; QSocketNotifier *notifier; QDjViewApplication *application; Forwarder *forwarder; QSet instances; QSet streams; bool xembedFlag; int argc; const char* argv[4]; QEventLoop *eventLoop; QObjectList pendingDelete; int returnCode; bool quitFlag; int pipeRead; int pipeWrite; int pipeRequest; }; #endif // QDJVIEWPLUGIN_H /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "Q[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewprefs.cpp000066400000000000000000001230031264256014000171600ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qdjviewprefs.h" #include "qdjview.h" #include "qdjvu.h" #include "djview.h" // ======================================== // QDJVIEWPREFS // ======================================== /*! \class QDjViewPrefs \brief Holds the preferences for the \a QDjView instances. */ /*! \enum QDjViewPrefs::Option \brief Miscellanenous flags. This enumeration defines flags describing (i) the visibility of the menubar, toolbar, etc. (ii) the page layout flags continuous and side by side. (iii) the interactive capabilities of the djvu widget. */ /*! \enum QDjViewPrefs::Tool \brief Toolbar flags. This enumeration defines flags describing the composition of the toolbar. */ /*! \class QDjViewPrefs::Saved \brief Mode dependent preferences. This structure holds the preferences that are saved separately for each viewer mode. There are four copies of this structure, for the standalone viewer mode, for the full screen mode, for the full page plugin mode, and for the embedded plugin mode. */ /*! The default toolbar composition. */ const QDjViewPrefs::Tools QDjViewPrefs::defaultTools = TOOLBAR_TOP | TOOLBAR_BOTTOM | TOOL_ZOOMCOMBO | TOOL_ZOOMBUTTONS | TOOL_PAGECOMBO | TOOL_PREVNEXT | TOOL_FIRSTLAST | TOOL_BACKFORW | TOOL_OPEN | TOOL_FIND | TOOL_SELECT | TOOL_PRINT | TOOL_LAYOUT | TOOL_WHATSTHIS; /*! The default set of miscellaneous flags. */ const QDjViewPrefs::Options QDjViewPrefs::defaultOptions = SHOW_MENUBAR | SHOW_TOOLBAR | SHOW_SIDEBAR | SHOW_STATUSBAR | SHOW_SCROLLBARS | SHOW_FRAME | SHOW_MAPAREAS | HANDLE_MOUSE | HANDLE_KEYBOARD | HANDLE_LINKS | HANDLE_CONTEXTMENU; static QPointer preferences; /*! Returns the single preference object. */ QDjViewPrefs * QDjViewPrefs::instance(void) { QMutex mutex; QMutexLocker locker(&mutex); if (! preferences) { preferences = new QDjViewPrefs(); preferences->load(); } return preferences; } QDjViewPrefs::Saved::Saved(void) : remember(true), options(defaultOptions), zoom(QDjVuWidget::ZOOM_FITWIDTH), nsBorderBrush(QBrush(Qt::lightGray)), nsBorderSize(8) { } QDjViewPrefs::QDjViewPrefs(void) : QObject(QCoreApplication::instance()), windowSize(640,400), windowMaximized(false), tools(defaultTools), gamma(2.2), white(QColor(Qt::white)), resolution(100), cacheSize(10*1024*1024), pixelCacheSize(256*1024), lensSize(300), lensPower(3), enableAnimations(true), advancedFeatures(false), showTextLabel(false), invertLuminance(false), mouseWheelZoom(false), restrictOverride(false), openGLAccel(false), slideShowDelay(10), modifiersForLens(Qt::ControlModifier|Qt::ShiftModifier), modifiersForSelect(Qt::ControlModifier), modifiersForLinks(Qt::ShiftModifier), thumbnailSize(64), thumbnailSmart(true), searchWordsOnly(true), searchCaseSensitive(false), searchRegExpMode(false), infoDialogTab(0), metaDialogTab(0), printerGamma(0.0), printReverse(false), printCollate(true) { Options mss = (SHOW_MENUBAR|SHOW_STATUSBAR|SHOW_SIDEBAR); forFullScreen.options &= ~(mss|SHOW_SCROLLBARS|SHOW_TOOLBAR|SHOW_SIDEBAR); forSlideShow = forFullScreen; forSlideShow.zoom = QDjVuWidget::ZOOM_FITPAGE; forSlideShow.remember = false; forSlideShow.nsBorderBrush = QBrush(Qt::black); forFullPagePlugin.options &= ~(mss); forEmbeddedPlugin.options &= ~(mss|SHOW_TOOLBAR); forEmbeddedPlugin.remember = false; forEmbeddedPlugin.zoom = 100; forEmbeddedPlugin.nsBorderBrush = QBrush(Qt::white); forEmbeddedPlugin.nsBorderSize = 0; } /*! Return a string with the djview version. */ QString QDjViewPrefs::versionString() { QString version = QString("%1.%2"); version = version.arg((DJVIEW_VERSION>>16)&0xFF); version = version.arg((DJVIEW_VERSION>>8)&0xFF); if (DJVIEW_VERSION & 0xFF) version = version + QString(".%1").arg(DJVIEW_VERSION&0xFF); return version; } /*! Return a string describing a set of modifier keys. */ QString QDjViewPrefs::modifiersToString(Qt::KeyboardModifiers m) { QStringList l; #ifdef Q_OS_DARWIN if (m & Qt::MetaModifier) l << "Control"; if (m & Qt::ControlModifier) l << "Command"; #else if (m & Qt::MetaModifier) l << "Meta"; if (m & Qt::ControlModifier) l << "Control"; #endif if (m & Qt::AltModifier) l << "Alt"; if (m & Qt::ShiftModifier) l << "Shift"; return l.join("+"); } /*! Return the modifiers described in string \a s. */ Qt::KeyboardModifiers QDjViewPrefs::stringToModifiers(QString s) { Qt::KeyboardModifiers m = Qt::NoModifier; QStringList l = s.split("+"); foreach(QString key, l) { key = key.toLower(); if (key == "shift") m |= Qt::ShiftModifier; else if (key == "alt") m |= Qt::AltModifier; #ifdef Q_OS_DARWIN else if (key == "control") m |= Qt::MetaModifier; else if (key == "command") m |= Qt::ControlModifier; #else else if (key == "meta") m |= Qt::MetaModifier; else if (key == "control") m |= Qt::ControlModifier; #endif } return m; } /*! Return a string describing a set of option flags. */ QString QDjViewPrefs::optionsToString(Options options) { const QMetaObject *mo = metaObject(); QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("Option")); return me.valueToKeys(static_cast(options)); } /*! Return the option flags described by a string. */ QDjViewPrefs::Options QDjViewPrefs::stringToOptions(QString s) { const QMetaObject *mo = metaObject(); QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("Option")); int options = me.keysToValue(s.toLatin1()); return QFlag(options); } /*! Return a string describing a set of toolbar flags. */ QString QDjViewPrefs::toolsToString(Tools tools) { const QMetaObject *mo = metaObject(); QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("Tool")); return me.valueToKeys(tools); } /*! Return the toolbar flags described by a string. */ QDjViewPrefs::Tools QDjViewPrefs::stringToTools(QString s) { const QMetaObject *mo = metaObject(); QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("Tool")); int tools = me.keysToValue(s.toLatin1()); return QFlag(tools); } void QDjViewPrefs::loadGroup(QSettings &s, QString name, Saved &saved) { s.beginGroup(name); if (s.contains("remember")) saved.remember = s.value("remember").toBool(); if (s.contains("options")) saved.options = stringToOptions(s.value("options").toString()); if (s.contains("zoom")) saved.zoom = s.value("zoom").toInt(); if (s.contains("state")) saved.state = s.value("state").toByteArray(); s.endGroup(); // we always want these options saved.options |= (QDjViewPrefs::HANDLE_MOUSE | QDjViewPrefs::HANDLE_KEYBOARD | QDjViewPrefs::HANDLE_LINKS ); } /*! Load recent files */ void QDjViewPrefs::loadRecent() { QSettings s; if (s.contains("recentFiles")) recentFiles = s.value("recentFiles").toStringList(); } /*! Load saved preferences and set all member variables. */ void QDjViewPrefs::load() { // load recent files loadRecent(); // load everything else QSettings s; int versionFix = 0; if (s.contains("versionFix")) versionFix = s.value("versionFix").toInt(); loadGroup(s, "forEmbeddedPlugin", forEmbeddedPlugin); loadGroup(s, "forFullPagePlugin", forFullPagePlugin); loadGroup(s, "forStandalone", forStandalone); loadGroup(s, "forFullScreen", forFullScreen); loadGroup(s, "forSlideShow", forSlideShow); if (s.contains("windowSize")) windowSize = s.value("windowSize").toSize(); if (s.contains("windowMaximized")) windowMaximized = s.value("windowMaximized").toBool(); if (s.contains("tools")) tools = stringToTools(s.value("tools").toString()); if (versionFix < 0x40200) tools |= TOOL_BACKFORW; if (s.contains("gamma")) gamma = s.value("gamma").toDouble(); if (s.contains("white")) white = QColor(s.value("white").toString()); if (s.contains("resolution")) resolution = s.value("resolution").toInt(); if (s.contains("cacheSize")) cacheSize = s.value("cacheSize").toLongLong(); if (s.contains("pixelCacheSize")) pixelCacheSize = s.value("pixelCacheSize").toInt(); if (s.contains("lensSize")) lensSize = s.value("lensSize").toInt(); if (s.contains("lensPower")) lensPower = s.value("lensPower").toInt(); if (s.contains("browserProgram")) browserProgram = s.value("browserProgram").toString(); if (s.contains("proxyUrl")) proxyUrl = s.value("proxyUrl").toString(); if (s.contains("enableAnimations")) enableAnimations = s.value("enableAnimations").toBool(); if (s.contains("advancedFeatures")) advancedFeatures = s.value("advancedFeatures").toBool(); if (s.contains("showTextLabel")) showTextLabel = s.value("showTextLabel").toBool(); if (s.contains("invertLuminance")) invertLuminance = s.value("invertLuminance").toBool(); if (s.contains("mouseWheelZoom")) mouseWheelZoom = s.value("mouseWheelZoom").toBool(); if (s.contains("language")) languageOverride = s.value("language").toString(); if (s.contains("restrictOverride")) restrictOverride = s.value("restrictOverride").toBool(); if (s.contains("openGLAccel")) openGLAccel = s.value("openGLAccel").toBool(); if (s.contains("slideShowDelay")) slideShowDelay = s.value("slideShowDelay").toInt(); if (s.contains("modifiersForLens")) modifiersForLens = stringToModifiers(s.value("modifiersForLens").toString()); if (s.contains("modifiersForSelect")) modifiersForSelect = stringToModifiers(s.value("modifiersForSelect").toString()); if (s.contains("modifiersForLinks")) modifiersForLinks = stringToModifiers(s.value("modifiersForLinks").toString()); if (s.contains("thumbnailSize")) thumbnailSize = s.value("thumbnailSize").toInt(); if (s.contains("thumbnailSmart")) thumbnailSmart = s.value("thumbnailSmart").toBool(); if (s.contains("searchWordsOnly")) searchWordsOnly = s.value("searchWordsOnly").toBool(); if (s.contains("searchCaseSensitive")) searchCaseSensitive = s.value("searchCaseSensitive").toBool(); if (s.contains("searchRegExpMode")) searchRegExpMode = s.value("searchRegExpMode").toBool(); if (s.contains("infoDialogTab")) infoDialogTab = s.value("infoDialogTab").toInt(); if (s.contains("metaDialogTab")) metaDialogTab = s.value("metaDialogTab").toInt(); if (s.contains("printerGamma")) printerGamma = s.value("printerGamma").toDouble(); if (s.contains("printerName")) printerName = s.value("printerName").toString(); if (s.contains("printFile")) printFile = s.value("printFile").toString(); if (s.contains("printCollate")) printCollate = s.value("printCollate").toBool(); if (s.contains("printReverse")) printCollate = s.value("printReverse").toBool(); // advertise change emit updated(); } void QDjViewPrefs::saveGroup(QSettings &s, QString name, Saved &saved) { s.beginGroup(name); s.setValue("remember", saved.remember); s.setValue("options", optionsToString(saved.options)); s.setValue("zoom", saved.zoom); s.setValue("state", saved.state); s.endGroup(); } /*! Save recent files. */ void QDjViewPrefs::saveRecent(void) { QSettings s; s.setValue("recentFiles", recentFiles); } /*! Save remembered state. */ void QDjViewPrefs::saveRemembered(void) { QSettings s; s.setValue("version", versionString()); int versionFix = 0; if (s.contains("versionFix")) versionFix = s.value("versionFix").toInt(); if (DJVIEW_VERSION > versionFix) s.setValue("versionFix", DJVIEW_VERSION); if (forEmbeddedPlugin.remember) saveGroup(s, "forEmbeddedPlugin", forEmbeddedPlugin); if (forFullPagePlugin.remember) saveGroup(s, "forFullPagePlugin", forFullPagePlugin); if (forStandalone.remember) saveGroup(s, "forStandalone", forStandalone); if (forFullScreen.remember) saveGroup(s, "forFullScreen", forFullScreen); if (forSlideShow.remember) saveGroup(s, "forSlideShow", forSlideShow); s.setValue("windowSize", windowSize); s.setValue("windowMaximized", windowMaximized); s.setValue("thumbnailSize", thumbnailSize); s.setValue("thumbnailSmart", thumbnailSmart); s.setValue("searchWordsOnly", searchWordsOnly); s.setValue("searchCaseSensitive", searchCaseSensitive); s.setValue("searchRegExpMode", searchRegExpMode); s.setValue("infoDialogTab", infoDialogTab); s.setValue("metaDialogTab", metaDialogTab); s.setValue("printerName", printerName); s.setValue("printFile", printFile); s.setValue("printCollate", printCollate); s.setValue("printReverse", printReverse); } /*! Save all member variables for later use. */ void QDjViewPrefs::save(void) { // save parts saveRecent(); saveRemembered(); // save everything else QSettings s; if (! forEmbeddedPlugin.remember) saveGroup(s, "forEmbeddedPlugin", forEmbeddedPlugin); if (! forFullPagePlugin.remember) saveGroup(s, "forFullPagePlugin", forFullPagePlugin); if (! forStandalone.remember) saveGroup(s, "forStandalone", forStandalone); if (! forFullScreen.remember) saveGroup(s, "forFullScreen", forFullScreen); if (! forSlideShow.remember) saveGroup(s, "forSlideShow", forSlideShow); s.setValue("tools", toolsToString(tools)); s.setValue("gamma", gamma); s.setValue("white", white.name()); s.setValue("resolution", resolution); s.setValue("cacheSize", cacheSize); s.setValue("pixelCacheSize", pixelCacheSize); s.setValue("lensSize", lensSize); s.setValue("lensPower", lensPower); s.setValue("browserProgram", browserProgram); s.setValue("proxyUrl", proxyUrl.toString()); s.setValue("enableAnimations", enableAnimations); s.setValue("advancedFeatures", advancedFeatures); s.setValue("showTextLabel", showTextLabel); s.setValue("invertLuminance", invertLuminance); s.setValue("mouseWheelZoom", mouseWheelZoom); s.setValue("modifiersForLens", modifiersToString(modifiersForLens)); s.setValue("modifiersForSelect", modifiersToString(modifiersForSelect)); s.setValue("modifiersForLinks", modifiersToString(modifiersForLinks)); s.setValue("language", languageOverride); s.setValue("restrictOverride", restrictOverride); s.setValue("openGLAccel", openGLAccel); s.setValue("slideShowDelay", slideShowDelay); s.setValue("printerGamma", printerGamma); } /*! \fn QDjViewPrefs::updated() This signal indicates that viewers should reload the preferences. */ // ======================================== // QDJVIEWGAMMAWIDGET // ======================================== class QDjViewGammaWidget : public QFrame { Q_OBJECT public: QDjViewGammaWidget(QWidget *parent = 0); double gamma() const; public slots: void setGamma(double); void setGammaTimesTen(int); protected: virtual void paintEvent(QPaintEvent *event); private: void paintRect(QPainter &painter, QRect r, bool strip); double g; }; QDjViewGammaWidget::QDjViewGammaWidget(QWidget *parent) : QFrame(parent), g(2.2) { setMinimumSize(64,64); setFrameShape(QFrame::Panel); setFrameShadow(QFrame::Sunken); setLineWidth(1); } double QDjViewGammaWidget::gamma() const { return g; } void QDjViewGammaWidget::setGamma(double gamma) { g = qBound(0.3, gamma, 5.0); update(); } void QDjViewGammaWidget::setGammaTimesTen(int gamma) { setGamma((double)gamma/10); } void QDjViewGammaWidget::paintEvent(QPaintEvent *event) { int w = width() - 16; int h = height() - 16; if (w >= 8 && h >= 8) { QPoint c = rect().center(); QPainter painter; painter.begin(this); int m = qMin( w, h ) / 4; m = m + m; QRect r(c.x()-m, c.y()-m, m, m); painter.fillRect(rect(), Qt::white); paintRect(painter, r.translated(m,0), true); paintRect(painter, r.translated(0,m+1), true); paintRect(painter, r.translated(m,m), false); paintRect(painter, r, false); painter.end(); QFrame::paintEvent(event); } } void QDjViewGammaWidget::paintRect(QPainter &painter, QRect r, bool strip) { if (strip) { // draw stripes painter.setPen(QPen(Qt::black, 1)); painter.setRenderHint(QPainter::Antialiasing, false); for(int i=r.top(); i<=r.bottom(); i+=2) painter.drawLine(r.left(), i, r.right(), i); } else { // see DjVuImage.cpp double gamma = g; if (gamma < 0.1) gamma = 0.1; else if (gamma > 10) gamma = 10; // see GPixmap.cpp double x = ::pow(0.5, 1.0/gamma); int gray = (int)floor(255.0 * x + 0.5); // fill gray = qBound(0, gray, 255); painter.fillRect(r, QColor(gray,gray,gray)); } } // ======================================== // QDJVIEWMODIFIERSCOMBOBOX // ======================================== class QDjViewModifiersComboBox : public QComboBox { Q_OBJECT Q_PROPERTY(Qt::KeyboardModifiers value READ value WRITE setValue) public: QDjViewModifiersComboBox(QWidget *parent); Qt::KeyboardModifiers value() const; public slots: void setValue(Qt::KeyboardModifiers m); void insertValue(Qt::KeyboardModifiers m); protected slots: void editingFinished(); private: static const char *none; }; const char* QDjViewModifiersComboBox::none = "None"; QDjViewModifiersComboBox::QDjViewModifiersComboBox(QWidget *parent) : QComboBox(parent) { setEditable(true); setInsertPolicy(QComboBox::NoInsert); // validator QStringList keynames; keynames << "Shift"; keynames << "Control"; keynames << "Alt"; #ifdef Q_OS_DARWIN keynames << "Command"; #else keynames << "Meta"; #endif QString keys = "(" + keynames.join("|") + ")"; keys = keys + "(\\+" + keys + ")*"; keys = keys + "|" + none; QRegExp re( keys, Qt::CaseInsensitive); setValidator(new QRegExpValidator(re, this)); // menu entries insertValue(Qt::ShiftModifier); insertValue(Qt::ControlModifier); insertValue(Qt::AltModifier); insertValue(Qt::MetaModifier); insertValue(Qt::ShiftModifier|Qt::ControlModifier); insertValue(Qt::ControlModifier|Qt::AltModifier); setValue(Qt::NoModifier); connect(lineEdit(), SIGNAL(editingFinished()), this, SLOT(editingFinished()) ); } void QDjViewModifiersComboBox::editingFinished() { QDjViewPrefs *prefs = QDjViewPrefs::instance(); QString text = lineEdit()->text(); Qt::KeyboardModifiers m = prefs->stringToModifiers(text); text = (m) ? prefs->modifiersToString(m) : none; setEditText(text); } Qt::KeyboardModifiers QDjViewModifiersComboBox::value() const { const_cast(this)->editingFinished(); QString text = lineEdit()->text(); QDjViewPrefs *prefs = QDjViewPrefs::instance(); return prefs->stringToModifiers(text); } void QDjViewModifiersComboBox::setValue(Qt::KeyboardModifiers m) { QDjViewPrefs *prefs = QDjViewPrefs::instance(); QString text = (m) ? prefs->modifiersToString(m) : none; setEditText(text); } void QDjViewModifiersComboBox::insertValue(Qt::KeyboardModifiers m) { QDjViewPrefs *prefs = QDjViewPrefs::instance(); QString text = (m) ? prefs->modifiersToString(m) : none; QVariant vm(m); if (findData(vm) < 0) insertItem(count(), text, vm); } // ======================================== // QDJVIEWPREFSDIALOG // ======================================== #include "ui_qdjviewprefsdialog.h" static QPointer prefsDialog; /*! Returns the single preference dialog. */ QDjViewPrefsDialog * QDjViewPrefsDialog::instance() { QMutex mutex; QMutexLocker locker(&mutex); if (! prefsDialog) { QDjViewPrefsDialog *main = new QDjViewPrefsDialog(); main->setWindowTitle(tr("Preferences[*] - DjView")); main->setAttribute(Qt::WA_DeleteOnClose, true); main->setAttribute(Qt::WA_QuitOnClose, false); prefsDialog = main; } return prefsDialog; } struct QDjViewPrefsDialog::Private { QDjVuContext *context; Ui::QDjViewPrefsDialog ui; QDjViewPrefs::Saved saved[5]; int slideShowDelay; int currentSaved; }; QDjViewPrefsDialog::~QDjViewPrefsDialog() { delete d; } static inline void setHelp(QWidget *w, QString s) { w->setWhatsThis(s); } QDjViewPrefsDialog::QDjViewPrefsDialog() : QDialog(), d(new Private) { // sanitize d->context = 0; d->currentSaved = -1; // prepare ui setAttribute(Qt::WA_GroupLeader, true); d->ui.setupUi(this); // connect buttons (some are connected in the ui file) connect(d->ui.applyButton, SIGNAL(clicked()), this, SLOT(apply()) ); connect(d->ui.gammaSlider, SIGNAL(valueChanged(int)), d->ui.gammaWidget, SLOT(setGammaTimesTen(int)) ); connect(d->ui.forceResolutionCheckBox, SIGNAL(toggled(bool)), this, SLOT(forceResolutionChanged()) ); connect(d->ui.resetButton, SIGNAL(clicked()), this, SLOT(reset()) ); connect(d->ui.cacheClearButton, SIGNAL(clicked()), this, SLOT(cacheClear()) ); connect(d->ui.modeComboBox, SIGNAL(activated(int)), this, SLOT(modeComboChanged(int)) ); connect(d->ui.zoomCombo->lineEdit(), SIGNAL(editingFinished()), this, SLOT(zoomComboEdited()) ); // modified connectModified(d->ui.screenTab); connectModified(d->ui.rememberCheckBox); connectModified(d->ui.showGroupBox); connectModified(d->ui.modeGroupBox); connectModified(d->ui.keysTab); connectModified(d->ui.lensTab); connectModified(d->ui.networkTab); connectModified(d->ui.advancedTab); // whatsthis setHelp(d->ui.screenTab, tr("Screen gamma correction." "
    The best color rendition is achieved" " by adjusting the gamma correction slider" " and choosing the position that makes the" " gray square as uniform as possible." "

    Screen resolution." "
    This option forces a particular resolution instead of using" " the unreliable resolution advertised by the operating system." " Forcing the resolution to 100 dpi matches the behavior" " of the djvulibre command line tools." "") ); setHelp(d->ui.interfaceTab, tr("Initial interface setup." "
    DjView can run as a standalone viewer," " as a full screen viewer, as a full page browser plugin," " or as a plugin embedded inside a html page." " For each case, check the Remember box to" " automatically save and restore the interface setup." " Otherwise, specify an initial configuration." "") ); setHelp(d->ui.keysTab, tr("Modifiers keys." "
    Define which combination of modifier keys" " will show the manifying lens, temporarily enable" " the selection mode, or highlight the hyperlinks." "") ); setHelp(d->ui.lensTab, tr("Magnifying lens." "
    The magnifying lens appears when you depress" " the modifier keys specified in tab Keys." " This panel lets you choose the power and the size" " of the magnifying lens." "") ); setHelp(d->ui.advancedTab, tr("Advanced." "
    You can override the default interface language, " "disable the page animations, or enable additional " "menu entries that are useful for authoring DjVu files." "You can also disable the printing or saving restrictions " "dictated by certain web sites. The manual color " "correction can be useful with old printers." "")); setHelp(d->ui.networkTab, tr("Network proxy settings." "
    These proxy settings are used when" " the standalone djview viewer accesses" " a djvu document through a http url." " The djview plugin always uses the proxy" " settings of the web browser." "

    Cache settings." "
    The pixel cache stores image data" " located outside the visible area." " This cache makes panning smoother." " The decoded page cache contains partially" " decoded pages. It provides faster response times" " when navigating a multipage document or when returning" " to a previously viewed page. Clearing this cache" " might be useful to reflect a change in the page" " data without restarting the DjVu viewer.""" "") ); } void QDjViewPrefsDialog::connectModified(QWidget *w) { if (w->inherits("QComboBox")) connect(w, SIGNAL(editTextChanged(QString)), this, SLOT(setModified())); if (w->inherits("QComboBox")) connect(w, SIGNAL(currentIndexChanged(int)), this, SLOT(setModified())); if (w->inherits("QSpinBox")) connect(w, SIGNAL(valueChanged(int)), this, SLOT(setModified())); if (w->inherits("QAbstractButton")) connect(w, SIGNAL(toggled(bool)), this, SLOT(setModified())); if (w->inherits("QAbstractSlider")) connect(w, SIGNAL(valueChanged(int)), this, SLOT(setModified())); QObject *child; foreach(child, w->children()) if (child->isWidgetType()) connectModified(qobject_cast(child)); } void QDjViewPrefsDialog::load(QDjView *djview) { // load preferences into ui QDjViewPrefs *prefs = QDjViewPrefs::instance(); d->context = &djview->getDjVuContext(); // 1- screen tab d->ui.gammaSlider->setValue((int)(prefs->gamma * 10)); int res = prefs->resolution; d->ui.forceResolutionCheckBox->setChecked(res > 0); d->ui.resolutionSpinBox->setValue((res>0) ? res : logicalDpiY()); d->ui.invertLuminanceCheckBox->setChecked(prefs->invertLuminance); // 2- interface tab QComboBox *cb = d->ui.modeComboBox; cb->clear(); d->saved[0] = prefs->forStandalone; cb->addItem(tr("Standalone Viewer"), QDjView::STANDALONE); d->saved[1] = prefs->forFullScreen; cb->addItem(tr("Standalone Viewer (Full Screen mode)"), QDjView::STANDALONE_FULLSCREEN); d->saved[2] = prefs->forSlideShow; cb->addItem(tr("Standalone Viewer (Slideshow mode)"), QDjView::STANDALONE_SLIDESHOW); d->saved[3] = prefs->forFullPagePlugin; cb->addItem(tr("Full Page Plugin"), QDjView::FULLPAGE_PLUGIN); d->saved[4] = prefs->forEmbeddedPlugin; cb->addItem(tr("Embedded Plugin"), QDjView::EMBEDDED_PLUGIN); d->slideShowDelay = prefs->slideShowDelay; djview->fillZoomCombo(d->ui.zoomCombo); int n = qMax(0, cb->findData(djview->getViewerMode())); modeComboChanged(n); cb->setCurrentIndex(n); // 3- keys tab d->ui.keysForLensCombo->setValue(prefs->modifiersForLens); d->ui.keysForSelectCombo->setValue(prefs->modifiersForSelect); d->ui.keysForLinksCombo->setValue(prefs->modifiersForLinks); d->ui.wheelScrollButton->setChecked(! prefs->mouseWheelZoom); d->ui.wheelZoomButton->setChecked(prefs->mouseWheelZoom); // 4- lens tab bool lens = (prefs->lensPower > 0) && (prefs->lensSize > 0); d->ui.lensEnableCheckBox->setChecked(lens); d->ui.lensPowerSpinBox->setValue(lens ? qBound(1,prefs->lensPower,10) : 3); d->ui.lensSizeSpinBox->setValue(lens ? qBound(50,prefs->lensSize,500) : 300); // 5- network tab bool proxy = prefs->proxyUrl.isValid(); if (prefs->proxyUrl.scheme() != "http" || prefs->proxyUrl.host().isEmpty()) proxy = false; if (proxy) { QUrl url = prefs->proxyUrl; int port = url.port(); d->ui.proxyHostLineEdit->setText(url.host()); d->ui.proxyPortSpinBox->setValue(port>=0 ? port : 8080); d->ui.proxyUserLineEdit->setText(url.userName()); d->ui.proxyPasswordLineEdit->setText(url.password()); } d->ui.proxyCheckBox->setChecked(proxy); qreal k256 = 256 * 1024; qreal k1024 = 1024 * 1024; d->ui.pixelCacheSpinBox->setValue(qRound(prefs->pixelCacheSize / k256)); d->ui.pageCacheSpinBox->setValue(qRound(prefs->cacheSize / k1024)); // 6- advanced tab double pgamma = prefs->printerGamma; loadLanguageComboBox(prefs->languageOverride); d->ui.advancedCheckBox->setChecked(prefs->advancedFeatures); d->ui.animationCheckBox->setChecked(prefs->enableAnimations); d->ui.textLabelCheckBox->setChecked(prefs->showTextLabel); d->ui.restrictOverrideCheckBox->setChecked(prefs->restrictOverride); d->ui.openGLCheckBox->setChecked(prefs->openGLAccel); d->ui.printerManualCheckBox->setChecked(pgamma > 0); d->ui.printerGammaSpinBox->setValue((pgamma > 0) ? pgamma : 2.2); // no longer modified setWindowModified(false); d->ui.applyButton->setEnabled(false); } void QDjViewPrefsDialog::loadLanguageComboBox(QString lang) { // supported languages static const char *languages[] = { "cs","de","en","es","fr","it","ja","ru","uk", "zh_CN","zh_TW",0 } ; // get application QComboBox *cb = d->ui.languageComboBox; QCheckBox *db = d->ui.languageCheckBox; QDjViewApplication *app = qobject_cast(qApp); db->setEnabled(app != 0); cb->clear(); // prepare combobox static struct { const char *src; const char *com; } thisLang[] = { QT_TRANSLATE_NOOP3("Generic", "thisLanguage", "Name of THIS language") }; QString myLanguage = QApplication::translate("Generic", thisLang[0].src); if (myLanguage == thisLang[0].src) myLanguage = "English"; int index = -1; if (app) for (int i=0; languages[i]; i++) { QString nlang = languages[i]; QString xlang = QString::null; QTranslator *dTrans = new QTranslator(); QTranslator *qTrans = new QTranslator(); if (app->loadTranslators(QStringList(nlang), dTrans, qTrans)) xlang = dTrans->translate("Generic", thisLang[0].src); else if (nlang == "en" || nlang.startsWith("en")) xlang = "English"; if (lang == nlang && xlang.size() > 0) index = cb->count(); if (index < 0 && xlang == myLanguage) index = cb->count(); if (xlang.size() > 0) cb->addItem(xlang, nlang); delete dTrans; delete qTrans; } db->setChecked(index >= 0 && lang.size() > 0); cb->setCurrentIndex(index); } void QDjViewPrefsDialog::apply() { // save ui into preferences QDjViewPrefs *prefs = QDjViewPrefs::instance(); // 1- screen tab prefs->gamma = d->ui.gammaSlider->value() / 10.0; prefs->resolution = 0; if (d->ui.forceResolutionCheckBox->isChecked()) prefs->resolution = d->ui.resolutionSpinBox->value(); prefs->invertLuminance = d->ui.invertLuminanceCheckBox->isChecked(); // 2- interface tab QComboBox *cb = d->ui.modeComboBox; int n = cb->currentIndex(); modeComboChanged(n); for (int i=0; i<5; i++) switch (cb->itemData(i).toInt()) { case QDjView::STANDALONE: prefs->forStandalone = d->saved[i]; break; case QDjView::STANDALONE_SLIDESHOW: prefs->forSlideShow = d->saved[i]; break; case QDjView::STANDALONE_FULLSCREEN: prefs->forFullScreen = d->saved[i]; break; case QDjView::EMBEDDED_PLUGIN: prefs->forEmbeddedPlugin = d->saved[i]; break; case QDjView::FULLPAGE_PLUGIN: prefs->forFullPagePlugin = d->saved[i]; break; } // 3- keys prefs->modifiersForLens = d->ui.keysForLensCombo->value(); prefs->modifiersForSelect = d->ui.keysForSelectCombo->value(); prefs->modifiersForLinks = d->ui.keysForLinksCombo->value(); prefs->mouseWheelZoom = d->ui.wheelZoomButton->isChecked(); // 4- lens tab bool lens = d->ui.lensEnableCheckBox->isChecked(); prefs->lensPower = (lens) ? d->ui.lensPowerSpinBox->value() : 0; prefs->lensSize = d->ui.lensSizeSpinBox->value(); // 5- network tab prefs->proxyUrl = QUrl(); if (d->ui.proxyCheckBox->isChecked()) { prefs->proxyUrl.setScheme("http"); prefs->proxyUrl.setHost(d->ui.proxyHostLineEdit->text()); prefs->proxyUrl.setPort(d->ui.proxyPortSpinBox->value()); prefs->proxyUrl.setUserName(d->ui.proxyUserLineEdit->text()); prefs->proxyUrl.setPassword(d->ui.proxyPasswordLineEdit->text()); } prefs->pixelCacheSize = d->ui.pixelCacheSpinBox->value() * 256 * 1024; prefs->cacheSize = d->ui.pageCacheSpinBox->value() * 1024 * 1024; // 6- advanced tab prefs->languageOverride = QString::null; if (d->ui.languageCheckBox->isChecked()) { int n = d->ui.languageComboBox->currentIndex(); prefs->languageOverride = d->ui.languageComboBox->itemData(n).toString(); } prefs->enableAnimations = d->ui.animationCheckBox->isChecked(); prefs->advancedFeatures = d->ui.advancedCheckBox->isChecked(); prefs->showTextLabel = d->ui.textLabelCheckBox->isChecked(); prefs->restrictOverride = d->ui.restrictOverrideCheckBox->isChecked(); prefs->openGLAccel = d->ui.openGLCheckBox->isChecked(); prefs->printerGamma = 0; if (d->ui.printerManualCheckBox->isChecked()) prefs->printerGamma = d->ui.printerGammaSpinBox->value(); // broadcast change setWindowModified(false); d->ui.applyButton->setEnabled(false); prefs->save(); emit prefs->updated(); } void QDjViewPrefsDialog::reset() { // 1- gamma tab d->ui.gammaSlider->setValue(22); d->ui.forceResolutionCheckBox->setChecked(true); d->ui.resolutionSpinBox->setValue(100); // 2- interface tab QDjViewPrefs::Saved defsaved; QDjViewPrefs::Options optMSS = (QDjViewPrefs::SHOW_MENUBAR| QDjViewPrefs::SHOW_STATUSBAR| QDjViewPrefs::SHOW_SIDEBAR); QDjViewPrefs::Options optS = QDjViewPrefs::SHOW_SCROLLBARS; QDjViewPrefs::Options optT = QDjViewPrefs::SHOW_TOOLBAR; QComboBox *cb = d->ui.modeComboBox; for (int i=0; i<5; i++) { d->saved[i] = defsaved; switch (cb->itemData(i).toInt()) { case QDjView::STANDALONE_SLIDESHOW: d->saved[i].remember = false; d->saved[i].zoom = QDjVuWidget::ZOOM_FITPAGE; case QDjView::STANDALONE_FULLSCREEN: d->saved[i].options &= ~(optMSS|optS|optT); case QDjView::STANDALONE: break; case QDjView::EMBEDDED_PLUGIN: d->saved[i].remember = false; d->saved[i].options &= ~(optMSS|optT); d->saved[i].zoom = 100; break; case QDjView::FULLPAGE_PLUGIN: d->saved[i].options &= ~(optMSS); break; } } d->slideShowDelay = 10; d->currentSaved = -1; modeComboChanged(d->ui.modeComboBox->currentIndex()); // 3- keys tab d->ui.keysForLensCombo->setValue(Qt::ShiftModifier|Qt::ControlModifier); d->ui.keysForSelectCombo->setValue(Qt::ControlModifier); d->ui.keysForLinksCombo->setValue(Qt::ShiftModifier); // 4- lens tab d->ui.lensEnableCheckBox->setChecked(true); d->ui.lensPowerSpinBox->setValue(3); d->ui.lensSizeSpinBox->setValue(300); // 5- network tab d->ui.proxyCheckBox->setChecked(false); d->ui.pixelCacheSpinBox->setValue(1); d->ui.pageCacheSpinBox->setValue(10); // 6- advanced tab d->ui.languageCheckBox->setChecked(false); d->ui.animationCheckBox->setChecked(true); d->ui.advancedCheckBox->setChecked(false); d->ui.textLabelCheckBox->setChecked(false); d->ui.openGLCheckBox->setChecked(false); d->ui.printerManualCheckBox->setChecked(false); d->ui.printerGammaSpinBox->setValue(2.2); } void QDjViewPrefsDialog::setModified() { d->ui.applyButton->setEnabled(true); setWindowModified(true); } void QDjViewPrefsDialog::done(int result) { if (result == QDialog::Accepted) apply(); QDialog::done(result); } void QDjViewPrefsDialog::cacheClear() { if (d->context) ddjvu_cache_clear(*d->context); } template static inline void set_reset(QFlags &x, T y, bool plus, bool minus=true) { if (plus) x |= y; else if (minus) x &= ~y; } void QDjViewPrefsDialog::modeComboChanged(int n) { QComboBox *cb = d->ui.modeComboBox; if (d->currentSaved >=0 && d->currentSaved <5) { // save ui values QDjViewPrefs::Saved &saved = d->saved[d->currentSaved]; saved.remember = d->ui.rememberCheckBox->isChecked(); set_reset(saved.options, QDjViewPrefs::SHOW_MENUBAR, d->ui.menuBarCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_TOOLBAR, d->ui.toolBarCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_SCROLLBARS, d->ui.scrollBarsCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_STATUSBAR, d->ui.statusBarCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_SIDEBAR, d->ui.sideBarCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_FRAME, d->ui.frameCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::SHOW_MAPAREAS, d->ui.mapAreasCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::LAYOUT_CONTINUOUS, d->ui.continuousCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::LAYOUT_SIDEBYSIDE, d->ui.sideBySideCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::LAYOUT_COVERPAGE, d->ui.coverPageCheckBox->isChecked() ); set_reset(saved.options, QDjViewPrefs::LAYOUT_RIGHTTOLEFT, d->ui.rtolCheckBox->isChecked() ); // zoom bool okay; int zoomIndex = d->ui.zoomCombo->currentIndex(); QString zoomText = d->ui.zoomCombo->lineEdit()->text(); int zoom = zoomText.replace(QRegExp("\\s*%?$"),"").trimmed().toInt(&okay); if (okay && zoom>=QDjVuWidget::ZOOM_MIN && zoom<=QDjVuWidget::ZOOM_MAX) saved.zoom = zoom; else if (zoomIndex >= 0) saved.zoom = d->ui.zoomCombo->itemData(zoomIndex).toInt(); // delay if (cb->itemData(d->currentSaved) == QDjView::STANDALONE_SLIDESHOW) d->slideShowDelay = d->ui.slideShowSpinBox->value(); } d->currentSaved = n; if (d->currentSaved >=0 && d->currentSaved <5) { // save modified flag bool modified = isWindowModified(); // load ui values QDjViewPrefs::Saved &saved = d->saved[d->currentSaved]; d->ui.rememberCheckBox->setChecked(saved.remember); QDjViewPrefs::Options opt = saved.options; d->ui.menuBarCheckBox->setChecked(opt & QDjViewPrefs::SHOW_MENUBAR); d->ui.toolBarCheckBox->setChecked(opt & QDjViewPrefs::SHOW_TOOLBAR); d->ui.scrollBarsCheckBox->setChecked(opt & QDjViewPrefs::SHOW_SCROLLBARS); d->ui.statusBarCheckBox->setChecked(opt & QDjViewPrefs::SHOW_STATUSBAR); d->ui.sideBarCheckBox->setChecked(opt & QDjViewPrefs::SHOW_SIDEBAR); d->ui.frameCheckBox->setChecked(opt & QDjViewPrefs::SHOW_FRAME); d->ui.mapAreasCheckBox->setChecked(opt & QDjViewPrefs::SHOW_MAPAREAS); d->ui.continuousCheckBox->setChecked(opt & QDjViewPrefs::LAYOUT_CONTINUOUS); d->ui.sideBySideCheckBox->setChecked(opt & QDjViewPrefs::LAYOUT_SIDEBYSIDE); d->ui.coverPageCheckBox->setChecked(opt & QDjViewPrefs::LAYOUT_COVERPAGE); d->ui.rtolCheckBox->setChecked(opt & QDjViewPrefs::LAYOUT_RIGHTTOLEFT); // zoom int zoomIndex = d->ui.zoomCombo->findData(QVariant(saved.zoom)); d->ui.zoomCombo->clearEditText(); d->ui.zoomCombo->setCurrentIndex(zoomIndex); if (zoomIndex < 0 && saved.zoom >= QDjVuWidget::ZOOM_MIN && saved.zoom <= QDjVuWidget::ZOOM_MAX) d->ui.zoomCombo->setEditText(QString("%1%").arg(saved.zoom)); else if (zoomIndex >= 0) d->ui.zoomCombo->setEditText(d->ui.zoomCombo->itemText(zoomIndex)); // delay d->ui.slideShowSpinBox->setValue(d->slideShowDelay); d->ui.slideShowSpinBox->setVisible(d->currentSaved == 2); d->ui.slideShowLabel->setVisible(d->currentSaved == 2); // reset modified flag setWindowModified(modified); } } void QDjViewPrefsDialog::zoomComboEdited() { bool okay; QString zoomText = d->ui.zoomCombo->lineEdit()->text(); int zoom = zoomText.replace(QRegExp("\\s*%?$"),"").trimmed().toInt(&okay); if (d->ui.zoomCombo->findText(zoomText) >= 0) d->ui.zoomCombo->setEditText(zoomText); else if (okay && zoom >= QDjVuWidget::ZOOM_MIN && zoom <= QDjVuWidget::ZOOM_MAX) d->ui.zoomCombo->setEditText(QString("%1%").arg(zoom)); } void QDjViewPrefsDialog::forceResolutionChanged() { if (! d->ui.forceResolutionCheckBox->isChecked()) d->ui.resolutionSpinBox->setValue(physicalDpiY()); } // ---------------------------------------- // MOC #include "qdjviewprefs.moc" /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewprefs.h000066400000000000000000000170011264256014000166250ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEWPREFS_H #define QDJVIEWPREFS_H #if AUTOCONF # include "config.h" #endif #include "version.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ======================================== // QDJVIEWPREFS // ======================================== class QDjViewPrefs : public QObject { Q_OBJECT Q_ENUMS(Option Tool) public: enum Option { SHOW_MENUBAR = 0x000001, SHOW_TOOLBAR = 0x000002, SHOW_SIDEBAR = 0x000004, SHOW_STATUSBAR = 0x000010, SHOW_SCROLLBARS = 0x000020, SHOW_FRAME = 0x000100, SHOW_MAPAREAS = 0x000200, SHOW_MASK = 0x000FFF, LAYOUT_CONTINUOUS = 0x001000, LAYOUT_SIDEBYSIDE = 0x002000, LAYOUT_COVERPAGE = 0x004000, LAYOUT_RIGHTTOLEFT = 0x008000, LAYOUT_MASK = 0x00F000, HANDLE_MOUSE = 0x100000, HANDLE_KEYBOARD = 0x200000, HANDLE_LINKS = 0x400000, HANDLE_CONTEXTMENU = 0x800000, }; enum Tool { TOOLBAR_TOP = 0x80000000, TOOLBAR_BOTTOM = 0x40000000, TOOLBAR_AUTOHIDE = 0x10000000, TOOL_MODECOMBO = 0x00001, TOOL_MODEBUTTONS = 0x00002, TOOL_ZOOMCOMBO = 0x00004, TOOL_ZOOMBUTTONS = 0x00008, TOOL_PAGECOMBO = 0x00010, TOOL_PREVNEXT = 0x00020, TOOL_FIRSTLAST = 0x00040, TOOL_BACKFORW = 0x00080, TOOL_NEW = 0x00100, TOOL_OPEN = 0x00200, TOOL_FIND = 0x00400, TOOL_SELECT = 0x00800, TOOL_SAVE = 0x01000, TOOL_PRINT = 0x02000, TOOL_LAYOUT = 0x04000, TOOL_ROTATE = 0x08000, TOOL_WHATSTHIS = 0x10000, }; Q_DECLARE_FLAGS(Options, Option) Q_DECLARE_FLAGS(Tools, Tool) static const Options defaultOptions; static const Tools defaultTools; static QString versionString(); QString modifiersToString(Qt::KeyboardModifiers); Qt::KeyboardModifiers stringToModifiers(QString); QString optionsToString(Options); Options stringToOptions(QString); QString toolsToString(Tools); Tools stringToTools(QString); struct Saved { Saved(); bool remember; //!< Save before closing. Options options; //!< Miscellaneous flags. int zoom; //!< Zoom factor. QByteArray state; //!< Toolbar and sidebar geometry. QBrush nsBorderBrush; //!< Border brush (not saved) int nsBorderSize; //!< Border size (not saved) }; // Preferences remembered between program invocations. Saved forEmbeddedPlugin; //!< Prefs for the embedded plugin mode. Saved forFullPagePlugin; //!< Prefs for the full page plugin mode. Saved forStandalone; //!< Prefs for the standalone viewer mode. Saved forFullScreen; //!< Prefs for the full screen mode. Saved forSlideShow; //!< Prefs for the slideshow mode. QSize windowSize; //!< Size of the standalone window. bool windowMaximized; //!< Window was maximized. // Preferences set via the preference dialog. Tools tools; //!< Toolbar composition. double gamma; //!< Gamma value of the target screen. QColor white; //!< White point of the target screen. int resolution; //!< Forced screen resolution or zero. qlonglong cacheSize; //!< Size of the decoded page cache. int pixelCacheSize; //!< Size of the pixel cache. int lensSize; //!< Size of the magnification lens. int lensPower; //!< Power of the magnification lens. QString browserProgram; //!< Preferred web browser. QUrl proxyUrl; //!< Proxy information. bool enableAnimations; //!< Animated page movements. bool advancedFeatures; //!< Advanced features. bool showTextLabel; //!< Show text label. bool invertLuminance; //!< Invert luminance by default. bool mouseWheelZoom; //!< Mouse wheel zooms instead of scroll. QString languageOverride; //!< Language settings bool restrictOverride; //!< Override noprint/nosave bool openGLAccel; //!< Use opengl acceleration int slideShowDelay; //!< Delay between page switches Qt::KeyboardModifiers modifiersForLens; //!< Keys for the lens. Qt::KeyboardModifiers modifiersForSelect; //!< Keys for selecting. Qt::KeyboardModifiers modifiersForLinks; //!< Keys for showing the links. // Sidebar preferences int thumbnailSize; bool thumbnailSmart; bool searchWordsOnly; bool searchCaseSensitive; bool searchRegExpMode; // Dialog preferences int infoDialogTab; //!< Active tab in info dialog. int metaDialogTab; //!< Active tab in meta dialog. double printerGamma; //!< Gamma value for the printer. QString printerName; //!< Name of the printer QString printFile; //!< Output file for print data bool printReverse; //!< Print revere flag bool printCollate; //!< Print collate flag // Recent files QStringList recentFiles; //!< Recently opened files public: static QDjViewPrefs *instance(void); public slots: void loadRecent(); void load(); void saveRecent(); void saveRemembered(); void save(); signals: void updated(); private: QDjViewPrefs(void); void loadGroup(QSettings &s, QString name, Saved &saved); void saveGroup(QSettings &s, QString name, Saved &saved); friend class QDjViewPrefsDialog; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDjViewPrefs::Options) Q_DECLARE_OPERATORS_FOR_FLAGS(QDjViewPrefs::Tools) // ======================================== // QDJVIEWPREFSDIALOG // ======================================== class QDjView; class QDjViewPrefsDialog : public QDialog { Q_OBJECT public: ~QDjViewPrefsDialog(); static QDjViewPrefsDialog *instance(); public slots: void load(QDjView *djview); void apply(); void reset(); virtual void done(int); protected slots: void cacheClear(); void modeComboChanged(int); void zoomComboEdited(); void setModified(); void forceResolutionChanged(); private: QDjViewPrefsDialog(); void connectModified(QWidget *w); void loadLanguageComboBox(QString lang); struct Private; Private *d; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" "qlonglong" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewprefsdialog.ui000066400000000000000000001323331264256014000202010ustar00rootroot00000000000000 QDjViewPrefsDialog 0 0 622 437 Dialog 0 Qt::ElideNone &Screen Gamma 6 0 0 0 <html>Screen color correction.<br>Adjust slider until gray shades look similar.</html> Qt::RichText Qt::AlignCenter true gammaSlider 5 50 22 Qt::Horizontal QSlider::TicksBelow 5 6 0 Darker Qt::Horizontal 40 20 Lighter Qt::Horizontal 5 20 119 119 119 119 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 5 20 true Display Force screen &resolution true Qt::Horizontal QSizePolicy::Maximum 40 20 0 0 Qt::AlignCenter dpi 25 600 100 Qt::Horizontal QSizePolicy::Maximum 80 20 Force inverted luminance &Interface 6 0 Options for modeComboBox Qt::Horizontal 40 20 &Remember initial state from last invocation Show &Menu bar &Tool bar Sc&rollbars Stat&us bar &Side bar Qt::Vertical 20 40 Display &Zoom: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter zoomCombo true Timer: slideShowSpinBox true s 3600 10 Qt::Vertical QSizePolicy::Preferred 20 9 Display page &frames Display &annotations Qt::Vertical 20 40 Layout Continuous Qt::Vertical QSizePolicy::Preferred 20 9 Side-by-side true Qt::Horizontal QSizePolicy::Fixed 9 20 Cover Page Right-to-Left Qt::Horizontal 40 20 Qt::Vertical 20 40 &Keys Keys 9 9 For displaying hyper&links: keysForLinksCombo For &selecting text or images: keysForSelectCombo For displaying the &lens: keysForLensCombo true true true Mouse wheel Mouse wheel scrolls the page true Mouse wheel changes the zoom factor Qt::Vertical 20 5 &Lens 6 9 Enable magnifying &lens true Lens options 9 6 Lens &size: lensSizeSpinBox Magnifying &power: lensPowerSpinBox x 1 10 3 pixels 50 500 50 300 Qt::Vertical 20 5 &Network true Proxy settings Use pro&xy to access the network false &Host: proxyHostLineEdit 1 0 &Port: proxyPortSpinBox 65535 8080 &User: proxyUserLineEdit 1 0 Pass&word: proxyPasswordLineEdit QLineEdit::Password Cache 9 6 &Clear false MB 32 10 MB 6 1 1 &Decoded page cache: pageCacheSpinBox &Pixel cache: pixelCacheSpinBox Qt::Vertical 17 8 &Advanced Interface Force language (next time djview runs) false Qt::Horizontal 40 20 Enable page animations true Enable advanced features in menus Show hidden text in status bar Miscellaneous Render with openGL when available true Override saving and printing restrictions Manual printer color correction false Qt::AlignCenter gamma= 1 0.500000000000000 5.000000000000000 0.100000000000000 2.200000000000000 Qt::Horizontal 5 20 Qt::Vertical 20 5 6 0 &Defaults false Qt::Horizontal 32 32 false &Apply &Ok Cancel QDjViewModifiersComboBox QComboBox

    qdjviewprefs.h
    QDjViewGammaWidget QFrame
    qdjviewprefs.h
    1
    tabWidget gammaSlider forceResolutionCheckBox resolutionSpinBox invertLuminanceCheckBox modeComboBox rememberCheckBox menuBarCheckBox toolBarCheckBox scrollBarsCheckBox statusBarCheckBox sideBarCheckBox zoomCombo slideShowSpinBox frameCheckBox mapAreasCheckBox continuousCheckBox sideBySideCheckBox coverPageCheckBox rtolCheckBox keysForLensCombo keysForSelectCombo keysForLinksCombo wheelScrollButton wheelZoomButton lensEnableCheckBox lensPowerSpinBox lensSizeSpinBox proxyCheckBox proxyHostLineEdit proxyPortSpinBox proxyUserLineEdit proxyPasswordLineEdit pixelCacheSpinBox pageCacheSpinBox cacheClearButton languageCheckBox languageComboBox animationCheckBox advancedCheckBox textLabelCheckBox openGLCheckBox restrictOverrideCheckBox printerManualCheckBox printerGammaSpinBox resetButton applyButton okButton cancelButton okButton clicked() QDjViewPrefsDialog accept() 530 426 96 254 cancelButton clicked() QDjViewPrefsDialog reject() 611 426 179 282 lensEnableCheckBox toggled(bool) lensGroupBox setEnabled(bool) 91 47 101 53 printerManualCheckBox toggled(bool) printerGammaSpinBox setEnabled(bool) 119 86 119 86 forceResolutionCheckBox toggled(bool) resolutionSpinBox setEnabled(bool) 227 309 503 309 rememberCheckBox toggled(bool) showGroupBox setDisabled(bool) 118 95 117 169 sideBySideCheckBox toggled(bool) coverPageCheckBox setEnabled(bool) 589 225 472 247 sideBySideCheckBox toggled(bool) rtolCheckBox setEnabled(bool) 474 217 472 271 rememberCheckBox toggled(bool) modeGroupBox setDisabled(bool) 162 85 180 123 rememberCheckBox toggled(bool) layoutGroupBox setDisabled(bool) 249 86 600 215 languageCheckBox toggled(bool) languageComboBox setEnabled(bool) 119 77 119 77 proxyCheckBox toggled(bool) proxySettings setEnabled(bool) 119 77 119 77 djview4-4.10.5/src/qdjviewprintdialog.ui000066400000000000000000000245731264256014000202240ustar00rootroot00000000000000 QDjViewPrintDialog 0 0 427 361 Dialog 9 6 0 Print 9 6 Print 9 6 &Document true C&urrent page 0 6 &Pages to Qt::AlignCenter Qt::Horizontal QSizePolicy::Minimum 40 10 Destination 9 6 Print to file 1 0 6 :/images/icon_open.png 0 6 0 5 0 0 Printer name: QFrame::Box QFrame::Sunken 0 0 0 0 Choose 0 9 6 &Defaults false false Qt::Horizontal 61 20 &Ok true true false &Cancel false 9 6 Qt::Horizontal Stop cancelButton clicked() QDjViewPrintDialog reject() 426 310 472 336 fromPageCombo activated(int) pageRangeButton click() 150 152 44 163 toPageCombo activated(int) pageRangeButton click() 245 155 40 161 djview4-4.10.5/src/qdjviewsavedialog.ui000066400000000000000000000177501264256014000200250ustar00rootroot00000000000000 QDjViewSaveDialog 0 0 405 300 Dialog 9 6 Save 9 6 &Document true C&urrent page 0 6 &Pages to Qt::AlignCenter Qt::Horizontal QSizePolicy::Minimum 40 16 Destination 9 6 0 6 0 5 0 0 Format: Bundled DjVu Document Indirect DjVu Document 0 6 :/images/icon_open.png 0 9 6 Qt::Horizontal 40 10 &Ok true true false &Cancel false 9 6 Qt::Horizontal Stop false fromPageCombo activated(int) pageRangeButton click() 158 163 76 158 toPageCombo activated(int) pageRangeButton click() 248 155 44 154 cancelButton clicked() QDjViewSaveDialog reject() 375 342 443 367 djview4-4.10.5/src/qdjviewsidebar.cpp000066400000000000000000001356341264256014000174670ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= 0x50000 # include #endif #include #include #include "qdjvu.h" #include "qdjvuwidget.h" #include "qdjviewsidebar.h" #include "qdjview.h" // ======================================= // QDJVIEWOUTLINE // ======================================= QDjViewOutline::QDjViewOutline(QDjView *djview) : QWidget(djview), djview(djview), loaded(false) { tree = new QTreeWidget(this); tree->setColumnCount(1); tree->setItemsExpandable(true); tree->setUniformRowHeights(true); tree->header()->hide(); tree->header()->setStretchLastSection(true); tree->setEditTriggers(QAbstractItemView::NoEditTriggers); tree->setSelectionBehavior(QAbstractItemView::SelectRows); tree->setSelectionMode(QAbstractItemView::SingleSelection); tree->setTextElideMode(Qt::ElideRight); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); layout->addWidget(tree); connect(tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(itemActivated(QTreeWidgetItem*)) ); connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(clear()) ); connect(djview, SIGNAL(documentOpened(QDjVuDocument*)), this, SLOT(clear()) ); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(refresh()) ); connect(djview->getDjVuWidget(), SIGNAL(pageChanged(int)), this, SLOT(pageChanged(int)) ); connect(djview->getDjVuWidget(), SIGNAL(layoutChanged()), this, SLOT(refresh()) ); setWhatsThis(tr("Document outline.
    " "This panel display the document outline, " "or the page names when the outline is not available, " "Double-click any entry to jump to the selected page." "")); if (djview->pageNum() > 0) refresh(); } void QDjViewOutline::clear() { tree->clear(); loaded = false; } void QDjViewOutline::refresh() { QDjVuDocument *doc = djview->getDocument(); if (doc && !loaded && djview->pageNum()>0) { miniexp_t outline = doc->getDocumentOutline(); if (outline == miniexp_dummy) return; loaded = true; if (outline) { if (!miniexp_consp(outline) || miniexp_car(outline) != miniexp_symbol("bookmarks")) { QString msg = tr("Outline data is corrupted"); qWarning("%s", (const char*)msg.toLocal8Bit()); } tree->clear(); QTreeWidgetItem *root = new QTreeWidgetItem(); fillItems(root, miniexp_cdr(outline)); while (root->childCount() > 0) tree->insertTopLevelItem(tree->topLevelItemCount(), root->takeChild(0) ); if (tree->topLevelItemCount() == 1) tree->topLevelItem(0)->setExpanded(true); delete root; } else { tree->clear(); QTreeWidgetItem *root = new QTreeWidgetItem(tree); root->setText(0, tr("Pages")); root->setFlags(Qt::ItemIsEnabled); root->setData(0, Qt::UserRole, -1); for (int pageno=0; pagenopageNum(); pageno++) { QTreeWidgetItem *item = new QTreeWidgetItem(root); QString name = djview->pageName(pageno); item->setText(0, tr("Page %1").arg(name)); item->setData(0, Qt::UserRole, pageno); item->setData(0, Qt::UserRole+1, pageno); item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); item->setToolTip(0, tr("Go: page %1.").arg(name)); item->setWhatsThis(0, whatsThis()); } tree->setItemExpanded(root, true); } pageChanged(djview->getDjVuWidget()->page()); } } int QDjViewOutline::pageNumber(const char *link) { if (link && link[0] == '#') return djview->pageNumber(QString::fromUtf8(link+1)); if (link == 0 || link[0] != '?') return -1; QByteArray burl = QByteArray("http://f/f") + link; #if QT_VERSION >= 0x50000 QUrlQuery qurl(QUrl::fromEncoded(burl)); #else QUrl qurl = QUrl::fromEncoded(burl); #endif if (qurl.hasQueryItem("page")) return djview->pageNumber(qurl.queryItemValue("page")); else if (qurl.hasQueryItem("pageno")) return djview->pageNumber("$" + qurl.queryItemValue("pageno")); return -1; } static const QRegExp spaces("\\s+"); void QDjViewOutline::fillItems(QTreeWidgetItem *root, miniexp_t expr) { while(miniexp_consp(expr)) { miniexp_t s = miniexp_car(expr); expr = miniexp_cdr(expr); if (miniexp_consp(s) && miniexp_consp(miniexp_cdr(s)) && miniexp_stringp(miniexp_car(s)) && miniexp_stringp(miniexp_cadr(s)) ) { // fill item const char *name = miniexp_to_str(miniexp_car(s)); const char *link = miniexp_to_str(miniexp_cadr(s)); int pageno = pageNumber(link); QString pagename = (pageno>=0)?djview->pageName(pageno):QString(); QTreeWidgetItem *item = new QTreeWidgetItem(root); QString text = QString::fromUtf8(name); if (name && name[0]) item->setText(0, text.replace(spaces," ")); else if (! pagename.isEmpty()) item->setText(0, tr("Page %1").arg(pagename)); item->setFlags(0); item->setWhatsThis(0, whatsThis()); if (link && link[0]) { QString slink = QString::fromUtf8(link); item->setData(0, Qt::UserRole+1, slink); item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); item->setToolTip(0, tr("Go: %1").arg(slink)); if (pageno >= 0) item->setData(0, Qt::UserRole, pageno); if (! pagename.isEmpty()) item->setToolTip(0, tr("Go: page %1.").arg(pagename)); } // recurse fillItems(item, miniexp_cddr(s)); } } } void QDjViewOutline::pageChanged(int pageno) { int fp = -1; QTreeWidgetItem *fi = 0; // find current selection QList sel = tree->selectedItems(); QTreeWidgetItem *si = 0; if (sel.size() == 1) si = sel[0]; // current selection has priority if (si) searchItem(si, pageno, fi, fp); // search for (int i=0; itopLevelItemCount(); i++) searchItem(tree->topLevelItem(i), pageno, fi, fp); // select if (si && fi && si != fi) tree->setItemSelected(si, false); if (fi && si != fi) { tree->setCurrentItem(fi); tree->setItemSelected(fi, true); tree->scrollToItem(fi); } } void QDjViewOutline::searchItem(QTreeWidgetItem *item, int pageno, QTreeWidgetItem *&fi, int &fp) { QVariant data = item->data(0, Qt::UserRole); if (data.type() == QVariant::Int) { int page = data.toInt(); if (page>=0 && page<=pageno && page>fp) { fi = item; fp = page; } } for (int i=0; ichildCount(); i++) searchItem(item->child(i), pageno, fi, fp); } void QDjViewOutline::itemActivated(QTreeWidgetItem *item) { QVariant data = item->data(0, Qt::UserRole+1); if (data.type() == QVariant::String) { QString link = data.toString(); if (link.size() > 0) djview->goToLink(link); } else if (data.type() == QVariant::Int) { int pageno = data.toInt(); if (pageno >= 0) djview->goToPage(pageno); } } // ======================================= // QDJVIEWTHUMBNAILS // ======================================= class QDjViewThumbnails::View : public QListView { Q_OBJECT public: View(QDjViewThumbnails *widget); protected: QStyleOptionViewItem viewOptions() const; private: QDjViewThumbnails *widget; }; class QDjViewThumbnails::Model : public QAbstractListModel { Q_OBJECT public: ~Model(); Model(QDjViewThumbnails*); virtual int rowCount(const QModelIndex &parent) const; virtual QVariant data(const QModelIndex &index, int role) const; int getSize() { return size; } int getSmart() { return smart; } public slots: void setSize(int); void setSmart(bool); void scheduleRefresh(); protected slots: void documentClosed(QDjVuDocument *doc); void documentReady(QDjVuDocument *doc); void thumbnail(int); void refresh(); private: QDjView *djview; QDjViewThumbnails *widget; QStringList names; ddjvu_format_t *format; QIcon icon; int size; bool smart; bool refreshScheduled; int pageInProgress; QIcon makeIcon(int pageno) const; QSize makeHint(int pageno) const; }; // ---------------------------------------- // QDJVIEWTHUMBNAILS::VIEW QDjViewThumbnails::View::View(QDjViewThumbnails *widget) : QListView(widget), widget(widget) { setDragEnabled(false); setEditTriggers(QAbstractItemView::NoEditTriggers); setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::SingleSelection); setTextElideMode(Qt::ElideRight); setViewMode(QListView::IconMode); setFlow(QListView::LeftToRight); setWrapping(true); setMovement(QListView::Static); setResizeMode(QListView::Adjust); setSpacing(8); setUniformItemSizes(true); } QStyleOptionViewItem QDjViewThumbnails::View::viewOptions() const { int size = widget->model->getSize(); QStyleOptionViewItem opt = QListView::viewOptions(); opt.decorationAlignment = Qt::AlignCenter; opt.decorationPosition = QStyleOptionViewItem::Top; opt.decorationSize = QSize(size, size); opt.displayAlignment = Qt::AlignCenter; return opt; } // ---------------------------------------- // QDJVIEWTHUMBNAILS::MODEL QDjViewThumbnails::Model::~Model() { if (format) ddjvu_format_release(format); } QDjViewThumbnails::Model::Model(QDjViewThumbnails *widget) : QAbstractListModel(widget), djview(widget->djview), widget(widget), format(0), size(0), smart(true), refreshScheduled(false), pageInProgress(-1) { // create format #if DDJVUAPI_VERSION < 18 unsigned int masks[3] = { 0xff0000, 0xff00, 0xff }; format = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 3, masks); #else unsigned int masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; format = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 4, masks); #endif ddjvu_format_set_row_order(format, true); ddjvu_format_set_y_direction(format, true); ddjvu_format_set_ditherbits(format, QPixmap::defaultDepth()); // set size setSize(64); // connect connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), this, SLOT(documentClosed(QDjVuDocument*)) ); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), this, SLOT(documentReady(QDjVuDocument*)) ); // update if (djview->pageNum() > 0) documentReady(djview->getDocument()); } void QDjViewThumbnails::Model::documentClosed(QDjVuDocument *doc) { if (names.size() > 0) { beginRemoveRows(QModelIndex(),0,names.size()-1); names.clear(); pageInProgress = -1; endRemoveRows(); } disconnect(doc, 0, this, 0); } void QDjViewThumbnails::Model::documentReady(QDjVuDocument *doc) { if (names.size() > 0) { beginRemoveRows(QModelIndex(),0,names.size()-1); names.clear(); pageInProgress = -1; endRemoveRows(); } int pagenum = djview->pageNum(); if (pagenum > 0) { beginInsertRows(QModelIndex(),0,pagenum-1); for (int pageno=0; pagenopageName(pageno); endInsertRows(); } connect(doc, SIGNAL(thumbnail(int)), this, SLOT(thumbnail(int)) ); connect(doc, SIGNAL(pageinfo()), this, SLOT(scheduleRefresh()) ); connect(doc, SIGNAL(idle()), this, SLOT(scheduleRefresh()) ); widget->pageChanged(djview->getDjVuWidget()->page()); scheduleRefresh(); } void QDjViewThumbnails::Model::thumbnail(int pageno) { QModelIndex mi = index(pageno); emit dataChanged(mi, mi); scheduleRefresh(); } void QDjViewThumbnails::Model::scheduleRefresh() { if (! refreshScheduled) QTimer::singleShot(0, this, SLOT(refresh())); refreshScheduled = true; } void QDjViewThumbnails::Model::refresh() { QDjVuDocument *doc = djview->getDocument(); ddjvu_status_t status; refreshScheduled = false; if (doc && pageInProgress >= 0) { status = ddjvu_thumbnail_status(*doc, pageInProgress, 0); if (status >= DDJVU_JOB_OK) pageInProgress = -1; } if (doc && pageInProgress < 0 && widget->isVisible()) { QRect dr = widget->view->rect(); for (int i=0; iview->visualRect(mi))) { status = ddjvu_thumbnail_status(*doc, i, 0); if (status == DDJVU_JOB_NOTSTARTED) { if (smart && !ddjvu_document_check_pagedata(*doc, i)) continue; status = ddjvu_thumbnail_status(*doc, i, 1); if (status == DDJVU_JOB_STARTED) { pageInProgress = i; break; } } } } } } void QDjViewThumbnails::Model::setSmart(bool b) { if (b != smart) { smart = b; scheduleRefresh(); } } void QDjViewThumbnails::Model::setSize(int newSize) { newSize = qBound(16, newSize, 256); if (newSize != size) { size = newSize; QPixmap pixmap(size,size); pixmap.fill(); QPainter painter; int s8 = size/8; if (s8 >= 1) { QPolygon poly; poly << QPoint(s8,0) << QPoint(size-2*s8,0) << QPoint(size-s8-1,s8) << QPoint(size-s8-1,size-1) << QPoint(s8,size-1); QPainter painter(&pixmap); painter.setBrush(Qt::NoBrush); painter.setPen(Qt::darkGray); painter.drawPolygon(poly); } icon = QIcon(pixmap); } emit layoutChanged(); } QIcon QDjViewThumbnails::Model::makeIcon(int pageno) const { QDjVuDocument *doc = djview->getDocument(); if (doc) { // render thumbnail int w = size; int h = size; QImage img(size, size, QImage::Format_RGB32); int status = ddjvu_thumbnail_status(*doc, pageno, 0); if (status == DDJVU_JOB_NOTSTARTED) { const_cast(this)->scheduleRefresh(); } else if (ddjvu_thumbnail_render(*doc, pageno, &w, &h, format, img.bytesPerLine(), (char*)img.bits() )) { QPixmap pixmap(size,size); pixmap.fill(); QPoint dst((size-w)/2, (size-h)/2); QRect src(0,0,w,h); QPainter painter; painter.begin(&pixmap); painter.drawImage(dst, img, src); painter.setBrush(Qt::NoBrush); painter.setPen(Qt::darkGray); painter.drawRect(dst.x(), dst.y(), w-1, h-1); painter.end(); return QIcon(pixmap); } } return icon; } QSize QDjViewThumbnails::Model::makeHint(int) const { QFontMetrics metrics(widget->view->font()); return QSize(size, size+metrics.height()); } int QDjViewThumbnails::Model::rowCount(const QModelIndex &) const { return names.size(); } QVariant QDjViewThumbnails::Model::data(const QModelIndex &index, int role) const { if (index.isValid()) { int pageno = index.row(); if (pageno>=0 && pagenowhatsThis(); case Qt::UserRole: return pageno; case Qt::SizeHintRole: return makeHint(pageno); default: break; } } } return QVariant(); } // ---------------------------------------- // QDJVIEWTHUMBNAILS QDjViewThumbnails::QDjViewThumbnails(QDjView *djview) : QWidget(djview), djview(djview) { model = new Model(this); selection = new QItemSelectionModel(model); view = new View(this); view->setModel(model); view->setSelectionModel(selection); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); layout->addWidget(view); connect(djview->getDjVuWidget(), SIGNAL(pageChanged(int)), this, SLOT(pageChanged(int)) ); connect(view, SIGNAL(activated(const QModelIndex&)), this, SLOT(activated(const QModelIndex&)) ); menu = new QMenu(this); QActionGroup *group = new QActionGroup(this); QAction *action; action = menu->addAction(tr("Tiny","thumbnail menu")); connect(action,SIGNAL(triggered()),this,SLOT(setSize()) ); action->setCheckable(true); action->setActionGroup(group); action->setData(32); action = menu->addAction(tr("Small","thumbnail menu")); connect(action,SIGNAL(triggered()),this,SLOT(setSize()) ); action->setCheckable(true); action->setActionGroup(group); action->setData(64); action = menu->addAction(tr("Medium","thumbnail menu")); connect(action,SIGNAL(triggered()),this,SLOT(setSize()) ); action->setCheckable(true); action->setActionGroup(group); action->setData(96); action = menu->addAction(tr("Large","thumbnail menu")); connect(action,SIGNAL(triggered()),this,SLOT(setSize()) ); action->setCheckable(true); action->setActionGroup(group); action->setData(160); menu->addSeparator(); action = menu->addAction(tr("Smart","thumbnail menu")); connect(action,SIGNAL(toggled(bool)),this,SLOT(setSmart(bool)) ); action->setCheckable(true); action->setData(true); updateActions(); #ifdef Q_OS_DARWIN QString mc = tr("Control Left Mouse Button"); #else QString mc = tr("Right Mouse Button"); #endif setWhatsThis(tr("Document thumbnails.
    " "This panel display thumbnails for the document pages. " "Double click a thumbnail to jump to the selected page. " "%1 to change the thumbnail size or the refresh mode. " "The smart refresh mode only computes thumbnails " "when the page data is present (displayed or cached.)" "").arg(mc) ); } void QDjViewThumbnails::updateActions(void) { QAction *action; int size = model->getSize(); bool smart = model->getSmart(); foreach(action, menu->actions()) { QVariant data = action->data(); if (data.type() == QVariant::Bool) action->setChecked(smart); else action->setChecked(data.toInt() == size); } } void QDjViewThumbnails::pageChanged(int pageno) { if (pageno >= 0 && pageno < djview->pageNum()) { QModelIndex mi = model->index(pageno); if (! selection->isSelected(mi)) selection->select(mi, QItemSelectionModel::ClearAndSelect); view->scrollTo(mi); } } void QDjViewThumbnails::activated(const QModelIndex &index) { if (index.isValid()) { int pageno = index.row(); if (pageno>=0 && pagenopageNum()) djview->goToPage(pageno); } } int QDjViewThumbnails::size() { return model->getSize(); } void QDjViewThumbnails::setSize(int size) { model->setSize(size); updateActions(); } void QDjViewThumbnails::setSize() { QAction *action = qobject_cast(sender()); if (action) setSize(action->data().toInt()); } bool QDjViewThumbnails::smart() { return model->getSmart(); } void QDjViewThumbnails::setSmart(bool smart) { model->setSmart(smart); updateActions(); } void QDjViewThumbnails::contextMenuEvent(QContextMenuEvent *event) { menu->exec(event->globalPos()); event->accept(); } // ======================================= // QDJVIEWFIND // ======================================= class QDjViewFind::Model : public QAbstractListModel { // This class implements the listview model. // But the bulk contains private data for qdjviewfind! Q_OBJECT public: Model(QDjViewFind*); // model stuff public: virtual int rowCount(const QModelIndex &parent) const; virtual QVariant data(const QModelIndex &index, int role) const; void modelClear(); int modelFind(int pageno); bool modelSelect(int pageno); void modelAdd(int pageno, int hits); private: struct RowInfo { int pageno; int hits; QString name; }; QList pages; // private data stuff public: void nextHit(bool backwards); void startFind(bool backwards, int delay=0); void stopFind(); typedef QList Hit; typedef QList Hits; QMap hits; protected: virtual bool eventFilter(QObject*, QEvent*); public slots: void documentClosed(QDjVuDocument*); void documentReady(QDjVuDocument*); void clear(); void doHighlights(int pageno); void doPending(); void workTimeout(); void animTimeout(); void makeSelectionVisible(); void pageChanged(int); void textChanged(); void pageinfo(); void itemActivated(const QModelIndex&); private: friend class QDjViewFind; QDjViewFind *widget; QDjView *djview; QTimer *animTimer; QTimer *workTimer; QItemSelectionModel *selection; QAbstractButton *animButton; QIcon animIcon; QIcon findIcon; QRegExp find; int curWork; int curPage; int curHit; bool searchBackwards; bool caseSensitive; bool wordOnly; bool regExpMode; bool working; bool pending; }; // ---------------------------------------- // QDJVIEWFIND::MODEL QDjViewFind::Model::Model(QDjViewFind *widget) : QAbstractListModel(widget), widget(widget), djview(widget->djview), selection(0), animButton(0), curPage(0), curHit(0), searchBackwards(false), caseSensitive(false), wordOnly(true), regExpMode(false), working(false), pending(false) { selection = new QItemSelectionModel(this); animTimer = new QTimer(this); workTimer = new QTimer(this); workTimer->setSingleShot(true); connect(animTimer, SIGNAL(timeout()), this, SLOT(animTimeout())); connect(workTimer, SIGNAL(timeout()), this, SLOT(workTimeout())); findIcon = QIcon(":/images/icon_empty.png"); } int QDjViewFind::Model::rowCount(const QModelIndex&) const { return pages.size(); } QVariant QDjViewFind::Model::data(const QModelIndex &index, int role) const { if (index.isValid()) { int row = index.row(); if (row>=0 && rowwhatsThis(); default: break; } } } return QVariant(); } void QDjViewFind::Model::modelClear() { int nrows = pages.size(); if (nrows > 0) { beginRemoveRows(QModelIndex(), 0, nrows-1); pages.clear(); endRemoveRows(); } } int QDjViewFind::Model::modelFind(int pageno) { int lo = 0; int hi = pages.size(); while (lo < hi) { int k = (lo + hi - 1) / 2; if (pageno > pages[k].pageno) lo = k + 1; else if (pageno < pages[k].pageno) hi = k; else lo = hi = k; } return lo; } bool QDjViewFind::Model::modelSelect(int pageno) { int lo = modelFind(pageno); QModelIndex mi = index(lo); if (lo < pages.size() && pages[lo].pageno == pageno) { if (!selection->isSelected(mi)) selection->select(mi, QItemSelectionModel::ClearAndSelect); return true; } selection->select(mi, QItemSelectionModel::Clear); return false; } void QDjViewFind::Model::modelAdd(int pageno, int hits) { QString name = djview->pageName(pageno); RowInfo info; info.pageno = pageno; info.hits = hits; if (hits == 1) info.name = tr("Page %1 (1 hit)").arg(name); else info.name = tr("Page %1 (%n hits)", 0, hits).arg(name); int lo = modelFind(pageno); if (lo < pages.size() && pages[lo].pageno == pageno) { pages[lo] = info; QModelIndex mi = index(lo); emit dataChanged(mi, mi); } else { beginInsertRows(QModelIndex(), lo, lo); pages.insert(lo, info); endInsertRows(); if (pageno == djview->getDjVuWidget()->page()) modelSelect(pageno); } } bool QDjViewFind::Model::eventFilter(QObject*, QEvent *event) { switch (event->type()) { case QEvent::Show: if (working) { animTimer->start(); workTimer->start(); } default: break; } return false; } void QDjViewFind::Model::documentClosed(QDjVuDocument *doc) { disconnect(doc, 0, this, 0); stopFind(); clear(); curWork = 0; curPage = 0; curHit = -1; searchBackwards = false; pending = false; widget->eraseText(); widget->combo->setEnabled(false); widget->label->setText(QString()); widget->stack->setCurrentWidget(widget->label); } void QDjViewFind::Model::documentReady(QDjVuDocument *doc) { curWork = djview->getDjVuWidget()->page(); curPage = curWork; curHit = -1; if (doc) { widget->combo->setEnabled(true); connect(doc, SIGNAL(pageinfo()), this, SLOT(pageinfo())); connect(doc, SIGNAL(idle()), this, SLOT(pageinfo())); if (! find.isEmpty()) startFind(false); } } static bool miniexp_get_int(miniexp_t &r, int &x) { if (! miniexp_numberp(miniexp_car(r))) return false; x = miniexp_to_int(miniexp_car(r)); r = miniexp_cdr(r); return true; } static bool miniexp_get_rect(miniexp_t &r, QRect &rect) { int x1,y1,x2,y2; if (! (miniexp_get_int(r, x1) && miniexp_get_int(r, y1) && miniexp_get_int(r, x2) && miniexp_get_int(r, y2) )) return false; if (x20 && s[--l].isSpace()) c += 1; return c; } static QString chopped(QString s, int c) { s.chop(c); return s; } static bool miniexp_get_text(miniexp_t exp, QString &result, QMap &positions, int &state) { miniexp_t type = miniexp_car(exp); int typenum = parse_text_type(type); miniexp_t r = exp = miniexp_cdr(exp); if (! miniexp_symbolp(type)) return false; QRect rect; if (! miniexp_get_rect(r, rect)) return false; miniexp_t s = miniexp_car(r); state = qMax(state, typenum); if (miniexp_stringp(s) && !miniexp_cdr(r)) { int c = count_final_spaces(result); if (state >= 2 && !result.endsWith('\n')) result = chopped(result,c) + "\n"; else if (state >= 1 && c == 0) result += " "; state = -1; positions[result.size()] = exp; result += QString::fromUtf8(miniexp_to_str(s)).trimmed(); r = miniexp_cdr(r); } while(miniexp_consp(s)) { miniexp_get_text(s, result, positions, state); r = miniexp_cdr(r); s = miniexp_car(r); } if (r) return false; state = qMax(state, typenum); return true; } static QList > miniexp_search_text(miniexp_t exp, QRegExp regex) { QList > hits; QString text; QMap positions; // build string int state = -1; if (! miniexp_get_text(exp, text, positions, state)) return hits; // search hits int offset = 0; int match; while ((match = regex.indexIn(text, offset)) >= 0) { QList hit; int endmatch = match + regex.matchedLength(); offset += 1; if (endmatch <= match) continue; QMap::const_iterator pos = positions.lowerBound(match); while (pos != positions.begin() && pos.key() > match) --pos; for (; pos != positions.end() && pos.key() < endmatch; ++pos) hit += pos.value(); hits += hit; if (pos != positions.end()) offset = pos.key(); else break; } return hits; } void QDjViewFind::Model::clear() { QDjVuWidget *djvuWidget = djview->getDjVuWidget(); QMap::const_iterator pos; for (pos=hits.begin(); pos!=hits.end(); ++pos) if (pos.value().size() > 0) djvuWidget->clearHighlights(pos.key()); pending = false; hits.clear(); modelClear(); } void QDjViewFind::Model::doHighlights(int pageno) { if (hits.contains(pageno)) { QColor color = Qt::blue; QDjVuWidget *djvu = djview->getDjVuWidget(); Hit pageHit; color.setAlpha(96); foreach(pageHit, hits[pageno]) { QRect rect; miniexp_t exp; foreach(exp, pageHit) { if (miniexp_get_rect(exp, rect)) djvu->addHighlight(pageno, rect.x(), rect.y(), rect.width(), rect.height(), color, true ); } } } } void QDjViewFind::Model::doPending() { QDjVuWidget *djvu = djview->getDjVuWidget(); while (pending && hits.contains(curPage) && pages.size()>0) { Hits pageHits = hits[curPage]; int nhits = pageHits.size(); if (searchBackwards) { if (curHit < 0 || curHit >= nhits) curHit = nhits; curHit--; } else { if (curHit < 0 || curHit >= nhits) curHit = -1; curHit++; } if (curHit >= 0 && curHit < nhits) { // jump to position pending = false; Hit hit = pageHits[curHit]; QRect rect; if (hit.size() > 0 && miniexp_get_rect(hit[0], rect)) { QDjVuWidget::Position pos; pos.pageNo = curPage; pos.posPage = rect.center(); pos.inPage = true; djvu->setPosition(pos, djvu->viewport()->rect().center()); } } else { // next page curHit = -1; if (searchBackwards) { curPage -= 1; if (curPage < 0) curPage = djview->pageNum() - 1; } else { curPage += 1; if (curPage >= djview->pageNum()) curPage = 0; } } } if (! pending) djview->statusMessage(QString()); } void QDjViewFind::Model::workTimeout() { // do some work int startingPoint = curWork; bool somePagesWithText = false; doPending(); while (working) { if (hits.contains(curWork)) { somePagesWithText = true; } else { QString name = djview->pageName(curWork); QDjVuDocument *doc = djview->getDocument(); miniexp_t exp = doc->getPageText(curWork, false); if (exp == miniexp_dummy) { // data not present if (pending) djview->statusMessage(tr("Searching page %1 (waiting for data.)") .arg(name) ); if (pending || widget->isVisible()) doc->getPageText(curWork, true); // timer will be reactivated by pageinfo() return; } Hits pageHits; hits[curWork] = pageHits; if (exp != miniexp_nil) { somePagesWithText = true; if (pending) djview->statusMessage(tr("Searching page %1.").arg(name)); pageHits = miniexp_search_text(exp, find); hits[curWork] = pageHits; if (pageHits.size() > 0) { modelAdd(curWork, pageHits.size()); doHighlights(curWork); doPending(); makeSelectionVisible(); } // enough break; } } // next page int pageNum = djview->pageNum(); if (searchBackwards) { if (curWork <= 0) curWork = pageNum; curWork -= 1; } else { curWork += 1; if (curWork >= pageNum) curWork = 0; } // finished? if (curWork == startingPoint) { stopFind(); djview->statusMessage(QString()); if (! pages.size()) { QString msg = tr("No hits!"); if (! somePagesWithText) { widget->eraseText(); widget->combo->setEnabled(false); msg = tr("Document is not searchable. " "No page contains information " "about its textual content."); } else if (! find.isValid()) { msg = tr("Invalid regular expression."); } widget->stack->setCurrentWidget(widget->label); widget->label->setText(msg); } } } // restart timer if (working) workTimer->start(0); } void QDjViewFind::Model::animTimeout() { if (animButton && !animIcon.isNull()) { if (animButton->icon().cacheKey() == findIcon.cacheKey()) animButton->setIcon(animIcon); else animButton->setIcon(findIcon); } } void QDjViewFind::Model::nextHit(bool backwards) { djview->getDjVuWidget()->terminateAnimation(); if (working && backwards != searchBackwards) { pending = false; startFind(backwards); } searchBackwards = backwards; if (! find.isEmpty()) { pending = true; doPending(); if (working && pending && !workTimer->isActive()) workTimer->start(0); } } void QDjViewFind::Model::startFind(bool backwards, int delay) { stopFind(); searchBackwards = backwards; if (! find.isEmpty() && djview->pageNum() > 0) { widget->label->setText(QString()); widget->stack->setCurrentWidget(widget->view); animButton = (backwards) ? widget->upButton : widget->downButton; animIcon = animButton->icon(); animTimer->start(250); workTimer->start(delay); curWork = djview->getDjVuWidget()->page(); working = true; } } void QDjViewFind::Model::stopFind() { animTimer->stop(); workTimer->stop(); if (animButton) { animButton->setIcon(animIcon); animButton = 0; } working = false; } void QDjViewFind::Model::pageinfo() { if (working && !workTimer->isActive()) workTimer->start(0); } void QDjViewFind::Model::makeSelectionVisible() { QModelIndexList s = selection->selectedIndexes(); if (s.size() > 0) widget->view->scrollTo(s[0]); } void QDjViewFind::Model::pageChanged(int pageno) { QDjVuWidget *djvu = djview->getDjVuWidget(); if (djvu && djvu->animationInProgress()) return; if (pageno != curPage) { curHit = -1; curPage = pageno; pending = false; } curWork = pageno; } void QDjViewFind::Model::textChanged() { stopFind(); clear(); QString s = widget->text(); widget->label->setText(QString()); widget->stack->setCurrentWidget(widget->label); if (s.isEmpty()) { find = QRegExp(); } else { if (!regExpMode) { s = QRegExp::escape(widget->text()); s.replace(QRegExp("\\s+"), " "); } if (wordOnly) s = "\\b" + s; find = QRegExp(s); if (caseSensitive) find.setCaseSensitivity(Qt::CaseSensitive); else find.setCaseSensitivity(Qt::CaseInsensitive); startFind(searchBackwards, 250); } } void QDjViewFind::Model::itemActivated(const QModelIndex &mi) { if (mi.isValid()) { int row = mi.row(); if (row >= 0 && row < pages.size() && pages[row].hits > 0) { curPage = pages[row].pageno; curHit = -1; pending = true; doPending(); } } } // ---------------------------------------- // QDJVIEWFIND QDjViewFind::QDjViewFind(QDjView *djview) : QWidget(djview), djview(djview), model(0), view(0) { model = new Model(this); installEventFilter(model); view = new QListView(this); view->setModel(model); view->setSelectionModel(model->selection); view->setDragEnabled(false); view->setEditTriggers(QAbstractItemView::NoEditTriggers); view->setSelectionBehavior(QAbstractItemView::SelectRows); view->setSelectionMode(QAbstractItemView::SingleSelection); view->setTextElideMode(Qt::ElideMiddle); view->setViewMode(QListView::ListMode); view->setWrapping(false); view->setResizeMode(QListView::Adjust); caseSensitiveAction = new QAction(tr("Case sensitive"), this); caseSensitiveAction->setCheckable(true); caseSensitiveAction->setChecked(model->caseSensitive); wordOnlyAction = new QAction(tr("Words only"), this); wordOnlyAction->setCheckable(true); wordOnlyAction->setChecked(model->wordOnly); regExpModeAction = new QAction(tr("Regular expression"), this); regExpModeAction->setCheckable(true); regExpModeAction->setChecked(model->regExpMode); menu = new QMenu(this); menu->addAction(caseSensitiveAction); menu->addAction(wordOnlyAction); menu->addAction(regExpModeAction); QBoxLayout *vlayout = new QVBoxLayout(this); combo = new QComboBox(this); combo->setEditable(true); combo->setMaxCount(8); combo->setInsertPolicy(QComboBox::InsertAtTop); combo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); vlayout->addWidget(combo); QBoxLayout *hlayout = new QHBoxLayout; hlayout->setSpacing(0); vlayout->addLayout(hlayout); upButton = new QToolButton(this); upButton->setIcon(QIcon(":/images/icon_up.png")); upButton->setToolTip(tr("Find Previous (Shift+F3) ")); upButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); hlayout->addWidget(upButton); downButton = new QToolButton(this); downButton->setIcon(QIcon(":/images/icon_down.png")); downButton->setToolTip(tr("Find Next (F3) ")); downButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); hlayout->addWidget(downButton); hlayout->addStretch(2); resetButton = new QToolButton(this); resetButton->setIcon(QIcon(":/images/icon_erase.png")); resetButton->setToolTip(tr("Reset search options to default values.")); resetButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); hlayout->addWidget(resetButton); QToolButton *optionButton = new QToolButton(this); optionButton->setText(tr("Options")); optionButton->setPopupMode(QToolButton::InstantPopup); optionButton->setToolButtonStyle(Qt::ToolButtonTextOnly); optionButton->setMenu(menu); optionButton->setAttribute(Qt::WA_CustomWhatsThis); optionButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); hlayout->addWidget(optionButton); stack = new QStackedLayout(); view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); view->setFrameShadow(QFrame::Sunken); view->setFrameShape(QFrame::StyledPanel); stack->addWidget(view); label = new QLabel(this); label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); label->setAlignment(Qt::AlignCenter); label->setWordWrap(true); label->setFrameShadow(QFrame::Sunken); label->setFrameShape(QFrame::StyledPanel); stack->addWidget(label); vlayout->addLayout(stack); connect(djview, SIGNAL(documentClosed(QDjVuDocument*)), model, SLOT(documentClosed(QDjVuDocument*)) ); connect(djview, SIGNAL(documentReady(QDjVuDocument*)), model, SLOT(documentReady(QDjVuDocument*)) ); connect(view, SIGNAL(activated(const QModelIndex&)), model, SLOT(itemActivated(const QModelIndex&))); connect(djview->getDjVuWidget(), SIGNAL(pageChanged(int)), this, SLOT(pageChanged(int))); connect(combo->lineEdit(), SIGNAL(textChanged(QString)), model, SLOT(textChanged())); connect(combo->lineEdit(), SIGNAL(returnPressed()), this, SLOT(findAgain())); connect(caseSensitiveAction, SIGNAL(triggered(bool)), this, SLOT(setCaseSensitive(bool))); connect(wordOnlyAction, SIGNAL(triggered(bool)), this, SLOT(setWordOnly(bool))); connect(regExpModeAction, SIGNAL(triggered(bool)), this, SLOT(setRegExpMode(bool))); connect(upButton, SIGNAL(clicked()), this, SLOT(findPrev())); connect(downButton, SIGNAL(clicked()), this, SLOT(findNext())); connect(resetButton, SIGNAL(clicked()), this, SLOT(eraseText())); setWhatsThis (tr("Finding text.
    " "Search hits appear progressively as soon as you type " "a search string. Typing enter jumps to the next hit. " "To move to the previous or next hit, you can also use " "the arrow buttons or the shortcuts F3 or " "Shift-F3. You can also double click a page name. " "Use the Options menu to search words only or " "to specify the case sensitivity." "")); wordOnlyAction->setStatusTip (tr("Specify whether search hits must begin on a word boundary.")); caseSensitiveAction->setStatusTip (tr("Specify whether searches are case sensitive.")); regExpModeAction->setStatusTip (tr("Regular expressions describe complex string matching patterns.")); regExpModeAction->setWhatsThis (tr("Regular Expression Quick Guide
      " "
    • The dot . matches any character.
    • " "
    • Most characters match themselves.
    • " "
    • Prepend a backslash \\ to match special" " characters ()[]{}|*+.?!^$\\.
    • " "
    • \\b matches a word boundary.
    • " "
    • \\w matches a word character.
    • " "
    • \\d matches a digit character.
    • " "
    • \\s matches a blank character.
    • " "
    • \\n matches a newline character.
    • " "
    • [a-b] matches characters in range" " a-b.
    • " "
    • [^a-b] matches characters outside range" " a-b.
    • " "
    • a|b matches either regular expression" " a or regular expression b.
    • " "
    • a{n,m} matches regular expression" " a repeated n to m" " times.
    • " "
    • a?, a*, and a+" " are shorthands for a{0,1}, a{0,}, " " and a{1,}.
    • " "
    • Use parentheses () to group regular expressions " " before ?+*{.
    • " "
    ")); eraseText(); combo->setEnabled(false); label->setText(QString()); stack->setCurrentWidget(label); if (djview->getDocument()) model->documentReady(djview->getDocument()); } void QDjViewFind::contextMenuEvent(QContextMenuEvent *event) { menu->exec(event->globalPos()); event->accept(); } void QDjViewFind::takeFocus(Qt::FocusReason reason) { if (combo->isVisible()) combo->setFocus(reason); } QString QDjViewFind::text() { return combo->lineEdit()->text(); } bool QDjViewFind::caseSensitive() { return model->caseSensitive; } bool QDjViewFind::wordOnly() { return model->wordOnly; } bool QDjViewFind::regExpMode() { return model->regExpMode; } void QDjViewFind::setText(QString s) { if (s != text()) combo->lineEdit()->setText(s); } void QDjViewFind::selectAll() { combo->lineEdit()->selectAll(); combo->lineEdit()->setFocus(); } void QDjViewFind::eraseText() { setText(QString::null); setRegExpMode(false); setWordOnly(true); setCaseSensitive(false); } void QDjViewFind::setCaseSensitive(bool b) { if (b != model->caseSensitive) { caseSensitiveAction->setChecked(b); model->caseSensitive = b; model->textChanged(); } } void QDjViewFind::setWordOnly(bool b) { if (b != model->wordOnly) { wordOnlyAction->setChecked(b); model->wordOnly = b; model->textChanged(); } } void QDjViewFind::setRegExpMode(bool b) { if (b != model->regExpMode) { regExpModeAction->setChecked(b); model->regExpMode = b; model->textChanged(); } } void QDjViewFind::findNext() { if (text().isEmpty()) djview->showFind(); model->nextHit(false); } void QDjViewFind::findPrev() { if (text().isEmpty()) djview->showFind(); model->nextHit(true); } void QDjViewFind::findAgain() { if (model->searchBackwards) findPrev(); else findNext(); } void QDjViewFind::pageChanged(int pageno) { if (pageno >= 0 && pageno < djview->pageNum()) { model->pageChanged(pageno); if (model->modelSelect(pageno)) model->makeSelectionVisible(); } } // ---------------------------------------- // MOC #include "qdjviewsidebar.moc" /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjviewsidebar.h000066400000000000000000000100201264256014000171110ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVIEWSIDEBAR_H #define QDJVIEWSIDEBAR_H #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include #include #include #include "qdjvu.h" #include "qdjvuwidget.h" #include "qdjview.h" class QAction; class QComboBox; class QContextMenuEvent; class QItemSelectionModel; class QLabel; class QLineEdit; class QListView; class QMenu; class QPushButton; class QStackedLayout; class QToolButton; class QTreeWidget; class QTreeWidgetItem; // ---------------------------------------- // OUTLINE class QDjViewOutline : public QWidget { Q_OBJECT public: QDjViewOutline(QDjView *djview); public slots: void clear(); void refresh(); protected slots: void pageChanged(int pageno); void itemActivated(QTreeWidgetItem *item); private: QDjView *djview; QTreeWidget *tree; bool loaded; int pageNumber(const char *link); void fillItems(QTreeWidgetItem *item, miniexp_t expr); void searchItem(QTreeWidgetItem *item, int pageno, QTreeWidgetItem *&fi, int &fp); }; // ---------------------------------------- // THUMBNAILS class QDjViewThumbnails : public QWidget { Q_OBJECT Q_PROPERTY(int size READ size WRITE setSize) Q_PROPERTY(bool smart READ smart WRITE setSmart) public: QDjViewThumbnails(QDjView *djview); int size(); bool smart(); public slots: void setSize(int); void setSmart(bool); protected slots: void setSize(); void pageChanged(int pageno); void activated(const QModelIndex &index); protected: void contextMenuEvent(QContextMenuEvent *event); void updateActions(); private: class Model; class View; QDjView *djview; Model *model; View *view; QItemSelectionModel *selection; QMenu *menu; }; // ---------------------------------------- // THUMBNAILS class QDjViewFind : public QWidget { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive) Q_PROPERTY(bool wordOnly READ wordOnly WRITE setWordOnly) public: QDjViewFind(QDjView *djview); void takeFocus(Qt::FocusReason); QString text(); bool caseSensitive(); bool wordOnly(); bool regExpMode(); public slots: void selectAll(); void eraseText(); void setText(QString s); void setCaseSensitive(bool); void setWordOnly(bool); void setRegExpMode(bool); void findNext(); void findPrev(); void findAgain(); protected slots: void pageChanged(int); protected: void contextMenuEvent(QContextMenuEvent *event); private: class Model; QDjView *djview; Model *model; QListView *view; QMenu *menu; QComboBox *combo; QToolButton *upButton; QToolButton *downButton; QToolButton *resetButton; QStackedLayout *stack; QLabel *label; QAction *caseSensitiveAction; QAction *wordOnlyAction; QAction *regExpModeAction; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvu.cpp000066400000000000000000000634641264256014000156160ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include "qdjvu.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= 0x50000 # include #endif #if DDJVUAPI_VERSION < 17 # error "DDJVUAPI_VERSION>=17 is required !" #endif // ---------------------------------------- // QDJVUCONTEXT /*! \class QDjVuContext \brief Represents a \a ddjvu_context_t object. This QObject subclass holds a \a ddjvu_context_t object and transparently hooks the DDJVUAPI message queue into the Qt messaging system. DDJVUAPI messages are then forwarded to the virtual function \a QDjVuContext::handle which transforms then into signals emitted by the proper object from the message loop thread. */ /*! Construct a \a QDJVuContext object. Argument \a programname is the name of the program. This name is used to report error messages and locate localized messages. Argument \a parent defines its parent in the \a QObject hierarchy. */ QDjVuContext::QDjVuContext(const char *programname, QObject *parent) : QObject(parent), context(0), flag(false) { context = ddjvu_context_create(programname); ddjvu_message_set_callback(context, callback, (void*)this); ddjvu_cache_set_size(context, 30*1024*1024); } QDjVuContext::~QDjVuContext() { ddjvu_context_release(context); context = 0; } /*! \property QDjVuContext::cacheSize \brief The size of the decoded page cache in bytes. The default cache size is 30 megabytes. */ long QDjVuContext::cacheSize() const { return ddjvu_cache_get_size(context); } void QDjVuContext::setCacheSize(long size) { ddjvu_cache_set_size(context, size); } void QDjVuContext::callback(ddjvu_context_t *, void *closure) { QDjVuContext *qcontext = (QDjVuContext*)closure; if (! qcontext->flag) { qcontext->flag = true; QEvent *qevent = new QEvent(QEvent::User); QCoreApplication::postEvent(qcontext, qevent); } } bool QDjVuContext::event(QEvent *event) { if (event->type() == QEvent::User) { flag = false; ddjvu_message_t *message; while ((message = ddjvu_message_peek(context))) { handle(message); ddjvu_message_pop(context); } return true; } return QObject::event(event); } /*! Processes DDJVUAPI messages. The Qt message loop automatically passes all DDJVUAPI messages to this virtual function . This function then forwards them to the \a handle function of the suitable \a QDjVuDocument, \a QDjVuPage or \a QDjVuJob object. Most messages eventually result into the emission of a suitable signal. */ bool QDjVuContext::handle(ddjvu_message_t *msg) { if (msg->m_any.page) { QObject *p = (QObject*)ddjvu_page_get_user_data(msg->m_any.page); QDjVuPage *q = (p) ? qobject_cast(p) : 0; if (q && q->handle(msg)) return true; } if (msg->m_any.job) { ddjvu_job_t *djob = 0; ddjvu_job_t *pjob = 0; if (msg->m_any.document) djob = ddjvu_document_job(msg->m_any.document); if (msg->m_any.page) pjob = ddjvu_page_job(msg->m_any.page); if (msg->m_any.job != djob && msg->m_any.job != pjob) { QObject *p = (QObject*)ddjvu_job_get_user_data(msg->m_any.job); QDjVuJob *q = (p) ? qobject_cast(p) : 0; if (q && q->handle(msg)) return true; } } if (msg->m_any.document) { QObject *p = (QObject*)ddjvu_document_get_user_data(msg->m_any.document); QDjVuDocument *q = (p) ? qobject_cast(p) : 0; if (q && q->handle(msg)) return true; } switch(msg->m_any.tag) { case DDJVU_ERROR: emit error(QString::fromLocal8Bit(msg->m_error.message), QString::fromLocal8Bit(msg->m_error.filename), msg->m_error.lineno); return true; case DDJVU_INFO: emit info(QString::fromLocal8Bit(msg->m_info.message)); return true; default: break; } return false; } /*! \fn QDjVuContext::isValid() Indicate if this object is associated with a \a ddjvu_context_t object. Use this function to determine if the construction was successful. */ /*! \fn QDjVuContext::operator ddjvu_context_t*() Return a pointer to the corresponding \a ddjvu_context_t object. */ /*! \fn QDjVuContext::error(QString msg, QString filename, int lineno) This signal is emitted when processing a DDJVUAPI error message that is not attached to any document, page, or job. This only hapens when a DDJVUAPI function is used incorrectly or when calling \a QDjVuDocument::setFileName or \a QDjVuDocument::setUrl. */ /*! \fn QDjVuContext::info(QString msg) This signal is emitted when processing a DDJVUAPI info message that is not attached to any document, page, or job. This is quite rare and not very useful. */ // ---------------------------------------- // QDJVUDOCUMENTPRIVATE class QDjVuDocumentPrivate : public QObject { Q_OBJECT public: QMutex mutex; bool autoDelete; int refCount; QSet running; bool docReady; QDjVuDocument *docPointer; minivar_t documentOutline; minivar_t documentAnnotations; QVector pageAnnotations; QVector pageText; QDjVuDocumentPrivate(); void add(QObject *p); void add(QDjVuPage *p); public slots: void docinfo(); protected slots: void remove(QObject *p); void pageinfo(); void emitidle(); signals: void idle(); }; QDjVuDocumentPrivate::QDjVuDocumentPrivate() : mutex(QMutex::Recursive), autoDelete(false), refCount(0), docReady(false), docPointer(0) { } void QDjVuDocumentPrivate::add(QObject *p) { connect(p, SIGNAL(destroyed(QObject*)), this, SLOT(remove(QObject*))); mutex.lock(); running.insert(p); mutex.unlock(); } void QDjVuDocumentPrivate::emitidle() { emit idle(); } void QDjVuDocumentPrivate::remove(QObject *p) { mutex.lock(); running.remove(p); int size = running.size(); disconnect(p, 0, this, 0); mutex.unlock(); if (! size) QTimer::singleShot(0, this, SLOT(emitidle())); } void QDjVuDocumentPrivate::add(QDjVuPage *p) { if (ddjvu_page_decoding_done(*p)) return; connect(p, SIGNAL(pageinfo()), this, SLOT(pageinfo())); add((QObject*)(p)); } void QDjVuDocumentPrivate::pageinfo() { QDjVuPage *p = qobject_cast(sender()); if (p && ddjvu_page_decoding_done(*p)) remove(p); } void QDjVuDocumentPrivate::docinfo() { if (!docReady && ddjvu_document_decoding_done(*docPointer)) { QMutexLocker locker(&mutex); int pageNum = ddjvu_document_get_pagenum(*docPointer); documentOutline = miniexp_dummy; documentAnnotations = miniexp_dummy; pageAnnotations.resize(pageNum); pageText.resize(pageNum); for (int i=0; iautoDelete = autoDelete; priv->docPointer = this; connect(priv, SIGNAL(idle()), this, SIGNAL(idle())); connect(this, SIGNAL(docinfo()), priv, SLOT(docinfo())); } /*! \overload */ QDjVuDocument::QDjVuDocument(QObject *parent) : QObject(parent), document(0), priv(new QDjVuDocumentPrivate) { priv->autoDelete = false; priv->docPointer = this; connect(priv, SIGNAL(idle()), this, SIGNAL(idle())); connect(this, SIGNAL(docinfo()), priv, SLOT(docinfo())); } /*! Increments the reference count. */ void QDjVuDocument::ref() { priv->mutex.lock(); priv->refCount++; priv->mutex.unlock(); } /*! Decrements the reference count. If the object was created with flag \a autoDelete, function \a deleteLater() is called when the reference count reaches 0. */ void QDjVuDocument::deref() { priv->mutex.lock(); bool finished = !(--priv->refCount) && priv->autoDelete; priv->mutex.unlock(); if (finished) delete this; } /*! Associates the \a QDjVuDocument object with the \a QDjVuContext object \ctx in order to decode the DjVu file \a f. */ bool QDjVuDocument::setFileName(QDjVuContext *ctx, QString f, bool cache) { QMutexLocker locker(&priv->mutex); if (isValid()) { ddjvu_document_set_user_data(document, 0); ddjvu_document_release(document); priv->running.clear(); document = 0; } QFileInfo info(f); if (! info.isReadable()) { qWarning("QDjVuDocument::setFileName: cannot read file"); return false; } #if DDJVUAPI_VERSION >= 19 QByteArray b = f.toUtf8(); document = ddjvu_document_create_by_filename_utf8(*ctx, b, cache); #else QByteArray b = QFile::encodeName(f); document = ddjvu_document_create_by_filename(*ctx, b, cache); #endif if (! document) { qWarning("QDjVuDocument::setFileName: cannot create decoder"); return false; } ddjvu_document_set_user_data(document, (void*)this); priv->docinfo(); return true; } /*! Associates the \a QDjVuDocument object with with the \a QDjVuContext object \ctx in order to decode the DjVu data located at URL \a url. This is only useful inside a subclass of this class because you must redefine virtual function \a newstream in order to provide access to the data. */ bool QDjVuDocument::setUrl(QDjVuContext *ctx, QUrl url, bool cache) { QMutexLocker locker(&priv->mutex); if (isValid()) { ddjvu_document_set_user_data(document, 0); ddjvu_document_release(document); priv->running.clear(); document = 0; } QByteArray b = url.toEncoded(); if (! b.size()) { qWarning("QDjVuDocument::setUrl: invalid url"); return false; } document = ddjvu_document_create(*ctx, b, cache); if (! document) { qWarning("QDjVuDocument::setUrl: cannot create"); return false; } ddjvu_document_set_user_data(document, (void*)this); priv->docinfo(); return true; } static bool string_is_on(QString val) { QString v = val.toLower(); return v == "yes" || v == "on" || v == "true" || v == "1"; } static bool string_is_off(QString val) { QString v = val.toLower(); return v == "no" || v == "off" || v == "false" || v == "0"; } /*! Overloaded version of \a setUrl. Cache setup is determined heuristically from the url and the url arguments. */ bool QDjVuDocument::setUrl(QDjVuContext *ctx, QUrl url) { bool cache = true; if (url.path().section('/', -1).indexOf('.') < 0) cache = false; bool djvuopts = false; QPair pair; #if QT_VERSION >= 0x50000 QList > qitems = QUrlQuery(url).queryItems(); #else QList > qitems = url.queryItems(); #endif foreach(pair, qitems) { if (pair.first.toLower() == "djvuopts") djvuopts = true; else if (!djvuopts || pair.first.toLower() != "cache") continue; else if (string_is_on(pair.second)) cache = true; else if (string_is_off(pair.second)) cache = false; } return setUrl(ctx, url, cache); } /*! This virtual function is called when receiving a DDJVUAPI \a m_newstream message. This happens when the decoder has been setup with functon \a setUrl. You must then override this virtual function in order to setup the data transfer. Data is passed to the decoder using the \a streamWrite and \a streamClose member functions with the specified \a streamid. See also the DDJVUAPI documentation for the \a m_newstream message. */ void QDjVuDocument::newstream(int, QString, QUrl) { qWarning("QDjVuDocument::newstream called but not implemented"); } /*! Write data into the decoder stream \a streamid. */ void QDjVuDocument::streamWrite(int streamid, const char *data, unsigned long len ) { QMutexLocker locker(&priv->mutex); if (! isValid()) qWarning("QDjVuDocument::streamWrite: invalid document"); else ddjvu_stream_write(document, streamid, data, len); } /*! Close the decoder stream \a streamid. Setting argument \a stop to \a true indicates that the stream was closed because the data transfer was interrupted by the user. */ void QDjVuDocument::streamClose(int streamid, bool stop) { QMutexLocker locker(&priv->mutex); if (! isValid()) qWarning("QDjVuDocument::streamClose: invalid document"); else ddjvu_stream_close(document, streamid, stop); } /*! Processes DDJVUAPI messages for this document. The default implementation emits signals for the \a m_error, \a m_info, \a m_docinfo, \a m_pageingo and \a m_thumbnail messsages. It also calls the virtual function \a newstream when processing a \m newstream message. The return value is a boolean indicating if the message has been processed or rejected. */ bool QDjVuDocument::handle(ddjvu_message_t *msg) { switch(msg->m_any.tag) { case DDJVU_DOCINFO: ddjvu_document_check_pagedata(document, 0); emit docinfo(); return true; case DDJVU_PAGEINFO: emit pageinfo(); return true; case DDJVU_THUMBNAIL: emit thumbnail(msg->m_thumbnail.pagenum); return true; case DDJVU_NEWSTREAM: { QUrl url; QString name; if (msg->m_newstream.url) url = QUrl::fromEncoded(msg->m_newstream.url); if (msg->m_newstream.name) name = QString::fromLatin1(msg->m_newstream.name); newstream(msg->m_newstream.streamid, name, url); } return true; case DDJVU_ERROR: emit error(QString::fromLocal8Bit(msg->m_error.message), QString::fromLocal8Bit(msg->m_error.filename), msg->m_error.lineno); return true; case DDJVU_INFO: emit info(QString::fromLocal8Bit(msg->m_info.message)); return true; default: break; } return false; } /*! Return number of decoding threads running for this document. */ int QDjVuDocument::runningProcesses(void) { return priv->running.size(); } /*! Obtains the cached document annotations. This function returns \a miniexp_dummy if this information is not yet available. Check again some time after receiving signal \a docinfo(). */ miniexp_t QDjVuDocument::getDocumentAnnotations() { QMutexLocker locker(&priv->mutex); if (! priv->docReady) return miniexp_dummy; if (priv->documentAnnotations != miniexp_dummy) return priv->documentAnnotations; #if DDJVUAPI_VERSION <= 17 priv->documentAnnotations = miniexp_nil; #else priv->documentAnnotations = ddjvu_document_get_anno(document,1); ddjvu_miniexp_release(document, priv->documentAnnotations); #endif return priv->documentAnnotations; } /*! Obtains the cached document outline. This function returns \a miniexp_dummy if this information is not yet available. Check again some time after receiving signal \a docinfo(). */ miniexp_t QDjVuDocument::getDocumentOutline() { QMutexLocker locker(&priv->mutex); if (! priv->docReady) return miniexp_dummy; if (priv->documentOutline != miniexp_dummy) return priv->documentOutline; priv->documentOutline = ddjvu_document_get_outline(document); ddjvu_miniexp_release(document, priv->documentOutline); return priv->documentOutline; } /*! Obtains the cached annotations for page \a pageno. If this information is not yet available, this function returns \a miniexp_dummy and, if \a start is true, starts loading the page data. Check again after receiving signal \a pageinfo(). */ miniexp_t QDjVuDocument::getPageAnnotations(int pageno, bool start) { QMutexLocker locker(&priv->mutex); if (! priv->docReady) return miniexp_dummy; if (pageno<0 || pageno>=priv->pageAnnotations.size()) return miniexp_dummy; minivar_t expr = priv->pageAnnotations[pageno]; if (expr != miniexp_dummy) return expr; if (! (start || ddjvu_document_check_pagedata(*this, pageno))) return expr; expr = ddjvu_document_get_pageanno(document, pageno); ddjvu_miniexp_release(document, expr); if (expr != miniexp_dummy) priv->pageAnnotations[pageno] = expr; return expr; } /*! Obtains the cached hidden text for page \a pageno. If this information is not yet available, this function returns \a miniexp_dummy and, if \a start is true, starts loading the page data. Check again after receiving signal \a pageinfo(). */ miniexp_t QDjVuDocument::getPageText(int pageno, bool start) { QMutexLocker locker(&priv->mutex); if (! priv->docReady) return miniexp_dummy; if (pageno<0 || pageno>=priv->pageText.size()) return miniexp_dummy; minivar_t expr = priv->pageText[pageno]; if (expr != miniexp_dummy) return expr; if (! (start || ddjvu_document_check_pagedata(*this, pageno))) return expr; expr = ddjvu_document_get_pagetext(document, pageno, 0); ddjvu_miniexp_release(document, expr); if (expr != miniexp_dummy) priv->pageText[pageno] = expr; return expr; } /*! \fn QDjVuDocument::isValid() Indicate if this object is associated with a valid \a ddjvu_document_t object. Use this function to determine whether \a setFileName or \a setUrl was successful. */ /*! \fn QDjVuDocument::operator ddjvu_document_t*() Return a pointer to the corresponding \a ddjvu_document_t object. */ /*! \fn QDjVuDocument::error(QString msg, QString filename, int lineno) This signal is emitted when processing a DDJVUAPI \a m_error message that is related to this document. */ /*! \fn QDjVuDocument::info(QString msg) This signal is emitted when processing a DDJVUAPI \a m_info message that is related to this document. */ /*! \fn QDjVuDocument::docinfo() This signal is emitted when the document initialization is complete. Use \a ddjvu_document_decoding_status to determine whether the operation was successful. */ /*! \fn QDjVuDocument::pageinfo() This signal is emitted when the data for a new page has been received in full. This is useful when used in relation with the DDJVUAPI function \a ddjvu_document_get_pageinfo. */ /*! \fn QDjVuDocument::thumbnail(int pagenum) This signal is emitted when the thumbnail for page \a pagenum is ready. This is useful when used in relation with the DDJVUAPI functions \a ddjvu_thumnail_status and \a ddjvu_thumbnail_render. */ /*! \fn QDjVuDocument::idle() This signal is emitted when all decoding threads for this document are terminated. */ // ---------------------------------------- // QDJVUPAGE /*! \class QDjVuPage \brief Represent a \a ddjvu_page_t object. */ /*! Construct a \a QDjVuPage object for page \a pageno of document \a doc. Argument \a parent indicates its parent in the \a QObject hierarchy. */ QDjVuPage::QDjVuPage(QDjVuDocument *doc, int pageno, QObject *parent) : QObject(parent), page(0), pageno(pageno) { page = ddjvu_page_create_by_pageno(*doc, pageno); if (! page) { qWarning("QDjVuPage: invalid page number"); return; } ddjvu_page_set_user_data(page, (void*)this); doc->priv->add(this); } QDjVuPage::~QDjVuPage() { pageno = -1; if (page) { ddjvu_page_set_user_data(page, 0); ddjvu_page_release(page); page = 0; } } /*! Processes DDJVUAPI messages for this page. The default implementation emits signals for the \a m_error, \a m_info, \a m_pageinfo, \a m_chunk and \a m_relayout and \a m_redisplay messsages. The return value is a boolean indicating if the message has been processed or rejected. */ bool QDjVuPage::handle(ddjvu_message_t *msg) { switch(msg->m_any.tag) { case DDJVU_PAGEINFO: emit pageinfo(); return true; case DDJVU_CHUNK: emit chunk(QString::fromLatin1(msg->m_chunk.chunkid)); return true; case DDJVU_RELAYOUT: emit relayout(); return true; case DDJVU_REDISPLAY: emit redisplay(); return true; case DDJVU_ERROR: emit error(QString::fromLocal8Bit(msg->m_error.message), QString::fromLocal8Bit(msg->m_error.filename), msg->m_error.lineno); return true; case DDJVU_INFO: emit info(QString::fromLocal8Bit(msg->m_info.message)); return true; default: break; } return false; } /*! Returns the page number associated with this page. */ int QDjVuPage::pageNo() { return pageno; } /*! \fn QDjVuPage::isValid() Indicate if this object is associated with a valid \a ddjvu_page_t object. Use this function to determine whether the construction was successful. */ /*! \fn QDjVuPage::operator ddjvu_page_t * () Return a pointer to the corresponding \a ddjvu_page_t object. */ /*! \fn QDjVuPage::error(QString msg, QString filename, int lineno) This signal is emitted when processing a DDJVUAPI \a m_error message that is related to this page. */ /*! \fn QDjVuPage::info(QString msg) This signal is emitted when processing a DDJVUAPI \a m_info message that is related to this page. */ /*! \fn QDjVuPage::pageinfo() This signal is emitted when processing a DDJVUAPI \a m_pageinfo message that is related to this page. This happens twice during the page decoding process. The first time when the basic page information is present, and the second time when the decoding process terminates. Use \a ddjvu_page_decoding_status function to determine what is going on. */ /*! \fn QDjVuPage::relayout() This signal is emitted when processing a DDJVUAPI \a m_relayout message that is related to this page. */ /*! \fn QDjVuPage::redisplay() This signal is emitted when processing a DDJVUAPI \a m_redisplay message that is related to this page. */ /*! \fn QDjVuPage::chunk(QString chunkid) This signal is emitted when processing a DDJVUAPI \a m_chunk message that is related to this page. */ // ---------------------------------------- // QDJVUJOB /*! \class QDjVuJob \brief Represents a \a ddjvu_job_t object. */ /*! Construct a \a QDjVuJob object. Argument \a job is the \a ddjvu_job_t object. Argument \a parent defines its parent in the \a QObject hierarchy. */ QDjVuJob::QDjVuJob(ddjvu_job_t *job, QObject *parent) : QObject(parent), job(job) { if (! job) qWarning("QDjVuJob: invalid job"); else ddjvu_job_set_user_data(job, (void*)this); } QDjVuJob::~QDjVuJob() { ddjvu_job_set_user_data(job, 0); ddjvu_job_release(job); job = 0; } /*! Processes DDJVUAPI messages for this job. The default implementation emits signals for the \a m_error, \a m_info, and \a m_progress messages. The return value is a boolean indicating if the message has been processed or rejected. */ bool QDjVuJob::handle(ddjvu_message_t *msg) { switch(msg->m_any.tag) { case DDJVU_ERROR: emit error(QString::fromLocal8Bit(msg->m_error.message), QString::fromLocal8Bit(msg->m_error.filename), msg->m_error.lineno); return true; case DDJVU_INFO: emit info(QString::fromLocal8Bit(msg->m_info.message)); return true; case DDJVU_PROGRESS: emit progress(msg->m_progress.percent); return true; default: break; } return false; } /*! \fn QDjVuJob::isValid() Indicate if this object is associated with a \a ddjvu_job_t object. */ /*! \fn QDjVuJob::operator ddjvu_job_t * () Return a pointer to the corresponding \a ddjvu_job_t object. */ /*! \fn QDjVuJob::error(QString msg, QString filename, int lineno) This signal is emitted when processing a DDJVUAPI \a m_error message that is related to this job. */ /*! \fn QDjVuJob::info(QString msg) This signal is emitted when processing a DDJVUAPI \a m_info message that is related to this job. */ /*! \fn QDjVuJob::progress(int percent) This signal is emitted when processing a DDJVUAPI \a m_progress message that is related to this job. Argument indicates the progress level from 1 to 100. */ // ---------------------------------------- // MOC #include "qdjvu.moc" /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "Q[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvu.h000066400000000000000000000120741264256014000152520ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVU_H #define QDJVU_H #if AUTOCONF # include "config.h" #endif // The following definition allow for using // this file without the libdjvu include files. #ifndef DDJVUAPI_H typedef struct ddjvu_context_s ddjvu_context_t; typedef union ddjvu_message_s ddjvu_message_t; typedef struct ddjvu_job_s ddjvu_job_t; typedef struct ddjvu_document_s ddjvu_document_t; typedef struct ddjvu_page_s ddjvu_page_t; #endif #ifndef MINIEXP_H typedef struct miniexp_s* miniexp_t; #endif // Qt includes #include #include #include // The following classes integrate the ddjvuapi with // the Qt memory management and event management scheme. // All ddjvuapi events are converted into signals sent // when the Qt event loop is called. These signal are // emitted by all objects listed in the event message. // // All classes below define implicit conversion // into pointers to the corresponding ddjvuapi objects. class QDjVuContext; class QDjVuDocument; class QDjVuDocumentPrivate; class QDjVuPage; class QDjVuJob; class QDjVuContext : public QObject { Q_OBJECT Q_PROPERTY(long cacheSize READ cacheSize WRITE setCacheSize) private: static void callback(ddjvu_context_t *context, void *closure); ddjvu_context_t *context; bool flag; // might become private pointer in the future protected: virtual bool handle(ddjvu_message_t*); public: virtual ~QDjVuContext(); QDjVuContext(const char *programname=0, QObject *parent=0); long cacheSize() const; void setCacheSize(long); virtual bool event(QEvent*); operator ddjvu_context_t*() { return context; } signals: void error(QString msg, QString filename, int lineno); void info(QString msg); }; class QDjVuDocument : public QObject { Q_OBJECT private: friend class QDjVuContext; friend class QDjVuPage; friend class QDjVuJob; ddjvu_document_t *document; QDjVuDocumentPrivate *priv; protected: virtual bool handle(ddjvu_message_t*); public: virtual ~QDjVuDocument(); QDjVuDocument(QObject *parent); QDjVuDocument(bool autoDelete=false, QObject *parent=0); void ref(); void deref(); bool setFileName(QDjVuContext *ctx, QString filename, bool cache=true); protected: bool setUrl(QDjVuContext *ctx, QUrl url); bool setUrl(QDjVuContext *ctx, QUrl url, bool cache); virtual void newstream(int streamid, QString name, QUrl url); public: void streamWrite(int streamid, const char *data, unsigned long len ); void streamClose(int streamid, bool stop = false); operator ddjvu_document_t*() { return document; } virtual bool isValid() { return document != 0; } public: int runningProcesses(void); miniexp_t getDocumentAnnotations(); miniexp_t getDocumentOutline(); miniexp_t getPageAnnotations(int pageno, bool start=true); miniexp_t getPageText(int pageno, bool start=true); signals: void error(QString msg, QString filename, int lineno); void info(QString msg); void docinfo(void); void pageinfo(void); void thumbnail(int pagenum); void idle(void); }; class QDjVuPage : public QObject { Q_OBJECT private: friend class QDjVuContext; friend class QDjVuDocument; ddjvu_page_t *page; int pageno; // might become private pointer in the future protected: virtual bool handle(ddjvu_message_t*); public: virtual ~QDjVuPage(); QDjVuPage(QDjVuDocument *doc, int pageno, QObject *parent=0); operator ddjvu_page_t*() { return page; } bool isValid() { return page!=0; } int pageNo(); signals: void error(QString msg, QString filename, int lineno); void info(QString msg); void chunk(QString chunkid); void pageinfo(); void relayout(); void redisplay(); }; class QDjVuJob : public QObject { Q_OBJECT private: friend class QDjVuContext; friend class QDjVuDocument; ddjvu_job_t *job; protected: virtual bool handle(ddjvu_message_t*); public: virtual ~QDjVuJob(); QDjVuJob(ddjvu_job_t *job, QObject *parent=0); operator ddjvu_job_t*() { return job; } signals: void error(QString msg, QString filename, int lineno); void info(QString msg); void progress(int percent); }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "Q[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvunet.cpp000066400000000000000000000306221264256014000163130ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include "qdjvunet.h" #include "qdjviewprefs.h" #include #include #include #include #include #include #include #if QT_VERSION >= 0x40400 #include #include #include #include #include #include #include class QDjVuNetDocument::Private : public QObject { Q_OBJECT public: Private(QDjVuNetDocument *q); ~Private(); QDjVuNetDocument *q; QMap reqid; QMap reqok; QDjVuContext *ctx; QUrl url; bool cache; public slots: void readyRead(); void finished(); void error(QNetworkReply::NetworkError code); void sslErrors(const QList&); void authenticationRequired (QNetworkReply *reply, QAuthenticator *auth); void proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth); private: void doRead(QNetworkReply *reply, int streamid); void doError(QNetworkReply *reply, int streamid); bool doAuth(QString why, QAuthenticator *auth); }; QDjVuNetDocument::Private::Private(QDjVuNetDocument *q) : QObject(q), q(q) { QNetworkAccessManager *mgr = manager(); connect(mgr, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)) ); connect(mgr, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(const QNetworkProxy&,QAuthenticator*)) ); } QDjVuNetDocument::Private::~Private() { QMap::iterator it; for(it = reqid.begin(); it != reqid.end(); ++it) { QNetworkReply *reply = it.key(); int streamid = it.value(); if (streamid >= 0) ddjvu_stream_close(*q, streamid, true); reply->abort(); reply->deleteLater(); } reqid.clear(); reqok.clear(); } void QDjVuNetDocument::Private::doRead(QNetworkReply *reply, int streamid) { QByteArray b = reply->readAll(); if (streamid >= 0 && b.size() > 0) { if (! reqok.value(reply, false)) { int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QUrl location = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); QByteArray type = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray(); // check redirection if (location.isValid()) { reqid[reply] = -1; QUrl nurl = reply->url().resolved(location); if (streamid > 0 || status == 307) { q->newstream(streamid, QString(), nurl); return; } // Permanent redirect on main stream changes the base url. ddjvu_stream_close(*q, streamid, false); q->setUrl(ctx, nurl, cache); if (q->isValid()) return; } // check status code if (status != 200 && status != 203 && status != 0) { QString msg = tr("Received http status %1 while retrieving %2.", "%1 is an http status code") .arg(status) .arg(reply->url().toString()); emit q->error(msg, __FILE__, __LINE__); return; } // check content type if (type.startsWith("text/")) { QString msg = tr("Received <%1> data while retrieving %2.", "%1 is a mime type") .arg(QString::fromLatin1(type)) .arg(reply->url().toString()); emit q->error(msg, __FILE__, __LINE__); } reqok[reply] = true; } // process data ddjvu_stream_write(*q, streamid, b.data(), b.size()); } } void QDjVuNetDocument::Private::doError(QNetworkReply *reply, int streamid) { QNetworkReply::NetworkError code = reply->error(); if (streamid >= 0 && code != QNetworkReply::NoError) { QString msg = tr("%1 while retrieving '%2'.") .arg(reply->errorString()) .arg(reply->url().toString()); emit q->error(msg , __FILE__, __LINE__); ddjvu_stream_close(*q, streamid, false); reqid[reply] = -1; } } void QDjVuNetDocument::Private::readyRead() { QNetworkReply *reply = qobject_cast(sender()); if (reply) { int streamid = reqid.value(reply, -1); if (streamid >= 0) doRead(reply, streamid); } } void QDjVuNetDocument::Private::finished() { QNetworkReply *reply = qobject_cast(sender()); if (reply) { int streamid = reqid.value(reply, -1); if (streamid >= 0) { if (reply->bytesAvailable() > 0) doRead(reply, streamid); if (reply->error() != QNetworkReply::NoError) doError(reply, streamid); else ddjvu_stream_close(*q, streamid, false); } } reqid.remove(reply); reqok.remove(reply); reply->deleteLater(); } void QDjVuNetDocument::Private::error(QNetworkReply::NetworkError) { QNetworkReply *reply = qobject_cast(sender()); if (reply) { int streamid = reqid.value(reply, -1); if (streamid >= 0) doError(reply, streamid); } } void QDjVuNetDocument::Private::sslErrors(const QList&) { QNetworkReply *reply = qobject_cast(sender()); if (reply) { static QSet sslWhiteList; QString host = reply->url().host(); bool okay = sslWhiteList.contains(host); if (! okay) { QString why = tr("Cannot validate the certificate for server %1.").arg(host); emit q->sslWhiteList(why, okay); if (okay) sslWhiteList += host; } if (okay) reply->ignoreSslErrors(); } } bool QDjVuNetDocument::Private::doAuth(QString why, QAuthenticator *auth) { QString user = auth->user(); QString pass = QString::null; q->emit authRequired(why, user, pass); if (pass.isNull()) return false; auth->setUser(user); auth->setPassword(pass); return true; } void QDjVuNetDocument::Private::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) { QString host = reply->url().host(); QString why = tr("Authentication required for %1 (%2).").arg(auth->realm()).arg(host); if (! doAuth(why, auth)) reply->abort(); } void QDjVuNetDocument::Private::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) { QString why = tr("Authentication required for proxy %1.").arg(proxy.hostName()); doAuth(why, auth); } /*! \class QDjVuNetDocument \brief Represents DjVu documents accessible via the network This class is derived from \a QDjVuDocument and reimplements method \a newstream to handle documents available throught network requests. */ QDjVuNetDocument::~QDjVuNetDocument() { delete p; } /*! Construct a \a QDjVuNetDocument object. See \a QDjVuDocument::QDjVuDocument for the other two arguments. */ QDjVuNetDocument::QDjVuNetDocument(bool autoDelete, QObject *parent) : QDjVuDocument(autoDelete, parent), p(new QDjVuNetDocument::Private(this)) { } /*! \overload */ QDjVuNetDocument::QDjVuNetDocument(QObject *parent) : QDjVuDocument(parent), p(new QDjVuNetDocument::Private(this)) { } /*! Returns the \a QNetworkAccessManager used to reach the network. */ QNetworkAccessManager* QDjVuNetDocument::manager() { static QPointer mgr; QObject *app = QCoreApplication::instance(); if (! mgr) mgr = new QNetworkAccessManager(app); return mgr; } /*! Sets the application proxy using the host, port, user, and password specified by url \a proxyUrl. The proxy type depends on the url scheme. Recognized schemes are \a "http", \a "ftp", and \a "socks5". */ void QDjVuNetDocument::setProxy(QUrl proxyUrl) { QNetworkProxy proxy; QString scheme = proxyUrl.scheme(); if (scheme == "http") proxy.setType(QNetworkProxy::HttpCachingProxy); if (scheme == "ftp") proxy.setType(QNetworkProxy::FtpCachingProxy); else if (scheme == "socks5") proxy.setType(QNetworkProxy::Socks5Proxy); proxy.setHostName(proxyUrl.host()); proxy.setPort(proxyUrl.port()); proxy.setUser(proxyUrl.userName()); proxy.setPassword(proxyUrl.password()); QNetworkProxy::setApplicationProxy(proxy); } /*! Associates the \a QDjVuDocument object with with the \a QDjVuContext object \ctx in order to decode the DjVu data located at URL \a url. */ bool QDjVuNetDocument::setUrl(QDjVuContext *ctx, QUrl url, bool cache) { if (url.isValid()) { if (url.scheme() == "file" && url.host().isEmpty()) QDjVuDocument::setFileName(ctx, url.toLocalFile(), cache); else QDjVuDocument::setUrl(ctx, url, cache); } if (isValid()) { p->url = url; p->ctx = ctx; p->cache = cache; return true; } return false; } /* Perform a request. */ void QDjVuNetDocument::newstream(int streamid, QString, QUrl url) { QString message = tr("Requesting '%1'").arg(url.toString()); QNetworkRequest request(url); QString agent = "Djview/" + QDjViewPrefs::versionString(); request.setRawHeader("User-Agent", agent.toLatin1()); QNetworkReply *reply = manager()->get(request); connect(reply, SIGNAL(readyRead()), p, SLOT(readyRead()) ); connect(reply, SIGNAL(finished()), p, SLOT(finished()) ); connect(reply, SIGNAL(sslErrors(const QList&)), p, SLOT(sslErrors(const QList&)) ); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), p, SLOT(error(QNetworkReply::NetworkError)) ); p->reqid[reply] = streamid; p->reqok[reply] = false; emit info(message); } /*! \fn void QDjVuNetDocument::authRequired(QString why, QString &user, QString &pass) This signal is emitted when a username and password is required. String \a why contains a suitable description of the purpose of the username and password. Simply set \a user and \a pass and the credentials will be remembered. */ /*! \fn QDjVuNetDocument::sslWhiteList(QString host, bool &okay) This signal is emitted when there are recoverable errors on a ssl connection such as an inability to validate the certificate. String \a why contains a description of the problem. Setting \a okay to true allows the connection to proceed for the current session. */ // ---------------------------------------- // MOC #include "qdjvunet.moc" #else // QT_VERSION < 0x40400 // ---------------------------------------- // STUBS QT < 4.4.0 class QDjVuNetDocument::Private : public QObject { Q_OBJECT public: Private() : QObject() { } }; QDjVuNetDocument::~QDjVuNetDocument() { } QDjVuNetDocument::QDjVuNetDocument(bool autoDelete, QObject *parent) : QDjVuDocument(autoDelete, parent) { } QDjVuNetDocument::QDjVuNetDocument(QObject *parent) : QDjVuDocument(parent) { } bool QDjVuNetDocument::setUrl(QDjVuContext *ctx, QUrl url, bool cache) { if (url.isValid() && url.scheme() == "file") if (url.host().isEmpty() || url.host() == "localhost") return setFileName(ctx, url.toLocalFile(), cache); return false; } QNetworkAccessManager* QDjVuNetDocument::manager() { return 0; } void QDjVuNetDocument::setProxy(QUrl) { } void QDjVuNetDocument::newstream(int, QString, QUrl) { } #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "Q[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvunet.h000066400000000000000000000033571264256014000157650ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVUNET_H #define QDJVUNET_H #if AUTOCONF # include "config.h" #endif #include class QAuthenticator; class QNetworkAccessManager; class QDjVuNetDocument : public QDjVuDocument { Q_OBJECT public: ~QDjVuNetDocument(); QDjVuNetDocument(bool autoDelete=false, QObject *parent=0); QDjVuNetDocument(QObject *parent); bool setUrl(QDjVuContext *ctx, QUrl url, bool cache=true); static QNetworkAccessManager* manager(); static void setProxy(QUrl proxyurl); protected: virtual void newstream(int streamid, QString name, QUrl url); signals: void authRequired(QString why, QString &user, QString &pass); void sslWhiteList(QString why, bool &okay); private: class Private; Private *p; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "Q[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvuwidget.cpp000066400000000000000000005222031264256014000170110ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #if AUTOCONF # include "config.h" #endif #include #include #include #include #include #include "qdjvu.h" #include "qdjvuwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= 0x040600 #include #endif #ifdef QT_OPENGL_LIB # include # include #endif #if DDJVUAPI_VERSION < 17 # error "DDJVUAPI_VERSION>=17 is required !" #endif #if DDJVUAPI_VERSION >= 18 # ifndef QDJVUWIDGET_PIXMAP_CACHE # define QDJVUWIDGET_PIXMAP_CACHE 1 # endif #endif #ifdef Q_NO_USING_KEYWORD # define BEGIN_ANONYMOUS_NAMESPACE # define END_ANONYMOUS_NAMESPACE # define QRectMapper QDjVu_QRectMapper # define Page QDjVu_Page # define Cache QDjVu_Cache # define MapArea QDjVu_MapArea # define Keywords QDjVu_Keywords # define DragMode QDjVu_DragMode #else # define BEGIN_ANONYMOUS_NAMESPACE namespace { # define END_ANONYMOUS_NAMESPACE } #endif typedef QDjVuWidget::Align Align; typedef QDjVuWidget::DisplayMode DisplayMode; typedef QDjVuWidget::Position Position; typedef QDjVuWidget::PageInfo PageInfo; typedef QDjVuWidget::Priority Priority; #define ZOOM_STRETCH QDjVuWidget::ZOOM_STRETCH #define ZOOM_ONE2ONE QDjVuWidget::ZOOM_ONE2ONE #define ZOOM_FITPAGE QDjVuWidget::ZOOM_FITPAGE #define ZOOM_FITWIDTH QDjVuWidget::ZOOM_FITWIDTH #define ZOOM_MIN QDjVuWidget::ZOOM_MIN #define ZOOM_100 QDjVuWidget::ZOOM_100 #define ZOOM_MAX QDjVuWidget::ZOOM_MAX #define DISPLAY_COLOR QDjVuWidget::DISPLAY_COLOR #define DISPLAY_STENCIL QDjVuWidget::DISPLAY_STENCIL #define DISPLAY_BG QDjVuWidget::DISPLAY_BG #define DISPLAY_FG QDjVuWidget::DISPLAY_FG #define DISPLAY_TEXT QDjVuWidget::DISPLAY_TEXT #define ALIGN_TOP QDjVuWidget::ALIGN_TOP #define ALIGN_LEFT QDjVuWidget::ALIGN_LEFT #define ALIGN_CENTER QDjVuWidget::ALIGN_CENTER #define ALIGN_BOTTOM QDjVuWidget::ALIGN_BOTTOM #define ALIGN_RIGHT QDjVuWidget::ALIGN_RIGHT #define PRIORITY_DEFAULT QDjVuWidget::PRIORITY_DEFAULT #define PRIORITY_ANNO QDjVuWidget::PRIORITY_ANNO #define PRIORITY_CGI QDjVuWidget::PRIORITY_CGI #define PRIORITY_USER QDjVuWidget::PRIORITY_USER // ---------------------------------------- // UTILITIES static inline void rect_to_qrect(const ddjvu_rect_t &rect, QRect &qrect) { qrect.setRect(rect.x, rect.y, rect.w, rect.h ); } static inline void qrect_to_rect(const QRect &qrect, ddjvu_rect_t &rect) { qrect.getRect(&rect.x, &rect.y, (int*)&rect.w, (int*)&rect.h); } static inline int scale_int(int x, int numerator, int denominator) { qint64 y = (qint64)x * numerator; return (int)(y + denominator - 1)/denominator; } static QSize scale_size(int w, int h, int numerator, int denominator, int rot=0) { int sw = scale_int(w,numerator,denominator); int sh = scale_int(h,numerator,denominator); return (rot & 1) ? QSize(sh, sw) : QSize(sw, sh); } static bool all_numbers(const char *s) { for (int i=0; s[i]; i++) if (s[i]<'0' || s[i]>'9') return false; return true; } template static inline int ksmallest(T *v, int n, int k) { int lo = 0; int hi = n-1; while (lov[m]) qSwap(v[lo],v[m]); if (v[m]>v[hi]) { qSwap(v[m],v[hi]); if (v[lo]>v[m]) qSwap(v[lo],v[m]); } /* Extract pivot, place sentinel */ pivot = v[m]; v[m] = v[lo+1]; v[lo+1] = v[lo]; v[lo] = pivot; /* Partition */ l = lo; h = hi; loop: do ++l; while (v[l]pivot); if (l < h) { qSwap(v[l],v[h]); goto loop; } /* Finish up */ if (k <= h) hi = h; else if (k >= l) lo = l; else break; } return v[k]; } static QCursor qcursor_by_name(const char *s, int hotx=8, int hoty=8) { QString name(s); QPixmap pixmap(name); if (pixmap.isNull()) return QCursor(); hotx = (hotx * pixmap.width()) / 16; hoty = (hoty * pixmap.height()) / 16; return QCursor(pixmap, hotx, hoty); } static QRegion cover_region(QRegion region, const QRect &brect) { QVector rects = region.rects(); // dilate region QRegion dilated; for (int i=0; i myarea; QList myrect; for (int i=0; i= 0) { int na = myarea[j] + a; QRect nr = myrect[j].united(r); if (nr.width() * nr.height() < 2 * na ) { myarea[j] = na; myrect[j] = nr; break; } } if (j < 0) { myarea << a; myrect << r; } } // recompose region QRegion ret; for (int i=0; i 0) m = qMin(m, (r.right() - s.x()) / v.x()); if (v.x() < 0) m = qMin(m, (r.left() - s.x()) / v.x()); if (v.y() > 0) m = qMin(m, (r.bottom() - s.y()) / v.y()); if (v.y() < 0) m = qMin(m, (r.top() - s.y()) / v.y()); return m; } static bool miniexp_get_int(miniexp_t &r, int &x) { if (! miniexp_numberp(miniexp_car(r))) return false; x = miniexp_to_int(miniexp_car(r)); r = miniexp_cdr(r); return true; } static bool miniexp_get_rect(miniexp_t &r, QRect &rect) { int x, y, w, h; if (! (miniexp_get_int(r, x) && miniexp_get_int(r, y) && miniexp_get_int(r, w) && miniexp_get_int(r, h) )) return false; if (w<0 || h<0 || r) return false; rect.setRect(x, y, w, h); return true; } static bool miniexp_get_rect_from_points(miniexp_t &r, QRect &rect) { int x1,y1,x2,y2; if (! (miniexp_get_int(r, x1) && miniexp_get_int(r, y1) && miniexp_get_int(r, x2) && miniexp_get_int(r, y2) )) return false; if (x2 &points) { rect = QRect(); points.clear(); while (miniexp_consp(r)) { int x, y; if (!miniexp_get_int(r, x) || !miniexp_get_int(r, y)) return false; points << QPoint(x,y); rect |= QRect(x,y,1,1); } if (r || points.size() < 2) return false; return true; } static bool miniexp_get_color(miniexp_t &r, QColor &color) { const char *s = miniexp_to_name(miniexp_car(r)); if (! (s && s[0]=='#')) return false; color.setNamedColor(QString::fromUtf8(s)); if (! color.isValid()) return false; r = miniexp_cdr(r); return true; } QString miniexp_to_qstring(miniexp_t r) { const char *s = miniexp_to_str(r); if (s) return QString::fromUtf8(s); return QString(); } void flatten_hiddentext_sub(miniexp_t p, minivar_t &d) { miniexp_t type = miniexp_car(p); miniexp_t r = miniexp_cdr(p); QRect rect; if (miniexp_symbolp(type) && miniexp_get_rect_from_points(r, rect) ) { if (miniexp_stringp(miniexp_car(r))) { d = miniexp_cons(p, d); } else { while (miniexp_consp(r)) { flatten_hiddentext_sub(miniexp_car(r), d); r = miniexp_cdr(r); } d = miniexp_cons(type, d); } } } miniexp_t flatten_hiddentext(miniexp_t p) { // Output list contains // - terminals of the hidden text tree // (keyword x1 y1 x2 y2 string) // - or a keyword symbol indicating the need for a separator // page,column,region,para,line,word minivar_t d; flatten_hiddentext_sub(p, d); d = miniexp_reverse(d); // Uncomment the following line to print it: // miniexp_pprint(d, 72); return d; } void invert_luminance(QImage &img) { if (img.format() == QImage::Format_RGB32 || img.format() == QImage::Format_ARGB32 ) { int w = img.width(); int h = img.height(); for (int y=0; y> 16) & 0xff; qint32 g = (word >> 8) & 0xff; qint32 b = (word >> 0) & 0xff; word &= 0xff000000; qint32 s = 255 - qMax(r,qMax(g,b)) - qMin(r,qMin(g,b)); word |= ((r+s)<<16) | ((b+s)<<8) | (g+s); *words++ = word; } } } else { // revert to standard inversion. img.invertPixels(); } } // ---------------------------------------- // Position /*! \class QDjVuWidget::Position \brief Defines a position in the document. Variable \a pageNo indicates the closest page number. Flag \a inPage indicates that the position falls inside a page with known geometry. Variable \a posPage then indicates the position within the full resolution page coordinates (same coordinates as those used for the DjVu page annotations). Variable \a posView usually indicates the position relative to, in general, the top-left corner of the page rectangle. In fact variables \a hAnchor and \a vAnchor indicate the coordinates of the reference point as a percentages of the width and height relative to the top left corner. These are always zero when the position is returned by QDjVuWidget::position. Finally flag \a doPage makes sure that \a pageNo is indeed the closest page. This is always false when the position is returned by QDjVuWidget::position. */ Position::Position() : pageNo(0), posPage(0,0), posView(0,0), inPage(false), doPage(false), hAnchor(0), vAnchor(0) { } // ---------------------------------------- // QRECTMAPPER BEGIN_ANONYMOUS_NAMESPACE class QRectMapper { private: ddjvu_rectmapper_t *p; public: ~QRectMapper(); QRectMapper(); QRectMapper(const QRect &in, const QRect &out); void setMap(const QRect &in, const QRect &out); void setTransform(int rotation, bool mirrorx=false, bool mirrory=false); QPoint mapped(const QPoint &p); QRect mapped(const QRect &r); QPoint unMapped(const QPoint &p); QRect unMapped(const QRect &r); }; QRectMapper::~QRectMapper() { ddjvu_rectmapper_release(p); p = 0; } QRectMapper::QRectMapper() : p(0) { } QRectMapper::QRectMapper(const QRect &in, const QRect &out) : p(0) { setMap(in, out); } void QRectMapper::setMap(const QRect &in, const QRect &out) { ddjvu_rect_t rin, rout; ddjvu_rectmapper_release(p); p = 0; qrect_to_rect(in, rin); qrect_to_rect(out, rout); p = ddjvu_rectmapper_create(&rin, &rout); } void QRectMapper::setTransform(int rotation, bool mirrorx, bool mirrory) { if (!p) qWarning("QRectMapper: please call setMap first."); ddjvu_rectmapper_modify(p, rotation, (mirrorx?1:0), (mirrory?1:0)); } QPoint QRectMapper::mapped(const QPoint &qp) { QPoint q = qp; if (p) ddjvu_map_point(p, &q.rx(), &q.ry()); return q; } QRect QRectMapper::mapped(const QRect &qr) { QRect q; ddjvu_rect_t r; qrect_to_rect(qr, r); if (p) ddjvu_map_rect(p, &r); rect_to_qrect(r, q); return q; } QPoint QRectMapper::unMapped(const QPoint &qp) { QPoint q = qp; if (p) ddjvu_unmap_point(p, &q.rx(), &q.ry()); return q; } QRect QRectMapper::unMapped(const QRect &qr) { QRect q; ddjvu_rect_t r; qrect_to_rect(qr, r); if (p) ddjvu_unmap_rect(p, &r); rect_to_qrect(r, q); return q; } END_ANONYMOUS_NAMESPACE // ---------------------------------------- // PRIORITIZED SETTINGS // Some settings can be set/unset from several sources BEGIN_ANONYMOUS_NAMESPACE template class Prioritized { public: Prioritized(); operator Value() const; void set(Priority priority, Value value); void unset(Priority priority); void reduce(Priority priority); private: bool flags[PRIORITY_USER+1]; Value values[PRIORITY_USER+1]; }; template Prioritized::Prioritized() { for (int i=0; i<=PRIORITY_USER; i++) flags[i] = false; } template Prioritized::operator Value() const { for (int i=PRIORITY_USER; i>0; i--) if (flags[i]) return values[i]; return values[PRIORITY_DEFAULT]; } template void Prioritized::set(Priority priority, Value val) { values[priority] = val; flags[priority] = true; } template void Prioritized::unset(Priority priority) { flags[priority] = false; } template void Prioritized::reduce(Priority priority) { for (int i=PRIORITY_USER; i>priority; i--) if (flags[i]) { flags[i-1] = flags[i]; values[i-1] = values[i]; flags[i] = false; } } END_ANONYMOUS_NAMESPACE // ---------------------------------------- // QDJVULENS (declaration) class QDjVuLens : public QWidget { Q_OBJECT public: QDjVuLens(int size, int mag, QDjVuPrivate *priv, QDjVuWidget *widget); protected: virtual bool event(QEvent *event); virtual void paintEvent(QPaintEvent *event); virtual void moveEvent(QMoveEvent *event); virtual void resizeEvent(QResizeEvent *event); virtual bool eventFilter(QObject*, QEvent*); private: QDjVuPrivate *priv; QDjVuWidget *widget; QRect lensRect; int mag; public slots: void recenter(const QPoint &p); void redisplay(); private: void refocus(); }; // ---------------------------------------- // QDJVUPRIVATE BEGIN_ANONYMOUS_NAMESPACE struct MapArea { minivar_t expr; miniexp_t url; miniexp_t target; miniexp_t comment; miniexp_t areaType; QRect areaRect; QList areaPoints; miniexp_t borderType; QColor borderColor; QColor hiliteColor; QColor foregroundColor; unsigned char borderWidth; bool borderAlwaysVisible; unsigned char hiliteOpacity; bool pushpin; bool lineArrow; unsigned char lineWidth; bool rectNeedsRotation; MapArea(); bool error(const char *err, int pageno, miniexp_t info); bool parse(miniexp_t anno, int pageno=-1); bool isClickable(bool hyperlink=true); bool clicked(void); bool hasTransient(bool allLinks=false); bool hasPermanent(); bool contains(const QPoint &p); void maybeRotate(struct Page *p); QPainterPath contour(QRectMapper &m, QPoint &offset); void update(QWidget *w, QRectMapper &m, QPoint offset, bool clicked=false); void paintBorder(QPaintDevice *w, QRectMapper &m, QPoint offset, bool allLinks=false); void paintPermanent(QPaintDevice *w, QRectMapper &m, QPoint o, double z=100); void paintTransient(QPaintDevice *w, QRectMapper &m, QPoint o, bool allLinks=false); }; struct Page { int pageno; int width; // page coordinates int height; // page coordinates int dpi; // zero to indicate unknown size QRect rect; // desk coordinates QRect viewRect; // viewport coordinates QRectMapper mapper; // from page to desk coordinates QDjVuPage *page; // the page decoder minivar_t annotations; // the djvu page annotations minivar_t hiddenText; // the hidden djvu page text int initialRot; // initial rotation (used for text) QList mapAreas; // the list of mapareas bool redisplay; // must redisplay bool infoNeeded; // we want the page info now. void clear() { delete page; page=0; } ~Page() { clear(); }; Page() : pageno(-1),width(0),height(0),dpi(0),page(0), annotations(miniexp_dummy),hiddenText(miniexp_dummy), initialRot(-1),redisplay(false), infoNeeded(false) { clear(); } }; struct Cache { QRect rect; // desk coordinates QImage image; #if QDJVUWIDGET_PIXMAP_CACHE QPixmap pixmap; #endif }; enum { CHANGE_STATS = 0x1, // recompute estimated page sizes CHANGE_PAGES = 0x2, // change the displayed pages CHANGE_SIZE = 0x4, // update the recorded size of displayed pages CHANGE_SCALE = 0x8, // update the scale of displayed pages CHANGE_POSITIONS = 0x10, // update the disposition of the pages CHANGE_SCALE_PASS2 = 0x20, // internal CHANGE_VIEW = 0x40, // move to a new position CHANGE_VISIBLE = 0x80, // update the visible rectangle CHANGE_SCROLLBARS = 0x100, // update the scrollbars UPDATE_BORDERS = 0x200, // redisplay the visible desk surface UPDATE_PAGES = 0x400, // redisplay, possibly by scrolling smartly UPDATE_ALL = 0x800, // redisplay everything REFRESH_PAGES = 0x1000, // redraw pages with new pixels SCHEDULED = 0x8000 // internal: change scheduled }; enum DragMode { DRAG_NONE, DRAG_PANNING, DRAG_LENSING, DRAG_SELECTING, DRAG_LINKING }; END_ANONYMOUS_NAMESPACE class QDjVuPrivate : public QObject { Q_OBJECT private: virtual ~QDjVuPrivate(); QDjVuPrivate(QDjVuWidget *widget); friend class QDjVuWidget; friend class QDjVuLens; public: QDjVuWidget * const widget; // the widget QDjVuDocument *doc; bool docFailed; // page decoding has failed bool docStopped; // page decoding has stopped bool docReady; // page decoding is done int numPages; // total number of pages Position currentPos; // last clicked position QPoint currentPoint; // last clicked point Position cursorPos; // cursor position QPoint cursorPoint; // cursor point // display int zoom; int rotation; DisplayMode display; Align hAlign; Align vAlign; bool frame; bool continuous; bool sideBySide; bool coverPage; bool rightToLeft; QBrush borderBrush; // layout int layoutChange; // scheduled changes int layoutLoop; // loop avoidance counter QPoint movePoint; // desired viewport point (CHANGE_VIEW) Position movePos; // desired page point (CHANGE_VIEW) QVector pageData; // all pages QList pageLayout; // pages in current layout QList pageVisible; // pages visible in viewport QMap pageMap; // keyed by page number QRect deskRect; // desk rectangle (0,0,w,h) QRect visibleRect; // visible rectangle (desk coordinates) int zoomFactor; // effective zoom level int savedFactor; // temporary factor used for gestures int estimatedWidth; // median of known page widths int estimatedHeight; // median of known page heights QSize unknownSize; // displayed page size when unknown (pixels) int borderSize; // size of borders around pages (pixels) int separatorSize; // size of separation between pages (pixels) int shadowSize; // size of the page shadow (pixels) // page requests int pageRequestDelay; // delay when scrollbars are down QTimer *pageRequestTimer; // timer for page requests // painting int pixelCacheSize; // size of pixel cache QRect selectedRect; // selection rectangle (viewport coord) double gamma; // display gamma bool invertLuminance; // invert images QColor white; // display white point int sdpi; // screen dpi ddjvu_format_t *renderFormat; // ddjvu format QList pixelCache; // pixel cache // gui bool keyboardEnabled; // obey keyboard commands bool mouseEnabled; // obey mouse commands bool hyperlinkEnabled; // follow hyperlinks bool animationEnabled; // animate position changes bool changingSBars; // set while changing scrollbars bool mouseWheelZoom; // mouse wheel function DragMode dragMode; // dragging mode QPoint dragStart; // starting point for dragging QMenu* contextMenu; // popup menu QDjVuLens *lens; // lens (only while lensing) int lensMag; // lens maginification int lensSize; // lens size double hourGlassRatio; // hour glass timer ratio int lineStep; // pixels moved by arrow keys Qt::MouseButtons buttons; // current mouse buttons Qt::KeyboardModifiers modifiers; // current modifiers Qt::KeyboardModifiers modifiersForLinks; // keys to show hyperlink Qt::KeyboardModifiers modifiersForLens; // keys to show lens Qt::KeyboardModifiers modifiersForSelect; // keys to select QList animationPosition; // list of positions to hit QPoint animationPoint; // reference point QTimer *animationTimer; // animation timer // prioritized settings Prioritized qBorderSize; Prioritized qZoom; Prioritized qBorderBrush; Prioritized qDisplay; Prioritized qHAlign; Prioritized qVAlign; // hyperlinks bool displayMapAreas; Page *currentMapAreaPage; MapArea *currentMapArea; QString currentUrl; QString currentTarget; QString currentComment; bool currentLinkDisplayed; bool allLinksDisplayed; QTimer *toolTipTimer; // messages int maxMessages; QList errorMessages; QList infoMessages; // cursors QCursor cursHandOpen; QCursor cursHandClosed; void initWidget(bool noaccel); void changeLayout(int change, int delay=0); void getAnnotationsAndText(Page *p); bool requestPage(Page *p); int findClosestPage(const QPoint&, const QList&, Page**, int*); Position findPosition(const QPoint &point, bool closestAnchor=false); void updateModifiers(Qt::KeyboardModifiers, Qt::MouseButtons); void updatePosition(const QPoint &point, bool click=false, bool links=true); void updateCurrentPoint(const Position &pos); void adjustSettings(Priority priority, miniexp_t expr); void prepareMapAreas(Page*); bool mustDisplayMapArea(MapArea*); void checkCurrentMapArea(bool forceno=false); void showTransientMapAreas(bool); void updateTransientMapArea(Page*, MapArea*); void trimPixelCache(); void addToPixelCache(const QRect &rect, QImage image); bool paintHiddenText(QImage&, Page*, const QRect&, const QRect *pr=0); bool paintMapAreas(QImage&, Page*, const QRect&, bool, const QRect *pr=0); bool paintPage(QPainter&, Page*, const QRegion&); void paintAll(QPainter&, const QRegion&); bool pointerScroll(const QPoint &p); void changeSelectedRectangle(const QRect &rect); bool eventFilter(QObject*, QEvent*); void clearAnimation(void); bool computeAnimation(const Position&, const QPoint&); void changeBorderSize(void); void changeZoom(void); void changeBorderBrush(void); void changeDisplay(void); void changeHAlign(void); void changeVAlign(void); QRect hourGlassRect(void) const; void pageinfoPage(QDjVuPage*); public slots: void makeLayout(); void makePageRequests(); void docinfo(); void pageinfo(); void pageinfoPage(); void redisplayPage(); void error(QString msg, QString filename, int lineno); void info(QString msg); void makeToolTip(); void animate(); }; QDjVuPrivate::~QDjVuPrivate() { if (doc) doc->deref(); doc = 0; if (renderFormat) ddjvu_format_release(renderFormat); renderFormat = 0; } QDjVuPrivate::QDjVuPrivate(QDjVuWidget *widget) : widget(widget) { // doc doc = 0; docReady = false; docStopped = false; docFailed = false; numPages = 1; // aspect zoom = 100; rotation = 0; frame = true; display = DISPLAY_COLOR; hAlign = ALIGN_CENTER; vAlign = ALIGN_CENTER; sideBySide = false; continuous = false; coverPage = false; rightToLeft = false; borderBrush = QBrush(Qt::lightGray); unknownSize = QSize(128,128); borderSize = 8; separatorSize = 12; shadowSize = 2; // prioritized qBorderSize.set(PRIORITY_DEFAULT, borderSize); qZoom.set(PRIORITY_DEFAULT, zoom); qBorderBrush.set(PRIORITY_DEFAULT, borderBrush); qDisplay.set(PRIORITY_DEFAULT, display); qHAlign.set(PRIORITY_DEFAULT, hAlign); qVAlign.set(PRIORITY_DEFAULT, vAlign); // gui contextMenu = 0; keyboardEnabled = true; hyperlinkEnabled = true; mouseEnabled = true; animationEnabled = true; lineStep = 12; buttons = (Qt::MouseButtons)(-1); modifiers = (Qt::KeyboardModifiers)(-1); modifiersForLinks = Qt::ShiftModifier; modifiersForLens = Qt::ShiftModifier|Qt::ControlModifier; modifiersForSelect = Qt::ControlModifier; changingSBars = false; dragMode = DRAG_NONE; lens = 0; lensMag = 3; lensSize = 300; hourGlassRatio = 0; animationTimer = new QTimer(this); animationTimer->setSingleShot(false); connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate())); // scheduled changes layoutChange = 0; layoutLoop = 0; pageRequestDelay = 250; pageRequestTimer = new QTimer(this); pageRequestTimer->setSingleShot(true); // render format gamma = 2.2; invertLuminance = false; white = QColor(Qt::white); sdpi = 100; #if DDJVUAPI_VERSION < 18 unsigned int masks[3] = { 0xff0000, 0xff00, 0xff }; renderFormat = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 3, masks); #else unsigned int masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; renderFormat = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 4, masks); #endif ddjvu_format_set_row_order(renderFormat, true); ddjvu_format_set_y_direction(renderFormat, true); ddjvu_format_set_ditherbits(renderFormat, QPixmap::defaultDepth()); ddjvu_format_set_gamma(renderFormat, gamma); // misc maxMessages = 20; displayMapAreas = true; currentMapAreaPage = 0; currentMapArea = 0; currentLinkDisplayed = false; allLinksDisplayed = false; pixelCacheSize = 256 * 1024; // cursors cursHandOpen = qcursor_by_name(":/images/cursor_hand_open.png"); cursHandClosed = qcursor_by_name(":/images/cursor_hand_closed.png"); // tooltips toolTipTimer = new QTimer(this); toolTipTimer->setSingleShot(true); // connect connect(pageRequestTimer, SIGNAL(timeout()), this, SLOT(makePageRequests()) ); connect(toolTipTimer, SIGNAL(timeout()), this, SLOT(makeToolTip()) ); connect(widget->horizontalScrollBar(), SIGNAL(sliderReleased()), this, SLOT(makePageRequests()) ); connect(widget->verticalScrollBar(), SIGNAL(sliderReleased()), this, SLOT(makePageRequests()) ); } // ---------------------------------------- // LAYOUT // Schedule a layout recomputation. void QDjVuPrivate::changeLayout(int change, int delay) { int oldChange = layoutChange; layoutChange = oldChange | change | SCHEDULED; layoutLoop = 0; if (! (oldChange & SCHEDULED)) QTimer::singleShot(delay, this, SLOT(makeLayout())); } // Perform a scheduled layout recomputation. void QDjVuPrivate::makeLayout() { // save position int futureLayoutChange = 0; if (docReady && !(layoutChange & CHANGE_VIEW)) { movePoint = currentPoint; movePos = currentPos; } // adjust layout information while (layoutChange && docReady) { // Recompute estimated page sizes if (layoutChange & CHANGE_STATS) { int k = 0; QVector widthVec(numPages+1); QVector heightVec(numPages+1); layoutChange &= ~CHANGE_STATS; futureLayoutChange |= CHANGE_STATS; for (int i=0; i 0) { int dpi = pageData[i].dpi; widthVec[k] = pageData[i].width * 100 / dpi; heightVec[k] = pageData[i].height * 100 / dpi; k += 1; } if (k > 0) { futureLayoutChange &= ~CHANGE_STATS; estimatedWidth = ksmallest(widthVec.data(), k, k/2); estimatedHeight = ksmallest(heightVec.data(), k, k/2); for (int i=0; i=numPages) { qWarning("makeLayout: invalid page number"); movePos.pageNo = widget->page(); } int loPage = movePos.pageNo; int hiPage = qMin(numPages, loPage+1); if (continuous) { loPage = 0; hiPage = numPages; } else if (sideBySide && coverPage) { loPage = qMax(0, (loPage & 1) ? loPage : loPage-1); hiPage = qMin(numPages, (loPage & 1) ? loPage+2 : loPage+1); } else if (sideBySide) { loPage = qMax(0, (loPage & 1) ? loPage-1 : loPage); hiPage = qMin(numPages, loPage+2); } for (int i=loPage; i= hiPage + 2) pageData[i].clear(); // Display settings are unclear when showing multiple page. // We use the annotations of the first displayed page as a proxy. adjustSettings(PRIORITY_ANNO, pageLayout[0]->annotations); } // Layout page sizes else if (layoutChange & CHANGE_SIZE) { layoutChange &= ~CHANGE_SIZE; Page *p; foreach(p, pageLayout) { int n = p->pageno; if (! p->infoNeeded) continue; if (p->dpi <= 0) { ddjvu_pageinfo_t info; ddjvu_status_t status; status = ddjvu_document_get_pageinfo(*doc, n, &info); if (status == DDJVU_JOB_OK) if (info.dpi > 0 && info.width > 0 && info.height > 0) { p->dpi = info.dpi; p->width = info.width; p->height = info.height; #if DDJVUAPI_VERSION >= 18 p->initialRot = info.rotation; #endif } layoutChange |= CHANGE_SCALE; layoutChange |= UPDATE_BORDERS; } getAnnotationsAndText(p); } } // Layout scaled page size else if (layoutChange & CHANGE_SCALE) { // some setups require two passes layoutChange &= ~CHANGE_SCALE; layoutChange &= ~CHANGE_SCALE_PASS2; layoutChange |= CHANGE_POSITIONS; if (pageLayout.size() > 1) if (zoom==ZOOM_FITWIDTH || zoom==ZOOM_FITPAGE) layoutChange |= CHANGE_SCALE_PASS2; // rescale pages Page *p; int r = rotation; int vpw = qMax(64, widget->viewport()->width() - 2*borderSize); int vph = qMax(64, widget->viewport()->height() - 2*borderSize); zoomFactor = zoom; foreach(p, pageLayout) { QSize size; if (p->width <= 0 || p->height <= 0) { size = unknownSize; } else if (p->dpi <= 0) { size = (zoom <= 0) ? unknownSize : scale_size(p->width, p->height, zoom*sdpi, 10000, r); } else if (layoutChange & CHANGE_SCALE_PASS2) { size = scale_size(p->width, p->height, sdpi, p->dpi, r); } else if (zoom == ZOOM_ONE2ONE) { size = scale_size(p->width, p->height, p->dpi, p->dpi, r); } else if (zoom == ZOOM_STRETCH) { int v2pw = (sideBySide) ? (vpw-separatorSize)/2 : vpw; size = QSize(v2pw, vph); } else if (zoom == ZOOM_FITWIDTH) { int pgw = (r&1) ? p->height : p->width; size = scale_size(p->width, p->height, vpw, pgw, r); zoomFactor = (vpw * p->dpi * 100) / (pgw * sdpi); } else if (zoom == ZOOM_FITPAGE) { int pgw = (r&1) ? p->height : p->width; int pgh = (r&1) ? p->width : p->height; if (vpw*pgh > vph*pgw) { vpw = vph; pgw = pgh; } size = scale_size(p->width, p->height, vpw, pgw, r); zoomFactor = (vpw * p->dpi * 100) / (pgw * sdpi); } else size = scale_size(p->width, p->height, zoom*sdpi,100*p->dpi,r); p->rect.setSize(size); } } // Layout page positions else if (layoutChange & CHANGE_POSITIONS) { layoutChange |= CHANGE_VIEW; layoutChange |= CHANGE_SCROLLBARS; layoutChange &= ~CHANGE_POSITIONS; // position pages Page *p; QRect fullRect; if (! continuous) { // single page or side by side pages int x = borderSize; int s = pageLayout.size(); for (int i=0; irect.moveTo(x,borderSize); fullRect |= p->rect; x = x + p->rect.width() + separatorSize; } foreach(p, pageLayout) { int dy = fullRect.height() - p->rect.height(); if (vAlign == ALIGN_CENTER) p->rect.translate(0, dy/2); else if (vAlign == ALIGN_BOTTOM) p->rect.translate(0, dy); } } else if (!sideBySide) { // continuous single pages int y = borderSize; foreach(p, pageLayout) { p->rect.moveTo(borderSize, y); y = y + p->rect.height() + separatorSize; fullRect |= p->rect; } foreach(p, pageLayout) { int dx = fullRect.width() - p->rect.width(); if (hAlign == ALIGN_CENTER) p->rect.translate(dx/2, 0); else if (hAlign == ALIGN_RIGHT) p->rect.translate(dx,0); } } else { // continuous side-by-side pages int wLeft = 0; int wTotal = 0; int k = 0; while(k < pageLayout.size()) { Page *lp = pageLayout[k++]; Page *rp = lp; if (k < pageLayout.size() && (k>1 || !coverPage)) rp = pageLayout[k++]; if (rightToLeft) { Page *tmp=lp; lp=rp; rp=tmp; } int lw = lp->rect.width(); wLeft = qMax(wLeft, lw); wTotal = qMax(wTotal, lw); if (rp) wTotal = qMax(wTotal, lw+rp->rect.width()+separatorSize); } int y = borderSize; k = 0; while(k < pageLayout.size()) { Page *lp = pageLayout[k++]; Page *rp = lp; if (k < pageLayout.size() && (k > 1 || !coverPage)) rp = pageLayout[k++]; if (rightToLeft) { Page *tmp=lp; lp=rp; rp=tmp; } int h = qMax(lp->rect.height(), rp->rect.height()); int ly, ry, lx, rx; ly = ry = y; if (vAlign==ALIGN_BOTTOM) { ly += (h - lp->rect.height()); ry += (h - rp->rect.height()); } else if (vAlign==ALIGN_CENTER) { ly += (h - lp->rect.height())/2; ry += (h - rp->rect.height())/2; } if (hAlign==ALIGN_LEFT) { lx = borderSize; rx = lx + lp->rect.width() + separatorSize; } else if (hAlign==ALIGN_RIGHT) { if (rp == lp) rx = wTotal + borderSize + separatorSize; else rx = wTotal + borderSize - rp->rect.width(); lx = rx - separatorSize - lp->rect.width(); } else if (lp == rp) { lx = borderSize+wLeft+(separatorSize-lp->rect.width())/2; rx = lx; } else { lx = borderSize + wLeft - lp->rect.width(); rx = borderSize + wLeft + separatorSize; } lp->rect.moveTo(lx, ly); if (rp != lp) rp->rect.moveTo(rx, ry); fullRect |= lp->rect; fullRect |= rp->rect; y = y + h + separatorSize; } } // setup rectangles fullRect.adjust(-borderSize, -borderSize, +borderSize, +borderSize ); deskRect = fullRect; // setup mappers foreach(p, pageLayout) { int w = (p->width>0) ? p->width : unknownSize.width(); int h = (p->height>0) ? p->height : unknownSize.height(); p->mapper.setMap(QRect(0,0,w,h), p->rect); p->mapper.setTransform(rotation, false, true); } // clear pixel cache pixelCache.clear(); } // Layout page positions else if (layoutChange & CHANGE_SCALE_PASS2) { Page *p; // compute usable viewport size (minus margins and separators) int vw = widget->viewport()->width() - 2*borderSize - 2; int vh = widget->viewport()->height() - 2*borderSize - 2; if (sideBySide && pageLayout.size()>1) vw = vw - separatorSize; vw = qMax(64, vw); vh = qMax(64, vh); // compute target size for zoom 100% int dw = deskRect.width() - 2*borderSize; int dh = deskRect.height() - 2*borderSize; if (sideBySide && pageLayout.size()>1) dw = dw - separatorSize; if (continuous) { dh = 0; foreach(p, pageLayout) dh = qMax(dh, p->rect.height()); } // compute zoom factor into vw/dw if (zoom == ZOOM_FITPAGE && vw*dh > vh*dw) { vw = vh; dw = dh; } zoomFactor = vw * 100 / dw; // apply zoom int r = rotation; foreach(p, pageLayout) { QSize size = unknownSize; int dpi = (p->dpi > 0) ? p->dpi : 100; if (p->width>0 && p->height>0) size = scale_size(p->width, p->height, vw * sdpi, dw * dpi, r); p->rect.setSize(size); } // prepare further adjustments layoutChange |= CHANGE_POSITIONS; layoutChange &= ~CHANGE_SCALE_PASS2; } // Viewport adjustment else if (layoutChange & CHANGE_VIEW) { if (pageMap.contains(movePos.pageNo)) { Page *p = pageMap[movePos.pageNo]; QPoint dp = p->rect.topLeft(); if (movePos.hAnchor > 0 && movePos.hAnchor <= 100) dp.rx() += (p->rect.width() - 1) * movePos.hAnchor / 100; if (movePos.vAnchor > 0 && movePos.vAnchor <= 100) dp.ry() += (p->rect.height() - 1) * movePos.vAnchor / 100; QPoint sdp = dp; if (movePos.inPage && p->dpi) dp = p->mapper.mapped(movePos.posPage); else if (!movePos.inPage) dp += movePos.posView; // special case: unknown page geometry if (! p->dpi) if (movePos.inPage || movePos.vAnchor || movePos.hAnchor) futureLayoutChange = CHANGE_VIEW; // special case: not the closest page if (movePos.doPage) if (movePos.pageNo != findClosestPage(dp, pageLayout, 0, 0)) dp = sdp; // perform move visibleRect.moveTo(dp - movePoint); } layoutChange |= CHANGE_VISIBLE; layoutChange &= ~CHANGE_VIEW; } // Layout page visibility adjustment else if (layoutChange & CHANGE_VISIBLE) { Page *p; QSize vpSize = widget->viewport()->size(); QRect &rv = visibleRect; QRect &rd = deskRect; // adjust size rv.setSize(vpSize); // reposition rectVisible according to alignment. rv.moveRight(qMin(rv.right(), rd.right())); rv.moveLeft(qMax(rv.left(), rd.left())); rv.moveBottom(qMin(rv.bottom(), rd.bottom())); rv.moveTop(qMax(rv.top(), rd.top())); if (hAlign == ALIGN_RIGHT) rv.moveRight(qMin(rv.right(), rd.right())); if (vAlign == ALIGN_BOTTOM) rv.moveBottom(qMin(rv.bottom(), rd.bottom())); QPoint cd = rd.center(); QPoint cv = rv.center(); if (hAlign==ALIGN_CENTER && rv.width()>=rd.width()) cv.setX(cd.x()); if (vAlign==ALIGN_CENTER && rv.height()>=rd.height()) cv.setY(cd.y()); rv.moveCenter(cv); // delete QDjVuPage that are too far away int sw = rv.width(); int sh = rv.height(); QRect v = rv.adjusted(-sw, -sh, +sw, +sh); foreach(p, pageLayout) if (p->page && !v.intersects(p->rect)) p->clear(); // construct pageVisible array and schedule page requests pageVisible.clear(); foreach(p, pageLayout) if (rv.intersects(p->rect)) pageVisible.append(p); // schedule page requests QScrollBar *hBar = widget->horizontalScrollBar(); QScrollBar *vBar = widget->verticalScrollBar(); if (hBar->isSliderDown() || vBar->isSliderDown()) pageRequestTimer->start(pageRequestDelay); else pageRequestTimer->start(0); // synchronize currentpoint and cursorpos updateCurrentPoint(movePos); updatePosition(cursorPoint, false, false); // continue layoutChange |= UPDATE_PAGES; layoutChange &= ~CHANGE_VISIBLE; } // scrollbar adjustment else if (layoutChange & CHANGE_SCROLLBARS) { QRect &rv = visibleRect; QRect rd = deskRect.united(rv); QScrollBar *hBar = widget->horizontalScrollBar(); QScrollBar *vBar = widget->verticalScrollBar(); int vmin = rd.top(); int vmax = rd.bottom() + 1 - rv.height(); int hmin = rd.left(); int hmax = rd.right() + 1 - rv.width(); // loop prevention if (++layoutLoop >= 4) { if (hBar->isVisible() && hmax <= hmin) hmax = hmin + 1; if (vBar->isVisible() && vmax <= vmin) vmax = vmin + 1; } // set scrollbars changingSBars = true; vBar->setMinimum(vmin); vBar->setMaximum(vmax); vBar->setPageStep(rv.height()); vBar->setSingleStep(lineStep * 2); vBar->setValue(rv.top()); hBar->setMinimum(hmin); hBar->setMaximum(hmax); hBar->setPageStep(rv.width()); hBar->setSingleStep(lineStep * 2); hBar->setValue(rv.left()); changingSBars = false; layoutChange &= ~CHANGE_SCROLLBARS; } // force redraw else if (layoutChange & UPDATE_ALL) { Page *p; QRect &rv = visibleRect; foreach(p, pageLayout) p->viewRect = p->rect.translated(-rv.topLeft()); layoutChange &= ~UPDATE_ALL; layoutChange &= ~UPDATE_PAGES; layoutChange &= ~UPDATE_BORDERS; widget->viewport()->update(); checkCurrentMapArea(); emit widget->layoutChanged(); } // otherwise try scrolling else if (layoutChange & UPDATE_PAGES) { Page *p; QRect &rv = visibleRect; // redraw on failure layoutChange |= UPDATE_ALL; // determine potential scroll int dx = 0; int dy = 0; bool scroll = false; foreach(p, pageVisible) if (p->viewRect.size() == p->rect.size()) { scroll = true; dx = p->rect.left() - rv.left() - p->viewRect.left(); dy = p->rect.top() - rv.top() - p->viewRect.top(); break; } if (! scroll) continue; // verify potential scroll QRect rs = widget->viewport()->rect(); rs &= rs.translated(-dx,-dy); if (rs.isEmpty()) continue; foreach(p, pageLayout) { QRect rect = p->rect.translated(-rv.topLeft()); if (rs.intersects(p->viewRect)) p->viewRect.translate(dx,dy); else p->viewRect = rect; if (rv.intersects(p->rect)) if (p->viewRect != rect) scroll = false; } if (! scroll) continue; layoutChange &= ~UPDATE_PAGES; layoutChange &= ~UPDATE_ALL; dragStart += QPoint(dx,dy); selectedRect.translate(dx, dy); // Tooltips mess things up during scrolls QToolTip::showText(QPoint(),QString()); // hourGlass messes things up too widget->setHourGlassRatio(0); // Attention: scroll can generate a paintEvent // and call makeLayout again. This is why we // do these four things before. widget->viewport()->scroll(dx,dy); checkCurrentMapArea(); emit widget->layoutChanged(); } else if (layoutChange & UPDATE_BORDERS) { Page *p; QRegion region = widget->viewport()->rect(); foreach(p, pageVisible) region -= p->viewRect; layoutChange &= ~UPDATE_BORDERS; widget->viewport()->update(region); emit widget->layoutChanged(); } else if (layoutChange & REFRESH_PAGES) { Page *p; bool changes = false; foreach(p, pageLayout) if (p->redisplay) { if (visibleRect.intersects(p->rect)) widget->viewport()->update(p->viewRect); p->redisplay = false; changes = true; } if (changes) pixelCache.clear(); layoutChange &= ~REFRESH_PAGES; } else { // deschedule if (layoutChange & ~SCHEDULED) qWarning("QDjVuWidget::makeLayout: unknown bits"); layoutChange = 0; } } // deschedule layoutChange &= ~SCHEDULED; layoutChange |= futureLayoutChange; } // Make all page requests void QDjVuPrivate::makePageRequests(void) { Page *p; QRect &rv = visibleRect; bool found = false; if (! doc) return; // visible pages foreach(p, pageVisible) if (p && rv.intersects(p->rect)) found |= requestPage(p); // search more if document is idle (prefetch/predecode) if (!found && !doc->runningProcesses()) { if (continuous) { int sw = rv.width() / 2; int sh = rv.height() / 2; QRect brv = rv.adjusted(-sw,-sh,sw,sh); foreach(p, pageLayout) if (!p->page && brv.intersects(p->rect)) found |= requestPage(p); } else if (pageVisible.size() > 0) { int pmin = pageVisible[0]->pageno; int pmax = pageVisible[0]->pageno; foreach(p, pageVisible) { pmax = qMax(pmax, p->pageno); pmin = qMin(pmin, p->pageno); } if (pmax+1 < numPages) found |= requestPage(&pageData[pmax+1]); if (! found && pmin-1 >= 0) found |= requestPage(&pageData[pmin-1]); if (! found && pmax+2 < numPages) found |= requestPage(&pageData[pmax+2]); if (! found && pmin-2 >= 0) found |= requestPage(&pageData[pmin-2]); } } } // Obtain page annotations and hidden text if not present void QDjVuPrivate::getAnnotationsAndText(Page *p) { if (p->annotations == miniexp_dummy) { p->annotations = doc->getPageAnnotations(p->pageno); if (p->annotations) if (pageLayout.size() > 0 && p == pageLayout[0]) adjustSettings(PRIORITY_ANNO, p->annotations); if (p->annotations) prepareMapAreas(p); } if (p->hiddenText == miniexp_dummy) { miniexp_t expr = doc->getPageText(p->pageno); if (expr != miniexp_dummy) p->hiddenText = flatten_hiddentext(expr); } } // Create the page decoder and connects its slots. bool QDjVuPrivate::requestPage(Page *p) { bool result = false; if (! p->page) { // create and connect page p->page = new QDjVuPage(doc, p->pageno); connect(p->page, SIGNAL(pageinfo()), this, SLOT(pageinfoPage())); connect(p->page, SIGNAL(redisplay()), this, SLOT(redisplayPage())); connect(p->page, SIGNAL(error(QString,QString,int)), this, SLOT(error(QString,QString,int)) ); connect(p->page, SIGNAL(info(QString)), this, SLOT(info(QString)) ); if (! p->page->isValid()) emit widget->errorCondition(p->pageno); // decoded page found in the cache (needed with djvulibre <= 3.5.27) if (ddjvu_page_decoding_status(*(p->page)) >= DDJVU_JOB_OK) pageinfoPage(p->page); // schedule redisplay p->redisplay = true; changeLayout(REFRESH_PAGES); result = true; } if (! p->infoNeeded) { p->infoNeeded = true; changeLayout(CHANGE_SIZE); } getAnnotationsAndText(p); return result; } // finds closest page to a point in desk coordinates int QDjVuPrivate::findClosestPage(const QPoint &deskPoint, const QList &pages, Page **pp, int *pd) { Page *p; Page *bestPage = 0; int bestDistance = 0; foreach(p, pages) { int distance = 0; if (deskPoint.y() < p->rect.top()) distance += p->rect.top() - deskPoint.y(); else if (deskPoint.y() > p->rect.bottom() - 1) distance += deskPoint.y() - p->rect.bottom() + 1; if (deskPoint.x() < p->rect.left()) distance += p->rect.left() - deskPoint.x(); else if (deskPoint.x() > p->rect.right() - 1) distance += deskPoint.x() - p->rect.right() + 1; if (bestPage==0 || distancepageno; } // compute Position for a given viewport point. Position QDjVuPrivate::findPosition(const QPoint &point, bool closestAnchor) { Position pos; Page *bestPage = 0; int bestDistance = 0; QPoint deskPoint = visibleRect.topLeft() + point; findClosestPage(deskPoint, pageVisible, &bestPage, &bestDistance); if (! bestPage) findClosestPage(deskPoint, pageLayout, &bestPage, &bestDistance); if (bestPage) { pos.pageNo = bestPage->pageno; pos.posView = deskPoint - bestPage->rect.topLeft(); pos.posPage = bestPage->mapper.unMapped(deskPoint); pos.inPage = (bestDistance == 0 && bestPage->dpi > 0); if (closestAnchor) { int w = bestPage->rect.width() - 1; int h = bestPage->rect.height() - 1; pos.hAnchor = 100 * qBound(0, pos.posView.x(), w) / w; pos.vAnchor = 100 * qBound(0, pos.posView.y(), h) / h; int x = w * pos.hAnchor / 100; int y = h * pos.vAnchor / 100; pos.posView = pos.posView - QPoint(x,y); } } return pos; } // when the pointer moves void QDjVuPrivate::updatePosition(const QPoint &point, bool click, bool links) { if (point.isNull()) return; // locate bool changed = false; cursorPoint = point; Position pos = findPosition(point); if (! pageMap.contains(pos.pageNo)) return; if (pos.pageNo != cursorPos.pageNo || pos.inPage != cursorPos.inPage || pos.posView != cursorPos.posView || pos.posPage != cursorPos.posPage ) changed = true; // update cursorPos = pos; if (click) updateCurrentPoint(pos); if (! changed) return; // emit pointerposition signal PageInfo info; Page *p = pageMap.value(pos.pageNo,0); if (p != 0) { info.pageno = pos.pageNo; info.width = p->width; info.height = p->height; info.dpi = p->dpi; info.segment = widget->getSegmentForRect(selectedRect, info.pageno); info.selected = selectedRect; emit widget->pointerPosition(pos, info); } // check mapareas if (links) checkCurrentMapArea(); } // when the view moves void QDjVuPrivate::updateCurrentPoint(const Position &pos) { QPoint point; bool changePos = !pos.doPage; if (pageMap.contains(pos.pageNo)) { Page *p = pageMap[pos.pageNo]; point = p->rect.topLeft(); if (pos.hAnchor > 0 && pos.hAnchor <= 100) point.rx() += (p->rect.width() - 1) * pos.hAnchor / 100; if (pos.vAnchor > 0 && pos.vAnchor <= 100) point.ry() += (p->rect.height() - 1) * pos.vAnchor / 100; if (pos.inPage && p->dpi > 0) point = p->mapper.mapped(pos.posPage); else if (!pos.inPage) point += pos.posView; } else { int n = pageLayout.size(); if (n > 0 && pos.pageNo < pageLayout[0]->pageno) point = pageLayout[0]->rect.topLeft(); else if (n > 0 && pos.pageNo > pageLayout[n-1]->pageno) point = pageLayout[n-1]->rect.bottomRight(); } // check visibility if (! visibleRect.contains(point)) { changePos = true; point.ry() = qBound(visibleRect.top() + borderSize, point.y(), visibleRect.bottom() - borderSize); point.rx() = qBound(visibleRect.left() + borderSize, point.x(), visibleRect.right() - borderSize); } // update currentPoint currentPoint = point - visibleRect.topLeft(); // update currentPos int oldPage = currentPos.pageNo; if (changePos || pos.hAnchor || pos.vAnchor) currentPos = findPosition(currentPoint); else currentPos = pos; if (oldPage != currentPos.pageNo) emit widget->pageChanged(currentPos.pageNo); } // ---------------------------------------- // QDJVUPRIVATE SLOTS void QDjVuPrivate::docinfo() { ddjvu_status_t status; status = ddjvu_document_decoding_status(*doc); if (status == DDJVU_JOB_OK && !docReady) { docReady = true; numPages = ddjvu_document_get_pagenum(*doc); pageData.clear(); pageData.resize(numPages); for (int i=0; i 0) requestPage((pageMap[0] = &pageData[0])); } else if (status == DDJVU_JOB_STOPPED && !docStopped) { docStopped = true; emit widget->stopCondition(-1); widget->viewport()->update(); } else if (status == DDJVU_JOB_FAILED && !docFailed) { docFailed = true; emit widget->errorCondition(-1); widget->viewport()->update(); } } void QDjVuPrivate::pageinfo() { changeLayout(CHANGE_SIZE, 250); } void QDjVuPrivate::pageinfoPage() { QObject *send = sender(); pageinfoPage(qobject_cast(send)); } void QDjVuPrivate::pageinfoPage(QDjVuPage *page) { if (page) { Page *p = 0; int pageno = page->pageNo(); if (pageno>=0 && pagenodpi <= 0) { ddjvu_page_rotation_t rot; rot = ddjvu_page_get_initial_rotation(*page); ddjvu_page_set_rotation(*page, rot); int w = ddjvu_page_get_width(*page); int h = ddjvu_page_get_height(*page); int d = ddjvu_page_get_resolution(*page); if (d > 0 && w > 0 && h > 0) { p->width = w; p->height = h; p->dpi = d; p->initialRot = rot; changeLayout(CHANGE_STATS|CHANGE_SCALE|UPDATE_BORDERS); } } break; case DDJVU_JOB_STOPPED: docStopped = true; emit widget->stopCondition(page->pageNo()); break; case DDJVU_JOB_FAILED: emit widget->errorCondition(page->pageNo()); break; default: break; } } } void QDjVuPrivate::redisplayPage() { QObject *send = sender(); QDjVuPage *page = qobject_cast(send); if (page) { int pageno = page->pageNo(); if (pageMap.contains(pageno)) { Page *p = pageMap[pageno]; if (p && !p->redisplay) { p->redisplay = true; changeLayout(REFRESH_PAGES); } } } } void QDjVuPrivate::error(QString message, QString filename, int lineno) { emit widget->error(message, filename, lineno); errorMessages.prepend(message); while (errorMessages.size() > maxMessages) errorMessages.removeLast(); } void QDjVuPrivate::info(QString message) { emit widget->info(message); infoMessages.prepend(message); while (infoMessages.size() > maxMessages) infoMessages.removeLast(); } // ---------------------------------------- // QDJVUWIDGET /*! \class QDjVuWidget \brief Widget for display DjVu documents. Class \a QDjVuWidget implements the elementary widget for displaying DjVu documents. It appears as a display area possibly surrounded by horizontal and vertical scrollbars. The display area can show a single page, two pages side by side, or all pages in continuously scrollable area. */ QDjVuWidget::~QDjVuWidget() { delete priv; priv = 0; } // This is a helper for the constructors void QDjVuPrivate::initWidget(bool opengl) { // set widget policies widget->setFocusPolicy(Qt::StrongFocus); widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); // set opengl acceleration #if QT_VERSION >= 0x040400 if (opengl) { const char *ge = 0; #ifdef QT_OPENGL_LIB QGLWidget *gw = 0; if (! QGLFormat::hasOpenGL()) ge = "cannot find openGL on this system"; if (!ge) gw = new QGLWidget(); if (gw && !ge && !gw->isValid()) ge = "cannot setup openGL context"; if (gw && !ge && !gw->format().directRendering()) ge = "cannot setup openGL direct rendering"; if (gw && !ge) { gw->setFocusPolicy(Qt::ClickFocus); widget->setViewport(gw); } else if (gw) delete gw; #else ge = "disabled at compilation time"; #endif if (!ge) qWarning("Using openGL rendering"); else qWarning("Using default rendering (%s)", ge); } #endif // setup viewport QWidget *vp = widget->viewport(); #if QT_VERSION >= 0x50000 vp->setAttribute(Qt::WA_OpaquePaintEvent); #elif QT_VERSION >= 0x040100 vp->setAttribute(Qt::WA_OpaquePaintEvent); vp->setAttribute(Qt::WA_NativeWindow); #else vp->setAttribute(Qt::WA_StaticContents); vp->setAttribute(Qt::WA_NoSystemBackground); vp->setAttribute(Qt::WA_NativeWindow); #endif #if QT_VERSION >= 0x040600 vp->grabGesture(Qt::PinchGesture); #endif vp->setMouseTracking(true); } /*! Construct a \a QDjVuWidget instance. Argument \a parent is the parent of this widget in the \a QObject hierarchy. Setting argument \a opengl to true enables openGL acceleration */ QDjVuWidget::QDjVuWidget(bool opengl, QWidget *parent) : QAbstractScrollArea(parent), priv(new QDjVuPrivate(this)) { priv->initWidget(opengl); } /*! Overloaded constructor */ QDjVuWidget::QDjVuWidget(QWidget *parent) : QAbstractScrollArea(parent), priv(new QDjVuPrivate(this)) { priv->initWidget(false); } /*! This overloaded constructor calls \a setDocument. */ QDjVuWidget::QDjVuWidget(QDjVuDocument *doc, bool opengl, QWidget *parent) : QAbstractScrollArea(parent), priv(new QDjVuPrivate(this)) { priv->initWidget(opengl); setDocument(doc); } /*! This overloaded constructor calls \a setDocument. */ QDjVuWidget::QDjVuWidget(QDjVuDocument *doc, QWidget *parent) : QAbstractScrollArea(parent), priv(new QDjVuPrivate(this)) { priv->initWidget(false); setDocument(doc); } // ---------------------------------------- // MESSAGE /*! Return one of the last error messages. Argument \a n indicates which message should be returned. Value 0 corresponds to the most recent message. */ QString QDjVuWidget::pastErrorMessage(int n) { if (0 <= n && n < priv->errorMessages.size()) return priv->errorMessages.at(n); return QString(); } /*! Return one of the last informational messages. Argument \a n indicates which message should be returned. Value 0 corresponds to the most recent message. */ QString QDjVuWidget::pastInfoMessage(int n) { if (0 <= n && n < priv->infoMessages.size()) return priv->infoMessages.at(n); return QString(); } // ---------------------------------------- // QDJVUWIDGET PROPERTIES /*! \property QDjVuWidget::document The \a QDjVuDocument object shown in this widget. */ QDjVuDocument * QDjVuWidget::document(void) const { return priv->doc; } /*! Specify the \a QDjVuDocument shown by this widget. The caller is responsible to ensure that the document object \a d remains allocated until the djvu widget is either destroyed or directed to use another document. Two techniques are interesting: The first consists of capturing the document signal \a destroyed() and to call \a setDocument(0) before the destruction occurs. The second consists of allocating the document object in \a autoDelete mode, since the djvu widget calls methods \a ref() and \a deref() adequately. */ void QDjVuWidget::setDocument(QDjVuDocument *d) { if (d != priv->doc) { // cleanup if (priv->doc) { priv->adjustSettings(PRIORITY_ANNO, miniexp_nil); priv->adjustSettings(PRIORITY_CGI, miniexp_nil); disconnect(priv->doc, 0, priv, 0); priv->doc->deref(); } priv->doc = 0; priv->pageData.clear(); priv->pageLayout.clear(); priv->pageMap.clear(); priv->pageVisible.clear(); priv->currentMapAreaPage = 0; priv->currentMapArea = 0; priv->dragMode = DRAG_NONE; delete priv->lens; priv->lens = 0; // setup if (d) d->ref(); priv->doc = d; priv->docReady = false; priv->docStopped = false; priv->docFailed = false; priv->numPages = 1; if (! (priv->doc && priv->doc->isValid())) priv->docFailed = true; // connect if (priv->doc) { connect(priv->doc, SIGNAL(docinfo()), priv, SLOT(docinfo())); connect(priv->doc, SIGNAL(pageinfo()), priv, SLOT(pageinfo())); connect(priv->doc, SIGNAL(error(QString,QString,int)), priv, SLOT(error(QString,QString,int))); connect(priv->doc, SIGNAL(info(QString)), priv, SLOT(info(QString))); connect(priv->doc, SIGNAL(idle()), priv, SLOT(makePageRequests())); priv->docinfo(); } // update priv->estimatedWidth = 0; priv->estimatedHeight = 0; priv->visibleRect.setRect(0,0,0,0); priv->currentPos = Position(); priv->currentPoint = QPoint(priv->borderSize,priv->borderSize); priv->cursorPos = Position(); priv->cursorPoint = QPoint(0,0); priv->layoutChange = 0; priv->changeLayout(CHANGE_STATS|CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::page The page currently displayed. When getting the property, this is the number of the page that is closest to the center of the display area. When setting the property, the topleft corner of the desired page replaces the topleft corner of the current page. Default: page 0. */ int QDjVuWidget::page(void) const { return qBound(0, priv->currentPos.pageNo, priv->numPages); } void QDjVuWidget::setPage(int n, bool keep) { int currentPageNo = page(); if (n != currentPageNo && n>=0 && nnumPages) { Position pos; QPoint pnt(priv->borderSize, priv->borderSize); if (keep) { pnt = priv->currentPoint; pos = priv->findPosition(pnt); } pos.pageNo = n; pos.doPage = true; pos.inPage = false; setPosition(pos, pnt); } } /*! \property QDjVuWidget::position The document position associated with a viewport point. The default point is close to the topLeft corner of the viewport. When setting the position, flag \a Position::inPage is used to determine if the document position is expressed in full resolution page coordinates (\a Position::posPage) or in pixels relative to the top left page corner (\a Position::posView) or the point specified by the \a Position::hAnchor and \a Position::vAnchor. When \a Position::inPage is \a true, variable \a Position::posPage must be contained inside the full resolution page rectangle. */ Position QDjVuWidget::position(void) const { QPoint topLeft(priv->borderSize, priv->borderSize); return position(topLeft); } QPoint QDjVuWidget::hotSpot() const { return priv->currentPoint; } Position QDjVuWidget::position(const QPoint &point) const { return priv->findPosition(point); } void QDjVuWidget::setPosition(const Position &pos) { QPoint topLeft(priv->borderSize, priv->borderSize); setPosition(pos, topLeft); } void QDjVuWidget::setPosition(const Position &pos, const QPoint &p, bool animate) { // animation priv->clearAnimation(); if (animate && priv->animationEnabled) if (priv->computeAnimation(pos, p)) return; // standard procedure priv->movePoint = p; priv->movePos = pos; if (priv->pageMap.contains(pos.pageNo)) priv->changeLayout(CHANGE_VIEW|CHANGE_SCROLLBARS); else priv->changeLayout(CHANGE_PAGES|CHANGE_VIEW|CHANGE_SCROLLBARS); } /*! Unlike \a position() which sets the anchor fields \a pos.hAnchor and \a pos.vAnchor to zero, this version determines where to place the anchor to minimize the length of vector \a pos.posView. */ Position QDjVuWidget::positionWithClosestAnchor(const QPoint &point) const { return priv->findPosition(point, true); } /*! \property QDjVuWidget::rotation Number of counter-clockwise quarter turns applied to the pages. Only the low two bits of this number are meaningful. Default: 0. */ int QDjVuWidget::rotation(void) const { return priv->rotation; } void QDjVuWidget::setRotation(int r) { if (r != priv->rotation) { priv->rotation = r; priv->changeLayout(CHANGE_SCALE|UPDATE_ALL); } } /*! \property QDjVuWidget::zoom Zoom factor applied to the pages. Positive zoom factors take into account the resolution of the page images and assumes that the display resolution is 100 dpi. Negative zoom factors define special behaviors: \a ZOOM_ONE2ONE displays one image pixel for one screen pixel. \a ZOOM_FITWIDTH and \a ZOOM_FITPAGE dynamically compute the zoom factor to fit the page(s) inside the display area. Default: \a ZOOM_100. */ int QDjVuWidget::zoom(void) const { return priv->zoom; } void QDjVuWidget::setZoom(int z) { priv->qZoom.set(PRIORITY_USER, z); priv->changeZoom(); } void QDjVuPrivate::changeZoom(void) { int z = qZoom; switch(z) { case ZOOM_STRETCH: case ZOOM_ONE2ONE: case ZOOM_FITWIDTH: case ZOOM_FITPAGE: break; default: z = qBound((int)ZOOM_MIN, z, (int)ZOOM_MAX); break; } if (zoom != z) { zoom = z; changeLayout(CHANGE_SCALE|UPDATE_ALL); } } /*! Return the effective zoom factor of the current page. This is the same as \a zoom() when the zoom factor is positive. Otherwise this function returns the dynamically computed zoom factor. */ int QDjVuWidget::zoomFactor(void) const { if (priv->zoom >= ZOOM_MIN && priv->zoom <= ZOOM_MAX) return priv->zoom; if (priv->zoomFactor >= ZOOM_MIN && priv->zoomFactor <= ZOOM_MAX) return priv->zoomFactor; // Only when ZOOM_ONE2ONE or ZOOM_STRETCH is selected: priv->makeLayout(); if (! priv->pageMap.contains(priv->currentPos.pageNo)) return 100; Page *p = priv->pageMap[priv->currentPos.pageNo]; if (p->dpi>0 && p->width>0) return (p->rect.width() * p->dpi * 100) / (p->width * priv->sdpi); return 100; } /*! \property QDjVuWidget::gamma Gamma factor of the display. Default 2.2. */ double QDjVuWidget::gamma(void) const { return priv->gamma; } void QDjVuWidget::setGamma(double gamma) { priv->gamma = gamma; ddjvu_format_set_gamma(priv->renderFormat, gamma); priv->pixelCache.clear(); priv->changeLayout(UPDATE_ALL); } /*! \property QDjVuWidget::invertLuminance Display image with inverted luminance. */ bool QDjVuWidget::invertLuminance(void) const { return priv->invertLuminance; } void QDjVuWidget::setInvertLuminance(bool b) { priv->invertLuminance = b; priv->pixelCache.clear(); priv->changeLayout(UPDATE_ALL); } /*! \property QDjVuWidget::invertLuminance Specify whether mouse wheel zooms the image or scrolls the page. */ bool QDjVuWidget::mouseWheelZoom(void) const { return priv->mouseWheelZoom; } void QDjVuWidget::setMouseWheelZoom(bool b) { priv->mouseWheelZoom = b; } /*! \property QDjVuWidget::white White point of the display. This is a noop when DDJVUAPI_VERSION<20. Default 0xffffff. */ QColor QDjVuWidget::white(void) const { return priv->white; } void QDjVuWidget::setWhite(QColor w) { #if DDJVUAPI_VERSION >= 20 priv->white = w; ddjvu_format_set_white(priv->renderFormat, w.blue(), w.green(), w.red()); priv->pixelCache.clear(); priv->changeLayout(UPDATE_ALL); #endif } /*! \property QDjVuWidget::screenDpi Resolution of the screen. Default is 100dpi. */ int QDjVuWidget::screenDpi(void) const { return priv->sdpi; } void QDjVuWidget::setScreenDpi(int sdpi) { sdpi = qBound(25, sdpi, 600); if (priv->sdpi != sdpi) { priv->sdpi = sdpi; priv->changeLayout(CHANGE_SCALE|UPDATE_ALL); } } /*! \property QDjVuWidget::displayMode Display mode for the DjVu images. Default: \a DISPLAY_COLOR. */ DisplayMode QDjVuWidget::displayMode(void) const { return priv->display; } void QDjVuWidget::setDisplayMode(DisplayMode m) { priv->qDisplay.set(PRIORITY_USER, m); priv->changeDisplay(); } void QDjVuPrivate::changeDisplay() { if (display != qDisplay) { display = qDisplay; pixelCache.clear(); changeLayout(UPDATE_ALL); } } /*! \property QDjVuWidget::displayFrame When this property is true, a frame is displayed around each page. Default: \a true. */ bool QDjVuWidget::displayFrame(void) const { return priv->frame; } void QDjVuWidget::setDisplayFrame(bool b) { if (b != priv->frame) { priv->frame = b; priv->changeLayout(UPDATE_ALL); } } /*! \property QDjVuWidget::sideBySide Determine the layout of the pages shown in the displayed area. Setting this property to \a true displays pages side by side. This can be combined with the \a continuous property. Default: \a false. */ bool QDjVuWidget::sideBySide(void) const { return priv->sideBySide; } void QDjVuWidget::setSideBySide(bool b) { if (b != priv->sideBySide) { priv->sideBySide = b; priv->changeLayout(CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::coverPage Determine whether the first page must be show alone when multipage documents are displayed side-by-side. Default: \a false. */ bool QDjVuWidget::coverPage(void) const { return priv->coverPage; } void QDjVuWidget::setCoverPage(bool b) { if (b != priv->coverPage) { priv->coverPage = b; if (priv->sideBySide) priv->changeLayout(CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::rightToLeft Determine whether the side-by-side pages should be displayed right-to-left instead of left-to-right. Default: \a false. */ bool QDjVuWidget::rightToLeft(void) const { return priv->rightToLeft; } void QDjVuWidget::setRightToLeft(bool b) { if (b != priv->rightToLeft) { priv->rightToLeft = b; if (priv->sideBySide) priv->changeLayout(CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::continuous Determine the layout of the pages shown in the displayed area. Setting this property to \a true displays all the document pages in a continuously scrollable area. This can be combined with the \a sideBySide property. Default: \a false. */ bool QDjVuWidget::continuous(void) const { return priv->continuous; } void QDjVuWidget::setContinuous(bool b) { if (b != priv->continuous) { priv->continuous = b; priv->changeLayout(CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::horizAlign Determine the horizontal alignment of the pages in the display area. Horizontal alignment can be complicated in continuous mode. Default: \a ALIGN_CENTER. */ Align QDjVuWidget::horizAlign(void) const { return priv->hAlign; } void QDjVuWidget::setHorizAlign(Align a) { priv->qHAlign.set(PRIORITY_USER, a); priv->changeHAlign(); } void QDjVuPrivate::changeHAlign(void) { if (hAlign != qHAlign) { hAlign = qHAlign; changeLayout(CHANGE_POSITIONS); } } /*! \property QDjVuWidget::vertAlign Determine the vertical alignment of the pages in the display area. Vertical alignment can be very subtle in continuous mode because it only matters when pages are also displayed side by side. Default: \a ALIGN_CENTER. */ Align QDjVuWidget::vertAlign(void) const { return priv->vAlign; } void QDjVuWidget::setVertAlign(Align a) { priv->qVAlign.set(PRIORITY_USER, a); priv->changeVAlign(); } void QDjVuPrivate::changeVAlign(void) { if (vAlign != qVAlign) { vAlign = qVAlign; changeLayout(CHANGE_POSITIONS); } } /*! \property QDjVuWidget::borderBrush Brush used to fill the part of the display area that is not covered by a page. Default: light gray. */ QBrush QDjVuWidget::borderBrush(void) const { return priv->borderBrush; } void QDjVuWidget::setBorderBrush(QBrush b) { priv->qBorderBrush.set(PRIORITY_USER, b); priv->changeBorderBrush(); } void QDjVuPrivate::changeBorderBrush(void) { if (borderBrush != qBorderBrush) { borderBrush = qBorderBrush; changeLayout(UPDATE_BORDERS); } } /*! \property QDjVuWidget::borderSize The minimal size of the border around the pages. Default: 8 pixels. */ int QDjVuWidget::borderSize(void) const { return priv->borderSize; } void QDjVuWidget::setBorderSize(int b) { priv->qBorderSize.set(PRIORITY_USER, b); priv->changeBorderSize(); } void QDjVuPrivate::changeBorderSize(void) { if (borderSize != qBorderSize) { borderSize = qBorderSize; changeLayout(CHANGE_POSITIONS); } } /*! \property QDjVuWidget::separatorSize The size of the gap between pages in side-by-side mode. Default: 12 pixels. */ int QDjVuWidget::separatorSize(void) const { return priv->separatorSize; } void QDjVuWidget::setSeparatorSize(int b) { b = qMax(0, b); if (b != priv->separatorSize) { priv->separatorSize = b; if (priv->sideBySide || priv->continuous) priv->changeLayout(CHANGE_PAGES|UPDATE_ALL); } } /*! \property QDjVuWidget::contextMenu Menu displayed when the user invokes a context menu for this widget. Default: no context menu. */ QMenu* QDjVuWidget::contextMenu(void) const { return priv->contextMenu; } void QDjVuWidget::setContextMenu(QMenu *m) { priv->contextMenu = m; } /*! \property QDjVuWidget::displayMapAreas Indicates whether the mapareas specified in the annotations should be displayed. Default: \a true. */ bool QDjVuWidget::displayMapAreas(void) const { return priv->displayMapAreas; } void QDjVuWidget::setDisplayMapAreas(bool b) { if (b != priv->displayMapAreas) { priv->displayMapAreas = b; viewport()->update(); priv->checkCurrentMapArea(); priv->showTransientMapAreas(priv->allLinksDisplayed); } } /*! \property QDjVuWidget::keyboardEnabled Enables keyboard interaction. This property controls the behavior of arrows keys, page movement keys, and various shortcut keys. Default: \a true. */ bool QDjVuWidget::keyboardEnabled(void) const { return priv->keyboardEnabled; } void QDjVuWidget::enableKeyboard(bool b) { if (b != priv->keyboardEnabled) priv->keyboardEnabled = b; } /*! \property QDjVuWidget::mouseEnabled Enables mouse interaction. Default: \a true. */ bool QDjVuWidget::mouseEnabled(void) const { return priv->mouseEnabled; } void QDjVuWidget::enableMouse(bool b) { if (b != priv->mouseEnabled) priv->mouseEnabled = b; } /*! \property QDjVuWidget::hyperlinkEnabled Enables hyperlinks. This propery indicates whether hyperlink feedback is displayed, and whether the signals \a pointerEnter, \a pointerLeave and \a pointerClick are emitted. You must also set \a mouseEnabled and \a displayMapAreas to \a true. Default: \a true. */ bool QDjVuWidget::hyperlinkEnabled(void) const { return priv->hyperlinkEnabled; } void QDjVuWidget::enableHyperlink(bool b) { if (b != priv->hyperlinkEnabled) { priv->hyperlinkEnabled = b; priv->checkCurrentMapArea(); } } /*! \property QDjVuWidget::animationEnabled Enables animation on position changes. This property indicates whether certain position changes are performed using a display animation. Default: \a true. */ bool QDjVuWidget::animationEnabled(void) const { return priv->animationEnabled; } void QDjVuWidget::enableAnimation(bool b) { priv->clearAnimation(); priv->animationEnabled = b; } /*! \property QDjVuWidget::animationInProgress Read-only property that tells whether an animation is in progress. */ bool QDjVuWidget::animationInProgress(void) const { if (priv->animationEnabled) if (! priv->animationPosition.isEmpty()) return true; return false; } /*! \property QDjVuWidget::pixelCacheSize Defines the maximal number of pixels in the cache for decoded images segments. */ int QDjVuWidget::pixelCacheSize(void) const { return priv->pixelCacheSize; } void QDjVuWidget::setPixelCacheSize(int s) { int oldPixelCacheSize = priv->pixelCacheSize; priv->pixelCacheSize = s; if (s < oldPixelCacheSize) priv->trimPixelCache(); } /*! \property QDjVuWidget::lensPower Sets the power of the magnification lens. Legal value range from 0x to 10x. Value 0x disables the lens. Default is 3x. */ int QDjVuWidget::lensPower(void) const { return priv->lensMag; } void QDjVuWidget::setLensPower(int mag) { priv->lensMag = qBound(0,mag,10); } /*! \property QDjVuWidget::lensSize Sets the size of the magnification lens. Legal value range from 0 to 500 pixels. Value 0 disables the lens. Default is 300. */ int QDjVuWidget::lensSize(void) const { return priv->lensSize; } void QDjVuWidget::setLensSize(int size) { priv->lensSize = qBound(0,size,500); } /*! \property QDjVuWidget::hourGlassRatio Setups the hour glass timer indicator. Nothing is displayed when value is zero. Otherwise it indicates that one should display the specified fraction of time before switching page in slideshow more. */ double QDjVuWidget::hourGlassRatio() const { return priv->hourGlassRatio; } QRect QDjVuPrivate::hourGlassRect() const { int bs = qBound(4, borderSize / 2, 16); int hs = qBound(16, borderSize * 6, 64); int w = widget->viewport()->width(); int h = widget->viewport()->height(); if (w > hs+bs+bs && h > hs+bs+bs) return QRect(w-bs-hs,h-bs-hs,hs,hs); return QRect(); } void QDjVuWidget::setHourGlassRatio(double ratio) { if (ratio != priv->hourGlassRatio && ratio>=0 && ratio<=1) { priv->hourGlassRatio = ratio; QRect rect = priv->hourGlassRect(); if (!rect.isEmpty()) viewport()->update(rect.adjusted(-2,-2,2,2)); } } /*! \property QDjVuWidget::modifiersForLens Sets the modifier that should be depressed in order to display the magnifying lens. Default: Control + Shift. */ Qt::KeyboardModifiers QDjVuWidget::modifiersForLens() const { return priv->modifiersForLens; } void QDjVuWidget::setModifiersForLens(Qt::KeyboardModifiers m) { if (priv->modifiersForLens != m) { priv->modifiersForLens = m; if (priv->dragMode == DRAG_NONE) modifierEvent(priv->modifiers, priv->buttons, priv->cursorPoint); } } /*! \property QDjVuWidget::modifiersForSelect Sets the modifier that should be depressed in conjunction with the left mouse button in order to select a rectangular area. Default: Control. */ Qt::KeyboardModifiers QDjVuWidget::modifiersForSelect() const { return priv->modifiersForSelect; } void QDjVuWidget::setModifiersForSelect(Qt::KeyboardModifiers m) { if (priv->modifiersForSelect != m) { priv->modifiersForSelect = m; if (priv->dragMode == DRAG_NONE) modifierEvent(priv->modifiers, priv->buttons, priv->cursorPoint); } } /*! \property QDjVuWidget::modifiersForLinks Sets the modifier that should be depressed in order to display all hyperlinks. Default: Shift. */ Qt::KeyboardModifiers QDjVuWidget::modifiersForLinks() const { return priv->modifiersForLinks; } void QDjVuWidget::setModifiersForLinks(Qt::KeyboardModifiers m) { if (priv->modifiersForLinks != m) { priv->modifiersForLinks = m; priv->showTransientMapAreas(m!=Qt::NoModifier && m==priv->modifiers); if (priv->dragMode == DRAG_NONE) modifierEvent(priv->modifiers, priv->buttons, priv->cursorPoint); } } // ---------------------------------------- // MAPAREAS AND HIDDEN TEXT BEGIN_ANONYMOUS_NAMESPACE struct Keywords { // maparea keywords miniexp_t url, rect, oval, poly, line, text; miniexp_t none, xxor, border; miniexp_t shadow_in, shadow_out, shadow_ein, shadow_eout; miniexp_t border_avis, hilite, opacity; miniexp_t arrow, width, lineclr; miniexp_t backclr, textclr, pushpin; // hiddentext keywords miniexp_t h[7]; Keywords() { #define S(n,s) n=miniexp_symbol(s) #define D(n) S(n,#n) // maparea D(url); D(rect); D(oval); D(poly); D(line); D(text); D(none); S(xxor,"xor"); D(border); D(shadow_in); D(shadow_out); D(shadow_ein); D(shadow_eout); D(border_avis); D(hilite); D(opacity); D(arrow); D(width); D(lineclr); D(backclr); D(textclr); D(pushpin); // hidden text S(h[0],"page"); S(h[1],"column"); S(h[2],"region"); S(h[3],"para"); S(h[4],"line"); S(h[5],"word"); S(h[6],"char"); #undef D #undef S } }; Q_GLOBAL_STATIC(Keywords, keywords) END_ANONYMOUS_NAMESPACE MapArea::MapArea() { expr = miniexp_nil; url = target = comment = miniexp_nil; areaType = borderType = miniexp_nil; borderWidth = 1; borderAlwaysVisible = false; hiliteOpacity = 50; lineArrow = false; lineWidth = 1; foregroundColor = Qt::black; pushpin = false; rectNeedsRotation = false; } bool MapArea::error(const char *err, int pageno, miniexp_t info) { if (pageno >= 0) qWarning("Error in maparea for page %d\n%s\n%s\n", pageno+1, err, miniexp_to_str(miniexp_pname(info, 72)) ); return false; } bool MapArea::parse(miniexp_t full, int pageno) { Keywords &k = *keywords(); expr = full; miniexp_t anno = miniexp_cdr(full); miniexp_t q = miniexp_car(anno); int itmp; // hyperlink if (miniexp_stringp(q)) { const char *s = miniexp_to_str(q); url = (s && s[0]) ? q : miniexp_nil; } else if (miniexp_consp(q) && miniexp_car(q)==k.url) { if (! (miniexp_stringp(miniexp_cadr(q)) && miniexp_stringp(miniexp_caddr(q)) && ! miniexp_cdddr(q) ) ) return error("Bad url", pageno, q); url = miniexp_cadr(q); target = miniexp_caddr(q); const char *s = miniexp_to_str(url); if (! (s && s[0])) url = target = miniexp_nil; } else if (q) return error("Bad url", pageno, full); else error("Some viewers prefer \"\" over () for empty urls.", pageno, full ); // comment anno = miniexp_cdr(anno); q = miniexp_car(anno); if (miniexp_stringp(q)) { const char *s = miniexp_to_str(q); if (s && s[0]) comment = q; } else if (q) return error("Bad comment", pageno, full); else error("Some viewers prefer \"\" over () for empty comments.", pageno, full ); // area anno = miniexp_cdr(anno); q = miniexp_car(anno); areaType = miniexp_car(q); if (areaType == k.rect || areaType == k.oval || areaType == k.text) { q = miniexp_cdr(q); if (!miniexp_get_rect(q, areaRect) || q) return error("Bad rectangle", pageno, miniexp_car(anno)); } else if (areaType == k.poly) { q = miniexp_cdr(q); if (!miniexp_get_points(q, areaRect, areaPoints)) return error("Bad polygon", pageno, miniexp_car(anno)); } else if (areaType == k.line) { q = miniexp_cdr(q); if (!miniexp_get_points(q,areaRect,areaPoints) || areaPoints.size()!=2) return error("Bad line", pageno, miniexp_car(anno)); } else return error("Bad area", pageno, full); // remaining while (miniexp_consp(anno = miniexp_cdr(anno))) { q = miniexp_car(anno); miniexp_t s = miniexp_car(q); miniexp_t a = miniexp_cdr(q); // borders if (s==k.none || s==k.xxor || s==k.border || s==k.shadow_in || s==k.shadow_out || s==k.shadow_ein || s==k.shadow_eout ) { if (s==k.none) { borderWidth = 0; } else if (s==k.xxor) { borderWidth = 1; } else if (s==k.border) { if (! miniexp_get_color(a, borderColor)) return error("Color expected", pageno, q); borderWidth = 1; } else { if (! miniexp_get_int(a, itmp)) return error("Integer expected", pageno, q); borderWidth = qBound(1, itmp, 32); if (areaType != k.rect) return error("Only for rectangle maparea", pageno, q); } if (borderType) error("Multiple border specification", pageno, full); borderType = s; } // border avis else if (s == k.border_avis) { borderAlwaysVisible = true; } // hilite else if (s == k.hilite) { if (areaType != k.rect) error("Only for rectangle maparea", pageno, q); else if (! miniexp_get_color(a, hiliteColor)) return error("Color expected", pageno, q); } else if (s == k.opacity) { if (areaType != k.rect) error("Only for rectangle maparea", pageno, q); else if (! miniexp_get_int(a, itmp)) return error("Integer expected", pageno, q); hiliteOpacity = qBound(0, itmp, 200); } // line stuff else if (s == k.arrow) { if (areaType != k.line) error("Only for line maparea", pageno, q); lineArrow = true; } else if (s == k.width) { if (areaType != k.line) error("Only for line maparea", pageno, q); if (! miniexp_get_int(a, itmp)) return error("Integer expected", pageno, q); lineWidth = qBound(1, itmp, 32); } else if (s == k.lineclr) { if (areaType != k.line) error("Only for line maparea", pageno, q); if (! miniexp_get_color(a, foregroundColor)) return error("Color expected", pageno, q); } // text stuff else if (s == k.backclr) { if (areaType != k.text) error("Only for text maparea", pageno, q); if (! miniexp_get_color(a, hiliteColor)) return error("Color expected", pageno, q); hiliteOpacity = 200; } else if (s == k.textclr) { if (areaType != k.text) error("Only for text maparea", pageno, q); if (! miniexp_get_color(a, foregroundColor)) return error("Color expected", pageno, q); } else if (s == k.pushpin) { if (areaType != k.text) error("Only for text maparea", pageno, q); pushpin = true; } else error("Unrecognized specification", pageno, q); // test for extra arguments if (a) error("Extra arguments were ignored", pageno, q); } // border type sanity checks if (areaType == k.line) { if (borderType && borderType != k.none) error("Line maparea should not specify a border.", pageno, expr); if (miniexp_stringp(url)) error("Line maparea should not specify a url.", pageno, expr); borderType = miniexp_nil; url = miniexp_nil; } else if (borderType == miniexp_nil) { error("Maparea without border type defaults to (xor).", pageno, expr); borderType = k.xxor; } return true; } bool MapArea::clicked(void) { Keywords &k = *keywords(); if (areaType == k.text && pushpin) { areaType = k.pushpin; // fake area type borderType = miniexp_nil; // no border hiliteColor = QColor(); // no hilite return true; } else if (areaType == k.pushpin) { parse(expr); // restore return true; } return false; } bool MapArea::isClickable(bool hyperlink) { Keywords &k = *keywords(); if (url && hyperlink) return true; if (areaType == k.pushpin) return true; if (areaType == k.text && pushpin) return true; return false; } bool MapArea::hasTransient(bool allLinks) { Keywords &k = *keywords(); if (areaType == miniexp_nil || borderAlwaysVisible) return false; if (allLinks && miniexp_stringp(url)) return true; if (borderType == k.none || borderType == miniexp_nil) return false; return true; } bool MapArea::hasPermanent() { Keywords &k = *keywords(); if (hiliteColor.isValid() || areaType == k.line || areaType == k.text || areaType == k.pushpin ) return true; return false; } void MapArea::maybeRotate(struct Page *p) { if (rectNeedsRotation && p->dpi >= 0) { int rot = p->initialRot; if (rot > 0) { int rw = (rot&1) ? p->height : p->width; int rh = (rot&1) ? p->width : p->height; QRectMapper mapper; mapper.setMap(QRect(0,0,rw,rh), QRect(0,0,p->width,p->height)); mapper.setTransform(rot, false, false); areaRect = mapper.mapped(areaRect); } rectNeedsRotation = false; } } QPainterPath MapArea::contour(QRectMapper &m, QPoint &offset) { Keywords &k = *keywords(); QRect rect = m.mapped(areaRect).translated(-offset); QPainterPath path; if (areaType == k.poly) { QPoint p = m.mapped(areaPoints[0]) - offset; path.moveTo(p); for (int j=1; j maps page coordinates to // widget coordinates translated by . Keywords &k = *keywords(); int bw = borderWidth; QRect rect = m.mapped(areaRect).translated(-offset); if (! rect.intersects(w->rect())) return; if (areaType == k.oval || areaType == k.poly) { int bw2 = (bw / 2) + 1; QPainterPath path = contour(m, offset); rect.adjust(-bw2, -bw2, bw2, bw2); QBitmap bm(rect.width(),rect.height()); bm.clear(); QPainter paint; paint.begin(&bm); paint.translate(-rect.topLeft()); paint.strokePath(path, QPen(Qt::black, bw+4)); paint.end(); QRegion region(bm); region.translate(rect.topLeft()); w->update(region); } else if (clicked && (areaType == k.text || areaType == k.pushpin)) { int bw2 = (bw / 2) + 1; w->update(rect.adjusted(-bw2-1, -bw2-1, bw2+1, bw2+1)); } else { int bw2 = (bw / 2) + 1; QRegion region = rect.adjusted(-bw2-1, -bw2-1, bw2+1, bw2+1); region = region.subtracted(rect.adjusted(bw+1, bw+1, -bw-1, -bw-1)); w->update(region); } } void MapArea::paintBorder(QPaintDevice *w, QRectMapper &m, QPoint offset, bool allLinks) { // The mapper maps page coordinates to // widget coordinates translated by . Keywords &k = *keywords(); QRect rect = m.mapped(areaRect).translated(-offset); bool forceXor = false; if (allLinks && miniexp_stringp(url)) forceXor = (borderType == k.none || borderType == miniexp_nil); QPainter paint(w); paint.setRenderHint(QPainter::Antialiasing); paint.setRenderHint(QPainter::TextAntialiasing); if (borderType == k.border) { QPainterPath path = contour(m, offset); paint.strokePath(path, QPen(borderColor, borderWidth)); } else if (borderType == k.xxor || forceXor) { QPainterPath path = contour(m, offset); paint.strokePath(path, QPen(Qt::white, borderWidth)); paint.strokePath(path, QPen(Qt::black, borderWidth, Qt::DashLine)); } else if (borderType == k.shadow_in || borderType==k.shadow_out) { rect.adjust(0,0,+1,+1); int bw = borderWidth; bw = qMin(bw, qMin(rect.width()/4, rect.height()/4)); QRect irect = rect.adjusted(bw, bw, -bw, -bw); paint.setPen(Qt::NoPen); QColor c1(255,255,255,100); QColor c2(0,0,0,100); QPolygon p(6); p[0] = irect.bottomLeft(); p[1] = rect.bottomLeft(); p[2] = rect.bottomRight(); p[3] = rect.topRight(); p[4] = irect.topRight(); p[5] = irect.bottomRight(); paint.setBrush((borderType==k.shadow_in) ? c1 : c2); paint.drawPolygon(p); p[0] = irect.bottomLeft(); p[1] = rect.bottomLeft(); p[2] = rect.topLeft(); p[3] = rect.topRight(); p[4] = irect.topRight(); p[5] = irect.topLeft(); paint.setBrush((borderType==k.shadow_in) ? c2 : c1); paint.drawPolygon(p); } else if (borderType == k.shadow_ein || borderType==k.shadow_eout) { rect.adjust(0,0,+1,+1); int bw = borderWidth; bw = qMin(bw, qMin(rect.width()/4, rect.height()/4)); QRect irect = rect.adjusted(bw, bw, -bw, -bw); paint.setBrush(Qt::NoBrush); QColor c1(255,255,255,100); QColor c2(0,0,0,100); QPolygon p(3); paint.setPen(QPen((borderType==k.shadow_ein) ? c1 : c2, 1)); p[0] = irect.bottomLeft(); p[1] = irect.topLeft(); p[2] = irect.topRight(); paint.drawPolyline(p); p[0] = rect.bottomLeft(); p[1] = rect.bottomRight(); p[2] = rect.topRight(); paint.drawPolyline(p); paint.setPen(QPen((borderType==k.shadow_ein) ? c2 : c1, 1)); p[0] = irect.bottomLeft(); p[1] = irect.bottomRight(); p[2] = irect.topRight(); paint.drawPolyline(p); p[0] = rect.bottomLeft(); p[1] = rect.topLeft(); p[2] = rect.topRight(); paint.drawPolyline(p); } } void MapArea::paintPermanent(QPaintDevice *w, QRectMapper &m, QPoint offset, double z) { // The mapper maps page coordinates to // widget coordinates translated by . Keywords &k = *keywords(); QRect rect = m.mapped(areaRect).translated(-offset); if (hasPermanent()) { QPainter paint(w); paint.setRenderHint(QPainter::Antialiasing); paint.setRenderHint(QPainter::TextAntialiasing); if (hiliteColor.isValid() && hiliteOpacity>0) { QColor color = hiliteColor; color.setAlpha(hiliteOpacity*255/200); paint.fillRect(rect, color); } if (areaType == k.line) { QPen pen(foregroundColor, lineWidth); pen.setJoinStyle(Qt::MiterJoin); paint.setPen(pen); paint.setBrush(foregroundColor); QPoint pFrom = m.mapped(areaPoints[0]) - offset; QPoint pTo = m.mapped(areaPoints[1]) - offset; if (lineArrow) { QPointF v = pFrom - pTo; qreal vn = sqrt(v.x() * v.x() + v.y() * v.y()); v = v * qMin(0.25, (10.0 / vn)); QPointF v90 = QPointF(-v.y()/2.0, v.x()/2.0); QPointF p[3]; p[0] = pTo; p[1] = pTo + v - v90; p[2] = pTo + v + v90; paint.drawPolygon(p, 3); paint.drawLine(pFrom, pTo+ v * 0.5); } else { paint.drawLine(pFrom, pTo); } } else if (areaType == k.text) { int bw = borderWidth + 2; bw = qMin(bw, qMin(rect.width()/4, rect.height()/4)); QRect r = rect.adjusted(bw, bw, -bw, -bw); QString s = miniexp_to_qstring(comment); paint.setPen(foregroundColor); int flags = Qt::AlignCenter|Qt::AlignVCenter|Qt::TextWordWrap; QFont font = paint.font(); // estimate font size int size = (int)(z * 0.12); while (size > 1) { QRect br; font.setPixelSize(size); paint.setFont(font); paint.drawText(r,flags|Qt::TextDontPrint,s,&br); if (r.contains(br)) { // found good font size paint.drawText(r,flags,s,0); break; } size -= 1; } } else if (areaType == k.pushpin) { QPixmap pixmap; pixmap.load(":/images/text_pushpin.png"); if (! pixmap.isNull()) { QRect r = pixmap.rect().translated(rect.topLeft()); if (r.width() > rect.width()) { r.setHeight(r.height() * rect.width() / r.width()); r.setWidth(rect.width()); } if (r.height() > rect.height()) { r.setWidth(r.width() * rect.height() / r.height()); r.setHeight(rect.height()); } paint.drawPixmap(r, pixmap); } } } if (! hasTransient()) paintBorder(w, m, offset); } void MapArea::paintTransient(QPaintDevice *w, QRectMapper &m, QPoint offset, bool allLinks) { if (hasTransient(allLinks)) paintBorder(w, m, offset, allLinks); } void QDjVuPrivate::prepareMapAreas(Page *p) { // remove annotation mapareas. int j = p->mapAreas.size(); while (--j >= 0) if (p->mapAreas[j].expr) p->mapAreas.removeAt(j); // parse annotations. if (p->annotations && p->annotations != miniexp_dummy) { miniexp_t *annos; annos = ddjvu_anno_get_hyperlinks(p->annotations); if (annos) { for (int i=0; annos[i]; i++) { MapArea data; miniexp_t anno = annos[i]; if (data.parse(anno, p->pageno)) { data.clicked(); // collapse pushpins p->mapAreas << data; } } free(annos); } } } bool QDjVuPrivate::mustDisplayMapArea(MapArea *area) { if (allLinksDisplayed) return true; if (area != currentMapArea) return false; if (hyperlinkEnabled && mouseEnabled) return true; return false; } void QDjVuPrivate::checkCurrentMapArea(bool forceno) { const Position &pos = cursorPos; Page *savedMapAreaPage = currentMapAreaPage; MapArea *savedMapArea = currentMapArea; Page *newMapAreaPage = 0; MapArea *newMapArea = 0; // locate new maparea if (displayMapAreas && !forceno && pos.inPage) if (pageMap.contains(pos.pageNo)) { Page *p = pageMap[pos.pageNo]; for (int i=0; imapAreas.size(); i++) { MapArea &area = p->mapAreas[i]; area.maybeRotate(p); if (area.expr && area.areaRect.contains(pos.posPage) && area.contains(pos.posPage) ) { newMapArea = &area; newMapAreaPage = p; break; } } } // change map area if (savedMapArea != newMapArea) { currentMapArea = 0; currentMapAreaPage = 0; if (savedMapArea) { if (savedMapArea->hasTransient()) if (currentLinkDisplayed && !allLinksDisplayed) savedMapArea->update(widget->viewport(), savedMapAreaPage->mapper, visibleRect.topLeft()); emit widget->pointerLeave(pos, savedMapArea->expr); } currentUrl = QString(); currentTarget = QString(); currentComment = QString(); currentLinkDisplayed = false; if (newMapArea) { currentMapArea = newMapArea; currentMapAreaPage = newMapAreaPage; currentUrl = miniexp_to_qstring(currentMapArea->url); currentTarget = miniexp_to_qstring(currentMapArea->target); currentComment = miniexp_to_qstring(currentMapArea->comment); if (mustDisplayMapArea(newMapArea)) newMapArea->update(widget->viewport(), newMapAreaPage->mapper, visibleRect.topLeft()); emit widget->pointerEnter(pos, currentMapArea->expr); } widget->modifierEvent(modifiers, buttons, cursorPoint); widget->chooseTooltip(); } } void QDjVuPrivate::showTransientMapAreas(bool b) { b = b && displayMapAreas && hyperlinkEnabled && mouseEnabled; if (b != allLinksDisplayed) { Page *p; allLinksDisplayed = b; foreach (p, pageVisible) for (int i=0; imapAreas.size(); i++) { MapArea &area = p->mapAreas[i]; area.maybeRotate(p); if (area.hasTransient(allLinksDisplayed)) area.update(widget->viewport(), p->mapper, visibleRect.topLeft() ); } } } /*! Removes all highlight rectangles installed for page \a pageno. */ void QDjVuWidget::clearHighlights(int pageno) { if (pageno>=0 && pagenopageData.size()) { Page *p = &priv->pageData[pageno]; int j = p->mapAreas.size(); while (--j >= 0) if (! p->mapAreas[j].expr) { MapArea &area = p->mapAreas[j]; if (priv->pageMap.contains(pageno) && p->dpi>0) area.update(viewport(), p->mapper, priv->visibleRect.topLeft()); priv->pixelCache.clear(); p->mapAreas.removeAt(j); } } } /*! Add a new highlight rectangle with color \a color, at position \a x, \a y, \a w, \a h on page \a pageno. Argument \a rc indicates whether coordinates are rotated (like annotations) or unrotated (like text). */ void QDjVuWidget::addHighlight(int pageno, int x, int y, int w, int h, QColor color, bool rc) { if (!priv->docReady) priv->docinfo(); if (pageno>=0 && pagenopageData.size() && w>0 && h>0) { Page *p = &priv->pageData[pageno]; Keywords &k = *keywords(); MapArea area; area.areaType = k.rect; area.areaRect = QRect(x,y,w,h); area.hiliteColor = color; area.hiliteColor.setAlpha(255); area.hiliteOpacity = color.alpha() * 200 / 255; area.borderType = miniexp_nil; area.rectNeedsRotation = rc; area.maybeRotate(p); p->mapAreas << area; priv->pixelCache.clear(); if (priv->pageMap.contains(pageno) && p->dpi>0) area.update(viewport(), p->mapper, priv->visibleRect.topLeft()); } } /*! Returns the url string for the maparea located below the pointer. This function is valid when called from signal \a pointerEnter, \a pointerLeave, or \a pointerClick. */ QString QDjVuWidget::linkUrl(void) { if (priv->hyperlinkEnabled && priv->mouseEnabled) return priv->currentUrl; return QString(); } /*! Returns the target string for the maparea located below the pointer. This function is valid when called from signal \a pointerEnter, \a pointerLeave, or \a pointerClick. */ QString QDjVuWidget::linkTarget(void) { if (priv->hyperlinkEnabled && priv->mouseEnabled) return priv->currentTarget; return QString(); } /*! Returns the comment string for the maparea located below the pointer. This function is valid when called from signal \a pointerEnter, \a pointerLeave, or \a pointerClick. */ QString QDjVuWidget::linkComment(void) { return priv->currentComment; } /*! Determine the text around a particular point. Produces an array of three string. The middle string is the selected information. All the strings represent the line. Returns true on success. */ bool QDjVuWidget::getTextForPointer(QString results[]) { Position &pos = priv->cursorPos; if (!pos.inPage || !priv->pageMap.contains(pos.pageNo)) return false; Page *page = priv->pageMap[pos.pageNo]; // map point int rot = page->initialRot; int w = (rot&1) ? page->height : page->width; int h = (rot&1) ? page->width : page->height; QRectMapper mapper; mapper.setMap(QRect(0,0,w,h), page->rect); mapper.setTransform(rot + priv->rotation, false, true); QPoint posRot = mapper.unMapped(pos.posView + page->rect.topLeft()); // search zones Keywords &k = *keywords(); miniexp_t q = page->hiddenText; miniexp_t l = page->hiddenText; while(miniexp_consp(q)) { QRect rect; miniexp_t type = miniexp_car(q); miniexp_t r = miniexp_cdr(type); if (miniexp_consp(type)) type = miniexp_car(type); if (miniexp_consp(r) && miniexp_get_rect_from_points(r, rect) && rect.adjusted(-2,-2,2,2).contains(posRot) ) break; q = miniexp_cdr(q); int sep = 0; for (sep=0; sep<7; sep++) if (type == k.h[sep]) break; if (sep <= 4) l = q; } if (miniexp_consp(q)) { int state = 0; bool separator = false; results[0] = results[1] = results[2] = QString(); while (miniexp_consp(l)) { miniexp_t type = miniexp_car(l); miniexp_t s = miniexp_nth(5, type); bool is = miniexp_stringp(s); if (miniexp_consp(type)) type = miniexp_car(type); if (state == 1) state = 2; if (is && separator) results[state] += " "; if (l == q) state = 1; l = miniexp_cdr(l); if (miniexp_stringp(s)) results[state] += miniexp_to_qstring(s); int sep = 0; for (sep=0; sep<7; sep++) if (type == k.h[sep]) break; if (sep <= 5) separator = true; else if (is) separator = false; if (sep <= 4 && state >= 1) break; } return true; } return false; } /*! Returns the text spanned with a particular rectangle \a target in viewport coordinates. Returns the empty string if no text is available. */ QString QDjVuWidget::getTextForRect(const QRect &vtarget) { QRect target = vtarget; target.translate(priv->visibleRect.topLeft()); Keywords &k = *keywords(); int separator = 6; QString ans; Page *p; foreach(p, priv->pageVisible) { // quick check miniexp_t q = p->hiddenText; if (p->initialRot < 0 || q == miniexp_nil || q == miniexp_dummy) continue; QRect pagerect = target.intersected(p->rect); if (!p->hiddenText || pagerect.isEmpty()) { separator = 0; continue; } // map rectangle int rot = p->initialRot; int w = (rot&1) ? p->height : p->width; int h = (rot&1) ? p->width : p->height; QRectMapper mapper; mapper.setMap(QRect(0,0,w,h), p->rect); mapper.setTransform(rot + priv->rotation, false, true); pagerect = mapper.unMapped(pagerect); // loop while (miniexp_consp(q)) { miniexp_t r = miniexp_car(q); q = miniexp_cdr(q); miniexp_t type = r; if (miniexp_consp(r)) { QRect rect; type = miniexp_car(r); r = miniexp_cdr(r); if (miniexp_symbolp(type) && miniexp_get_rect_from_points(r, rect) && pagerect.intersects(rect) ) { if (!ans.isEmpty()) { if (separator == 0) ans += "\n\f"; else if (separator <= 4) ans += "\n"; else if (separator <= 5) ans += " "; } separator = 6; ans += miniexp_to_qstring(miniexp_car(r)); } } for (int s=separator-1; s>=0; s--) if (type == k.h[s]) separator = s; } } return ans; } /*! Returns the image corresponding to a particular rectangle \a rect in viewport coordinates. Image is painted using the current display mode. */ QImage QDjVuWidget::getImageForRect(const QRect &rect) { priv->changeSelectedRectangle(QRect()); QImage img(rect.width(), rect.height(), QImage::Format_RGB32); QRegion region = rect; QPainter paint; paint.begin(&img); paint.translate(- rect.topLeft()); priv->paintAll(paint, region); paint.end(); return img; } /*! Returns a page coordinate rectangle describing the part of page \a pageNo that is covered by rectangle \a rect. */ QRect QDjVuWidget::getSegmentForRect(const QRect &rect, int pageNo) { QRect ans; if (priv->pageMap.contains(pageNo)) { Page *p = priv->pageMap[pageNo]; const QRect &v = priv->visibleRect; QRect d = rect.translated(v.topLeft()).intersected(p->rect); if (p->dpi && !d.isEmpty()) ans = p->mapper.unMapped(d.intersected(p->rect)); } return ans; } /*! Indicate whether the page size if known */ bool QDjVuWidget::pageSizeKnown(int pageno) const { if (pageno >= 0 && pageno < priv->pageData.size()) return (priv->pageData[pageno].dpi > 0); return false; } // ---------------------------------------- // SETTINGS FROM ANNOTATIONS /*! \enum QDjVuWidget::Priority Levels for prioritized properties. Certain properties can be set at various priority levels for defining the default values, annotation options, cgi options, and user specified values. Priority levels matter when one changes the current document or the current page: new property values might be unmasked when the annotation or cgi level values are unset. The prioritized properties are: \a borderSize, \a zoom, \a borderBrush, \a displayMode, \a horizAlign, \a vertAlign. */ /*! The property setting function always set the prioritized properties at priority level \a PRIORITY_USER. This function downgrades all options set with a priority higher than \a priority to priority level \a priority. */ void QDjVuWidget::reduceOptionsToPriority(Priority priority) { priv->qBorderSize.reduce(priority); priv->qZoom.reduce(priority); priv->qBorderBrush.reduce(priority); priv->qDisplay.reduce(priority); priv->qHAlign.reduce(priority); priv->qVAlign.reduce(priority); // Apply changes priv->changeZoom(); priv->changeHAlign(); priv->changeVAlign(); priv->changeDisplay(); priv->changeBorderSize(); priv->changeBorderBrush(); } void QDjVuPrivate::adjustSettings(Priority priority, miniexp_t annotations) { // Reset everything qZoom.unset(priority); qBorderBrush.unset(priority); qDisplay.unset(priority); qHAlign.unset(priority); qVAlign.unset(priority); qBorderSize.unset(priority); // Analyse annotations if (annotations && annotations != miniexp_dummy) { const char *xbgcolor = ddjvu_anno_get_bgcolor(annotations); const char *xzoom = ddjvu_anno_get_zoom(annotations); const char *xmode = ddjvu_anno_get_mode(annotations); const char *xhorizalign = ddjvu_anno_get_horizalign(annotations); const char *xvertalign = ddjvu_anno_get_vertalign(annotations); // border color if (xbgcolor && xbgcolor[0]=='#') { QColor color(xbgcolor); qBorderBrush.set(priority, QBrush(color)); } // zoom if (xzoom == QLatin1String("stretch")) qZoom.set(priority, ZOOM_STRETCH); else if (xzoom == QLatin1String("one2one")) qZoom.set(priority, ZOOM_ONE2ONE); else if (xzoom == QLatin1String("width")) qZoom.set(priority, ZOOM_FITWIDTH); else if (xzoom == QLatin1String("page")) qZoom.set(priority, ZOOM_FITPAGE); else if (xzoom && xzoom[0]=='d' && all_numbers(xzoom+1)) { int zoom = strtol(xzoom+1,0,10); qZoom.set(priority, qBound((int)ZOOM_MIN, zoom, (int)ZOOM_MAX)); } // display mode if (xmode == QLatin1String("color")) qDisplay.set(priority, DISPLAY_COLOR); else if (xmode == QLatin1String("bw") || xmode == QLatin1String("black")) qDisplay.set(priority, DISPLAY_STENCIL); else if (xmode == QLatin1String("fore") || xmode == QLatin1String("fg")) qDisplay.set(priority, DISPLAY_FG); else if (xmode == QLatin1String("back") || xmode == QLatin1String("bg")) qDisplay.set(priority, DISPLAY_BG); // horiz align if (xhorizalign == QLatin1String("left")) qHAlign.set(priority, ALIGN_LEFT); else if (xhorizalign == QLatin1String("center")) qHAlign.set(priority, ALIGN_CENTER); else if (xhorizalign == QLatin1String("right")) qHAlign.set(priority, ALIGN_RIGHT); // vert align if (xvertalign == QLatin1String("top")) qVAlign.set(priority, ALIGN_TOP); else if (xvertalign == QLatin1String("center")) qVAlign.set(priority, ALIGN_CENTER); else if (xvertalign == QLatin1String("bottom")) qVAlign.set(priority, ALIGN_BOTTOM); // border size if (xbgcolor || xzoom || xhorizalign || xvertalign) qBorderSize.set(priority, 0); } // Apply changes changeZoom(); changeHAlign(); changeVAlign(); changeDisplay(); changeBorderSize(); changeBorderBrush(); } // ---------------------------------------- // PAINTING void QDjVuPrivate::trimPixelCache() { int pos; int pixels = 0; int sz = pixelCache.size(); for (pos = 0; pos < sz; pos++) { Cache &p = pixelCache[pos]; pixels += p.rect.width() * p.rect.height(); if (pixels > pixelCacheSize) break; } pos = qMin(pos, 256); // hard limit! while (sz-- > pos) pixelCache.removeLast(); } void QDjVuPrivate::addToPixelCache(const QRect &rect, QImage image) { if (qMin(rect.width(), rect.height()) < 128) { Cache c; c.rect = rect; c.image = image; pixelCache.prepend(c); trimPixelCache(); } } bool QDjVuPrivate::paintHiddenText(QImage &img, Page *p, const QRect &drect, const QRect *prect) { // do not paint anything unless display is display text bool okay = false; if (display != DISPLAY_TEXT) return okay; miniexp_t q = p->hiddenText; if (p->initialRot < 0 || q == miniexp_nil || q == miniexp_dummy) return okay; if (! prect) prect = &p->rect; // setup mapper int rot = p->initialRot; int w = (rot&1) ? p->height : p->width; int h = (rot&1) ? p->width : p->height; QRectMapper mapper; mapper.setMap(QRect(0,0,w,h), *prect); mapper.setTransform(rot + rotation, false, true); // setup painter QPainter paint(&img); paint.setRenderHint(QPainter::TextAntialiasing); QColor qblue = Qt::blue; QColor qwhite = Qt::white; qwhite.setAlpha(192); // loop over text int orientation = (4 - rot - rotation) & 3; while (miniexp_consp(q)) { miniexp_t r = miniexp_car(q); q = miniexp_cdr(q); if (miniexp_consp(r)) { QRect rect; miniexp_t s = miniexp_nth(5, r); miniexp_t g = miniexp_cdr(r); if (miniexp_symbolp(miniexp_car(r)) && miniexp_stringp(s) && miniexp_get_rect_from_points(g, rect) ) { rect = mapper.mapped(rect); // heuristically choose orientation int w = rect.width(); int h = rect.height(); QString text = miniexp_to_qstring(s).trimmed(); if (text.size() >= 2) if (((orientation & 1) && (w > 2*h)) || (!(orientation & 1) && (h > 2*w)) ) orientation ^= 1; if (!drect.intersects(rect)) continue; // paint frame okay = true; rect.translate(-drect.topLeft()); paint.setPen(QPen(qblue, 1)); paint.setBrush(qwhite); paint.drawRect(rect.adjusted(0,0,-1,-1)); if (w < 6 || h < 6) continue; // paint text paint.save(); paint.setClipRect(rect); rect = rect.adjusted(2,2,-2,-2); paint.translate(rect.topLeft()); paint.setPen(Qt::black); paint.setBrush(Qt::NoBrush); QFont font = paint.font(); font.setPixelSize(128); QFontMetrics metrics(font); #if QT_VERSION >= 0x40300 && !defined(Q_OS_WIN) QRect brect = metrics.tightBoundingRect(text); #else QRect brect = metrics.boundingRect(text); #endif double dw = rect.width(); double dh = rect.height(); double bw = brect.width(); double bh = brect.height(); if (dw > 1 && dh > 1 && bw > 1 && bh > 1) { switch(orientation) { case 2: paint.translate(dw, dh); paint.rotate(180); default: paint.scale(dw/bw, dh/bh); break; case 3: paint.translate(dw, dh); paint.rotate(180); case 1: paint.translate(dw, 0); paint.rotate(90); paint.scale(dh/bw, dw/bh); break; } paint.setFont(font); paint.drawText(-brect.topLeft(), text); } paint.restore(); } } } return okay; } bool QDjVuPrivate::paintMapAreas(QImage &img, Page *p, const QRect &r, bool perm, const QRect *prect) { // do not paint anything when disabled if (! displayMapAreas) return false; // setup mapper QRectMapper mapper; QRectMapper *pmapper = &p->mapper; if (! prect) prect = &p->rect; else { mapper.setMap(QRect(0,0,p->width,p->height), *prect); mapper.setTransform(rotation, false, true); pmapper = &mapper; } // warning: rect in desk coordinates. bool changed = false; for (int i=0; imapAreas.size(); i++) { QRect arect; MapArea &area = p->mapAreas[i]; QPoint p1 = pmapper->mapped(area.areaRect.topLeft()); QPoint p2 = pmapper->mapped(area.areaRect.bottomRight()); int bw2 = (area.borderWidth + 1) / 2; arect.setLeft(qMin(p1.x(),p2.x())-bw2); arect.setTop(qMin(p1.y(),p2.y())-bw2); arect.setRight(qMax(p1.x(),p2.x())+bw2); arect.setBottom(qMax(p1.y(),p2.y())+bw2); // The above code is necessary because mapping a small rect // can round to a rect of zero width or height. if (r.intersects(arect.adjusted(-8,-8,8,8))) { if (perm) { double z = (prect->width() * p->dpi * 100.0) / (p->width * sdpi); area.paintPermanent(&img, *pmapper, r.topLeft(), z); changed = true; } else if (mustDisplayMapArea(&area) && area.hasTransient(allLinksDisplayed)) { img.detach(); area.paintTransient(&img, *pmapper, r.topLeft(), allLinksDisplayed); changed = true; } } } return changed; } bool QDjVuPrivate::paintPage(QPainter &paint, Page *p, const QRegion ®ion) { // check if (region.isEmpty()) return true; if (p->dpi<=0 || p->page==0) return false; // caching QList cachelist; QRegion remainder = region; QPoint deskToView = - visibleRect.topLeft(); for (int i=0; iviewRect); // prune cache list QRegion shown = cover; for (int i=cachelist.size()-1; i>=0; i--) { QRect r = cachelist[i]->rect.translated(deskToView); r = region.intersected(r).boundingRect(); if (shown.intersected(r) == r) cachelist.removeAt(i); shown += r; } // process cached segments QRegion displayed; for (int i=0; iimage; QRect r = cache->rect; #if QDJVUWIDGET_PIXMAP_CACHE if (cache->pixmap.isNull()) cache->pixmap = QPixmap::fromImage(img, Qt::ThresholdDither); bool hastransient = paintMapAreas(img, p, r, false); #else paintMapAreas(img, p, r, false); #endif r.translate(deskToView); QRegion dr = region.intersected(r) - displayed; if (dr.isEmpty()) continue; QRect d = dr.boundingRect(); displayed += d; QRect s = d.translated(-r.topLeft()); #if QDJVUWIDGET_PIXMAP_CACHE if (hastransient) paint.drawImage(d.topLeft(), img, s, Qt::ThresholdDither); else paint.drawPixmap(d.topLeft(), cachelist[i]->pixmap, s); #else paint.drawImage(d.topLeft(), img, s, Qt::ThresholdDither); #endif } // mode for new segments ddjvu_render_mode_t mode = DDJVU_RENDER_COLOR; if (display == DISPLAY_STENCIL) mode = DDJVU_RENDER_BLACK; else if (display == DISPLAY_BG) mode = DDJVU_RENDER_BACKGROUND; else if (display == DISPLAY_FG) mode = DDJVU_RENDER_FOREGROUND; // render new segments QVector rects = cover.rects(); for (int i=0; ipage; qrect_to_rect(r, rr); qrect_to_rect(p->rect, pr); #if DDJVUAPI_VERSION < 18 p->initialRot = ddjvu_page_get_initial_rotation(*dp); #endif rot = p->initialRot + rotation; ddjvu_page_set_rotation(*dp, (ddjvu_page_rotation_t)(rot & 0x3)); if (! ddjvu_page_render(*dp, mode, &pr, &rr, renderFormat, img.bytesPerLine(), (char*)img.bits() )) return false; paintHiddenText(img, p, r); if (invertLuminance) invert_luminance(img); paintMapAreas(img, p, r, true); addToPixelCache(r, img); paintMapAreas(img, p, r, false); r.translate(deskToView); QRegion dr = region.intersected(r) - displayed; if (dr.isEmpty()) continue; QRect d = dr.boundingRect(); displayed += d; QRect s = d.translated(-r.topLeft()); paint.drawImage(d.topLeft(), img, s, Qt::ThresholdDither); } return true; } void QDjVuPrivate::paintAll(QPainter &paint, const QRegion &paintRegion) { // Document not ready yet if (pageLayout.isEmpty()) { bool waiting = (docReady || !docFailed) && !docStopped; QRect rect(QPoint(borderSize,borderSize), unknownSize); widget->paintEmpty(paint, rect, waiting, docStopped, docFailed); widget->paintDesk(paint, paintRegion-rect); widget->paintFrame(paint, rect, shadowSize); return; } // Document ready. Page *p; foreach(p, pageVisible) { // Paint page QRegion region = paintRegion & p->viewRect; if (! paintPage(paint, p, region)) { // Cannot paint page yet ddjvu_status_t s = DDJVU_JOB_FAILED; if (p->page && *(p->page)) s = ddjvu_page_decoding_status(*(p->page)); if (!p->page && pageRequestTimer->isActive()) s = DDJVU_JOB_STARTED; widget->paintEmpty(paint, p->viewRect, s==DDJVU_JOB_STARTED, s==DDJVU_JOB_STOPPED, s==DDJVU_JOB_FAILED); } // Paint frames to reduce flashing. if (frame) widget->paintFrame(paint, p->viewRect, shadowSize); } // Paint desk QRegion deskRegion = paintRegion; foreach(p, pageVisible) deskRegion -= p->viewRect; widget->paintDesk(paint, deskRegion); // Paint frames again if (frame) foreach(p, pageLayout) { QRect rect = p->rect.adjusted(0,0,shadowSize,shadowSize); if (visibleRect.intersects(rect)) widget->paintFrame(paint, p->viewRect, shadowSize); } // Paint selected rectangle if (! selectedRect.isEmpty()) { paint.setBrush(QColor(128,128,192,64)); paint.setPen(QPen(QColor(64,64,96,255), 1)); paint.drawRect(selectedRect.adjusted(0,0,-1,-1)); } // Paint hour glass if (hourGlassRatio > 0) { QRect rect = hourGlassRect(); if (! rect.isEmpty()) { const int tp = 360*16; paint.setPen(QPen()); paint.setBrush(QColor(128,128,192,128)); paint.drawPie(rect, tp/4, (int)(tp*hourGlassRatio)); } } } /*! \internal */ void QDjVuWidget::paintEvent(QPaintEvent *event) { // mark maparea if (priv->currentMapArea) { MapArea *a = priv->currentMapArea; priv->currentLinkDisplayed = priv->mustDisplayMapArea(a); } // paint everything QPainter paint(viewport()); QRegion region = event->region() & viewport()->rect(); priv->paintAll(paint, region); // debugging code #ifdef DEBUG_SHOW_PAINTED_AREAS QColor color(rand()%256,rand()%256,rand()%256); color.setAlpha(128); paint.setClipRegion(region); paint.fillRect(region.boundingRect(), color); #endif } // ---------------------------------------- // USER INTERFACE /*! Overridden \a QAbstractScrollArea virtual function. */ void QDjVuWidget::scrollContentsBy(int, int) { if (! priv->changingSBars) { QScrollBar *hBar = horizontalScrollBar(); QScrollBar *vBar = verticalScrollBar(); QPoint p = priv->visibleRect.topLeft(); if (hBar->maximum() > hBar->minimum()) p.rx() = hBar->sliderPosition(); if (vBar->maximum() > vBar->minimum()) p.ry() = vBar->sliderPosition(); QPoint np = p - priv->visibleRect.topLeft(); priv->movePoint = priv->currentPoint; priv->movePos = priv->findPosition(np + priv->movePoint); priv->changeLayout(CHANGE_VIEW); priv->clearAnimation(); } } /*! Overridden \a QAbstractScrollArea virtual function. */ bool QDjVuWidget::event(QEvent *event) { // Actual widget resize instead of viewport. if (event->type() == QEvent::Resize) priv->layoutLoop = 0; // Default function return QAbstractScrollArea::event(event); } /*! Overridden \a QAbstractScrollArea virtual function. */ bool QDjVuWidget::viewportEvent(QEvent *event) { switch (event->type()) { case QEvent::Enter: // Install filter to capture modifiers QApplication::instance()->installEventFilter(priv); break; case QEvent::Leave: // Remove filter to capture modifiers QApplication::instance()->removeEventFilter(priv); // Uncheck any active map area priv->checkCurrentMapArea(true); break; #if QT_VERSION >= 0x040600 case QEvent::Gesture: gestureEvent(event); if (event->isAccepted()) return true; break; #endif default: break; } // The default function calls the following // QAbstractScrollArea handlers: // - resizeEvent, paintEvent // - mouse{Press,Release,Move}Event // - contextMenuEvent return QAbstractScrollArea::viewportEvent(event); } /*! Overridden \a QAbstractScrollArea virtual function. */ void QDjVuWidget::resizeEvent(QResizeEvent *event) { QAbstractScrollArea::resizeEvent(event); int change = CHANGE_VISIBLE|CHANGE_SCROLLBARS; if (priv->zoom == ZOOM_FITWIDTH || priv->zoom == ZOOM_FITPAGE || priv->zoom == ZOOM_STRETCH ) change |= CHANGE_SCALE; // Do not reset loop counter // Update layout immediately because Qt40 gets confused // by asynchronous mixes of scrolls and resizes. // Also we do not want to reset the loop counter! priv->layoutChange |= change; priv->makeLayout(); } /* capture modifier changes */ bool QDjVuPrivate::eventFilter(QObject *, QEvent *event) { QEvent::Type type = event->type(); switch (type) { default: return false; case QEvent::KeyPress: case QEvent::KeyRelease: Qt::KeyboardModifiers change = Qt::NoModifier; QKeyEvent *kevent = (QKeyEvent*)event; switch (kevent->key()) { case Qt::Key_Shift: change = Qt::ShiftModifier; break; case Qt::Key_Control: change = Qt::ControlModifier; break; case Qt::Key_Alt: change = Qt::AltModifier; break; case Qt::Key_Meta: change = Qt::MetaModifier; break; default: return false; } if (type == QEvent::KeyPress) updateModifiers(modifiers | change, buttons); else updateModifiers(modifiers & ~change, buttons); } return false; } void QDjVuPrivate::updateModifiers(Qt::KeyboardModifiers newModifiers, Qt::MouseButtons newButtons) { Qt::KeyboardModifiers oldModifiers = modifiers; Qt::MouseButtons oldButtons = buttons; modifiers = newModifiers; buttons = newButtons; if (modifiers != oldModifiers) showTransientMapAreas(modifiers == modifiersForLinks && modifiers != Qt::NoModifier ); if (modifiers != oldModifiers || buttons != oldButtons ) widget->modifierEvent(modifiers, buttons, cursorPoint); } void QDjVuPrivate::changeSelectedRectangle(const QRect& rect) { QRect normRect = rect.normalized(); QRect newRect; if (normRect.width() >= 2 && normRect.height() >= 2) newRect = normRect; QRect oldRect = selectedRect; selectedRect = newRect; if (oldRect.isEmpty()) widget->viewport()->update(newRect.adjusted(-2,-2,2,2)); else if (newRect.isEmpty()) widget->viewport()->update(oldRect.adjusted(-2,-2,2,2)); else { QRegion region = QRegion(newRect) ^ QRegion(oldRect); QVector rects = region.rects(); QRegion dilated; for(int i=0; iviewport()->update(dilated); } } /*! This function should be called from \a modifierEvent. It sets the specified cursor, initiates the interactively selection of a rectangular area, and returns immediately. The interactive selection stops when all mouse buttons and modifiers are released. */ bool QDjVuWidget::startSelecting(const QPoint &point) { priv->updatePosition(point, true); if (priv->dragMode == DRAG_NONE) { priv->dragStart = point; priv->dragMode = DRAG_SELECTING; return true; } return false; } /*! This function should be called from \a modifierEvent. It initiates panning the display area, and returns immediately. Panning stops when all mouse buttons and modifiers are released. */ bool QDjVuWidget::startPanning(const QPoint &point) { priv->updatePosition(point, true); if (priv->dragMode == DRAG_NONE) { priv->dragStart = point; priv->dragMode = DRAG_PANNING; return true; } return false; } /*! This function should be called from \a modifierEvent. It initiates selecting the current hyperlink and returns immediately. Interaction stops when all mouse buttons and modifiers are released. Interaction changes to panning of the mouse moves more than 8 pixels. */ bool QDjVuWidget::startLinking(const QPoint &point) { priv->updatePosition(point, true); if (priv->dragMode == DRAG_NONE) { priv->dragStart = point; priv->dragMode = DRAG_LINKING; return true; } return false; } /*! This function should be called from \a modifierEvent. It initiates user interaction with the magnification lens and returns immediately. Lensing stops when all mouse buttons and modifiers are released. */ bool QDjVuWidget::startLensing(const QPoint &point) { if (priv->dragMode == DRAG_NONE && priv->lensMag>0 && priv->lensSize>0 ) { priv->dragStart = point; priv->dragMode = DRAG_LENSING; priv->lens = new QDjVuLens(priv->lensSize, priv->lensMag, priv, this); QRect r = priv->lens->geometry(); QPoint p = viewport()->mapToGlobal(point); r.translate(p - r.center()); priv->lens->setGeometry(r); priv->lens->show(); return true; } return false; } /*! Terminates user interaction initiated by \a startSelecting, \a startPanning ot \a startLensing. Returns \a true if such interaction was ongoing, \a false otherwise. */ bool QDjVuWidget::stopInteraction(void) { QRect temp; switch (priv->dragMode) { case DRAG_LINKING: priv->updatePosition(priv->cursorPoint, true); if (priv->currentMapArea && priv->currentMapArea->clicked()) { priv->pixelCache.clear(); priv->currentMapArea->update(priv->widget->viewport(), priv->currentMapAreaPage->mapper, priv->visibleRect.topLeft(), true); } else if (priv->currentMapArea && priv->currentMapArea->url && priv->hyperlinkEnabled ) emit pointerClick(priv->cursorPos, priv->currentMapArea->expr); break; case DRAG_SELECTING: priv->updatePosition(priv->cursorPoint, true); temp = priv->selectedRect; emit pointerSelect(viewport()->mapToGlobal(priv->cursorPoint), temp); priv->changeSelectedRectangle(QRect()); break; case DRAG_LENSING: priv->lens->hide(); priv->lens->deleteLater(); priv->lens = 0; break; case DRAG_PANNING: priv->updatePosition(priv->cursorPoint, true); break; default: return false; } priv->dragMode = DRAG_NONE; return true; } /*! This function is called when the set of depressed modifiers and mouse button changes while the cursor is at position \a point in the viewport. It is also called when the pointer crosses hyperlink boundaries or when the gui interaction settings change. */ void QDjVuWidget::modifierEvent(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, QPoint point) { if (priv->dragMode != DRAG_NONE && modifiers == Qt::NoModifier && buttons == Qt::NoButton) { stopInteraction(); } if (priv->dragMode == DRAG_NONE) { if (! priv->mouseEnabled) { viewport()->setCursor(Qt::ArrowCursor); } else if (buttons & Qt::RightButton) { return; // Wait for the contextMenuEvent } else if (modifiers == Qt::NoModifier && buttons == Qt::MidButton ) { viewport()->setCursor(Qt::CrossCursor); startSelecting(point); } else if (modifiers == Qt::ControlModifier && buttons == Qt::MidButton ) { viewport()->setCursor(priv->cursHandClosed); startPanning(point); } else if (modifiers == priv->modifiersForLens && modifiers != Qt::NoModifier ) { viewport()->setCursor(Qt::CrossCursor); startLensing(point); } else if (modifiers == priv->modifiersForSelect) { viewport()->setCursor(Qt::CrossCursor); if (buttons != Qt::NoButton) startSelecting(point); } else if (priv->currentMapArea && priv->currentMapArea->isClickable(priv->hyperlinkEnabled) ) { viewport()->setCursor(Qt::ArrowCursor); if (buttons != Qt::NoButton) startLinking(point); } else if (buttons != Qt::NoButton) { viewport()->setCursor(priv->cursHandClosed); startPanning(point); } else { viewport()->setCursor(priv->cursHandOpen); } } } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::mousePressEvent(QMouseEvent *event) { mouseMoveEvent(event); } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::mouseDoubleClickEvent(QMouseEvent *event) { mouseMoveEvent(event); } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::mouseReleaseEvent(QMouseEvent *event) { mouseMoveEvent(event); } bool QDjVuPrivate::pointerScroll(const QPoint &p) { int dx = 0; int dy = 0; QRect r = widget->viewport()->rect(); if (p.x() >= r.right()) dx = lineStep; else if (p.x() < r.left()) dx = -lineStep; if (p.y() >= r.bottom()) dy = lineStep; else if (p.y() < r.top()) dy = -lineStep; if (dx == 0 && dy == 0) return false; movePos = cursorPos; movePoint = cursorPoint - QPoint(dx,dy); changeLayout(CHANGE_VIEW|CHANGE_SCROLLBARS); clearAnimation(); return true; } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::mouseMoveEvent(QMouseEvent *event) { event->accept(); QPoint p = event->pos(); priv->cursorPoint = p; priv->updateModifiers(event->modifiers(), event->buttons()); switch (priv->dragMode) { case DRAG_LINKING: priv->updatePosition(event->pos()); p = p - priv->dragStart; if (p.manhattanLength() <= 8) break; viewport()->setCursor(priv->cursHandClosed); priv->dragMode = DRAG_PANNING; // fall through case DRAG_PANNING: priv->movePoint = priv->cursorPoint; priv->movePos = priv->cursorPos; priv->changeLayout(CHANGE_VIEW|CHANGE_SCROLLBARS); priv->clearAnimation(); break; case DRAG_SELECTING: priv->updatePosition(p); priv->changeSelectedRectangle(QRect(priv->dragStart, event->pos())); priv->pointerScroll(p); break; case DRAG_LENSING: priv->updatePosition(p); if (! priv->pointerScroll(p)) priv->lens->recenter(event->pos()); break; default: priv->updatePosition(p); break; } } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::keyPressEvent(QKeyEvent *event) { if (priv->keyboardEnabled) { // Capturing this signal can override any key binding bool done = false; emit keyPressSignal(event, done); if (done) return; // Standard key bindings Qt::KeyboardModifiers modifiers = event->modifiers(); switch(event->key()) { case Qt::Key_1: setZoom(100); break; case Qt::Key_2: setZoom(200); break; case Qt::Key_3: setZoom(300); break; case Qt::Key_W: setZoom(ZOOM_FITWIDTH); break; case Qt::Key_P: setZoom(ZOOM_FITPAGE); break; case Qt::Key_BracketLeft: priv->updateCurrentPoint(priv->cursorPos); rotateLeft(); break; case Qt::Key_BracketRight: priv->updateCurrentPoint(priv->cursorPos); rotateRight(); break; case Qt::Key_Plus: case Qt::Key_Equal: priv->updateCurrentPoint(priv->cursorPos); zoomIn(); break; case Qt::Key_Minus: priv->updateCurrentPoint(priv->cursorPos); zoomOut(); break; case Qt::Key_Home: if (modifiers == Qt::ControlModifier) firstPage(); else if (modifiers == Qt::NoModifier) moveToPageTop(); else return; break; case Qt::Key_End: if (modifiers==Qt::ControlModifier) lastPage(); else if (modifiers == Qt::NoModifier) moveToPageBottom(); else return; break; case Qt::Key_PageUp: prevPage(); break; case Qt::Key_PageDown: nextPage(); break; case Qt::Key_Space: if (modifiers==Qt::ShiftModifier) readPrev(); else if (modifiers == Qt::NoModifier) readNext(); else return; break; case Qt::Key_B: case Qt::Key_Backspace: if (modifiers==Qt::ShiftModifier) readNext(); else if (modifiers == Qt::NoModifier) readPrev(); else return; break; case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Down: if (modifiers == Qt::NoModifier) { int svstep = verticalScrollBar()->singleStep(); int shstep = horizontalScrollBar()->singleStep(); verticalScrollBar()->setSingleStep(priv->lineStep); horizontalScrollBar()->setSingleStep(priv->lineStep); QAbstractScrollArea::keyPressEvent(event); verticalScrollBar()->setSingleStep(svstep); horizontalScrollBar()->setSingleStep(shstep); } else return; break; case Qt::Key_H: { int pageno = page(); if (pageno>=0) clearHighlights(pageno); break; } default: // Return without accepting the event return; } // Only reach this point when key is accepted event->accept(); } } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::contextMenuEvent (QContextMenuEvent *event) { if (priv->contextMenu) { priv->contextMenu->exec(event->globalPos()); event->accept(); } } /*! Override \a QAbstractScrollArea virtual function. */ void QDjVuWidget::wheelEvent (QWheelEvent *event) { if (priv->mouseEnabled && event->orientation() == Qt::Vertical) { bool zoom = priv->mouseWheelZoom; if (event->modifiers() == Qt::ControlModifier) zoom = ! zoom; if (zoom) { static int zWheel = 0; zWheel += event->delta(); if (qAbs(zWheel) >= 120) { priv->updateCurrentPoint(priv->cursorPos); if (zWheel > 0) zoomIn(); else zoomOut(); zWheel = 0; } return; } } QAbstractScrollArea::wheelEvent(event); } /*! New virtual function. */ void QDjVuWidget::gestureEvent(QEvent *e) { #if QT_VERSION >= 0x040600 if (e->type() == QEvent::Gesture) { QGestureEvent *g = (QGestureEvent*)(e); QPinchGesture *p = (QPinchGesture*)(g->gesture(Qt::PinchGesture)); if (p) { g->accept(p); if (p->state() == Qt::GestureStarted) priv->savedFactor = priv->zoomFactor; if (p->state() == Qt::GestureCanceled) setZoom(priv->savedFactor); else if (p->changeFlags() & QPinchGesture::ScaleFactorChanged) { qreal z = priv->savedFactor * p->scaleFactor(); setZoom(qBound((int)ZOOM_MIN, (int)z, (int)ZOOM_MAX)); } return; } } #endif e->ignore(); } bool QDjVuPrivate::computeAnimation(const Position &pos, const QPoint &p) { // no animation unless layout is finalized. if (layoutChange) return false; if (0 > pos.pageNo || pos.pageNo >= numPages) return false; Position currentPos = findPosition(p); Position targetPos = pos; Page *currentPage = pageMap.value(currentPos.pageNo, 0); Page *targetPage = pageMap.value(targetPos.pageNo, 0); // Standardize target position if (targetPos.inPage && targetPage && targetPage->dpi > 0) { QPoint dp = targetPage->mapper.mapped(targetPos.posPage); targetPos.hAnchor = targetPos.vAnchor = 0; targetPos.posView = dp - targetPage->rect.topLeft(); targetPos.inPage = false; } if (targetPos.inPage) return false; // Both position on the same page if (currentPos.pageNo == targetPos.pageNo) { char dHAnchor = targetPos.hAnchor - currentPos.hAnchor; char dVAnchor = targetPos.vAnchor - currentPos.vAnchor; QPoint dPosView = targetPos.posView - currentPos.posView; const double profile[] = { 0.05, 0.3, 0.5, 0.7, 0.95 }; const int profileSize = (int)(sizeof(profile)/sizeof(double)); for (int i=0; istart(10); return true; } // Both position in the same view if (currentPage && targetPage) { // compute desk positions. QPointF cPoint = currentPage->rect.topLeft() + currentPos.posView; if (currentPos.hAnchor > 0 && currentPos.hAnchor <= 100) cPoint.rx() += currentPage->rect.width() * currentPos.hAnchor / 100.0; if (currentPos.vAnchor > 0 && currentPos.vAnchor <= 100) cPoint.ry() += currentPage->rect.height() * currentPos.vAnchor / 100.0; QPointF tPoint = targetPage->rect.topLeft() + targetPos.posView; if (targetPos.hAnchor > 0 && targetPos.hAnchor <= 100) tPoint.rx() += targetPage->rect.width() * targetPos.hAnchor / 100.0; if (targetPos.vAnchor > 0 && targetPos.vAnchor <= 100) tPoint.ry() += targetPage->rect.height() * targetPos.vAnchor / 100.0; // compute delta QPointF v = tPoint - cPoint; qreal cs = max_stay_in_rect(cPoint, currentPage->rect, v); qreal ts = max_stay_in_rect(tPoint, targetPage->rect, -v); const double profile[] = { 0.05, 0.3, 0.5, 0.75, 1 }; const int profileSize = (int)(sizeof(profile)/sizeof(double)); for (int i=0; irect.topLeft(); animationPosition << ipos; } for (int i=profileSize-1; i>=0; i--) { QPointF ipoint = tPoint - ts * profile[i] * v; Position ipos; ipos.pageNo = targetPos.pageNo; ipos.hAnchor = ipos.vAnchor = 0; ipos.inPage = ipos.doPage = false; ipos.posView = ipoint.toPoint() - targetPage->rect.topLeft(); animationPosition << ipos; } animationPoint = p; animationPosition << pos; animationTimer->start(10); return true; } // Too complex return false; } void QDjVuPrivate::clearAnimation(void) { animationTimer->stop(); animationPosition.clear(); } void QDjVuPrivate::animate(void) { if (! animationPosition.isEmpty()) { movePoint = animationPoint; movePos = animationPosition.takeFirst(); if (! pageMap.contains(movePos.pageNo)) changeLayout(CHANGE_VIEW|CHANGE_SCROLLBARS); else changeLayout(CHANGE_PAGES|CHANGE_VIEW|CHANGE_SCROLLBARS); } if (animationPosition.isEmpty()) animationTimer->stop(); } /*! Terminates all animations in progress and make sure the page layout is fully updated. */ void QDjVuWidget::terminateAnimation(void) { while (priv->animationPosition.size() > 1) priv->animationPosition.removeFirst(); priv->animate(); if (priv->layoutChange) priv->makeLayout(); } // ---------------------------------------- // VIRTUALS /*! Paint the gray area that surrounds the pages. Overload this function to redefine the appearance of this area. */ void QDjVuWidget::paintDesk(QPainter &p, const QRegion ®ion) { p.save(); p.setClipRegion(region, Qt::IntersectClip); p.setBrushOrigin(- priv->visibleRect.topLeft()); p.fillRect(region.boundingRect(), priv->borderBrush); p.restore(); } /*! Paint the frame and the shadow surrounding a page. Argument \a rect is the page rectangle. Overload this function to redefine the appearance of the page frame. */ void QDjVuWidget::paintFrame(QPainter &p, const QRect &crect, int sw) { QRect rect = crect.adjusted(0,0,-1,-1); if (!rect.isValid()) return; // draw shadow QBrush brush(QColor(0,0,0,80)); p.setPen(Qt::NoPen); p.setBrush(brush); p.drawRect(rect.right()+1, rect.top()+sw, sw, rect.height()); if (rect.width() > sw) p.drawRect(rect.left()+sw, rect.bottom()+1, rect.width()-sw, sw); // draw frame p.setBrush(Qt::NoBrush); QPen pen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); p.setPen(pen); p.drawRect(rect); } /*! Paint the page area while waiting for page data or when the decoding job has failed or has been stopped. Argument \a rect is the page rectangle. Argument \a status indicates what is going on. Overload this function to redefine the transient appearance of such pages. */ void QDjVuWidget::paintEmpty(QPainter &p, const QRect &rect, bool waiting, bool stopped, bool error ) { QString name; QPixmap pixmap; if (waiting) name = ":/images/djvu_logo.png"; else if (stopped) name = ":/images/djvu_stop.png"; else if (error) name = ":/images/djvu_fail.png"; if (!name.isEmpty()) pixmap.load(name); // start painting QBrush brush(priv->white); p.fillRect(rect, brush); if (pixmap.isNull()) return; if (pixmap.width() > rect.width()) return; if (pixmap.height() > rect.height()) return; p.save(); p.setClipRect(rect, Qt::IntersectClip); QSize s = pixmap.size() * 5 / 4; QPoint c = rect.center(); int imin = (rect.left() - c.x())/s.width(); int imax = (rect.right() - c.x())/s.width(); int jmin = (rect.top() - c.y())/s.height(); int jmax = (rect.bottom() - c.y())/s.height(); c -= QPoint( pixmap.width()/2, pixmap.height()/2 ); for (int i=imin; i<=imax; i++) for (int j=jmin; j<=jmax; j++) if (! ((i + j) & 1)) p.drawPixmap(c.x()+i*s.width(), c.y()+j*s.height(), pixmap); p.restore(); } /*! This function displays the current hyperlink comment in a tooltip. It is called whenever the pointer crosses hyperlink boundaries. */ void QDjVuWidget::chooseTooltip(void) { QToolTip::showText(QPoint(), QString()); priv->toolTipTimer->stop(); if (!linkComment().isEmpty()) priv->toolTipTimer->start(250); } void QDjVuPrivate::makeToolTip(void) { QWidget *w = widget->viewport(); QPoint p = w->mapToGlobal(cursorPoint); QToolTip::showText(p, currentComment, w); } // ---------------------------------------- // QDJVULENS QDjVuLens::QDjVuLens(int size, int magx, QDjVuPrivate *priv, QDjVuWidget *widget) : QWidget(widget, Qt::Window|Qt::Popup), priv(priv), widget(widget) { mag = qBound(1,magx,10); size = qBound(50,size,500); setGeometry(0,0,size,size); setCursor(Qt::CrossCursor); setMouseTracking(true); connect(widget,SIGNAL(layoutChanged()), this, SLOT(redisplay())); QApplication::instance()->installEventFilter(this); } bool QDjVuLens::eventFilter(QObject *object, QEvent *event) { return priv->eventFilter(object, event); } bool QDjVuLens::event(QEvent *event) { switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: case QEvent::MouseButtonRelease: case QEvent::MouseMove: { QMouseEvent *oldEvent = (QMouseEvent*)event; QPoint pos = oldEvent->globalPos(); QMouseEvent newEvent(oldEvent->type(), widget->viewport()->mapFromGlobal(pos), pos, oldEvent->button(), oldEvent->buttons(), oldEvent->modifiers()); return widget->viewportEvent(&newEvent); } default: break; } return QWidget::event(event); } void QDjVuLens::recenter(const QPoint &p) { QPoint npos; QRect rect = geometry(); QPoint pos = rect.center(); QRect vrect = widget->viewport()->rect(); npos.rx() = qBound(vrect.left(), p.x(), vrect.right()); npos.ry() = qBound(vrect.top(), p.y(), vrect.bottom()); npos = widget->viewport()->mapToGlobal(npos); rect.translate(npos - pos); vrect.moveTo(widget->viewport()->mapToGlobal(vrect.topLeft())); setVisible(vrect.intersects(rect)); setGeometry(rect); QCoreApplication::flush(); } void QDjVuLens::refocus(void) { QRect r = rect(); QPoint p = mapToGlobal(rect().center()); int sx = ( r.width() + mag - 1 ) / mag; int sy = ( r.height() + mag - 1 ) / mag; lensRect.setRect(0,0,sx,sy); QPoint vp = widget->viewport()->mapFromGlobal(p); lensRect.translate(vp - lensRect.center()); } void QDjVuLens::moveEvent(QMoveEvent *event) { refocus(); QPoint delta = event->pos() - event->oldPos(); QRect r = rect().adjusted(1,1,-1,-1); scroll(-mag*delta.x(), -mag*delta.y(), r); } void QDjVuLens::resizeEvent(QResizeEvent *) { refocus(); } void QDjVuLens::redisplay(void) { refocus(); update(); } void QDjVuLens::paintEvent(QPaintEvent *event) { // Copied from main painting code but simpler // TODO: maybe hyperlinks. QPainter paint(this); QRegion paintRegion = event->region(); QRegion deskRegion = paintRegion; QRectMapper mapper(lensRect, rect()); Page *p; ddjvu_render_mode_t mode = DDJVU_RENDER_COLOR; if (priv->display == DISPLAY_STENCIL) mode = DDJVU_RENDER_BLACK; else if (priv->display == DISPLAY_BG) mode = DDJVU_RENDER_BACKGROUND; else if (priv->display == DISPLAY_FG) mode = DDJVU_RENDER_FOREGROUND; foreach(p, priv->pageVisible) { QRect prect = mapper.mapped(p->viewRect); QRegion region = paintRegion & prect; if (region.isEmpty()) continue; paint.fillRect(prect, Qt::white); if (p->dpi>0 && p->page) { QRegion prgn = cover_region(region, prect); QVector rects = prgn.rects(); for (int i=0; ipage; QRect &r = rects[i]; qrect_to_rect(prect, pr); qrect_to_rect(r, rr); QImage img(r.width(), r.height(), QImage::Format_RGB32); rot = p->initialRot + priv->rotation; ddjvu_page_set_rotation(*dp,(ddjvu_page_rotation_t)(rot & 0x3)); if (ddjvu_page_render(*dp, mode, &pr, &rr, priv->renderFormat, img.bytesPerLine(), (char*)img.bits() )) { // priv->paintHiddenText(img, p, r, &prect); // When displaying in hidden text mode, // the above line paints the hidden text in the lens. // But the opposite behavior is more convenient // for proofreading. if (priv->invertLuminance) invert_luminance(img); priv->paintMapAreas(img, p, r, true, &prect); paint.drawImage(r.topLeft(), img, img.rect(), Qt::ThresholdDither); } } } deskRegion -= prect; } widget->paintDesk(paint, deskRegion); if (priv->frame) foreach(p, priv->pageVisible) { QRect prect = mapper.mapped(p->viewRect); widget->paintFrame(paint, prect, priv->shadowSize); } paint.setPen(Qt::gray); paint.setBrush(Qt::NoBrush); paint.drawRect(rect().adjusted(0,0,-1,-1)); } // ---------------------------------------- // MORE SLOTS static int preferredZoom[] = { ZOOM_MIN, ZOOM_MIN, 10, 25, 50, 75, 100, 150, 200, 300, 400, 600, 800, ZOOM_MAX, ZOOM_MAX }; /*! Increase the zoom factor. */ void QDjVuWidget::zoomIn(void) { int s = 1; int z = qBound((int)ZOOM_MIN, zoomFactor(), (int)ZOOM_MAX); while (z >= preferredZoom[s]) { s += 1; } setZoom(preferredZoom[s]); } /*! Decrease the zoom factor. */ void QDjVuWidget::zoomOut(void) { int s = 1; int z = qBound((int)ZOOM_MIN, zoomFactor(), (int)ZOOM_MAX); while (z > preferredZoom[s]) { s += 1; } setZoom(preferredZoom[s-1]); } /*! Maximize the maginification in order to keep rectangle \a rect visible. The rectangle is expressed in viewport coordinates. */ void QDjVuWidget::zoomRect(QRect rect) { rect = rect.normalized(); Position pos = priv->findPosition(rect.center()); pos.inPage = true; int z = zoomFactor(); int zw = z * viewport()->width() / qMax(1,rect.width()); int zh = z * viewport()->height() / qMax(1,rect.height()); z = qBound((int)ZOOM_MIN, qMin(zw, zh), (int)ZOOM_MAX); setZoom(z); setPosition(pos, viewport()->rect().center()); } /*! Rotate the page images clockwise. */ void QDjVuWidget::rotateRight(void) { setRotation((rotation() - 1) & 0x3); } /*! Rotate the page images counter-clockwise. */ void QDjVuWidget::rotateLeft(void) { setRotation((rotation() + 1) & 0x3); } /*! Set the display mode to \a DISPLAY_COLOR. */ void QDjVuWidget::displayModeColor(void) { setDisplayMode(DISPLAY_COLOR); } /*! Set the display mode to \a DISPLAY_STENCIL. */ void QDjVuWidget::displayModeStencil(void) { setDisplayMode(DISPLAY_STENCIL); } /*! Set the display mode to \a DISPLAY_BG. */ void QDjVuWidget::displayModeBackground(void) { setDisplayMode(DISPLAY_BG); } /*! Set the display mode to \a DISPLAY_FG. */ void QDjVuWidget::displayModeForeground(void) { setDisplayMode(DISPLAY_FG); } /*! Set the display mode to \a DISPLAY_TEXT. */ void QDjVuWidget::displayModeText(void) { setDisplayMode(DISPLAY_TEXT); } /*! Move to the next page. */ void QDjVuWidget::nextPage(void) { terminateAnimation(); int pageNo = page(); const QRect &dr = priv->deskRect; const QRect &vr = priv->visibleRect; const Page *pg = priv->pageMap.value(pageNo,0); while (pageNo < priv->numPages - 1) { pageNo += 1; if (priv->layoutChange || !priv->pageMap.contains(pageNo) || !pg) break; // Skip pages until we get a meaningful change. const QRect &pr = priv->pageMap[pageNo]->rect; if (! vr.contains(pr)) if (pr.top() != pg->rect.top() || vr.width() < dr.width()) break; } setPage(pageNo, true); } /*! Move to the previous page. */ void QDjVuWidget::prevPage(void) { terminateAnimation(); int pageNo = page(); const QRect &dr = priv->deskRect; const QRect &vr = priv->visibleRect; const Page *pg = priv->pageMap.value(pageNo,0); while (pageNo > 0) { pageNo -= 1; if (priv->layoutChange || !priv->pageMap.contains(pageNo) || !pg) break; // Skip pages until we get a meaningful change. const QRect &pr = priv->pageMap[pageNo]->rect; if (! vr.contains(pr)) if (pr.top() != pg->rect.top() || vr.width() < dr.width()) break; } setPage(pageNo, true); } /*! Move to the first page. */ void QDjVuWidget::firstPage(void) { terminateAnimation(); Position pos; pos.pageNo = 0; pos.inPage = false; pos.posView = pos.posPage = QPoint(0,0); setPosition(pos); } /*! Move to the last page. */ void QDjVuWidget::lastPage(void) { terminateAnimation(); Position pos; pos.pageNo = priv->numPages - 1; pos.inPage = false; pos.posView = pos.posPage = QPoint(0,0); pos.hAnchor = pos.vAnchor = 100; QPoint p; p.rx() = priv->visibleRect.width() - priv->borderSize; p.ry() = priv->visibleRect.height() - priv->borderSize; setPosition(pos, p); } /*! Move to top of current page. */ void QDjVuWidget::moveToPageTop(void) { terminateAnimation(); Position pos = priv->currentPos; pos.inPage = false; pos.posView = pos.posPage = QPoint(0,0); pos.hAnchor = 0; pos.vAnchor = 0; setPosition(pos); } /*! Move to bottom of current page. */ void QDjVuWidget::moveToPageBottom(void) { terminateAnimation(); Position pos = priv->currentPos; pos.inPage = false; pos.posView = pos.posPage = QPoint(0,0); pos.hAnchor = 0; pos.vAnchor = 100; QPoint p; p.rx() = priv->visibleRect.width() - priv->borderSize; p.ry() = priv->visibleRect.height() - priv->borderSize; setPosition(pos, p); } /*! Move to next position in approximate reading order. */ void QDjVuWidget::readNext(void) { terminateAnimation(); QPoint point = priv->currentPoint; Position pos = priv->currentPos; int bs = priv->borderSize; if (priv->pageMap.contains(pos.pageNo)) { Page *p = priv->pageMap[pos.pageNo]; QRect nv = priv->visibleRect.adjusted(bs,bs,-bs,-bs); QRect v = priv->visibleRect.intersected(p->rect); if (v.bottom() < p->rect.bottom()) { // scroll in page point.ry() = bs; nv.moveTop(v.bottom()); nv.moveBottom(qMin(nv.bottom(), p->rect.bottom())); pos.inPage = false; pos.posView.ry() = nv.top() - p->rect.top(); setPosition(pos, point); return; } } // find forward a partially hidden page while (pos.pageNo < priv->numPages - 1) { pos.pageNo += 1; pos.posView.ry() = 0; pos.vAnchor = 0; pos.hAnchor = 0; point.ry() = bs; if (! priv->pageMap.contains(pos.pageNo) || ! priv->visibleRect.contains(priv->pageMap[pos.pageNo]->rect) ) break; } pos.inPage = false; pos.doPage = true; setPosition(pos, point); } /*! Move to previous position in approximate reading order. */ void QDjVuWidget::readPrev(void) { terminateAnimation(); QPoint point = priv->currentPoint; Position pos = priv->currentPos; int bs = priv->borderSize; if (priv->pageMap.contains(pos.pageNo)) { Page *p = priv->pageMap[pos.pageNo]; QRect nv = priv->visibleRect.adjusted(bs,bs,-bs,-bs); QRect v = priv->visibleRect.intersected(p->rect); if (v.top() > p->rect.top()) { // scroll in page point.ry() = bs; nv.moveBottom(v.top()); nv.moveTop(qMax(nv.top(), p->rect.top())); pos.inPage = false; pos.posView.ry() = nv.top() - p->rect.top(); setPosition(pos, point); return; } } // find backward a partially hidden page while (pos.pageNo > 0) { pos.pageNo -= 1; pos.posView.ry() = 0; pos.vAnchor = 100; pos.hAnchor = 0; point.ry() = priv->visibleRect.height() - bs; if (! priv->pageMap.contains(pos.pageNo) || ! priv->visibleRect.contains(priv->pageMap[pos.pageNo]->rect) ) break; } pos.inPage = false; pos.doPage = true; setPosition(pos, point); } // ---------------------------------------- // MOC #include "qdjvuwidget.moc" // ---------------------------------------- // DOCUMENTATION /*! \class QDjVuWidget::PageInfo \brief Additional information for pointerPosition signal. Variable \a pageno is the page number. Variables \a width and \a height give the page size in pixels. Variable \a dpi gives the page resolution. Variable \a segment gives the page coordinates of the page segment covered by the selected rectangle All these variables are null when the page geometry is still unknown. */ /*! \enum QDjVuWidget::DisplayMode Modes for displaying a DjVu image. Only mode \a DISPLAY_COLOR is really useful. The other modes show various layers of the DjVu image. */ /*! \enum QDjVuWidget::Align Possible values of the alignment properties. */ /*! \fn QDjVuWidget::layoutChanged() This signal is emitted when the layout of the displayed pages has changed. This can happen when more data is available, or when the user changes zoom, rotation, layout, display mode, etc. */ /*! \fn QDjVuWidget::pageChanged(int pageno) This signal is emitted when the current page number is changed. This refer to the current page used when moving the document to keep reading (space bar). */ /*! \fn QDjVuWidget::pointerPosition(const Position &pos, const PageInfo &page) This signal is emitted when the mouse move. Variable \a pos reports the position of the mouse in the document. Variable \a page reports the page geometry. */ /*! \fn QDjVuWidget::pointerEnter(const Position &pos, miniexp_t maparea) This signal is emitted when the mouse enters a maparea. Variable \a pos reports the position of the mouse in the document. Variable \a maparea contains the area description. Additional information can be obtained using functions \a linkUrl, \a linkTarget, and \a linkComment. */ /*! \fn QDjVuWidget::pointerLeave(const Position &pos, miniexp_t maparea) This signal is emitted when the mouse leaves a maparea. Variable \a pos reports the position of the mouse in the document. Variable \a maparea contains the area description. Additional information can be obtained using functions \a linkUrl, \a linkTarget, and \a linkComment. */ /*! \fn QDjVuWidget::pointerClick(const Position &pos, miniexp_t maparea) This signal is emitted when the user clicks an hyperlink maparea. Variable \a pos reports the position of the mouse in the document. Variable \a maparea contains the area description. Additional information can be obtained using functions \a linkUrl, \a linkTarget, and \a linkComment. */ /*! \fn QDjVuWidget::pointerSelect(const QPoint &pos, const QRect &rect) This signal is emitted when the user has selected a rectangular area in the image. Argument \a rect gives the rectangle coordinates in the viewport. Argument \a pos is the global mouse position. Use \a getTextForRect and \a getImageForRect to extract associated information. */ /*! \fn QDjVuWidget::errorCondition(int pageno) This signal is emitted when an error occurs during decoding. Recorded error messages can be obtained using function \a errorMessage. Argument \a pageno is -1 if the error occurs at the document level. Otherwise it indicates the page with the error. */ /*! \fn QDjVuWidget::stopCondition(int pageno) This signal is emitted when decoding stops. Recorded error messages can be obtained using function \a errorMessage. Argument \a pageno is -1 if the condition occurs at the document level. Otherwise it indicates the page with the error. */ /*! \fn QDjVuWidget::keyPressSignal(QKeyEvent *event, bool &done) This signal is emitted from the widget's \a keyPressEvent routine. Setting flag \a done to \a true suppress any further processing. Otherwise default key bindings are applied. */ /*! \fn QDjVuWidget::error(QString message, QString filename, int lineno) This signal relays all error messages generated by the \a QDjVuDocument and \a QDjVuPage objects associated with this widget. The last few error messages are saved and are available via function \a pastErrorMessage(). Error message occur asynchronously and might be related to a background job such as prefetching pages. Use instead signal \a errorCondition() as an indicator that an error has just ocurred. */ /*! \fn QDjVuWidget::info(QString message) This signal relays all informational messages generated by the \a QDjVuDocument and \a QDjVuPage objects associated with this widget. The last few messages are saved and are available via function \a pastInfoMessage(). Note that informational message occur asynchronously and might not be relevant. */ /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvuwidget.h000066400000000000000000000271631264256014000164630ustar00rootroot00000000000000//C- -*- C++ -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006- Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ #ifndef QDJVUWIDGET_H #define QDJVUWIDGET_H #if AUTOCONF # include "config.h" #endif #include "qdjvu.h" #include #include #include #include class QDjVuPrivate; class QDjVuLens; class QDjVuWidget : public QAbstractScrollArea { Q_OBJECT Q_ENUMS(DisplayMode PointerMode Align Priority) Q_PROPERTY(int page READ page WRITE setPage) Q_PROPERTY(int rotation READ rotation WRITE setRotation) Q_PROPERTY(int zoom READ zoom WRITE setZoom) Q_PROPERTY(double gamma READ gamma WRITE setGamma) Q_PROPERTY(double bool READ invertLuminance WRITE setInvertLuminance) Q_PROPERTY(QColor white READ white WRITE setWhite) Q_PROPERTY(int screenDpi READ screenDpi WRITE setScreenDpi) Q_PROPERTY(DisplayMode displayMode READ displayMode WRITE setDisplayMode) Q_PROPERTY(bool displayFrame READ displayFrame WRITE setDisplayFrame) Q_PROPERTY(Align horizAlign READ horizAlign WRITE setHorizAlign) Q_PROPERTY(Align vertAlign READ vertAlign WRITE setVertAlign) Q_PROPERTY(bool continuous READ continuous WRITE setContinuous) Q_PROPERTY(bool sideBySide READ sideBySide WRITE setSideBySide) Q_PROPERTY(bool coverPage READ coverPage WRITE setCoverPage) Q_PROPERTY(bool rightToLeft READ rightToLeft WRITE setRightToLeft) Q_PROPERTY(QBrush borderBrush READ borderBrush WRITE setBorderBrush) Q_PROPERTY(int borderSize READ borderSize WRITE setBorderSize) Q_PROPERTY(int separatorSize READ separatorSize WRITE setSeparatorSize) Q_PROPERTY(int pixelCacheSize READ pixelCacheSize WRITE setPixelCacheSize) Q_PROPERTY(bool displayMapAreas READ displayMapAreas WRITE setDisplayMapAreas) Q_PROPERTY(bool keyboardEnabled READ keyboardEnabled WRITE enableKeyboard) Q_PROPERTY(bool hyperlinkEnabled READ hyperlinkEnabled WRITE enableHyperlink) Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE enableMouse) Q_PROPERTY(bool animationEnabled READ animationEnabled WRITE enableAnimation) Q_PROPERTY(bool animationInProgress READ animationInProgress) Q_PROPERTY(bool mouseWheelZoom READ mouseWheelZoom WRITE setMouseWheelZoom) Q_PROPERTY(int lensPower READ lensPower WRITE setLensPower) Q_PROPERTY(int lensSize READ lensSize WRITE setLensSize) Q_PROPERTY(double hourGlassRatio READ hourGlassRatio WRITE setHourGlassRatio) Q_PROPERTY(QDjVuDocument* document READ document WRITE setDocument) Q_PROPERTY(QMenu* contextMenu READ contextMenu WRITE setContextMenu) Q_PROPERTY(Position position READ position WRITE setPosition) Q_PROPERTY(Qt::KeyboardModifiers modifiersForLens READ modifiersForLens WRITE setModifiersForLens) Q_PROPERTY(Qt::KeyboardModifiers modifiersForSelect READ modifiersForSelect WRITE setModifiersForSelect) Q_PROPERTY(Qt::KeyboardModifiers modifiersForLinks READ modifiersForLinks WRITE setModifiersForLinks) public: enum { ZOOM_STRETCH = -4, //!< Stretch full page into viewport ZOOM_ONE2ONE = -3, //!< Maximal resolution for each page ZOOM_FITPAGE = -2, //!< Fit entire pages into viewport ZOOM_FITWIDTH = -1, //!< Fit page width into viewport ZOOM_MIN = 5, //!< Minimal magnification ZOOM_100 = 100, //!< Standard magnification ZOOM_MAX = 1200, //!< Maximal magnification }; enum DisplayMode { DISPLAY_COLOR, //!< Default dislplay mode DISPLAY_STENCIL, //!< Only display the b&w mask layer DISPLAY_BG, //!< Only display the background layer DISPLAY_FG, //!< Only display the foregroud layer DISPLAY_TEXT, //!< Overprint the text layer }; enum Align { ALIGN_TOP, //!< Align page top sides. ALIGN_LEFT = ALIGN_TOP, //!< Align page left sides. ALIGN_CENTER, //!< Center pages. ALIGN_BOTTOM, //!< Align page bottom sides. ALIGN_RIGHT = ALIGN_BOTTOM, //!< Align page right sides. }; enum Priority { PRIORITY_DEFAULT, //!< Priority for default option values. PRIORITY_ANNO, //!< Priority for annotation defined options. PRIORITY_CGI, //!< Priority for cgi defined options. PRIORITY_USER, //!< Priority for gui defined options. }; struct Position { int pageNo; QPoint posPage; QPoint posView; bool inPage; bool doPage; char hAnchor; char vAnchor; Position(); }; struct PageInfo { int pageno; int dpi; int width; int height; QRect segment; QRect selected; }; ~QDjVuWidget(); QDjVuWidget(QWidget *parent=0); QDjVuWidget(QDjVuDocument *doc, QWidget *parent=0); QDjVuWidget(bool opengl, QWidget *parent=0); QDjVuWidget(QDjVuDocument *doc, bool opengl, QWidget *parent=0); QDjVuDocument *document(void) const; int page(void) const; QPoint hotSpot(void) const; Position position(void) const; Position position(const QPoint &point) const; Position positionWithClosestAnchor(const QPoint &point) const; int rotation(void) const; int zoom(void) const; int zoomFactor(void) const; double gamma(void) const; bool invertLuminance(void) const; QColor white(void) const; int screenDpi(void) const; DisplayMode displayMode(void) const; bool displayFrame(void) const; Align horizAlign(void) const; Align vertAlign(void) const; bool continuous(void) const; bool sideBySide(void) const; bool coverPage(void) const; bool rightToLeft(void) const; QBrush borderBrush(void) const; int borderSize(void) const; int separatorSize(void) const; QMenu* contextMenu(void) const; int pixelCacheSize(void) const; bool displayMapAreas(void) const; bool keyboardEnabled(void) const; bool mouseEnabled(void) const; bool hyperlinkEnabled(void) const; bool animationEnabled(void) const; bool animationInProgress(void) const; bool mouseWheelZoom(void) const; int lensPower(void) const; int lensSize(void) const; double hourGlassRatio(void) const; Qt::KeyboardModifiers modifiersForLens() const; Qt::KeyboardModifiers modifiersForSelect() const; Qt::KeyboardModifiers modifiersForLinks() const; public slots: void setDocument(QDjVuDocument *d); void setPage(int p, bool keep=false); void setPosition(const Position &pos); void setPosition(const Position &pos, const QPoint &p, bool animate=true); void setRotation(int); void setZoom(int); void setGamma(double); void setInvertLuminance(bool); void setWhite(QColor); void setScreenDpi(int); void setDisplayMode(DisplayMode m); void setDisplayFrame(bool); void setHorizAlign(Align); void setVertAlign(Align); void setContinuous(bool); void setSideBySide(bool); void setCoverPage(bool); void setRightToLeft(bool); void setBorderBrush(QBrush); void setBorderSize(int); void setSeparatorSize(int); void setContextMenu(QMenu*); void setDisplayMapAreas(bool); void setPixelCacheSize(int); void enableKeyboard(bool); void enableMouse(bool); void enableHyperlink(bool); void enableAnimation(bool); void terminateAnimation(void); void setMouseWheelZoom(bool); void setLensPower(int); void setLensSize(int); void setHourGlassRatio(double ratio); void setModifiersForLens(Qt::KeyboardModifiers); void setModifiersForSelect(Qt::KeyboardModifiers); void setModifiersForLinks(Qt::KeyboardModifiers); void reduceOptionsToPriority(Priority); public: QString pastErrorMessage(int n=0); QString pastInfoMessage(int n=0); bool startSelecting(const QPoint &point); bool startPanning(const QPoint &point); bool startLensing(const QPoint &point); bool startLinking(const QPoint &point); bool stopInteraction(void); QString linkUrl(void); QString linkTarget(void); QString linkComment(void); QString getTextForRect(const QRect &rect); bool getTextForPointer(QString results[]); QImage getImageForRect(const QRect &rect); QRect getSegmentForRect(const QRect &rect, int pageNo); bool pageSizeKnown(int pageno) const; void clearHighlights(int pageno); void addHighlight(int pageno, int x, int y, int w, int h, QColor color, bool rc=false); protected: virtual bool event(QEvent *event); virtual bool viewportEvent (QEvent *event); virtual void scrollContentsBy(int dx, int dy); virtual void resizeEvent(QResizeEvent *event); virtual void keyPressEvent(QKeyEvent *event); virtual void modifierEvent(Qt::KeyboardModifiers, Qt::MouseButtons, QPoint); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void contextMenuEvent (QContextMenuEvent *event); virtual void wheelEvent(QWheelEvent *e); virtual void gestureEvent(QEvent *e); virtual void paintEvent(QPaintEvent *event); virtual void chooseTooltip(void); virtual void paintDesk(QPainter &p, const QRegion ®ion); virtual void paintFrame(QPainter &p, const QRect &rect, int width); virtual void paintEmpty(QPainter &p, const QRect &rect, bool, bool, bool); public slots: void nextPage(void); void prevPage(void); void firstPage(void); void lastPage(void); void moveToPageTop(void); void moveToPageBottom(void); void readNext(void); void readPrev(void); void zoomIn(void); void zoomOut(void); void zoomRect(QRect rect); void displayModeColor(void); void displayModeStencil(void); void displayModeBackground(void); void displayModeForeground(void); void displayModeText(void); void rotateRight(void); void rotateLeft(void); signals: void layoutChanged(); void pageChanged(int pageno); void pointerPosition(const Position &pos, const PageInfo &page); void pointerEnter(const Position &pos, miniexp_t maparea); void pointerLeave(const Position &pos, miniexp_t maparea); void pointerClick(const Position &pos, miniexp_t maparea); void pointerSelect(const QPoint &pointerPos, const QRect &rect); void errorCondition(int pageno); void stopCondition(int pageno); void keyPressSignal(QKeyEvent *event, bool &done); void error(QString message, QString filename, int lineno); void info(QString message); private: QDjVuPrivate *priv; friend class QDjVuPrivate; friend class QDjVuLens; }; #endif /* ------------------------------------------------------------- Local Variables: c++-font-lock-extra-types: ( "\\sw+_t" "[A-Z]\\sw*[a-z]\\sw*" ) End: ------------------------------------------------------------- */ djview4-4.10.5/src/qdjvuwidget.qrc000066400000000000000000000004741264256014000170150ustar00rootroot00000000000000 images/djvu_wait.png images/djvu_fail.png images/djvu_stop.png images/djvu_logo.png images/cursor_hand_closed.png images/cursor_hand_open.png djview4-4.10.5/src/tiff2pdf.c000066400000000000000000004755241264256014000156350ustar00rootroot00000000000000/* -*- C -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006 Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ // // The following code is derived from program "tiff2pdf" // whose copyright notice is reproduced below. // Changes were made to make it independent from the private // include file tiffiop.h. */ /* $Id: tiff2pdf.c,v 1.37.2.7 2009-01-01 00:10:43 bfriesen Exp $ * * tiff2pdf - converts a TIFF image to a PDF document * * Copyright (c) 2003 Ross Finlayson * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the name of * Ross Finlayson may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Ross Finlayson. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL ROSS FINLAYSON BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiff2pdf.h" #ifdef HAVE_TIFF2PDF #include #include #include #include #include #if HAVE_UNISTD_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_GETOPT_H # include #endif #if defined(__GNUC__) || defined(HAVE_LONG_LONG_INT) # define uint64 unsigned long long #elif defined(_MSC_VER) # define uint64 unsigned __int64 #else # define uint64 size_t #endif #ifndef HAVE_GETOPT_H /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ static int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ optopt, /* character checked for validity */ optreset; /* reset getopt */ static char *optarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" /* * getopt -- * Parse argc/argv argument vector. */ static int getopt(int argc, char * const argv[], const char *optstring) { static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ if (optreset || *place == 0) { /* update scanning pointer */ optreset = 0; place = argv[optind]; if (optind >= argc || *place++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } optopt = *place++; if (optopt == '-' && *place == 0) { /* "--" => end of options */ ++optind; place = EMSG; return (-1); } if (optopt == 0) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ place = EMSG; if (strchr(optstring, '-') == NULL) return -1; optopt = '-'; } } else optopt = *place++; /* See if option letter is one the caller wanted... */ if (optopt == ':' || (oli = strchr(optstring, optopt)) == NULL) { if (*place == 0) ++optind; if (opterr && *optstring != ':') (void)fprintf(stderr, "unknown option -- %c\n", optopt); return (BADCH); } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ optarg = NULL; if (*place == 0) ++optind; } else { /* Option-argument is either the rest of this argument or the entire next argument. */ if (*place) optarg = place; else if (argc > ++optind) optarg = argv[optind]; else { /* option-argument absent */ place = EMSG; if (*optstring == ':') return (BADARG); if (opterr) (void)fprintf(stderr, "option requires an argument -- %c\n", optopt); return (BADCH); } place = EMSG; ++optind; } return (optopt); /* return option letter */ } #endif #define TIFF2PDF_MODULE "tiff2pdf" #define PS_UNIT_SIZE 72.0F /* This type is of PDF color spaces. */ typedef enum { T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */ T2P_CS_GRAY = 0x02, /* Single channel */ T2P_CS_RGB = 0x04, /* Three channel tristimulus RGB */ T2P_CS_CMYK = 0x08, /* Four channel CMYK print inkset */ T2P_CS_LAB = 0x10, /* Three channel L*a*b* color space */ T2P_CS_PALETTE = 0x1000,/* One of the above with a color map */ T2P_CS_CALGRAY = 0x20, /* Calibrated single channel */ T2P_CS_CALRGB = 0x40, /* Calibrated three channel tristimulus RGB */ T2P_CS_ICCBASED = 0x80 /* ICC profile color specification */ } t2p_cs_t; /* This type is of PDF compression types. */ typedef enum{ T2P_COMPRESS_NONE=0x00 #ifdef CCITT_SUPPORT , T2P_COMPRESS_G4=0x01 #endif #if defined(JPEG_SUPPORT) || defined(OJPEG_SUPPORT) , T2P_COMPRESS_JPEG=0x02 #endif #ifdef ZIP_SUPPORT , T2P_COMPRESS_ZIP=0x04 #endif } t2p_compress_t; /* This type is whether TIFF image data can be used in PDF without transcoding. */ typedef enum{ T2P_TRANSCODE_RAW=0x01, /* The raw data from the input can be used without recompressing */ T2P_TRANSCODE_ENCODE=0x02 /* The data from the input is perhaps unencoded and reencoded */ } t2p_transcode_t; /* This type is of information about the data samples of the input image. */ typedef enum{ T2P_SAMPLE_NOTHING=0x0000, /* The unencoded samples are normal for the output colorspace */ T2P_SAMPLE_ABGR_TO_RGB=0x0001, /* The unencoded samples are the result of ReadRGBAImage */ T2P_SAMPLE_RGBA_TO_RGB=0x0002, /* The unencoded samples are contiguous RGBA */ T2P_SAMPLE_RGBAA_TO_RGB=0x0004, /* The unencoded samples are RGBA with premultiplied alpha */ T2P_SAMPLE_YCBCR_TO_RGB=0x0008, T2P_SAMPLE_YCBCR_TO_LAB=0x0010, T2P_SAMPLE_REALIZE_PALETTE=0x0020, /* The unencoded samples are indexes into the color map */ T2P_SAMPLE_SIGNED_TO_UNSIGNED=0x0040, /* The unencoded samples are signed instead of unsignd */ T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED=0x0040, /* The L*a*b* samples have a* and b* signed */ T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG=0x0100 /* The unencoded samples are separate instead of contiguous */ } t2p_sample_t; /* This type is of error status of the T2P struct. */ typedef enum{ T2P_ERR_OK = 0, /* This is the value of t2p->t2p_error when there is no error */ T2P_ERR_ERROR = 1 /* This is the value of t2p->t2p_error when there was an error */ } t2p_err_t; /* This struct defines a logical page of a TIFF. */ typedef struct { tdir_t page_directory; uint32 page_number; ttile_t page_tilecount; uint32 page_extra; } T2P_PAGE; /* This struct defines a PDF rectangle's coordinates. */ typedef struct { float x1; float y1; float x2; float y2; float mat[9]; } T2P_BOX; /* This struct defines a tile of a PDF. */ typedef struct { T2P_BOX tile_box; } T2P_TILE; /* This struct defines information about the tiles on a PDF page. */ typedef struct { ttile_t tiles_tilecount; uint32 tiles_tilewidth; uint32 tiles_tilelength; uint32 tiles_tilecountx; uint32 tiles_tilecounty; uint32 tiles_edgetilewidth; uint32 tiles_edgetilelength; T2P_TILE* tiles_tiles; } T2P_TILES; /* This struct is the context of a function to generate PDF from a TIFF. */ typedef struct { t2p_err_t t2p_error; T2P_PAGE* tiff_pages; T2P_TILES* tiff_tiles; tdir_t tiff_pagecount; uint16 tiff_compression; uint16 tiff_photometric; uint16 tiff_fillorder; uint16 tiff_bitspersample; uint16 tiff_samplesperpixel; uint16 tiff_planar; uint32 tiff_width; uint32 tiff_length; float tiff_xres; float tiff_yres; uint16 tiff_orientation; toff_t tiff_dataoffset; tsize_t tiff_datasize; uint16 tiff_resunit; uint16 pdf_centimeters; uint16 pdf_overrideres; uint16 pdf_overridepagesize; float pdf_defaultxres; float pdf_defaultyres; float pdf_xres; float pdf_yres; float pdf_defaultpagewidth; float pdf_defaultpagelength; float pdf_pagewidth; float pdf_pagelength; float pdf_imagewidth; float pdf_imagelength; T2P_BOX pdf_mediabox; T2P_BOX pdf_imagebox; uint16 pdf_majorversion; uint16 pdf_minorversion; uint32 pdf_catalog; uint32 pdf_pages; uint32 pdf_info; uint32 pdf_palettecs; uint16 pdf_fitwindow; uint32 pdf_startxref; unsigned char* pdf_fileid; unsigned char* pdf_datetime; unsigned char* pdf_creator; unsigned char* pdf_author; unsigned char* pdf_title; unsigned char* pdf_subject; unsigned char* pdf_keywords; t2p_cs_t pdf_colorspace; uint16 pdf_colorspace_invert; uint16 pdf_switchdecode; uint16 pdf_palettesize; unsigned char* pdf_palette; int pdf_labrange[4]; t2p_compress_t pdf_defaultcompression; uint16 pdf_defaultcompressionquality; t2p_compress_t pdf_compression; uint16 pdf_compressionquality; uint16 pdf_nopassthrough; t2p_transcode_t pdf_transcode; t2p_sample_t pdf_sample; uint32* pdf_xrefoffsets; uint32 pdf_xrefcount; tdir_t pdf_page; #ifdef OJPEG_SUPPORT tdata_t pdf_ojpegdata; uint32 pdf_ojpegdatalength; uint32 pdf_ojpegiflength; #endif float tiff_whitechromaticities[2]; float tiff_primarychromaticities[6]; float tiff_referenceblackwhite[2]; float* tiff_transferfunction[3]; int pdf_image_interpolate; /* 0 (default) : do not interpolate, 1 : interpolate */ uint16 tiff_transferfunctioncount; uint32 pdf_icccs; uint32 tiff_iccprofilelength; tdata_t tiff_iccprofile; /* fields for custom read/write procedures */ FILE *outputfile; int outputdisable; tsize_t outputwritten; } T2P; /* These functions are called by main. */ static int tiff2pdf_match_paper_size(float*, float*, char*); /* These functions are used to generate a PDF from a TIFF. */ #ifdef __cplusplus extern "C" { #endif static T2P* t2p_init(void); static void t2p_validate(T2P*); static tsize_t t2p_write_pdf(T2P*, TIFF*, TIFF*); static void t2p_free(T2P*); #ifdef __cplusplus } #endif static void t2p_read_tiff_init(T2P*, TIFF*); static int t2p_cmp_t2p_page(const void*, const void*); static void t2p_read_tiff_data(T2P*, TIFF*); static void t2p_read_tiff_size(T2P*, TIFF*); static void t2p_read_tiff_size_tile(T2P*, TIFF*, ttile_t); static int t2p_tile_is_right_edge(T2P_TILES, ttile_t); static int t2p_tile_is_bottom_edge(T2P_TILES, ttile_t); /* static int t2p_tile_is_edge(T2P_TILES, ttile_t); */ /* static int t2p_tile_is_corner_edge(T2P_TILES, ttile_t); */ static tsize_t t2p_readwrite_pdf_image(T2P*, TIFF*, TIFF*); static tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t); #ifdef OJPEG_SUPPORT static int t2p_process_ojpeg_tables(T2P*, TIFF*); #endif #ifdef JPEG_SUPPORT static int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t*, tstrip_t, uint32); #endif static void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32); static void t2p_write_advance_directory(T2P*, TIFF*); static tsize_t t2p_sample_planar_separate_to_contig(T2P*, unsigned char*, unsigned char*, tsize_t); static tsize_t t2p_sample_realize_palette(T2P*, unsigned char*); static tsize_t t2p_sample_abgr_to_rgb(tdata_t, uint32); static tsize_t t2p_sample_rgba_to_rgb(tdata_t, uint32); static tsize_t t2p_sample_rgbaa_to_rgb(tdata_t, uint32); static tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t, uint32); static tsize_t t2p_write_pdf_header(T2P*, TIFF*); static tsize_t t2p_write_pdf_obj_start(uint32, TIFF*); static tsize_t t2p_write_pdf_obj_end(TIFF*); /* static tsize_t t2p_write_pdf_name(unsigned char*, TIFF*); */ static tsize_t t2p_write_pdf_string(unsigned char*, TIFF*); static tsize_t t2p_write_pdf_stream(tdata_t, tsize_t, TIFF*); static tsize_t t2p_write_pdf_stream_start(TIFF*); static tsize_t t2p_write_pdf_stream_end(TIFF*); static tsize_t t2p_write_pdf_stream_dict(tsize_t, uint32, TIFF*); static tsize_t t2p_write_pdf_stream_dict_start(TIFF*); static tsize_t t2p_write_pdf_stream_dict_end(TIFF*); static tsize_t t2p_write_pdf_stream_length(tsize_t, TIFF*); static tsize_t t2p_write_pdf_catalog(T2P*, TIFF*); static tsize_t t2p_write_pdf_info(T2P*, TIFF*, TIFF*); static void t2p_pdf_currenttime(T2P*); static void t2p_pdf_tifftime(T2P*, TIFF*); static tsize_t t2p_write_pdf_pages(T2P*, TIFF*); static tsize_t t2p_write_pdf_page(uint32, T2P*, TIFF*); static void t2p_compose_pdf_page(T2P*); static void t2p_compose_pdf_page_orient(T2P_BOX*, uint16); static void t2p_compose_pdf_page_orient_flip(T2P_BOX*, uint16); /* static tsize_t t2p_write_pdf_page_content(T2P*, TIFF*); */ static tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t, T2P*, TIFF*); static tsize_t t2p_write_pdf_xobject_cs(T2P*, TIFF*); static tsize_t t2p_write_pdf_transfer(T2P*, TIFF*); static tsize_t t2p_write_pdf_transfer_dict(T2P*, TIFF*, uint16); static tsize_t t2p_write_pdf_transfer_stream(T2P*, TIFF*, uint16); static tsize_t t2p_write_pdf_xobject_calcs(T2P*, TIFF*); static tsize_t t2p_write_pdf_xobject_icccs(T2P*, TIFF*); static tsize_t t2p_write_pdf_xobject_icccs_dict(T2P*, TIFF*); static tsize_t t2p_write_pdf_xobject_icccs_stream(T2P*, TIFF*); /* static tsize_t t2p_write_pdf_xobject_cs_stream(T2P*, TIFF*); */ static tsize_t t2p_write_pdf_xobject_decode(T2P*, TIFF*); static tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t, T2P*, TIFF*); static tsize_t t2p_write_pdf_xreftable(T2P*, TIFF*); static tsize_t t2p_write_pdf_trailer(T2P*, TIFF*); static void t2p_disable(TIFF *tif) { T2P *t2p = (T2P*) TIFFClientdata(tif); t2p->outputdisable = 1; } static void t2p_enable(TIFF *tif) { T2P *t2p = (T2P*) TIFFClientdata(tif); t2p->outputdisable = 0; } /* * Procs for TIFFClientOpen */ static tsize_t t2pReadFile(TIFF *tif, tdata_t data, tsize_t size) { thandle_t client = TIFFClientdata(tif); TIFFReadWriteProc proc = TIFFGetReadProc(tif); if (proc) return proc(client, data, size); return -1; } static tsize_t t2pWriteFile(TIFF *tif, tdata_t data, tsize_t size) { thandle_t client = TIFFClientdata(tif); TIFFReadWriteProc proc = TIFFGetWriteProc(tif); if (proc) return proc(client, data, size); return -1; } static toff_t t2pSeekFile(TIFF *tif, toff_t offset, int whence) { thandle_t client = TIFFClientdata(tif); TIFFSeekProc proc = TIFFGetSeekProc(tif); if (proc) return proc(client, offset, whence); return -1; } static tsize_t t2p_readproc(thandle_t handle, tdata_t data, tsize_t size) { (void) handle, (void) data, (void) size; return -1; } static tsize_t t2p_writeproc(thandle_t handle, tdata_t data, tsize_t size) { T2P *t2p = (T2P*) handle; if (t2p->outputdisable <= 0 && t2p->outputfile) { tsize_t written = fwrite(data, 1, size, t2p->outputfile); t2p->outputwritten += written; return written; } return size; } static toff_t t2p_seekproc(thandle_t handle, toff_t offset, int whence) { T2P *t2p = (T2P*) handle; if (t2p->outputdisable <= 0 && t2p->outputfile) return fseek(t2p->outputfile, offset, whence); return offset; } static int t2p_closeproc(thandle_t handle) { (void) handle; return 0; } static toff_t t2p_sizeproc(thandle_t handle) { (void) handle; return -1; } static int t2p_mapproc(thandle_t handle, tdata_t *data, toff_t *offset) { (void) handle, (void) data, (void) offset; return -1; } static void t2p_unmapproc(thandle_t handle, tdata_t data, toff_t offset) { (void) handle, (void) data, (void) offset; } static uint64 checkAdd64(uint64 summand1, uint64 summand2, T2P* t2p) { uint64 bytes = summand1 + summand2; if (bytes - summand1 != summand2) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; bytes = 0; } return bytes; } static uint64 checkMultiply64(uint64 first, uint64 second, T2P* t2p) { uint64 bytes = first * second; if (second && bytes / second != first) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; bytes = 0; } return bytes; } /* This is the main function. The program converts one TIFF file to one PDF file, including multiple page TIFF files, tiled TIFF files, black and white. grayscale, and color TIFF files that contain data of TIFF photometric interpretations of bilevel, grayscale, RGB, YCbCr, CMYK separation, and ICC L*a*b* as supported by libtiff and PDF. If you have multiple TIFF files to convert into one PDF file then use tiffcp or other program to concatenate the files into a multiple page TIFF file. If the input TIFF file is of huge dimensions (greater than 10000 pixels height or width) convert the input image to a tiled TIFF if it is not already. The standard output is standard output. Set the output file name with the "-o output.pdf" option. All black and white files are compressed into a single strip CCITT G4 Fax compressed PDF, unless tiled, where tiled black and white images are compressed into tiled CCITT G4 Fax compressed PDF, libtiff CCITT support is assumed. Color and grayscale data can be compressed using either JPEG compression, ITU-T T.81, or Zip/Deflate LZ77 compression, per PNG 1.2 and RFC 1951. Set the compression type using the -j or -z options. JPEG compression support requires that libtiff be configured with JPEG support, and Zip/Deflate compression support requires that libtiff is configured with Zip support, in tiffconf.h. Use only one or the other of -j and -z. The -q option sets the image compression quality, that is 1-100 with libjpeg JPEG compression and one of 1, 10, 11, 12, 13, 14, or 15 for PNG group compression predictor methods, add 100, 200, ..., 900 to set zlib compression quality 1-9. PNG Group differencing predictor methods are not currently implemented. If the input TIFF contains single strip CCITT G4 Fax compressed information, then that is written to the PDF file without transcoding, unless the options of no compression and no passthrough are set, -d and -n. If the input TIFF contains JPEG or single strip Zip/Deflate compressed information, and they are configured, then that is written to the PDF file without transcoding, unless the options of no compression and no passthrough are set. The default page size upon which the TIFF image is placed is determined by the resolution and extent of the image data. Default values for the TIFF image resolution can be set using the -x and -y options. The page size can be set using the -p option for paper size, or -w and -l for paper width and length, then each page of the TIFF image is centered on its page. The distance unit for default resolution and page width and length can be set by the -u option, the default unit is inch. Various items of the output document information can be set with the -e, -c, -a, -t, -s, and -k tags. Setting the argument of the option to "" for these tags causes the relevant document information field to be not written. Some of the document information values otherwise get their information from the input TIFF image, the software, author, document name, and image description. The output PDF file conforms to the PDF 1.1 specification or PDF 1.2 if using Zip/Deflate compression. The Portable Document Format (PDF) specification is copyrighted by Adobe Systems, Incorporated. Todos derechos reservados. Here is a listing of the usage example and the options to the tiff2pdf program that is part of the libtiff distribution. Options followed by a colon have a required argument. usage: tiff2pdf [options] input.tif options: -o: output to file name -j: compress with JPEG (requires libjpeg configured with libtiff) -z: compress with Zip/Deflate (requires zlib configured with libtiff) -q: compression quality -n: no compressed data passthrough -d: do not compress (decompress) -i: invert colors -u: set distance unit, 'i' for inch, 'm' for centimeter -x: set x resolution default -y: set y resolution default -w: width in units -l: length in units -r: 'd' for resolution default, 'o' for resolution override -p: paper size, eg "letter", "legal", "a4" -f: set pdf "fit window" user preference -b: set PDF "Interpolate" user preference -e: date, overrides image or current date/time default, YYYYMMDDHHMMSS -c: creator, overrides image software default -a: author, overrides image artist default -t: title, overrides image document name default -s: subject, overrides image image description default -k: keywords -h: usage examples: tiff2pdf -o output.pdf input.tiff The above example would generate the file output.pdf from input.tiff. tiff2pdf input.tiff The above example would generate PDF output from input.tiff and write it to standard output. tiff2pdf -j -p letter -o output.pdf input.tiff The above example would generate the file output.pdf from input.tiff, putting the image pages on a letter sized page, compressing the output with JPEG. Please report bugs through: http://bugzilla.remotesensing.org/buglist.cgi?product=libtiff See also libtiff.3t, tiffcp. */ int tiff2pdf(TIFF *input, FILE *outputfile, int argc, const char **argv) { char *outfilename = ""; T2P *t2p = NULL; TIFF *output = NULL; tsize_t written = 0; int c; (void)written; t2p = t2p_init(); if (t2p == NULL){ TIFFError(TIFF2PDF_MODULE, "Can't initialize context"); goto fail; } while (argv && (c = getopt(argc, (void*)argv, "o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbh")) != -1){ switch (c) { case 'o': outfilename = optarg; break; #ifdef JPEG_SUPPORT case 'j': t2p->pdf_defaultcompression=T2P_COMPRESS_JPEG; break; #endif #ifndef JPEG_SUPPORT case 'j': TIFFWarning( TIFF2PDF_MODULE, "JPEG support in libtiff required for JPEG compression, ignoring option"); break; #endif #ifdef ZIP_SUPPORT case 'z': t2p->pdf_defaultcompression=T2P_COMPRESS_ZIP; break; #endif #ifndef ZIP_SUPPORT case 'z': TIFFWarning( TIFF2PDF_MODULE, "Zip support in libtiff required for Zip compression, ignoring option"); break; #endif case 'q': t2p->pdf_defaultcompressionquality=atoi(optarg); break; case 'n': t2p->pdf_nopassthrough=1; break; case 'd': t2p->pdf_defaultcompression=T2P_COMPRESS_NONE; break; case 'u': if(optarg[0]=='m'){ t2p->pdf_centimeters=1; } break; case 'x': t2p->pdf_defaultxres = (float)atof(optarg) / (t2p->pdf_centimeters?2.54F:1.0F); break; case 'y': t2p->pdf_defaultyres = (float)atof(optarg) / (t2p->pdf_centimeters?2.54F:1.0F); break; case 'w': t2p->pdf_overridepagesize=1; t2p->pdf_defaultpagewidth = ((float)atof(optarg) * PS_UNIT_SIZE) / (t2p->pdf_centimeters?2.54F:1.0F); break; case 'l': t2p->pdf_overridepagesize=1; t2p->pdf_defaultpagelength = ((float)atof(optarg) * PS_UNIT_SIZE) / (t2p->pdf_centimeters?2.54F:1.0F); break; case 'r': if(optarg[0]=='o'){ t2p->pdf_overrideres=1; } break; case 'p': if(tiff2pdf_match_paper_size( &(t2p->pdf_defaultpagewidth), &(t2p->pdf_defaultpagelength), optarg)){ t2p->pdf_overridepagesize=1; } else { TIFFWarning(TIFF2PDF_MODULE, "Unknown paper size %s, ignoring option", optarg); } break; case 'i': t2p->pdf_colorspace_invert=1; break; case 'f': t2p->pdf_fitwindow=1; break; case 'e': t2p->pdf_datetime = (unsigned char*)_TIFFmalloc(17); if(t2p->pdf_datetime==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for main", 17); goto fail; } if(strlen(optarg)==0){ t2p->pdf_datetime[0] = 0; } else { if(strlen(optarg)>14){optarg[14]=0;} t2p->pdf_datetime[0] = 'D'; t2p->pdf_datetime[1] = ':'; strcpy((char *)t2p->pdf_datetime + 2, optarg); } break; case 'c': t2p->pdf_creator = (unsigned char *) _TIFFmalloc(strlen(optarg) + 1); if(t2p->pdf_creator==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for main", (long)strlen(optarg) + 1); goto fail; } strcpy((char *)t2p->pdf_creator, optarg); t2p->pdf_creator[strlen(optarg)] = 0; break; case 'a': t2p->pdf_author = (unsigned char *) _TIFFmalloc(strlen(optarg) + 1); if(t2p->pdf_author==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for main", (long)strlen(optarg) + 1); goto fail; } strcpy((char *)t2p->pdf_author, optarg); t2p->pdf_author[strlen(optarg)]=0; break; case 't': t2p->pdf_title = (unsigned char*) _TIFFmalloc(strlen(optarg)+1); if(t2p->pdf_title==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for main", (long)strlen(optarg) + 1); goto fail; } strcpy((char *)t2p->pdf_title, optarg); t2p->pdf_title[strlen(optarg)] = 0; break; case 's': t2p->pdf_subject = (unsigned char*) _TIFFmalloc(strlen(optarg) + 1); if(t2p->pdf_subject==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for main", (long)strlen(optarg)+1); goto fail; } strcpy((char *)t2p->pdf_subject, optarg); t2p->pdf_subject[strlen(optarg)]=0; break; case 'k': t2p->pdf_keywords = (unsigned char*) _TIFFmalloc(strlen(optarg) + 1); if(t2p->pdf_keywords==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for main", (long)strlen(optarg) + 1); goto fail; } strcpy((char *)t2p->pdf_keywords, optarg); t2p->pdf_keywords[strlen(optarg)] = 0; break; case 'b': t2p->pdf_image_interpolate = 1; break; } } /* * Output */ t2p->outputdisable = 0; t2p->outputfile = outputfile; output = TIFFClientOpen(outfilename, "w", (thandle_t) t2p, t2p_readproc, t2p_writeproc, t2p_seekproc, t2p_closeproc, t2p_sizeproc, t2p_mapproc, t2p_unmapproc ); if (output == NULL) { TIFFError(TIFF2PDF_MODULE, "Can't initialize output descriptor"); goto fail; } /* * Validate */ t2p_validate(t2p); t2pSeekFile(output, (toff_t) 0, SEEK_SET); /* * Write */ written = t2p_write_pdf(t2p, input, output); if (t2p->t2p_error != 0) { TIFFError(TIFF2PDF_MODULE, "An error occurred creating output PDF file"); goto fail; } /* success: */ if (output != NULL) TIFFClose(output); if (t2p != NULL) t2p_free(t2p); return(EXIT_SUCCESS); fail: if(input != NULL) TIFFClose(input); if (output != NULL) TIFFClose(output); if (t2p != NULL) t2p_free(t2p); return(EXIT_FAILURE); } static int tiff2pdf_match_paper_size(float* width, float* length, char* papersize){ size_t i, len; const char* sizes[]={ "LETTER", "A4", "LEGAL", "EXECUTIVE", "LETTER", "LEGAL", "LEDGER", "TABLOID", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "A10", "A9", "A8", "A7", "A6", "A5", "A4", "A3", "A2", "A1", "A0", "2A0", "4A0", "2A", "4A", "B10", "B9", "B8", "B7", "B6", "B5", "B4", "B3", "B2", "B1", "B0", "JISB10", "JISB9", "JISB8", "JISB7", "JISB6", "JISB5", "JISB4", "JISB3", "JISB2", "JISB1", "JISB0", "C10", "C9", "C8", "C7", "C6", "C5", "C4", "C3", "C2", "C1", "C0", "RA2", "RA1", "RA0", "SRA4", "SRA3", "SRA2", "SRA1", "SRA0", "A3EXTRA", "A4EXTRA", "STATEMENT", "FOLIO", "QUARTO", NULL } ; const int widths[]={ 612, 595, 612, 522, 612,612,792,792, 612,792,1224,1584,2448,2016,792,2016,2448,2880, 74,105,147,210,298,420,595,842,1191,1684,2384,3370,4768,3370,4768, 88,125,176,249,354,499,709,1001,1417,2004,2835, 91,128,181,258,363,516,729,1032,1460,2064,2920, 79,113,162,230,323,459,649,918,1298,1298,2599, 1219,1729,2438,638,907,1276,1814,2551, 914,667, 396, 612, 609, 0 }; const int lengths[]={ 792,842,1008, 756,792,1008,1224,1224, 792,1224,1584,2448,3168,2880,6480,10296,12672,10296, 105,147,210,298,420,595,842,1191,1684,2384,3370,4768,6741,4768,6741, 125,176,249,354,499,709,1001,1417,2004,2835,4008, 128,181,258,363,516,729,1032,1460,2064,2920,4127, 113,162,230,323,459,649,918,1298,1837,1837,3677, 1729,2438,3458,907,1276,1814,2551,3628, 1262,914, 612, 936, 780, 0 }; len=strlen(papersize); for(i=0;ipdf_majorversion=1; t2p->pdf_minorversion=1; t2p->pdf_defaultxres=300.0; t2p->pdf_defaultyres=300.0; t2p->pdf_defaultpagewidth=612.0; t2p->pdf_defaultpagelength=792.0; t2p->pdf_xrefcount=3; /* Catalog, Info, Pages */ return(t2p); } /* This function frees a T2P context struct pointer and any allocated data fields of it. */ static void t2p_free(T2P* t2p){ int i=0; if(t2p != NULL){ if(t2p->pdf_xrefoffsets != NULL){ _TIFFfree( (tdata_t) t2p->pdf_xrefoffsets); } if(t2p->tiff_pages != NULL){ _TIFFfree( (tdata_t) t2p->tiff_pages); } for(i=0;itiff_pagecount;i++){ if(t2p->tiff_tiles[i].tiles_tiles != NULL){ _TIFFfree( (tdata_t) t2p->tiff_tiles[i].tiles_tiles); } } if(t2p->tiff_tiles != NULL){ _TIFFfree( (tdata_t) t2p->tiff_tiles); } if(t2p->pdf_palette != NULL){ _TIFFfree( (tdata_t) t2p->pdf_palette); } if(t2p->pdf_fileid != NULL){ _TIFFfree( (tdata_t) t2p->pdf_fileid); } if(t2p->pdf_datetime != NULL){ _TIFFfree( (tdata_t) t2p->pdf_datetime); } if(t2p->pdf_creator != NULL){ _TIFFfree( (tdata_t) t2p->pdf_creator); } if(t2p->pdf_author != NULL){ _TIFFfree( (tdata_t) t2p->pdf_author); } if(t2p->pdf_title != NULL){ _TIFFfree( (tdata_t) t2p->pdf_title); } if(t2p->pdf_subject != NULL){ _TIFFfree( (tdata_t) t2p->pdf_subject); } if(t2p->pdf_keywords != NULL){ _TIFFfree( (tdata_t) t2p->pdf_keywords); } #ifdef OJPEG_SUPPORT if(t2p->pdf_ojpegdata != NULL){ _TIFFfree( (tdata_t) t2p->pdf_ojpegdata); } #endif _TIFFfree( (tdata_t) t2p ); } return; } /* This function validates the values of a T2P context struct pointer before calling t2p_write_pdf with it. */ static void t2p_validate(T2P* t2p){ #ifdef JPEG_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_JPEG){ if(t2p->pdf_defaultcompressionquality>100 || t2p->pdf_defaultcompressionquality<1){ t2p->pdf_defaultcompressionquality=0; } } #endif #ifdef ZIP_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_ZIP){ uint16 m=t2p->pdf_defaultcompressionquality%100; if(t2p->pdf_defaultcompressionquality/100 > 9 || (m>1 && m<10) || m>15){ t2p->pdf_defaultcompressionquality=0; } if(t2p->pdf_defaultcompressionquality%100 !=0){ t2p->pdf_defaultcompressionquality/=100; t2p->pdf_defaultcompressionquality*=100; TIFFError( TIFF2PDF_MODULE, "PNG Group predictor differencing not implemented, assuming compression quality %u", t2p->pdf_defaultcompressionquality); } t2p->pdf_defaultcompressionquality%=100; if(t2p->pdf_minorversion<2){t2p->pdf_minorversion=2;} } #endif (void)0; return; } /* This function scans the input TIFF file for pages. It attempts to determine which IFD's of the TIFF file contain image document pages. For each, it gathers some information that has to do with the output of the PDF document as a whole. */ static void t2p_read_tiff_init(T2P* t2p, TIFF* input){ tdir_t directorycount=0; tdir_t i=0; uint16 pagen=0; uint16 paged=0; uint16 xuint16=0; directorycount=TIFFNumberOfDirectories(input); t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(directorycount * sizeof(T2P_PAGE)); if(t2p->tiff_pages==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for tiff_pages array, %s", directorycount * (long)sizeof(T2P_PAGE), TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } _TIFFmemset( t2p->tiff_pages, 0x00, directorycount * sizeof(T2P_PAGE)); t2p->tiff_tiles = (T2P_TILES*) _TIFFmalloc(directorycount * sizeof(T2P_TILES)); if(t2p->tiff_tiles==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for tiff_tiles array, %s", directorycount * (long)sizeof(T2P_TILES), TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } _TIFFmemset( t2p->tiff_tiles, 0x00, directorycount * sizeof(T2P_TILES)); for(i=0;it2p_error = T2P_ERR_ERROR; return; } if(TIFFGetField(input, TIFFTAG_PAGENUMBER, &pagen, &paged)){ if((pagen>paged) && (paged != 0)){ t2p->tiff_pages[t2p->tiff_pagecount].page_number = paged; } else { t2p->tiff_pages[t2p->tiff_pagecount].page_number = pagen; } goto ispage2; } if(TIFFGetField(input, TIFFTAG_SUBFILETYPE, &subfiletype)){ if ( ((subfiletype & FILETYPE_PAGE) != 0) || (subfiletype == 0)){ goto ispage; } else { goto isnotpage; } } if(TIFFGetField(input, TIFFTAG_OSUBFILETYPE, &subfiletype)){ if ((subfiletype == OFILETYPE_IMAGE) || (subfiletype == OFILETYPE_PAGE) || (subfiletype == 0) ){ goto ispage; } else { goto isnotpage; } } ispage: t2p->tiff_pages[t2p->tiff_pagecount].page_number=t2p->tiff_pagecount; ispage2: t2p->tiff_pages[t2p->tiff_pagecount].page_directory=i; if(TIFFIsTiled(input)){ t2p->tiff_pages[t2p->tiff_pagecount].page_tilecount = TIFFNumberOfTiles(input); } t2p->tiff_pagecount++; isnotpage: (void)0; } qsort((void*) t2p->tiff_pages, t2p->tiff_pagecount, sizeof(T2P_PAGE), t2p_cmp_t2p_page); for(i=0;itiff_pagecount;i++){ t2p->pdf_xrefcount += 5; TIFFSetDirectory(input, t2p->tiff_pages[i].page_directory ); if((TIFFGetField(input, TIFFTAG_PHOTOMETRIC, &xuint16) && (xuint16==PHOTOMETRIC_PALETTE)) || TIFFGetField(input, TIFFTAG_INDEXED, &xuint16)) { t2p->tiff_pages[i].page_extra++; t2p->pdf_xrefcount++; } #ifdef ZIP_SUPPORT if (TIFFGetField(input, TIFFTAG_COMPRESSION, &xuint16)) { if( (xuint16== COMPRESSION_DEFLATE || xuint16== COMPRESSION_ADOBE_DEFLATE) && ((t2p->tiff_pages[i].page_tilecount != 0) || TIFFNumberOfStrips(input)==1) && (t2p->pdf_nopassthrough==0) ){ if(t2p->pdf_minorversion<2){t2p->pdf_minorversion=2;} } } #endif if (TIFFGetField(input, TIFFTAG_TRANSFERFUNCTION, &(t2p->tiff_transferfunction[0]), &(t2p->tiff_transferfunction[1]), &(t2p->tiff_transferfunction[2]))) { if(t2p->tiff_transferfunction[1] != t2p->tiff_transferfunction[0]) { t2p->tiff_transferfunctioncount = 3; t2p->tiff_pages[i].page_extra += 4; t2p->pdf_xrefcount += 4; } else { t2p->tiff_transferfunctioncount = 1; t2p->tiff_pages[i].page_extra += 2; t2p->pdf_xrefcount += 2; } if(t2p->pdf_minorversion < 2) t2p->pdf_minorversion = 2; } else { t2p->tiff_transferfunctioncount=0; } if( TIFFGetField( input, TIFFTAG_ICCPROFILE, &(t2p->tiff_iccprofilelength), &(t2p->tiff_iccprofile)) != 0){ t2p->tiff_pages[i].page_extra++; t2p->pdf_xrefcount++; if(t2p->pdf_minorversion<3){t2p->pdf_minorversion=3;} } t2p->tiff_tiles[i].tiles_tilecount= t2p->tiff_pages[i].page_tilecount; if( (TIFFGetField(input, TIFFTAG_PLANARCONFIG, &xuint16) != 0) && (xuint16 == PLANARCONFIG_SEPARATE ) ){ TIFFGetField(input, TIFFTAG_SAMPLESPERPIXEL, &xuint16); t2p->tiff_tiles[i].tiles_tilecount/= xuint16; } if( t2p->tiff_tiles[i].tiles_tilecount > 0){ t2p->pdf_xrefcount += (t2p->tiff_tiles[i].tiles_tilecount -1)*2; TIFFGetField(input, TIFFTAG_TILEWIDTH, &( t2p->tiff_tiles[i].tiles_tilewidth) ); TIFFGetField(input, TIFFTAG_TILELENGTH, &( t2p->tiff_tiles[i].tiles_tilelength) ); t2p->tiff_tiles[i].tiles_tiles = (T2P_TILE*) _TIFFmalloc( t2p->tiff_tiles[i].tiles_tilecount * sizeof(T2P_TILE) ); if( t2p->tiff_tiles[i].tiles_tiles == NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_read_tiff_init, %s", t2p->tiff_tiles[i].tiles_tilecount * (long)sizeof(T2P_TILE), TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } } } return; } /* * This function is used by qsort to sort a T2P_PAGE* array of page structures * by page number. */ static int t2p_cmp_t2p_page(const void* e1, const void* e2){ return( ((T2P_PAGE*)e1)->page_number - ((T2P_PAGE*)e2)->page_number ); } /* This function sets the input directory to the directory of a given page and determines information about the image. It checks the image characteristics to determine if it is possible to convert the image data into a page of PDF output, setting values of the T2P struct for this page. It determines what color space is used in the output PDF to represent the image. It determines if the image can be converted as raw data without requiring transcoding of the image data. */ static void t2p_read_tiff_data(T2P* t2p, TIFF* input){ int i=0; uint16* r; uint16* g; uint16* b; uint16* a; uint16 xuint16; uint16* xuint16p; float* xfloatp; t2p->pdf_transcode = T2P_TRANSCODE_ENCODE; t2p->pdf_sample = T2P_SAMPLE_NOTHING; t2p->pdf_switchdecode = t2p->pdf_colorspace_invert; TIFFSetDirectory(input, t2p->tiff_pages[t2p->pdf_page].page_directory); TIFFGetField(input, TIFFTAG_IMAGEWIDTH, &(t2p->tiff_width)); if(t2p->tiff_width == 0){ TIFFError( TIFF2PDF_MODULE, "No support for %s with zero width", TIFFFileName(input) ); t2p->t2p_error = T2P_ERR_ERROR; return; } TIFFGetField(input, TIFFTAG_IMAGELENGTH, &(t2p->tiff_length)); if(t2p->tiff_length == 0){ TIFFError( TIFF2PDF_MODULE, "No support for %s with zero length", TIFFFileName(input) ); t2p->t2p_error = T2P_ERR_ERROR; return; } if(TIFFGetField(input, TIFFTAG_COMPRESSION, &(t2p->tiff_compression)) == 0){ TIFFError( TIFF2PDF_MODULE, "No support for %s with no compression tag", TIFFFileName(input) ); t2p->t2p_error = T2P_ERR_ERROR; return; } if( TIFFIsCODECConfigured(t2p->tiff_compression) == 0){ TIFFError( TIFF2PDF_MODULE, "No support for %s with compression type %u: not configured", TIFFFileName(input), t2p->tiff_compression ); t2p->t2p_error = T2P_ERR_ERROR; return; } TIFFGetFieldDefaulted(input, TIFFTAG_BITSPERSAMPLE, &(t2p->tiff_bitspersample)); switch(t2p->tiff_bitspersample){ case 1: case 2: case 4: case 8: break; case 0: TIFFWarning( TIFF2PDF_MODULE, "Image %s has 0 bits per sample, assuming 1", TIFFFileName(input)); t2p->tiff_bitspersample=1; break; default: TIFFError( TIFF2PDF_MODULE, "No support for %s with %u bits per sample", TIFFFileName(input), t2p->tiff_bitspersample); t2p->t2p_error = T2P_ERR_ERROR; return; } TIFFGetFieldDefaulted(input, TIFFTAG_SAMPLESPERPIXEL, &(t2p->tiff_samplesperpixel)); if(t2p->tiff_samplesperpixel>4){ TIFFError( TIFF2PDF_MODULE, "No support for %s with %u samples per pixel", TIFFFileName(input), t2p->tiff_samplesperpixel); t2p->t2p_error = T2P_ERR_ERROR; return; } if(t2p->tiff_samplesperpixel==0){ TIFFWarning( TIFF2PDF_MODULE, "Image %s has 0 samples per pixel, assuming 1", TIFFFileName(input)); t2p->tiff_samplesperpixel=1; } if(TIFFGetField(input, TIFFTAG_SAMPLEFORMAT, &xuint16) != 0 ){ switch(xuint16){ case 0: case 1: case 4: break; default: TIFFError( TIFF2PDF_MODULE, "No support for %s with sample format %u", TIFFFileName(input), xuint16); t2p->t2p_error = T2P_ERR_ERROR; return; break; } } TIFFGetFieldDefaulted(input, TIFFTAG_FILLORDER, &(t2p->tiff_fillorder)); if(TIFFGetField(input, TIFFTAG_PHOTOMETRIC, &(t2p->tiff_photometric)) == 0){ TIFFError( TIFF2PDF_MODULE, "No support for %s with no photometric interpretation tag", TIFFFileName(input) ); t2p->t2p_error = T2P_ERR_ERROR; return; } switch(t2p->tiff_photometric){ case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISBLACK: if (t2p->tiff_bitspersample==1){ t2p->pdf_colorspace=T2P_CS_BILEVEL; if(t2p->tiff_photometric==PHOTOMETRIC_MINISWHITE){ t2p->pdf_switchdecode ^= 1; } } else { t2p->pdf_colorspace=T2P_CS_GRAY; if(t2p->tiff_photometric==PHOTOMETRIC_MINISWHITE){ t2p->pdf_switchdecode ^= 1; } } break; case PHOTOMETRIC_RGB: t2p->pdf_colorspace=T2P_CS_RGB; if(t2p->tiff_samplesperpixel == 3){ break; } if(TIFFGetField(input, TIFFTAG_INDEXED, &xuint16)){ if(xuint16==1) goto photometric_palette; } if(t2p->tiff_samplesperpixel > 3) { if(t2p->tiff_samplesperpixel == 4) { t2p->pdf_colorspace = T2P_CS_RGB; if(TIFFGetField(input, TIFFTAG_EXTRASAMPLES, &xuint16, &xuint16p) && xuint16 == 1) { if(xuint16p[0] == EXTRASAMPLE_ASSOCALPHA){ t2p->pdf_sample=T2P_SAMPLE_RGBAA_TO_RGB; break; } if(xuint16p[0] == EXTRASAMPLE_UNASSALPHA){ t2p->pdf_sample=T2P_SAMPLE_RGBA_TO_RGB; break; } TIFFWarning( TIFF2PDF_MODULE, "RGB image %s has 4 samples per pixel, assuming RGBA", TIFFFileName(input)); break; } t2p->pdf_colorspace=T2P_CS_CMYK; t2p->pdf_switchdecode ^= 1; TIFFWarning( TIFF2PDF_MODULE, "RGB image %s has 4 samples per pixel, assuming inverse CMYK", TIFFFileName(input)); break; } else { TIFFError( TIFF2PDF_MODULE, "No support for RGB image %s with %u samples per pixel", TIFFFileName(input), t2p->tiff_samplesperpixel); t2p->t2p_error = T2P_ERR_ERROR; break; } } else { TIFFError( TIFF2PDF_MODULE, "No support for RGB image %s with %u samples per pixel", TIFFFileName(input), t2p->tiff_samplesperpixel); t2p->t2p_error = T2P_ERR_ERROR; break; } case PHOTOMETRIC_PALETTE: photometric_palette: if(t2p->tiff_samplesperpixel!=1){ TIFFError( TIFF2PDF_MODULE, "No support for palettized image %s with not one sample per pixel", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } t2p->pdf_colorspace=T2P_CS_RGB | T2P_CS_PALETTE; t2p->pdf_palettesize=0x0001<tiff_bitspersample; if(!TIFFGetField(input, TIFFTAG_COLORMAP, &r, &g, &b)){ TIFFError( TIFF2PDF_MODULE, "Palettized image %s has no color map", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } if(t2p->pdf_palette != NULL){ _TIFFfree(t2p->pdf_palette); t2p->pdf_palette=NULL; } t2p->pdf_palette = (unsigned char*) _TIFFmalloc(t2p->pdf_palettesize*3); if(t2p->pdf_palette==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_read_tiff_image, %s", t2p->pdf_palettesize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } for(i=0;ipdf_palettesize;i++){ t2p->pdf_palette[(i*3)] = (unsigned char) (r[i]>>8); t2p->pdf_palette[(i*3)+1]= (unsigned char) (g[i]>>8); t2p->pdf_palette[(i*3)+2]= (unsigned char) (b[i]>>8); } t2p->pdf_palettesize *= 3; break; case PHOTOMETRIC_SEPARATED: if(TIFFGetField(input, TIFFTAG_INDEXED, &xuint16)){ if(xuint16==1){ goto photometric_palette_cmyk; } } if( TIFFGetField(input, TIFFTAG_INKSET, &xuint16) ){ if(xuint16 != INKSET_CMYK){ TIFFError( TIFF2PDF_MODULE, "No support for %s because its inkset is not CMYK", TIFFFileName(input) ); t2p->t2p_error = T2P_ERR_ERROR; return; } } if(t2p->tiff_samplesperpixel==4){ t2p->pdf_colorspace=T2P_CS_CMYK; } else { TIFFError( TIFF2PDF_MODULE, "No support for %s because it has %u samples per pixel", TIFFFileName(input), t2p->tiff_samplesperpixel); t2p->t2p_error = T2P_ERR_ERROR; return; } break; photometric_palette_cmyk: if(t2p->tiff_samplesperpixel!=1){ TIFFError( TIFF2PDF_MODULE, "No support for palettized CMYK image %s with not one sample per pixel", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } t2p->pdf_colorspace=T2P_CS_CMYK | T2P_CS_PALETTE; t2p->pdf_palettesize=0x0001<tiff_bitspersample; if(!TIFFGetField(input, TIFFTAG_COLORMAP, &r, &g, &b, &a)){ TIFFError( TIFF2PDF_MODULE, "Palettized image %s has no color map", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } if(t2p->pdf_palette != NULL){ _TIFFfree(t2p->pdf_palette); t2p->pdf_palette=NULL; } t2p->pdf_palette = (unsigned char*) _TIFFmalloc(t2p->pdf_palettesize*4); if(t2p->pdf_palette==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_read_tiff_image, %s", t2p->pdf_palettesize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } for(i=0;ipdf_palettesize;i++){ t2p->pdf_palette[(i*4)] = (unsigned char) (r[i]>>8); t2p->pdf_palette[(i*4)+1]= (unsigned char) (g[i]>>8); t2p->pdf_palette[(i*4)+2]= (unsigned char) (b[i]>>8); t2p->pdf_palette[(i*4)+3]= (unsigned char) (a[i]>>8); } t2p->pdf_palettesize *= 4; break; case PHOTOMETRIC_YCBCR: t2p->pdf_colorspace=T2P_CS_RGB; if(t2p->tiff_samplesperpixel==1){ t2p->pdf_colorspace=T2P_CS_GRAY; t2p->tiff_photometric=PHOTOMETRIC_MINISBLACK; break; } t2p->pdf_sample=T2P_SAMPLE_YCBCR_TO_RGB; #ifdef JPEG_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_JPEG){ t2p->pdf_sample=T2P_SAMPLE_NOTHING; } #endif break; case PHOTOMETRIC_CIELAB: t2p->pdf_labrange[0]= -127; t2p->pdf_labrange[1]= 127; t2p->pdf_labrange[2]= -127; t2p->pdf_labrange[3]= 127; t2p->pdf_sample=T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED; t2p->pdf_colorspace=T2P_CS_LAB; break; case PHOTOMETRIC_ICCLAB: t2p->pdf_labrange[0]= 0; t2p->pdf_labrange[1]= 255; t2p->pdf_labrange[2]= 0; t2p->pdf_labrange[3]= 255; t2p->pdf_colorspace=T2P_CS_LAB; break; case PHOTOMETRIC_ITULAB: t2p->pdf_labrange[0]=-85; t2p->pdf_labrange[1]=85; t2p->pdf_labrange[2]=-75; t2p->pdf_labrange[3]=124; t2p->pdf_sample=T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED; t2p->pdf_colorspace=T2P_CS_LAB; break; case PHOTOMETRIC_LOGL: case PHOTOMETRIC_LOGLUV: TIFFError( TIFF2PDF_MODULE, "No support for %s with photometric interpretation LogL/LogLuv", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; default: TIFFError( TIFF2PDF_MODULE, "No support for %s with photometric interpretation %u", TIFFFileName(input), t2p->tiff_photometric); t2p->t2p_error = T2P_ERR_ERROR; return; } if(TIFFGetField(input, TIFFTAG_PLANARCONFIG, &(t2p->tiff_planar))){ switch(t2p->tiff_planar){ case 0: TIFFWarning( TIFF2PDF_MODULE, "Image %s has planar configuration 0, assuming 1", TIFFFileName(input)); t2p->tiff_planar=PLANARCONFIG_CONTIG; case PLANARCONFIG_CONTIG: break; case PLANARCONFIG_SEPARATE: t2p->pdf_sample=T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG; if(t2p->tiff_bitspersample!=8){ TIFFError( TIFF2PDF_MODULE, "No support for %s with separated planar configuration and %u bits per sample", TIFFFileName(input), t2p->tiff_bitspersample); t2p->t2p_error = T2P_ERR_ERROR; return; } break; default: TIFFError( TIFF2PDF_MODULE, "No support for %s with planar configuration %u", TIFFFileName(input), t2p->tiff_planar); t2p->t2p_error = T2P_ERR_ERROR; return; } } TIFFGetFieldDefaulted(input, TIFFTAG_ORIENTATION, &(t2p->tiff_orientation)); if(t2p->tiff_orientation>8){ TIFFWarning(TIFF2PDF_MODULE, "Image %s has orientation %u, assuming 0", TIFFFileName(input), t2p->tiff_orientation); t2p->tiff_orientation=0; } if(TIFFGetField(input, TIFFTAG_XRESOLUTION, &(t2p->tiff_xres) ) == 0){ t2p->tiff_xres=0.0; } if(TIFFGetField(input, TIFFTAG_YRESOLUTION, &(t2p->tiff_yres) ) == 0){ t2p->tiff_yres=0.0; } TIFFGetFieldDefaulted(input, TIFFTAG_RESOLUTIONUNIT, &(t2p->tiff_resunit)); if(t2p->tiff_resunit == RESUNIT_CENTIMETER) { t2p->tiff_xres *= 2.54F; t2p->tiff_yres *= 2.54F; } else if (t2p->tiff_resunit != RESUNIT_INCH && t2p->pdf_centimeters != 0) { t2p->tiff_xres *= 2.54F; t2p->tiff_yres *= 2.54F; } t2p_compose_pdf_page(t2p); t2p->pdf_transcode = T2P_TRANSCODE_ENCODE; if(t2p->pdf_nopassthrough==0){ #ifdef CCITT_SUPPORT if(t2p->tiff_compression==COMPRESSION_CCITTFAX4 ){ if(TIFFIsTiled(input) || (TIFFNumberOfStrips(input)==1) ){ t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_G4; } } #endif #ifdef ZIP_SUPPORT if(t2p->tiff_compression== COMPRESSION_ADOBE_DEFLATE || t2p->tiff_compression==COMPRESSION_DEFLATE){ if(TIFFIsTiled(input) || (TIFFNumberOfStrips(input)==1) ){ t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_ZIP; } } #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_JPEG; t2p_process_ojpeg_tables(t2p, input); } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_JPEG){ t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_JPEG; } #endif (void)0; } if(t2p->pdf_transcode!=T2P_TRANSCODE_RAW){ t2p->pdf_compression = t2p->pdf_defaultcompression; } #ifdef JPEG_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_JPEG){ if(t2p->pdf_colorspace & T2P_CS_PALETTE){ t2p->pdf_sample|=T2P_SAMPLE_REALIZE_PALETTE; t2p->pdf_colorspace ^= T2P_CS_PALETTE; t2p->tiff_pages[t2p->pdf_page].page_extra--; } } if(t2p->tiff_compression==COMPRESSION_JPEG){ if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ TIFFError( TIFF2PDF_MODULE, "No support for %s with JPEG compression and separated planar configuration", TIFFFileName(input)); t2p->t2p_error=T2P_ERR_ERROR; return; } } #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ TIFFError( TIFF2PDF_MODULE, "No support for %s with OJPEG compression and separated planar configuration", TIFFFileName(input)); t2p->t2p_error=T2P_ERR_ERROR; return; } } #endif if(t2p->pdf_sample & T2P_SAMPLE_REALIZE_PALETTE){ if(t2p->pdf_colorspace & T2P_CS_CMYK){ t2p->tiff_samplesperpixel=4; t2p->tiff_photometric=PHOTOMETRIC_SEPARATED; } else { t2p->tiff_samplesperpixel=3; t2p->tiff_photometric=PHOTOMETRIC_RGB; } } if (TIFFGetField(input, TIFFTAG_TRANSFERFUNCTION, &(t2p->tiff_transferfunction[0]), &(t2p->tiff_transferfunction[1]), &(t2p->tiff_transferfunction[2]))) { if(t2p->tiff_transferfunction[1] != t2p->tiff_transferfunction[0]) { t2p->tiff_transferfunctioncount=3; } else { t2p->tiff_transferfunctioncount=1; } } else { t2p->tiff_transferfunctioncount=0; } if(TIFFGetField(input, TIFFTAG_WHITEPOINT, &xfloatp)!=0){ t2p->tiff_whitechromaticities[0]=xfloatp[0]; t2p->tiff_whitechromaticities[1]=xfloatp[1]; if(t2p->pdf_colorspace & T2P_CS_GRAY){ t2p->pdf_colorspace |= T2P_CS_CALGRAY; } if(t2p->pdf_colorspace & T2P_CS_RGB){ t2p->pdf_colorspace |= T2P_CS_CALRGB; } } if(TIFFGetField(input, TIFFTAG_PRIMARYCHROMATICITIES, &xfloatp)!=0){ t2p->tiff_primarychromaticities[0]=xfloatp[0]; t2p->tiff_primarychromaticities[1]=xfloatp[1]; t2p->tiff_primarychromaticities[2]=xfloatp[2]; t2p->tiff_primarychromaticities[3]=xfloatp[3]; t2p->tiff_primarychromaticities[4]=xfloatp[4]; t2p->tiff_primarychromaticities[5]=xfloatp[5]; if(t2p->pdf_colorspace & T2P_CS_RGB){ t2p->pdf_colorspace |= T2P_CS_CALRGB; } } if(t2p->pdf_colorspace & T2P_CS_LAB){ if(TIFFGetField(input, TIFFTAG_WHITEPOINT, &xfloatp) != 0){ t2p->tiff_whitechromaticities[0]=xfloatp[0]; t2p->tiff_whitechromaticities[1]=xfloatp[1]; } else { t2p->tiff_whitechromaticities[0]=0.3457F; /* 0.3127F; */ t2p->tiff_whitechromaticities[1]=0.3585F; /* 0.3290F; */ } } if(TIFFGetField(input, TIFFTAG_ICCPROFILE, &(t2p->tiff_iccprofilelength), &(t2p->tiff_iccprofile))!=0){ t2p->pdf_colorspace |= T2P_CS_ICCBASED; } else { t2p->tiff_iccprofilelength=0; t2p->tiff_iccprofile=NULL; } #ifdef CCITT_SUPPORT if( t2p->tiff_bitspersample==1 && t2p->tiff_samplesperpixel==1){ t2p->pdf_compression = T2P_COMPRESS_G4; } #endif return; } /* This function returns the necessary size of a data buffer to contain the raw or uncompressed image data from the input TIFF for a page. */ static void t2p_read_tiff_size(T2P* t2p, TIFF* input){ uint32* sbc=NULL; #if defined(JPEG_SUPPORT) || defined (OJPEG_SUPPORT) unsigned char* jpt=NULL; tstrip_t i=0; tstrip_t stripcount=0; #endif uint64 k = 0; if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){ #ifdef CCITT_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_G4 ){ TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc); t2p->tiff_datasize=sbc[0]; return; } #endif #ifdef ZIP_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_ZIP){ TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc); t2p->tiff_datasize=sbc[0]; return; } #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_OJPEG){ if(!TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc)){ TIFFError(TIFF2PDF_MODULE, "Input file %s missing field: TIFFTAG_STRIPBYTECOUNTS", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } stripcount=TIFFNumberOfStrips(input); for(i=0;itiff_dataoffset))){ if(t2p->tiff_dataoffset != 0){ if(TIFFGetField(input, TIFFTAG_JPEGIFBYTECOUNT, &(t2p->tiff_datasize))!=0){ if((uint64)t2p->tiff_datasize < k) { TIFFWarning(TIFF2PDF_MODULE, "Input file %s has short JPEG interchange file byte count", TIFFFileName(input)); t2p->pdf_ojpegiflength=t2p->tiff_datasize; k = checkAdd64(k, t2p->tiff_datasize, t2p); k = checkAdd64(k, 6, t2p); k = checkAdd64(k, stripcount, t2p); k = checkAdd64(k, stripcount, t2p); t2p->tiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } return; } return; }else { TIFFError(TIFF2PDF_MODULE, "Input file %s missing field: TIFFTAG_JPEGIFBYTECOUNT", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } } } k = checkAdd64(k, stripcount, t2p); k = checkAdd64(k, stripcount, t2p); k = checkAdd64(k, 2048, t2p); t2p->tiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } return; } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_JPEG) { uint32 count = 0; if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0 ){ if(count > 4){ k += count; k -= 2; /* don't use EOI of header */ } } else { k = 2; /* SOI for first strip */ } stripcount=TIFFNumberOfStrips(input); if(!TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc)){ TIFFError(TIFF2PDF_MODULE, "Input file %s missing field: TIFFTAG_STRIPBYTECOUNTS", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return; } for(i=0;itiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } } #endif (void) 0; } k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); } if (k == 0) { /* Assume we had overflow inside TIFFScanlineSize */ t2p->t2p_error = T2P_ERR_ERROR; } t2p->tiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } return; } /* This function returns the necessary size of a data buffer to contain the raw or uncompressed image data from the input TIFF for a tile of a page. */ static void t2p_read_tiff_size_tile(T2P* t2p, TIFF* input, ttile_t tile){ uint32* tbc = NULL; uint16 edge=0; #ifdef JPEG_SUPPORT unsigned char* jpt; #endif uint64 k; edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile); edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile); if(t2p->pdf_transcode==T2P_TRANSCODE_RAW){ if(edge #if defined(JPEG_SUPPORT) || defined(OJPEG_SUPPORT) && !(t2p->pdf_compression==T2P_COMPRESS_JPEG) #endif ){ t2p->tiff_datasize=TIFFTileSize(input); if (t2p->tiff_datasize == 0) { /* Assume we had overflow inside TIFFTileSize */ t2p->t2p_error = T2P_ERR_ERROR; } return; } else { TIFFGetField(input, TIFFTAG_TILEBYTECOUNTS, &tbc); k=tbc[tile]; #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ k = checkAdd64(k, 2048, t2p); } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_JPEG) { uint32 count = 0; if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt)!=0){ if(count > 4){ k = checkAdd64(k, count, t2p); k -= 4; /* don't use EOI of header or SOI of tile */ } } } #endif t2p->tiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } return; } } k = TIFFTileSize(input); if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); } if (k == 0) { /* Assume we had overflow inside TIFFTileSize */ t2p->t2p_error = T2P_ERR_ERROR; } t2p->tiff_datasize = (tsize_t) k; if ((uint64) t2p->tiff_datasize != k) { TIFFError(TIFF2PDF_MODULE, "Integer overflow"); t2p->t2p_error = T2P_ERR_ERROR; } return; } /* * This functions returns a non-zero value when the tile is on the right edge * and does not have full imaged tile width. */ static int t2p_tile_is_right_edge(T2P_TILES tiles, ttile_t tile){ if( ((tile+1) % tiles.tiles_tilecountx == 0) && (tiles.tiles_edgetilewidth != 0) ){ return(1); } else { return(0); } } /* * This functions returns a non-zero value when the tile is on the bottom edge * and does not have full imaged tile length. */ static int t2p_tile_is_bottom_edge(T2P_TILES tiles, ttile_t tile){ if( ((tile+1) > (tiles.tiles_tilecount-tiles.tiles_tilecountx) ) && (tiles.tiles_edgetilelength != 0) ){ return(1); } else { return(0); } } /* This function reads the raster image data from the input TIFF for an image and writes the data to the output PDF XObject image dictionary stream. It returns the amount written or zero on error. */ static tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ tsize_t written=0; unsigned char* buffer=NULL; unsigned char* samplebuffer=NULL; tsize_t bufferoffset=0; tsize_t samplebufferoffset=0; tsize_t read=0; tstrip_t i=0; tstrip_t j=0; tstrip_t stripcount=0; tsize_t stripsize=0; tsize_t sepstripcount=0; tsize_t sepstripsize=0; #ifdef OJPEG_SUPPORT toff_t inputoffset=0; uint16 h_samp=1; uint16 v_samp=1; uint16 ri=1; uint32 rows=0; #endif #ifdef JPEG_SUPPORT unsigned char* jpt; float* xfloatp; uint32* sbc; unsigned char* stripbuffer; tsize_t striplength=0; uint32 max_striplength=0; #endif /* Fail if prior error (in particular, can't trust tiff_datasize) */ if (t2p->t2p_error != T2P_ERR_OK) return(0); if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){ #ifdef CCITT_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_G4){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if (buffer == NULL) { TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } TIFFReadRawStrip(input, 0, (tdata_t) buffer, t2p->tiff_datasize); if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ /* * make sure is lsb-to-msb * bit-endianness fill order */ TIFFReverseBits(buffer, t2p->tiff_datasize); } t2pWriteFile(output, (tdata_t) buffer, t2p->tiff_datasize); _TIFFfree(buffer); return(t2p->tiff_datasize); } #endif #ifdef ZIP_SUPPORT if (t2p->pdf_compression == T2P_COMPRESS_ZIP) { buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer == NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } TIFFReadRawStrip(input, 0, (tdata_t) buffer, t2p->tiff_datasize); if (t2p->tiff_fillorder==FILLORDER_LSB2MSB) { TIFFReverseBits(buffer, t2p->tiff_datasize); } t2pWriteFile(output, (tdata_t) buffer, t2p->tiff_datasize); _TIFFfree(buffer); return(t2p->tiff_datasize); } #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_OJPEG) { if(t2p->tiff_dataoffset != 0) { buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer == NULL) { TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(t2p->pdf_ojpegiflength==0){ inputoffset=t2pSeekFile(input, 0, SEEK_CUR); t2pSeekFile(input, t2p->tiff_dataoffset, SEEK_SET); t2pReadFile(input, (tdata_t) buffer, t2p->tiff_datasize); t2pSeekFile(input, inputoffset, SEEK_SET); t2pWriteFile(output, (tdata_t) buffer, t2p->tiff_datasize); _TIFFfree(buffer); return(t2p->tiff_datasize); } else { inputoffset=t2pSeekFile(input, 0, SEEK_CUR); t2pSeekFile(input, t2p->tiff_dataoffset, SEEK_SET); bufferoffset = t2pReadFile(input, (tdata_t) buffer, t2p->pdf_ojpegiflength); t2p->pdf_ojpegiflength = 0; t2pSeekFile(input, inputoffset, SEEK_SET); TIFFGetField(input, TIFFTAG_YCBCRSUBSAMPLING, &h_samp, &v_samp); buffer[bufferoffset++]= 0xff; buffer[bufferoffset++]= 0xdd; buffer[bufferoffset++]= 0x00; buffer[bufferoffset++]= 0x04; h_samp*=8; v_samp*=8; ri=(t2p->tiff_width+h_samp-1) / h_samp; TIFFGetField(input, TIFFTAG_ROWSPERSTRIP, &rows); ri*=(rows+v_samp-1)/v_samp; buffer[bufferoffset++]= (ri>>8) & 0xff; buffer[bufferoffset++]= ri & 0xff; stripcount=TIFFNumberOfStrips(input); for(i=0;ipdf_ojpegdata){ TIFFError(TIFF2PDF_MODULE, "No support for OJPEG image %s with bad tables", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); bufferoffset=t2p->pdf_ojpegdatalength; stripcount=TIFFNumberOfStrips(input); for(i=0;it2p_error = T2P_ERR_ERROR; return(0); } return(t2p->tiff_datasize); } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_JPEG) { uint32 count = 0; buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if (TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if(count > 4) { _TIFFmemcpy(buffer, jpt, count); bufferoffset += count - 2; } } stripcount=TIFFNumberOfStrips(input); TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc); for(i=0;imax_striplength) max_striplength=sbc[i]; } stripbuffer = (unsigned char*) _TIFFmalloc(max_striplength); if(stripbuffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s", max_striplength, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } for(i=0;itiff_length)){ TIFFError(TIFF2PDF_MODULE, "Can't process JPEG data in input file %s", TIFFFileName(input)); _TIFFfree(samplebuffer); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } } buffer[bufferoffset++]=0xff; buffer[bufferoffset++]=0xd9; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); _TIFFfree(stripbuffer); _TIFFfree(buffer); return(bufferoffset); } #endif (void)0; } if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;it2p_error=T2P_ERR_ERROR; return(0); } bufferoffset+=read; } } else { if(t2p->pdf_sample & T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG){ sepstripsize=TIFFStripSize(input); sepstripcount=TIFFNumberOfStrips(input); stripsize=sepstripsize*t2p->tiff_samplesperpixel; stripcount=sepstripcount/t2p->tiff_samplesperpixel; buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } samplebuffer = (unsigned char*) _TIFFmalloc(stripsize); if(samplebuffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } for(i=0;itiff_samplesperpixel;j++){ read = TIFFReadEncodedStrip(input, i + j*stripcount, (tdata_t) &(samplebuffer[samplebufferoffset]), sepstripsize); if(read==-1){ TIFFError(TIFF2PDF_MODULE, "Error on decoding strip %u of %s", i + j*stripcount, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; return(0); } samplebufferoffset+=read; } t2p_sample_planar_separate_to_contig( t2p, &(buffer[bufferoffset]), samplebuffer, samplebufferoffset); bufferoffset+=samplebufferoffset; } _TIFFfree(samplebuffer); goto dataready; } buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); memset(buffer, 0, t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;it2p_error=T2P_ERR_ERROR; return(0); } bufferoffset+=read; } if(t2p->pdf_sample & T2P_SAMPLE_REALIZE_PALETTE){ samplebuffer=(unsigned char*)_TIFFrealloc( (tdata_t) buffer, t2p->tiff_datasize * t2p->tiff_samplesperpixel); if(samplebuffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; _TIFFfree(buffer); } else { buffer=samplebuffer; t2p->tiff_datasize *= t2p->tiff_samplesperpixel; } t2p_sample_realize_palette(t2p, buffer); } if(t2p->pdf_sample & T2P_SAMPLE_RGBA_TO_RGB){ t2p->tiff_datasize=t2p_sample_rgba_to_rgb( (tdata_t)buffer, t2p->tiff_width*t2p->tiff_length); } if(t2p->pdf_sample & T2P_SAMPLE_RGBAA_TO_RGB){ t2p->tiff_datasize=t2p_sample_rgbaa_to_rgb( (tdata_t)buffer, t2p->tiff_width*t2p->tiff_length); } if(t2p->pdf_sample & T2P_SAMPLE_YCBCR_TO_RGB){ samplebuffer=(unsigned char*)_TIFFrealloc( (tdata_t)buffer, t2p->tiff_width*t2p->tiff_length*4); if(samplebuffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; _TIFFfree(buffer); return(0); } else { buffer=samplebuffer; } if(!TIFFReadRGBAImageOriented( input, t2p->tiff_width, t2p->tiff_length, (uint32*)buffer, ORIENTATION_TOPLEFT, 0)){ TIFFError(TIFF2PDF_MODULE, "Can't use TIFFReadRGBAImageOriented to extract RGB image from %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } t2p->tiff_datasize=t2p_sample_abgr_to_rgb( (tdata_t) buffer, t2p->tiff_width*t2p->tiff_length); } if(t2p->pdf_sample & T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED){ t2p->tiff_datasize=t2p_sample_lab_signed_to_unsigned( (tdata_t)buffer, t2p->tiff_width*t2p->tiff_length); } } dataready: t2p_disable(output); TIFFSetField(output, TIFFTAG_PHOTOMETRIC, t2p->tiff_photometric); TIFFSetField(output, TIFFTAG_BITSPERSAMPLE, t2p->tiff_bitspersample); TIFFSetField(output, TIFFTAG_SAMPLESPERPIXEL, t2p->tiff_samplesperpixel); TIFFSetField(output, TIFFTAG_IMAGEWIDTH, t2p->tiff_width); TIFFSetField(output, TIFFTAG_IMAGELENGTH, t2p->tiff_length); TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, t2p->tiff_length); TIFFSetField(output, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(output, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); switch(t2p->pdf_compression){ case T2P_COMPRESS_NONE: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_NONE); break; #ifdef CCITT_SUPPORT case T2P_COMPRESS_G4: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); break; #endif #ifdef JPEG_SUPPORT case T2P_COMPRESS_JPEG: if(t2p->tiff_photometric==PHOTOMETRIC_YCBCR) { uint16 hor = 0, ver = 0; if (TIFFGetField(input, TIFFTAG_YCBCRSUBSAMPLING, &hor, &ver) !=0 ) { if(hor != 0 && ver != 0){ TIFFSetField(output, TIFFTAG_YCBCRSUBSAMPLING, hor, ver); } } if(TIFFGetField(input, TIFFTAG_REFERENCEBLACKWHITE, &xfloatp)!=0){ TIFFSetField(output, TIFFTAG_REFERENCEBLACKWHITE, xfloatp); } } if(TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_JPEG)==0){ TIFFError(TIFF2PDF_MODULE, "Unable to use JPEG compression for input %s and output %s", TIFFFileName(input), TIFFFileName(output)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } TIFFSetField(output, TIFFTAG_JPEGTABLESMODE, 0); if(t2p->pdf_colorspace & (T2P_CS_RGB | T2P_CS_LAB)){ TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); if(t2p->tiff_photometric != PHOTOMETRIC_YCBCR){ TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); } else { TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); } } if(t2p->pdf_colorspace & T2P_CS_GRAY){ (void)0; } if(t2p->pdf_colorspace & T2P_CS_CMYK){ (void)0; } if(t2p->pdf_defaultcompressionquality != 0){ TIFFSetField(output, TIFFTAG_JPEGQUALITY, t2p->pdf_defaultcompressionquality); } break; #endif #ifdef ZIP_SUPPORT case T2P_COMPRESS_ZIP: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); if(t2p->pdf_defaultcompressionquality%100 != 0){ TIFFSetField(output, TIFFTAG_PREDICTOR, t2p->pdf_defaultcompressionquality % 100); } if(t2p->pdf_defaultcompressionquality/100 != 0){ TIFFSetField(output, TIFFTAG_ZIPQUALITY, (t2p->pdf_defaultcompressionquality / 100)); } break; #endif default: break; } t2p_enable(output); t2p->outputwritten = 0; #ifdef JPEG_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_JPEG && t2p->tiff_photometric == PHOTOMETRIC_YCBCR){ bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t)0, buffer, stripsize * stripcount); } else #endif { bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t)0, buffer, t2p->tiff_datasize); } if (buffer != NULL) { _TIFFfree(buffer); buffer=NULL; } if (bufferoffset == (tsize_t)-1) { TIFFError(TIFF2PDF_MODULE, "Error writing encoded strip to output PDF %s", TIFFFileName(output)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } written = t2p->outputwritten; return(written); } /* * This function reads the raster image data from the input TIFF for an image * tile and writes the data to the output PDF XObject image dictionary stream * for the tile. It returns the amount written or zero on error. */ static tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_t tile){ uint16 edge=0; tsize_t written=0; unsigned char* buffer=NULL; tsize_t bufferoffset=0; unsigned char* samplebuffer=NULL; tsize_t samplebufferoffset=0; tsize_t read=0; uint16 i=0; ttile_t tilecount=0; tsize_t tilesize=0; ttile_t septilecount=0; tsize_t septilesize=0; #ifdef JPEG_SUPPORT unsigned char* jpt; float* xfloatp; uint32 xuint32=0; #endif (void)tilesize; /* Fail if prior error (in particular, can't trust tiff_datasize) */ if (t2p->t2p_error != T2P_ERR_OK) return(0); edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile); edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile); if( (t2p->pdf_transcode == T2P_TRANSCODE_RAW) && ((edge == 0) #if defined(JPEG_SUPPORT) || defined(OJPEG_SUPPORT) || (t2p->pdf_compression == T2P_COMPRESS_JPEG) #endif ) ){ #ifdef CCITT_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_G4){ buffer= (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } t2pWriteFile(output, (tdata_t) buffer, t2p->tiff_datasize); _TIFFfree(buffer); return(t2p->tiff_datasize); } #endif #ifdef ZIP_SUPPORT if(t2p->pdf_compression == T2P_COMPRESS_ZIP){ buffer= (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } t2pWriteFile(output, (tdata_t) buffer, t2p->tiff_datasize); _TIFFfree(buffer); return(t2p->tiff_datasize); } #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_OJPEG){ if(! t2p->pdf_ojpegdata){ TIFFError(TIFF2PDF_MODULE, "No support for OJPEG image %s with " "bad tables", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } buffer=(unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); if(edge!=0){ if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile)){ buffer[7]= (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength >> 8) & 0xff; buffer[8]= (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength ) & 0xff; } if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile)){ buffer[9]= (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth >> 8) & 0xff; buffer[10]= (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth ) & 0xff; } } bufferoffset=t2p->pdf_ojpegdatalength; bufferoffset+=TIFFReadRawTile(input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); ((unsigned char*)buffer)[bufferoffset++]=0xff; ((unsigned char*)buffer)[bufferoffset++]=0xd9; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); _TIFFfree(buffer); return(bufferoffset); } #endif #ifdef JPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_JPEG){ unsigned char table_end[2]; uint32 count = 0; buffer= (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if (count > 0) { _TIFFmemcpy(buffer, jpt, count); bufferoffset += count - 2; table_end[0] = buffer[bufferoffset-2]; table_end[1] = buffer[bufferoffset-1]; } if (count > 0) { xuint32 = bufferoffset; bufferoffset += TIFFReadRawTile( input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset-2]), -1); buffer[xuint32-2]=table_end[0]; buffer[xuint32-1]=table_end[1]; } else { bufferoffset += TIFFReadRawTile( input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); } } t2pWriteFile(output, (tdata_t) buffer, bufferoffset); _TIFFfree(buffer); return(bufferoffset); } #endif (void)0; } if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for " "t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } read = TIFFReadEncodedTile( input, tile, (tdata_t) &buffer[bufferoffset], t2p->tiff_datasize); if(read==-1){ TIFFError(TIFF2PDF_MODULE, "Error on decoding tile %u of %s", tile, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; return(0); } } else { if(t2p->pdf_sample == T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG){ septilesize=TIFFTileSize(input); septilecount=TIFFNumberOfTiles(input); tilesize=septilesize*t2p->tiff_samplesperpixel; tilecount=septilecount/t2p->tiff_samplesperpixel; buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } samplebuffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(samplebuffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } samplebufferoffset=0; for(i=0;itiff_samplesperpixel;i++){ read = TIFFReadEncodedTile(input, tile + i*tilecount, (tdata_t) &(samplebuffer[samplebufferoffset]), septilesize); if(read==-1){ TIFFError(TIFF2PDF_MODULE, "Error on decoding tile %u of %s", tile + i*tilecount, TIFFFileName(input)); _TIFFfree(samplebuffer); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; return(0); } samplebufferoffset+=read; } t2p_sample_planar_separate_to_contig( t2p, &(buffer[bufferoffset]), samplebuffer, samplebufferoffset); bufferoffset+=samplebufferoffset; _TIFFfree(samplebuffer); } if(buffer==NULL){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " "for t2p_readwrite_pdf_image_tile, %s", (unsigned long)t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } read = TIFFReadEncodedTile( input, tile, (tdata_t) &buffer[bufferoffset], t2p->tiff_datasize); if(read==-1){ TIFFError(TIFF2PDF_MODULE, "Error on decoding tile %u of %s", tile, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; return(0); } } if(t2p->pdf_sample & T2P_SAMPLE_RGBA_TO_RGB){ t2p->tiff_datasize=t2p_sample_rgba_to_rgb( (tdata_t)buffer, t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth *t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } if(t2p->pdf_sample & T2P_SAMPLE_RGBAA_TO_RGB){ t2p->tiff_datasize=t2p_sample_rgbaa_to_rgb( (tdata_t)buffer, t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth *t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } if(t2p->pdf_sample & T2P_SAMPLE_YCBCR_TO_RGB){ TIFFError(TIFF2PDF_MODULE, "No support for YCbCr to RGB in tile for %s", TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(t2p->pdf_sample & T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED){ t2p->tiff_datasize=t2p_sample_lab_signed_to_unsigned( (tdata_t)buffer, t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth *t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } } if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile) != 0){ t2p_tile_collapse_left( buffer, TIFFTileRowSize(input), t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth, t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth, t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } t2p_disable(output); TIFFSetField(output, TIFFTAG_PHOTOMETRIC, t2p->tiff_photometric); TIFFSetField(output, TIFFTAG_BITSPERSAMPLE, t2p->tiff_bitspersample); TIFFSetField(output, TIFFTAG_SAMPLESPERPIXEL, t2p->tiff_samplesperpixel); if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile) == 0){ TIFFSetField( output, TIFFTAG_IMAGEWIDTH, t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth); } else { TIFFSetField( output, TIFFTAG_IMAGEWIDTH, t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth); } if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile) == 0){ TIFFSetField( output, TIFFTAG_IMAGELENGTH, t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); TIFFSetField( output, TIFFTAG_ROWSPERSTRIP, t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } else { TIFFSetField( output, TIFFTAG_IMAGELENGTH, t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); TIFFSetField( output, TIFFTAG_ROWSPERSTRIP, t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); } TIFFSetField(output, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(output, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); switch(t2p->pdf_compression){ case T2P_COMPRESS_NONE: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_NONE); break; #ifdef CCITT_SUPPORT case T2P_COMPRESS_G4: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); break; #endif #ifdef JPEG_SUPPORT case T2P_COMPRESS_JPEG: if (t2p->tiff_photometric==PHOTOMETRIC_YCBCR) { uint16 hor = 0, ver = 0; if (TIFFGetField(input, TIFFTAG_YCBCRSUBSAMPLING, &hor, &ver)!=0) { if (hor != 0 && ver != 0) { TIFFSetField(output, TIFFTAG_YCBCRSUBSAMPLING, hor, ver); } } if(TIFFGetField(input, TIFFTAG_REFERENCEBLACKWHITE, &xfloatp)!=0){ TIFFSetField(output, TIFFTAG_REFERENCEBLACKWHITE, xfloatp); } } TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_JPEG); TIFFSetField(output, TIFFTAG_JPEGTABLESMODE, 0); /* JPEGTABLESMODE_NONE */ if(t2p->pdf_colorspace & (T2P_CS_RGB | T2P_CS_LAB)){ TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); if(t2p->tiff_photometric != PHOTOMETRIC_YCBCR){ TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); } else { TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); } } if(t2p->pdf_colorspace & T2P_CS_GRAY){ (void)0; } if(t2p->pdf_colorspace & T2P_CS_CMYK){ (void)0; } if(t2p->pdf_defaultcompressionquality != 0){ TIFFSetField(output, TIFFTAG_JPEGQUALITY, t2p->pdf_defaultcompressionquality); } break; #endif #ifdef ZIP_SUPPORT case T2P_COMPRESS_ZIP: TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); if(t2p->pdf_defaultcompressionquality%100 != 0){ TIFFSetField(output, TIFFTAG_PREDICTOR, t2p->pdf_defaultcompressionquality % 100); } if(t2p->pdf_defaultcompressionquality/100 != 0){ TIFFSetField(output, TIFFTAG_ZIPQUALITY, (t2p->pdf_defaultcompressionquality / 100)); } break; #endif default: break; } t2p_enable(output); t2p->outputwritten = 0; bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t) 0, buffer, TIFFStripSize(output)); if (buffer != NULL) { _TIFFfree(buffer); buffer = NULL; } if (bufferoffset == -1) { TIFFError(TIFF2PDF_MODULE, "Error writing encoded tile to output PDF %s", TIFFFileName(output)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } written = t2p->outputwritten; return(written); } #ifdef OJPEG_SUPPORT static int t2p_process_ojpeg_tables(T2P* t2p, TIFF* input){ uint16 proc=0; void* q; uint32 q_length=0; void* dc; uint32 dc_length=0; void* ac; uint32 ac_length=0; uint16* lp; uint16* pt; uint16 h_samp=1; uint16 v_samp=1; unsigned char* ojpegdata; uint16 table_count; uint32 offset_table; uint32 offset_ms_l; uint32 code_count; uint32 i=0; uint32 dest=0; uint16 ri=0; uint32 rows=0; if(!TIFFGetField(input, TIFFTAG_JPEGPROC, &proc)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGProc field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(proc!=JPEGPROC_BASELINE && proc!=JPEGPROC_LOSSLESS){ TIFFError(TIFF2PDF_MODULE, "Bad JPEGProc field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(!TIFFGetField(input, TIFFTAG_JPEGQTABLES, &q_length, &q)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGQTables field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(q_length < (64U * t2p->tiff_samplesperpixel)){ TIFFError(TIFF2PDF_MODULE, "Bad JPEGQTables field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(!TIFFGetField(input, TIFFTAG_JPEGDCTABLES, &dc_length, &dc)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGDCTables field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(proc==JPEGPROC_BASELINE){ if(!TIFFGetField(input, TIFFTAG_JPEGACTABLES, &ac_length, &ac)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGACTables field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } } else { if(!TIFFGetField(input, TIFFTAG_JPEGLOSSLESSPREDICTORS, &lp)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGLosslessPredictors field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } if(!TIFFGetField(input, TIFFTAG_JPEGPOINTTRANSFORM, &pt)){ TIFFError(TIFF2PDF_MODULE, "Missing JPEGPointTransform field in OJPEG image %s", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } } if(!TIFFGetField(input, TIFFTAG_YCBCRSUBSAMPLING, &h_samp, &v_samp)){ h_samp=1; v_samp=1; } if(t2p->pdf_ojpegdata != NULL){ _TIFFfree(t2p->pdf_ojpegdata); t2p->pdf_ojpegdata=NULL; } t2p->pdf_ojpegdata = _TIFFmalloc(2048); if(t2p->pdf_ojpegdata == NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_process_ojpeg_tables, %s", 2048, TIFFFileName(input)); return(0); } _TIFFmemset(t2p->pdf_ojpegdata, 0x00, 2048); t2p->pdf_ojpegdatalength = 0; table_count=t2p->tiff_samplesperpixel; if(proc==JPEGPROC_BASELINE){ if(table_count>2) table_count=2; } ojpegdata=(unsigned char*)t2p->pdf_ojpegdata; ojpegdata[t2p->pdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xd8; ojpegdata[t2p->pdf_ojpegdatalength++]=0xff; if(proc==JPEGPROC_BASELINE){ ojpegdata[t2p->pdf_ojpegdatalength++]=0xc0; } else { ojpegdata[t2p->pdf_ojpegdatalength++]=0xc3; } ojpegdata[t2p->pdf_ojpegdatalength++]=0x00; ojpegdata[t2p->pdf_ojpegdatalength++]=(8 + 3*t2p->tiff_samplesperpixel); ojpegdata[t2p->pdf_ojpegdatalength++]=(t2p->tiff_bitspersample & 0xff); if(TIFFIsTiled(input)){ ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength >> 8) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength ) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth >> 8) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth ) & 0xff; } else { ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_length >> 8) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_length ) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_width >> 8) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= (t2p->tiff_width ) & 0xff; } ojpegdata[t2p->pdf_ojpegdatalength++]=(t2p->tiff_samplesperpixel & 0xff); for(i=0;itiff_samplesperpixel;i++){ ojpegdata[t2p->pdf_ojpegdatalength++]=i; if(i==0){ ojpegdata[t2p->pdf_ojpegdatalength] |= h_samp<<4 & 0xf0;; ojpegdata[t2p->pdf_ojpegdatalength++] |= v_samp & 0x0f; } else { ojpegdata[t2p->pdf_ojpegdatalength++]= 0x11; } ojpegdata[t2p->pdf_ojpegdatalength++]=i; } for(dest=0;desttiff_samplesperpixel;dest++){ ojpegdata[t2p->pdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xdb; ojpegdata[t2p->pdf_ojpegdatalength++]=0x00; ojpegdata[t2p->pdf_ojpegdatalength++]=0x43; ojpegdata[t2p->pdf_ojpegdatalength++]=dest; _TIFFmemcpy( &(ojpegdata[t2p->pdf_ojpegdatalength++]), &(((unsigned char*)q)[64*dest]), 64); t2p->pdf_ojpegdatalength+=64; } offset_table=0; for(dest=0;destpdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xc4; offset_ms_l=t2p->pdf_ojpegdatalength; t2p->pdf_ojpegdatalength+=2; ojpegdata[t2p->pdf_ojpegdatalength++]=dest & 0x0f; _TIFFmemcpy( &(ojpegdata[t2p->pdf_ojpegdatalength]), &(((unsigned char*)dc)[offset_table]), 16); code_count=0; offset_table+=16; for(i=0;i<16;i++){ code_count+=ojpegdata[t2p->pdf_ojpegdatalength++]; } ojpegdata[offset_ms_l]=((19+code_count)>>8) & 0xff; ojpegdata[offset_ms_l+1]=(19+code_count) & 0xff; _TIFFmemcpy( &(ojpegdata[t2p->pdf_ojpegdatalength]), &(((unsigned char*)dc)[offset_table]), code_count); offset_table+=code_count; t2p->pdf_ojpegdatalength+=code_count; } if(proc==JPEGPROC_BASELINE){ offset_table=0; for(dest=0;destpdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xc4; offset_ms_l=t2p->pdf_ojpegdatalength; t2p->pdf_ojpegdatalength+=2; ojpegdata[t2p->pdf_ojpegdatalength] |= 0x10; ojpegdata[t2p->pdf_ojpegdatalength++] |=dest & 0x0f; _TIFFmemcpy( &(ojpegdata[t2p->pdf_ojpegdatalength]), &(((unsigned char*)ac)[offset_table]), 16); code_count=0; offset_table+=16; for(i=0;i<16;i++){ code_count+=ojpegdata[t2p->pdf_ojpegdatalength++]; } ojpegdata[offset_ms_l]=((19+code_count)>>8) & 0xff; ojpegdata[offset_ms_l+1]=(19+code_count) & 0xff; _TIFFmemcpy( &(ojpegdata[t2p->pdf_ojpegdatalength]), &(((unsigned char*)ac)[offset_table]), code_count); offset_table+=code_count; t2p->pdf_ojpegdatalength+=code_count; } } if(TIFFNumberOfStrips(input)>1){ ojpegdata[t2p->pdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xdd; ojpegdata[t2p->pdf_ojpegdatalength++]=0x00; ojpegdata[t2p->pdf_ojpegdatalength++]=0x04; h_samp*=8; v_samp*=8; ri=(t2p->tiff_width+h_samp-1) / h_samp; TIFFGetField(input, TIFFTAG_ROWSPERSTRIP, &rows); ri*=(rows+v_samp-1)/v_samp; ojpegdata[t2p->pdf_ojpegdatalength++]= (ri>>8) & 0xff; ojpegdata[t2p->pdf_ojpegdatalength++]= ri & 0xff; } ojpegdata[t2p->pdf_ojpegdatalength++]=0xff; ojpegdata[t2p->pdf_ojpegdatalength++]=0xda; ojpegdata[t2p->pdf_ojpegdatalength++]=0x00; ojpegdata[t2p->pdf_ojpegdatalength++]=(6 + 2*t2p->tiff_samplesperpixel); ojpegdata[t2p->pdf_ojpegdatalength++]=t2p->tiff_samplesperpixel & 0xff; for(i=0;itiff_samplesperpixel;i++){ ojpegdata[t2p->pdf_ojpegdatalength++]= i & 0xff; if(proc==JPEGPROC_BASELINE){ ojpegdata[t2p->pdf_ojpegdatalength] |= ( ( (i>(table_count-1U)) ? (table_count-1U) : i) << 4U) & 0xf0; ojpegdata[t2p->pdf_ojpegdatalength++] |= ( (i>(table_count-1U)) ? (table_count-1U) : i) & 0x0f; } else { ojpegdata[t2p->pdf_ojpegdatalength++] = (i << 4) & 0xf0; } } if(proc==JPEGPROC_BASELINE){ t2p->pdf_ojpegdatalength++; ojpegdata[t2p->pdf_ojpegdatalength++]=0x3f; t2p->pdf_ojpegdatalength++; } else { ojpegdata[t2p->pdf_ojpegdatalength++]= (lp[0] & 0xff); t2p->pdf_ojpegdatalength++; ojpegdata[t2p->pdf_ojpegdatalength++]= (pt[0] & 0x0f); } return(1); } #endif #ifdef JPEG_SUPPORT static int t2p_process_jpeg_strip( unsigned char* strip, tsize_t* striplength, unsigned char* buffer, tsize_t* bufferoffset, tstrip_t no, uint32 height){ tsize_t i=0; uint16 ri =0; uint16 v_samp=1; uint16 h_samp=1; int j=0; i++; while(i<(*striplength)){ switch( strip[i] ){ case 0xd8: i+=2; break; case 0xc0: case 0xc1: case 0xc3: case 0xc9: case 0xca: if(no==0){ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); for(j=0;j>4) > h_samp) h_samp = (buffer[*bufferoffset+11+(2*j)]>>4); if( (buffer[*bufferoffset+11+(2*j)] & 0x0f) > v_samp) v_samp = (buffer[*bufferoffset+11+(2*j)] & 0x0f); } v_samp*=8; h_samp*=8; ri=((( ((uint16)(buffer[*bufferoffset+5])<<8) | (uint16)(buffer[*bufferoffset+6]) )+v_samp-1)/ v_samp); ri*=((( ((uint16)(buffer[*bufferoffset+7])<<8) | (uint16)(buffer[*bufferoffset+8]) )+h_samp-1)/ h_samp); buffer[*bufferoffset+5]= (unsigned char) ((height>>8) & 0xff); buffer[*bufferoffset+6]= (unsigned char) (height & 0xff); *bufferoffset+=strip[i+2]+2; i+=strip[i+2]+2; buffer[(*bufferoffset)++]=0xff; buffer[(*bufferoffset)++]=0xdd; buffer[(*bufferoffset)++]=0x00; buffer[(*bufferoffset)++]=0x04; buffer[(*bufferoffset)++]=(ri >> 8) & 0xff; buffer[(*bufferoffset)++]= ri & 0xff; } else { i+=strip[i+2]+2; } break; case 0xc4: case 0xdb: _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); *bufferoffset+=strip[i+2]+2; i+=strip[i+2]+2; break; case 0xda: if(no==0){ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); *bufferoffset+=strip[i+2]+2; i+=strip[i+2]+2; } else { buffer[(*bufferoffset)++]=0xff; buffer[(*bufferoffset)++]= (unsigned char)(0xd0 | ((no-1)%8)); i+=strip[i+2]+2; } _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), (*striplength)-i-1); *bufferoffset+=(*striplength)-i-1; return(1); default: i+=strip[i+2]+2; } } return(0); } #endif /* This functions converts a tilewidth x tilelength buffer of samples into an edgetilewidth x tilelength buffer of samples. */ static void t2p_tile_collapse_left( tdata_t buffer, tsize_t scanwidth, uint32 tilewidth, uint32 edgetilewidth, uint32 tilelength){ uint32 i=0; tsize_t edgescanwidth=0; edgescanwidth = (scanwidth * edgetilewidth + (tilewidth - 1))/ tilewidth; for(i=0;it2p_error = T2P_ERR_ERROR; return; } t2p_enable(output); return; } static tsize_t t2p_sample_planar_separate_to_contig(T2P* t2p, unsigned char* buffer, unsigned char* samplebuffer, tsize_t samplebuffersize){ tsize_t stride=0; tsize_t i=0; tsize_t j=0; stride=samplebuffersize/t2p->tiff_samplesperpixel; for(i=0;itiff_samplesperpixel;j++){ buffer[i*t2p->tiff_samplesperpixel + j] = samplebuffer[i + j*stride]; } } return(samplebuffersize); } static tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){ uint32 sample_count=0; uint16 component_count=0; uint32 palette_offset=0; uint32 sample_offset=0; uint32 i=0; uint32 j=0; sample_count=t2p->tiff_width*t2p->tiff_length; component_count=t2p->tiff_samplesperpixel; for(i=sample_count;i>0;i--){ palette_offset=buffer[i-1] * component_count; sample_offset= (i-1) * component_count; for(j=0;jpdf_palette[palette_offset+j]; } } return(0); } /* This functions converts in place a buffer of ABGR interleaved data into RGB interleaved data, discarding A. */ static tsize_t t2p_sample_abgr_to_rgb(tdata_t data, uint32 samplecount) { uint32 i=0; uint32 sample=0; for(i=0;i>8) & 0xff); ((char*)data)[i*3+2]= (char) ((sample>>16) & 0xff); } return(i*3); } /* * This functions converts in place a buffer of RGBA interleaved data * into RGB interleaved data, discarding A. */ static tsize_t t2p_sample_rgbaa_to_rgb(tdata_t data, uint32 samplecount) { uint32 i; for(i = 0; i < samplecount; i++) memcpy((uint8*)data + i * 3, (uint8*)data + i * 4, 3); return(i * 3); } /* * This functions converts in place a buffer of RGBA interleaved data * into RGB interleaved data, adding 255-A to each component sample. */ static tsize_t t2p_sample_rgba_to_rgb(tdata_t data, uint32 samplecount) { uint32 i = 0; uint32 sample = 0; uint8 alpha = 0; for (i = 0; i < samplecount; i++) { sample=((uint32*)data)[i]; alpha=(uint8)((255 - (sample & 0xff))); ((uint8 *)data)[i * 3] = (uint8) ((sample >> 24) & 0xff) + alpha; ((uint8 *)data)[i * 3 + 1] = (uint8) ((sample >> 16) & 0xff) + alpha; ((uint8 *)data)[i * 3 + 2] = (uint8) ((sample >> 8) & 0xff) + alpha; } return (i * 3); } /* This function converts the a and b samples of Lab data from signed to unsigned. */ static tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t buffer, uint32 samplecount){ uint32 i=0; for(i=0;ipdf_majorversion&0xff, t2p->pdf_minorversion&0xff); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t)"\n%\342\343\317\323\n", 7); return(written); } /* This function writes the beginning of a PDF object to output. */ static tsize_t t2p_write_pdf_obj_start(uint32 number, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; buflen=sprintf(buffer, "%lu", (unsigned long)number); written += t2pWriteFile(output, (tdata_t) buffer, buflen ); written += t2pWriteFile(output, (tdata_t) " 0 obj\n", 7); return(written); } /* This function writes the end of a PDF object to output. */ static tsize_t t2p_write_pdf_obj_end(TIFF* output){ tsize_t written=0; written += t2pWriteFile(output, (tdata_t) "endobj\n", 7); return(written); } /* This function writes a PDF string object to output. */ static tsize_t t2p_write_pdf_string(unsigned char* pdfstr, TIFF* output){ tsize_t written = 0; uint32 i = 0; char buffer[64]; uint32 len = 0; len = strlen((char *)pdfstr); written += t2pWriteFile(output, (tdata_t) "(", 1); for (i=0; i>\n", 4); return(written); } /* This function writes a number to output. */ static tsize_t t2p_write_pdf_stream_length(tsize_t len, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; buflen=sprintf(buffer, "%lu", (unsigned long)len); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "\n", 1); return(written); } /* This function writes the PDF Catalog structure to output. */ static tsize_t t2p_write_pdf_catalog(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; written += t2pWriteFile(output, (tdata_t)"<< \n/Type /Catalog \n/Pages ", 27); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_pages); written += t2pWriteFile(output, (tdata_t) buffer, buflen ); written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); if(t2p->pdf_fitwindow){ written += t2pWriteFile(output, (tdata_t) "/ViewerPreferences <>\n", 39); } written += t2pWriteFile(output, (tdata_t)">>\n", 3); return(written); } /* This function writes the PDF Info structure to output. */ static tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output){ tsize_t written = 0; unsigned char* info; char buffer[512]; int buflen = 0; (void) buflen; if(t2p->pdf_datetime==NULL){ t2p_pdf_tifftime(t2p, input); } if(strlen((char *)t2p->pdf_datetime) > 0){ written += t2pWriteFile(output, (tdata_t) "<< \n/CreationDate ", 18); written += t2p_write_pdf_string(t2p->pdf_datetime, output); written += t2pWriteFile(output, (tdata_t) "\n/ModDate ", 10); written += t2p_write_pdf_string(t2p->pdf_datetime, output); } written += t2pWriteFile(output, (tdata_t) "\n/Producer ", 11); _TIFFmemset((tdata_t)buffer, 0x00, sizeof(buffer)); buflen = sprintf(buffer, "libtiff / tiff2pdf - %d", TIFFLIB_VERSION); written += t2p_write_pdf_string((unsigned char*)buffer, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); if(t2p->pdf_creator != NULL){ if(strlen((char *)t2p->pdf_creator)>0){ if(strlen((char *)t2p->pdf_creator) > 511) { t2p->pdf_creator[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); written += t2p_write_pdf_string(t2p->pdf_creator, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } else{ if( TIFFGetField(input, TIFFTAG_SOFTWARE, &info) != 0){ if(strlen((char *)info) > 511) { info[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); written += t2p_write_pdf_string(info, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } if(t2p->pdf_author != NULL) { if(strlen((char *)t2p->pdf_author) > 0) { if(strlen((char *)t2p->pdf_author) > 511) { t2p->pdf_author[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Author ", 8); written += t2p_write_pdf_string(t2p->pdf_author, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } else{ if( TIFFGetField(input, TIFFTAG_ARTIST, &info) != 0){ if(strlen((char *)info) > 511) { info[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Author ", 8); written += t2p_write_pdf_string(info, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } else if ( TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0){ if(strlen((char *)info) > 511) { info[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Author ", 8); written += t2p_write_pdf_string(info, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } if(t2p->pdf_title != NULL) { if(strlen((char *)t2p->pdf_title) > 0) { if(strlen((char *)t2p->pdf_title) > 511) { t2p->pdf_title[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Title ", 7); written += t2p_write_pdf_string(t2p->pdf_title, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } else{ if( TIFFGetField(input, TIFFTAG_DOCUMENTNAME, &info) != 0){ if(strlen((char *)info) > 511) { info[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Title ", 7); written += t2p_write_pdf_string(info, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } if(t2p->pdf_subject != NULL) { if(strlen((char *)t2p->pdf_subject) > 0) { if(strlen((char *)t2p->pdf_subject) > 511) { t2p->pdf_subject[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); written += t2p_write_pdf_string(t2p->pdf_subject, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } else { if(TIFFGetField(input, TIFFTAG_IMAGEDESCRIPTION, &info) != 0) { if(strlen((char *)info) > 511) { info[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); written += t2p_write_pdf_string(info, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } if(t2p->pdf_keywords != NULL) { if(strlen((char *)t2p->pdf_keywords) > 0) { if(strlen((char *)t2p->pdf_keywords) > 511) { t2p->pdf_keywords[512] = '\0'; } written += t2pWriteFile(output, (tdata_t) "/Keywords ", 10); written += t2p_write_pdf_string(t2p->pdf_keywords, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); } } written += t2pWriteFile(output, (tdata_t) ">> \n", 4); return(written); } /* * This function fills a string of a T2P struct with the current time as a PDF * date string, it is called by t2p_pdf_tifftime. */ static void t2p_pdf_currenttime(T2P* t2p) { struct tm* currenttime; time_t timenow; timenow=time(0); currenttime=localtime(&timenow); sprintf((char *)t2p->pdf_datetime, "D:%.4d%.2d%.2d%.2d%.2d%.2d", (currenttime->tm_year+1900) % 65536, (currenttime->tm_mon+1) % 256, (currenttime->tm_mday) % 256, (currenttime->tm_hour) % 256, (currenttime->tm_min) % 256, (currenttime->tm_sec) % 256); return; } /* * This function fills a string of a T2P struct with the date and time of a * TIFF file if it exists or the current time as a PDF date string. */ static void t2p_pdf_tifftime(T2P* t2p, TIFF* input){ char* datetime; t2p->pdf_datetime = (unsigned char*) _TIFFmalloc(19); if(t2p->pdf_datetime == NULL){ TIFFError(TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_pdf_tiff_time", 17); t2p->t2p_error = T2P_ERR_ERROR; return; } t2p->pdf_datetime[16] = '\0'; if( TIFFGetField(input, TIFFTAG_DATETIME, &datetime) != 0 && (strlen(datetime) >= 19) ){ t2p->pdf_datetime[0]='D'; t2p->pdf_datetime[1]=':'; t2p->pdf_datetime[2]=datetime[0]; t2p->pdf_datetime[3]=datetime[1]; t2p->pdf_datetime[4]=datetime[2]; t2p->pdf_datetime[5]=datetime[3]; t2p->pdf_datetime[6]=datetime[5]; t2p->pdf_datetime[7]=datetime[6]; t2p->pdf_datetime[8]=datetime[8]; t2p->pdf_datetime[9]=datetime[9]; t2p->pdf_datetime[10]=datetime[11]; t2p->pdf_datetime[11]=datetime[12]; t2p->pdf_datetime[12]=datetime[14]; t2p->pdf_datetime[13]=datetime[15]; t2p->pdf_datetime[14]=datetime[17]; t2p->pdf_datetime[15]=datetime[18]; } else { t2p_pdf_currenttime(t2p); } return; } /* * This function writes a PDF Pages Tree structure to output. */ static tsize_t t2p_write_pdf_pages(T2P* t2p, TIFF* output) { tsize_t written=0; tdir_t i=0; char buffer[16]; int buflen=0; int page=0; written += t2pWriteFile(output, (tdata_t) "<< \n/Type /Pages \n/Kids [ ", 26); page = t2p->pdf_pages+1; for (i=0;itiff_pagecount;i++){ buflen=sprintf(buffer, "%d", page); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); if ( ((i+1)%8)==0 ) { written += t2pWriteFile(output, (tdata_t) "\n", 1); } page +=3; page += t2p->tiff_pages[i].page_extra; if(t2p->tiff_pages[i].page_tilecount>0){ page += (2 * t2p->tiff_pages[i].page_tilecount); } else { page +=2; } } written += t2pWriteFile(output, (tdata_t) "] \n/Count ", 10); _TIFFmemset(buffer, 0x00, 16); buflen=sprintf(buffer, "%d", t2p->tiff_pagecount); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " \n>> \n", 6); return(written); } /* This function writes a PDF Page structure to output. */ static tsize_t t2p_write_pdf_page(uint32 object, T2P* t2p, TIFF* output){ unsigned int i=0; tsize_t written=0; char buffer[16]; int buflen=0; written += t2pWriteFile(output, (tdata_t) "<<\n/Type /Page \n/Parent ", 24); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_pages); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); written += t2pWriteFile(output, (tdata_t) "/MediaBox [", 11); buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x2); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y2); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "] \n", 3); written += t2pWriteFile(output, (tdata_t) "/Contents ", 10); buflen=sprintf(buffer, "%lu", (unsigned long)(object + 1)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); written += t2pWriteFile(output, (tdata_t) "/Resources << \n", 15); if( t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount != 0 ){ written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12); for(i=0;itiff_tiles[t2p->pdf_page].tiles_tilecount;i++){ written += t2pWriteFile(output, (tdata_t) "/Im", 3); buflen = sprintf(buffer, "%u", t2p->pdf_page+1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "_", 1); buflen = sprintf(buffer, "%u", i+1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); buflen = sprintf( buffer, "%lu", (unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); if(i%4==3){ written += t2pWriteFile(output, (tdata_t) "\n", 1); } } written += t2pWriteFile(output, (tdata_t) ">>\n", 3); } else { written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12); written += t2pWriteFile(output, (tdata_t) "/Im", 3); buflen = sprintf(buffer, "%u", t2p->pdf_page+1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); buflen = sprintf( buffer, "%lu", (unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); written += t2pWriteFile(output, (tdata_t) ">>\n", 3); } if(t2p->tiff_transferfunctioncount != 0) { written += t2pWriteFile(output, (tdata_t) "/ExtGState <<", 13); t2pWriteFile(output, (tdata_t) "/GS1 ", 5); buflen = sprintf( buffer, "%lu", (unsigned long)(object + 3)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); written += t2pWriteFile(output, (tdata_t) ">> \n", 4); } written += t2pWriteFile(output, (tdata_t) "/ProcSet [ ", 11); if(t2p->pdf_colorspace == T2P_CS_BILEVEL || t2p->pdf_colorspace == T2P_CS_GRAY ){ written += t2pWriteFile(output, (tdata_t) "/ImageB ", 8); } else { written += t2pWriteFile(output, (tdata_t) "/ImageC ", 8); if(t2p->pdf_colorspace & T2P_CS_PALETTE){ written += t2pWriteFile(output, (tdata_t) "/ImageI ", 8); } } written += t2pWriteFile(output, (tdata_t) "]\n>>\n>>\n", 8); return(written); } /* This function composes the page size and image and tile locations on a page. */ static void t2p_compose_pdf_page(T2P* t2p){ uint32 i=0; uint32 i2=0; T2P_TILE* tiles=NULL; T2P_BOX* boxp=NULL; uint32 tilecountx=0; uint32 tilecounty=0; uint32 tilewidth=0; uint32 tilelength=0; int istiled=0; float f=0; t2p->pdf_xres = t2p->tiff_xres; t2p->pdf_yres = t2p->tiff_yres; if(t2p->pdf_overrideres) { t2p->pdf_xres = t2p->pdf_defaultxres; t2p->pdf_yres = t2p->pdf_defaultyres; } if(t2p->pdf_xres == 0.0) t2p->pdf_xres = t2p->pdf_defaultxres; if(t2p->pdf_yres == 0.0) t2p->pdf_yres = t2p->pdf_defaultyres; if (t2p->tiff_resunit != RESUNIT_CENTIMETER /* RESUNIT_NONE and */ && t2p->tiff_resunit != RESUNIT_INCH) { /* other cases */ t2p->pdf_imagewidth = ((float)(t2p->tiff_width))/t2p->pdf_xres; t2p->pdf_imagelength = ((float)(t2p->tiff_length))/t2p->pdf_yres; } else { t2p->pdf_imagewidth = ((float)(t2p->tiff_width))*PS_UNIT_SIZE/t2p->pdf_xres; t2p->pdf_imagelength = ((float)(t2p->tiff_length))*PS_UNIT_SIZE/t2p->pdf_yres; } if(t2p->pdf_overridepagesize != 0) { t2p->pdf_pagewidth = t2p->pdf_defaultpagewidth; t2p->pdf_pagelength = t2p->pdf_defaultpagelength; } else { t2p->pdf_pagewidth = t2p->pdf_imagewidth; t2p->pdf_pagelength = t2p->pdf_imagelength; } t2p->pdf_mediabox.x1=0.0; t2p->pdf_mediabox.y1=0.0; t2p->pdf_mediabox.x2=t2p->pdf_pagewidth; t2p->pdf_mediabox.y2=t2p->pdf_pagelength; t2p->pdf_imagebox.x1=0.0; t2p->pdf_imagebox.y1=0.0; t2p->pdf_imagebox.x2=t2p->pdf_imagewidth; t2p->pdf_imagebox.y2=t2p->pdf_imagelength; if(t2p->pdf_overridepagesize!=0){ t2p->pdf_imagebox.x1+=((t2p->pdf_pagewidth-t2p->pdf_imagewidth)/2.0F); t2p->pdf_imagebox.y1+=((t2p->pdf_pagelength-t2p->pdf_imagelength)/2.0F); t2p->pdf_imagebox.x2+=((t2p->pdf_pagewidth-t2p->pdf_imagewidth)/2.0F); t2p->pdf_imagebox.y2+=((t2p->pdf_pagelength-t2p->pdf_imagelength)/2.0F); } if(t2p->tiff_orientation > 4){ f=t2p->pdf_mediabox.x2; t2p->pdf_mediabox.x2=t2p->pdf_mediabox.y2; t2p->pdf_mediabox.y2=f; } istiled=((t2p->tiff_tiles[t2p->pdf_page]).tiles_tilecount==0) ? 0 : 1; if(istiled==0){ t2p_compose_pdf_page_orient(&(t2p->pdf_imagebox), t2p->tiff_orientation); return; } else { tilewidth=(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilewidth; tilelength=(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilelength; tilecountx=(t2p->tiff_width + tilewidth -1)/ tilewidth; (t2p->tiff_tiles[t2p->pdf_page]).tiles_tilecountx=tilecountx; tilecounty=(t2p->tiff_length + tilelength -1)/ tilelength; (t2p->tiff_tiles[t2p->pdf_page]).tiles_tilecounty=tilecounty; (t2p->tiff_tiles[t2p->pdf_page]).tiles_edgetilewidth= t2p->tiff_width % tilewidth; (t2p->tiff_tiles[t2p->pdf_page]).tiles_edgetilelength= t2p->tiff_length % tilelength; tiles=(t2p->tiff_tiles[t2p->pdf_page]).tiles_tiles; for(i2=0;i2x1 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * i * tilewidth) / (float)t2p->tiff_width); boxp->x2 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * (i+1) * tilewidth) / (float)t2p->tiff_width); boxp->y1 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * (i2+1) * tilelength) / (float)t2p->tiff_length); boxp->y2 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * i2 * tilelength) / (float)t2p->tiff_length); } boxp=&(tiles[i2*tilecountx+i].tile_box); boxp->x1 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * i * tilewidth) / (float)t2p->tiff_width); boxp->x2 = t2p->pdf_imagebox.x2; boxp->y1 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * (i2+1) * tilelength) / (float)t2p->tiff_length); boxp->y2 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * i2 * tilelength) / (float)t2p->tiff_length); } for(i=0;ix1 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * i * tilewidth) / (float)t2p->tiff_width); boxp->x2 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * (i+1) * tilewidth) / (float)t2p->tiff_width); boxp->y1 = t2p->pdf_imagebox.y1; boxp->y2 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * i2 * tilelength) / (float)t2p->tiff_length); } boxp=&(tiles[i2*tilecountx+i].tile_box); boxp->x1 = t2p->pdf_imagebox.x1 + ((float)(t2p->pdf_imagewidth * i * tilewidth) / (float)t2p->tiff_width); boxp->x2 = t2p->pdf_imagebox.x2; boxp->y1 = t2p->pdf_imagebox.y1; boxp->y2 = t2p->pdf_imagebox.y2 - ((float)(t2p->pdf_imagelength * i2 * tilelength) / (float)t2p->tiff_length); } if(t2p->tiff_orientation==0 || t2p->tiff_orientation==1){ for(i=0;i<(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilecount;i++){ t2p_compose_pdf_page_orient( &(tiles[i].tile_box) , 0); } return; } for(i=0;i<(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilecount;i++){ boxp=&(tiles[i].tile_box); boxp->x1 -= t2p->pdf_imagebox.x1; boxp->x2 -= t2p->pdf_imagebox.x1; boxp->y1 -= t2p->pdf_imagebox.y1; boxp->y2 -= t2p->pdf_imagebox.y1; if(t2p->tiff_orientation==2 || t2p->tiff_orientation==3){ boxp->x1 = t2p->pdf_imagebox.x2 - t2p->pdf_imagebox.x1 - boxp->x1; boxp->x2 = t2p->pdf_imagebox.x2 - t2p->pdf_imagebox.x1 - boxp->x2; } if(t2p->tiff_orientation==3 || t2p->tiff_orientation==4){ boxp->y1 = t2p->pdf_imagebox.y2 - t2p->pdf_imagebox.y1 - boxp->y1; boxp->y2 = t2p->pdf_imagebox.y2 - t2p->pdf_imagebox.y1 - boxp->y2; } if(t2p->tiff_orientation==8 || t2p->tiff_orientation==5){ boxp->y1 = t2p->pdf_imagebox.y2 - t2p->pdf_imagebox.y1 - boxp->y1; boxp->y2 = t2p->pdf_imagebox.y2 - t2p->pdf_imagebox.y1 - boxp->y2; } if(t2p->tiff_orientation==5 || t2p->tiff_orientation==6){ boxp->x1 = t2p->pdf_imagebox.x2 - t2p->pdf_imagebox.x1 - boxp->x1; boxp->x2 = t2p->pdf_imagebox.x2 - t2p->pdf_imagebox.x1 - boxp->x2; } if(t2p->tiff_orientation > 4){ f=boxp->x1; boxp->x1 = boxp->y1; boxp->y1 = f; f=boxp->x2; boxp->x2 = boxp->y2; boxp->y2 = f; t2p_compose_pdf_page_orient_flip(boxp, t2p->tiff_orientation); } else { t2p_compose_pdf_page_orient(boxp, t2p->tiff_orientation); } } return; } static void t2p_compose_pdf_page_orient(T2P_BOX* boxp, uint16 orientation){ float m1[9]; float f=0.0; if( boxp->x1 > boxp->x2){ f=boxp->x1; boxp->x1=boxp->x2; boxp->x2 = f; } if( boxp->y1 > boxp->y2){ f=boxp->y1; boxp->y1=boxp->y2; boxp->y2 = f; } boxp->mat[0]=m1[0]=boxp->x2-boxp->x1; boxp->mat[1]=m1[1]=0.0; boxp->mat[2]=m1[2]=0.0; boxp->mat[3]=m1[3]=0.0; boxp->mat[4]=m1[4]=boxp->y2-boxp->y1; boxp->mat[5]=m1[5]=0.0; boxp->mat[6]=m1[6]=boxp->x1; boxp->mat[7]=m1[7]=boxp->y1; boxp->mat[8]=m1[8]=1.0; switch(orientation){ case 0: case 1: break; case 2: boxp->mat[0]=0.0F-m1[0]; boxp->mat[6]+=m1[0]; break; case 3: boxp->mat[0]=0.0F-m1[0]; boxp->mat[4]=0.0F-m1[4]; boxp->mat[6]+=m1[0]; boxp->mat[7]+=m1[4]; break; case 4: boxp->mat[4]=0.0F-m1[4]; boxp->mat[7]+=m1[4]; break; case 5: boxp->mat[0]=0.0F; boxp->mat[1]=0.0F-m1[0]; boxp->mat[3]=0.0F-m1[4]; boxp->mat[4]=0.0F; boxp->mat[6]+=m1[4]; boxp->mat[7]+=m1[0]; break; case 6: boxp->mat[0]=0.0F; boxp->mat[1]=0.0F-m1[0]; boxp->mat[3]=m1[4]; boxp->mat[4]=0.0F; boxp->mat[7]+=m1[0]; break; case 7: boxp->mat[0]=0.0F; boxp->mat[1]=m1[0]; boxp->mat[3]=m1[4]; boxp->mat[4]=0.0F; break; case 8: boxp->mat[0]=0.0F; boxp->mat[1]=m1[0]; boxp->mat[3]=0.0F-m1[4]; boxp->mat[4]=0.0F; boxp->mat[6]+=m1[4]; break; } return; } static void t2p_compose_pdf_page_orient_flip(T2P_BOX* boxp, uint16 orientation){ float m1[9]; float f=0.0; if( boxp->x1 > boxp->x2){ f=boxp->x1; boxp->x1=boxp->x2; boxp->x2 = f; } if( boxp->y1 > boxp->y2){ f=boxp->y1; boxp->y1=boxp->y2; boxp->y2 = f; } boxp->mat[0]=m1[0]=boxp->x2-boxp->x1; boxp->mat[1]=m1[1]=0.0F; boxp->mat[2]=m1[2]=0.0F; boxp->mat[3]=m1[3]=0.0F; boxp->mat[4]=m1[4]=boxp->y2-boxp->y1; boxp->mat[5]=m1[5]=0.0F; boxp->mat[6]=m1[6]=boxp->x1; boxp->mat[7]=m1[7]=boxp->y1; boxp->mat[8]=m1[8]=1.0F; switch(orientation){ case 5: boxp->mat[0]=0.0F; boxp->mat[1]=0.0F-m1[4]; boxp->mat[3]=0.0F-m1[0]; boxp->mat[4]=0.0F; boxp->mat[6]+=m1[0]; boxp->mat[7]+=m1[4]; break; case 6: boxp->mat[0]=0.0F; boxp->mat[1]=0.0F-m1[4]; boxp->mat[3]=m1[0]; boxp->mat[4]=0.0F; boxp->mat[7]+=m1[4]; break; case 7: boxp->mat[0]=0.0F; boxp->mat[1]=m1[4]; boxp->mat[3]=m1[0]; boxp->mat[4]=0.0F; break; case 8: boxp->mat[0]=0.0F; boxp->mat[1]=m1[4]; boxp->mat[3]=0.0F-m1[0]; boxp->mat[4]=0.0F; boxp->mat[6]+=m1[0]; break; } return; } /* This function writes a PDF Contents stream to output. */ static tsize_t t2p_write_pdf_page_content_stream(T2P* t2p, TIFF* output){ tsize_t written=0; ttile_t i=0; char buffer[512]; int buflen=0; T2P_BOX box; if(t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount>0){ for(i=0;itiff_tiles[t2p->pdf_page].tiles_tilecount; i++){ box=t2p->tiff_tiles[t2p->pdf_page].tiles_tiles[i].tile_box; buflen=sprintf(buffer, "q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d_%ld Do Q\n", t2p->tiff_transferfunctioncount?"/GS1 gs ":"", box.mat[0], box.mat[1], box.mat[3], box.mat[4], box.mat[6], box.mat[7], t2p->pdf_page + 1, (long)(i + 1)); written += t2p_write_pdf_stream(buffer, buflen, output); } } else { box=t2p->pdf_imagebox; buflen=sprintf(buffer, "q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d Do Q\n", t2p->tiff_transferfunctioncount?"/GS1 gs ":"", box.mat[0], box.mat[1], box.mat[3], box.mat[4], box.mat[6], box.mat[7], t2p->pdf_page+1); written += t2p_write_pdf_stream(buffer, buflen, output); } return(written); } /* This function writes a PDF Image XObject stream dictionary to output. */ static tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t tile, T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; written += t2p_write_pdf_stream_dict(0, t2p->pdf_xrefcount+1, output); written += t2pWriteFile(output, (tdata_t) "/Type /XObject \n/Subtype /Image \n/Name /Im", 42); buflen=sprintf(buffer, "%u", t2p->pdf_page+1); written += t2pWriteFile(output, (tdata_t) buffer, buflen); if(tile != 0){ written += t2pWriteFile(output, (tdata_t) "_", 1); buflen=sprintf(buffer, "%lu", (unsigned long)tile); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } written += t2pWriteFile(output, (tdata_t) "\n/Width ", 8); _TIFFmemset((tdata_t)buffer, 0x00, 16); if(tile==0){ buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_width); } else { if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){ buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth); } else { buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth); } } written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "\n/Height ", 9); _TIFFmemset((tdata_t)buffer, 0x00, 16); if(tile==0){ buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_length); } else { if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){ buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); } else { buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); } } written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "\n/BitsPerComponent ", 19); _TIFFmemset((tdata_t)buffer, 0x00, 16); buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "\n/ColorSpace ", 13); written += t2p_write_pdf_xobject_cs(t2p, output); if (t2p->pdf_image_interpolate) written += t2pWriteFile(output, (tdata_t) "\n/Interpolate true", 18); if( (t2p->pdf_switchdecode != 0) #ifdef CCITT_SUPPORT && ! (t2p->pdf_colorspace == T2P_CS_BILEVEL && t2p->pdf_compression == T2P_COMPRESS_G4) #endif ){ written += t2p_write_pdf_xobject_decode(t2p, output); } written += t2p_write_pdf_xobject_stream_filter(tile, t2p, output); return(written); } /* * This function writes a PDF Image XObject Colorspace name to output. */ static tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[128]; int buflen=0; float X_W=1.0; float Y_W=1.0; float Z_W=1.0; if( (t2p->pdf_colorspace & T2P_CS_ICCBASED) != 0){ written += t2p_write_pdf_xobject_icccs(t2p, output); return(written); } if( (t2p->pdf_colorspace & T2P_CS_PALETTE) != 0){ written += t2pWriteFile(output, (tdata_t) "[ /Indexed ", 11); t2p->pdf_colorspace ^= T2P_CS_PALETTE; written += t2p_write_pdf_xobject_cs(t2p, output); t2p->pdf_colorspace |= T2P_CS_PALETTE; buflen=sprintf(buffer, "%u", (0x0001 << t2p->tiff_bitspersample)-1 ); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " ", 1); _TIFFmemset(buffer, 0x00, 16); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_palettecs ); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ]\n", 7); return(written); } if(t2p->pdf_colorspace & T2P_CS_BILEVEL){ written += t2pWriteFile(output, (tdata_t) "/DeviceGray \n", 13); } if(t2p->pdf_colorspace & T2P_CS_GRAY){ if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ written += t2p_write_pdf_xobject_calcs(t2p, output); } else { written += t2pWriteFile(output, (tdata_t) "/DeviceGray \n", 13); } } if(t2p->pdf_colorspace & T2P_CS_RGB){ if(t2p->pdf_colorspace & T2P_CS_CALRGB){ written += t2p_write_pdf_xobject_calcs(t2p, output); } else { written += t2pWriteFile(output, (tdata_t) "/DeviceRGB \n", 12); } } if(t2p->pdf_colorspace & T2P_CS_CMYK){ written += t2pWriteFile(output, (tdata_t) "/DeviceCMYK \n", 13); } if(t2p->pdf_colorspace & T2P_CS_LAB){ written += t2pWriteFile(output, (tdata_t) "[/Lab << \n", 10); written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12); X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0F; buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); written += t2pWriteFile(output, (tdata_t) buffer, buflen); X_W = 0.3457F; /* 0.3127F; */ /* D50, commented D65 */ Y_W = 0.3585F; /* 0.3290F; */ Z_W = 1.0F - (X_W + Y_W); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0F; buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/Range ", 7); buflen=sprintf(buffer, "[%d %d %d %d] \n", t2p->pdf_labrange[0], t2p->pdf_labrange[1], t2p->pdf_labrange[2], t2p->pdf_labrange[3]); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) ">>] \n", 5); } return(written); } static tsize_t t2p_write_pdf_transfer(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; written += t2pWriteFile(output, (tdata_t) "<< /Type /ExtGState \n/TR ", 25); if(t2p->tiff_transferfunctioncount == 1){ buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 1)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); } else { written += t2pWriteFile(output, (tdata_t) "[ ", 2); buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 1)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 2)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 3)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); written += t2pWriteFile(output, (tdata_t) "/Identity ] ", 12); } written += t2pWriteFile(output, (tdata_t) " >> \n", 5); return(written); } static tsize_t t2p_write_pdf_transfer_dict(T2P* t2p, TIFF* output, uint16 i){ tsize_t written=0; char buffer[32]; int buflen=0; (void)i; // XXX written += t2pWriteFile(output, (tdata_t) "/FunctionType 0 \n", 17); written += t2pWriteFile(output, (tdata_t) "/Domain [0.0 1.0] \n", 19); written += t2pWriteFile(output, (tdata_t) "/Range [0.0 1.0] \n", 18); buflen=sprintf(buffer, "/Size [%u] \n", (1<tiff_bitspersample)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/BitsPerSample 16 \n", 19); written += t2p_write_pdf_stream_dict(1<<(t2p->tiff_bitspersample+1), 0, output); return(written); } static tsize_t t2p_write_pdf_transfer_stream(T2P* t2p, TIFF* output, uint16 i){ tsize_t written=0; written += t2p_write_pdf_stream( t2p->tiff_transferfunction[i], (1<<(t2p->tiff_bitspersample+1)), output); return(written); } /* This function writes a PDF Image XObject Colorspace array to output. */ static tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[128]; int buflen=0; float X_W=0.0; float Y_W=0.0; float Z_W=0.0; float X_R=0.0; float Y_R=0.0; float Z_R=0.0; float X_G=0.0; float Y_G=0.0; float Z_G=0.0; float X_B=0.0; float Y_B=0.0; float Z_B=0.0; float x_w=0.0; float y_w=0.0; float z_w=0.0; float x_r=0.0; float y_r=0.0; float x_g=0.0; float y_g=0.0; float x_b=0.0; float y_b=0.0; float R=1.0; float G=1.0; float B=1.0; written += t2pWriteFile(output, (tdata_t) "[", 1); if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ written += t2pWriteFile(output, (tdata_t) "/CalGray ", 9); X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0F; } if(t2p->pdf_colorspace & T2P_CS_CALRGB){ written += t2pWriteFile(output, (tdata_t) "/CalRGB ", 8); x_w = t2p->tiff_whitechromaticities[0]; y_w = t2p->tiff_whitechromaticities[1]; x_r = t2p->tiff_primarychromaticities[0]; y_r = t2p->tiff_primarychromaticities[1]; x_g = t2p->tiff_primarychromaticities[2]; y_g = t2p->tiff_primarychromaticities[3]; x_b = t2p->tiff_primarychromaticities[4]; y_b = t2p->tiff_primarychromaticities[5]; z_w = y_w * ((x_g - x_b)*y_r - (x_r-x_b)*y_g + (x_r-x_g)*y_b); Y_R = (y_r/R) * ((x_g-x_b)*y_w - (x_w-x_b)*y_g + (x_w-x_g)*y_b) / z_w; X_R = Y_R * x_r / y_r; Z_R = Y_R * (((1-x_r)/y_r)-1); Y_G = ((0.0F-(y_g))/G) * ((x_r-x_b)*y_w - (x_w-x_b)*y_r + (x_w-x_r)*y_b) / z_w; X_G = Y_G * x_g / y_g; Z_G = Y_G * (((1-x_g)/y_g)-1); Y_B = (y_b/B) * ((x_r-x_g)*y_w - (x_w-x_g)*y_r + (x_w-x_r)*y_g) / z_w; X_B = Y_B * x_b / y_b; Z_B = Y_B * (((1-x_b)/y_b)-1); X_W = (X_R * R) + (X_G * G) + (X_B * B); Y_W = (Y_R * R) + (Y_G * G) + (Y_B * B); Z_W = (Z_R * R) + (Z_G * G) + (Z_B * B); X_W /= Y_W; Z_W /= Y_W; Y_W = 1.0; } written += t2pWriteFile(output, (tdata_t) "<< \n", 4); if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12); buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/Gamma 2.2 \n", 12); } if(t2p->pdf_colorspace & T2P_CS_CALRGB){ written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12); buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/Matrix ", 8); buflen=sprintf(buffer, "[%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f] \n", X_R, Y_R, Z_R, X_G, Y_G, Z_G, X_B, Y_B, Z_B); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/Gamma [2.2 2.2 2.2] \n", 22); } written += t2pWriteFile(output, (tdata_t) ">>] \n", 5); return(written); } /* This function writes a PDF Image XObject Colorspace array to output. */ static tsize_t t2p_write_pdf_xobject_icccs(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; written += t2pWriteFile(output, (tdata_t) "[/ICCBased ", 11); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_icccs); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " 0 R] \n", 7); return(written); } static tsize_t t2p_write_pdf_xobject_icccs_dict(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; written += t2pWriteFile(output, (tdata_t) "/N ", 3); buflen=sprintf(buffer, "%u \n", t2p->tiff_samplesperpixel); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) "/Alternate ", 11); t2p->pdf_colorspace ^= T2P_CS_ICCBASED; written += t2p_write_pdf_xobject_cs(t2p, output); t2p->pdf_colorspace |= T2P_CS_ICCBASED; written += t2p_write_pdf_stream_dict(t2p->tiff_iccprofilelength, 0, output); return(written); } static tsize_t t2p_write_pdf_xobject_icccs_stream(T2P* t2p, TIFF* output){ tsize_t written=0; written += t2p_write_pdf_stream( (tdata_t) t2p->tiff_iccprofile, (tsize_t) t2p->tiff_iccprofilelength, output); return(written); } /* This function writes a palette stream for an indexed color space to output. */ static tsize_t t2p_write_pdf_xobject_palettecs_stream(T2P* t2p, TIFF* output){ tsize_t written=0; written += t2p_write_pdf_stream( (tdata_t) t2p->pdf_palette, (tsize_t) t2p->pdf_palettesize, output); return(written); } /* This function writes a PDF Image XObject Decode array to output. */ static tsize_t t2p_write_pdf_xobject_decode(T2P* t2p, TIFF* output){ tsize_t written=0; int i=0; written += t2pWriteFile(output, (tdata_t) "/Decode [ ", 10); for (i=0;itiff_samplesperpixel;i++){ written += t2pWriteFile(output, (tdata_t) "1 0 ", 4); } written += t2pWriteFile(output, (tdata_t) "]\n", 2); return(written); } /* This function writes a PDF Image XObject stream filter name and parameters to output. */ static tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t tile, T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[16]; int buflen=0; if(t2p->pdf_compression==T2P_COMPRESS_NONE){ return(written); } written += t2pWriteFile(output, (tdata_t) "/Filter ", 8); switch(t2p->pdf_compression){ #ifdef CCITT_SUPPORT case T2P_COMPRESS_G4: written += t2pWriteFile(output, (tdata_t) "/CCITTFaxDecode ", 16); written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13); written += t2pWriteFile(output, (tdata_t) "<< /K -1 ", 9); if(tile==0){ written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_width); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_length); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } else { if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){ written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } else { written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){ written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } else { written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); buflen=sprintf( buffer, "%lu", (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); written += t2pWriteFile(output, (tdata_t) buffer, buflen); } } if(t2p->pdf_switchdecode == 0){ written += t2pWriteFile(output, (tdata_t) " /BlackIs1 true ", 16); } written += t2pWriteFile(output, (tdata_t) ">>\n", 3); break; #endif #ifdef JPEG_SUPPORT case T2P_COMPRESS_JPEG: written += t2pWriteFile(output, (tdata_t) "/DCTDecode ", 11); if(t2p->tiff_photometric != PHOTOMETRIC_YCBCR) { written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13); written += t2pWriteFile(output, (tdata_t) "<< /ColorTransform 0 >>\n", 24); } break; #endif #ifdef ZIP_SUPPORT case T2P_COMPRESS_ZIP: written += t2pWriteFile(output, (tdata_t) "/FlateDecode ", 13); if(t2p->pdf_compressionquality%100){ written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13); written += t2pWriteFile(output, (tdata_t) "<< /Predictor ", 14); _TIFFmemset(buffer, 0x00, 16); buflen=sprintf(buffer, "%u", t2p->pdf_compressionquality%100); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " /Columns ", 10); _TIFFmemset(buffer, 0x00, 16); buflen = sprintf(buffer, "%lu", (unsigned long)t2p->tiff_width); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " /Colors ", 9); _TIFFmemset(buffer, 0x00, 16); buflen=sprintf(buffer, "%u", t2p->tiff_samplesperpixel); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " /BitsPerComponent ", 19); _TIFFmemset(buffer, 0x00, 16); buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) ">>\n", 3); } break; #endif default: break; } return(written); } /* This function writes a PDF xref table to output. */ static tsize_t t2p_write_pdf_xreftable(T2P* t2p, TIFF* output){ tsize_t written=0; char buffer[21]; int buflen=0; uint32 i=0; written += t2pWriteFile(output, (tdata_t) "xref\n0 ", 7); buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 1)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); written += t2pWriteFile(output, (tdata_t) " \n0000000000 65535 f \n", 22); for (i=0;ipdf_xrefcount;i++){ sprintf(buffer, "%.10lu 00000 n \n", (unsigned long)t2p->pdf_xrefoffsets[i]); written += t2pWriteFile(output, (tdata_t) buffer, 20); } return(written); } /* * This function writes a PDF trailer to output. */ static tsize_t t2p_write_pdf_trailer(T2P* t2p, TIFF* output) { tsize_t written = 0; char buffer[32]; int buflen = 0; char fileidbuf[16]; int i = 0; for (i=0; i<(int)sizeof(fileidbuf); i++) fileidbuf[i] = (char) rand(); t2p->pdf_fileid = (unsigned char*)_TIFFmalloc(33); if(t2p->pdf_fileid == NULL) { TIFFError( TIFF2PDF_MODULE, "Can't allocate %u bytes of memory for t2p_write_pdf_trailer", 33 ); t2p->t2p_error = T2P_ERR_ERROR; return(0); } _TIFFmemset(t2p->pdf_fileid, 0x00, 33); for (i = 0; i < 16; i++) { sprintf((char *)t2p->pdf_fileid + 2 * i, "%.2hhX", fileidbuf[i]); } written += t2pWriteFile(output, (tdata_t) "trailer\n<<\n/Size ", 17); buflen = sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount+1)); written += t2pWriteFile(output, (tdata_t) buffer, buflen); _TIFFmemset(buffer, 0x00, 32); written += t2pWriteFile(output, (tdata_t) "\n/Root ", 7); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_catalog); written += t2pWriteFile(output, (tdata_t) buffer, buflen); _TIFFmemset(buffer, 0x00, 32); written += t2pWriteFile(output, (tdata_t) " 0 R \n/Info ", 12); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_info); written += t2pWriteFile(output, (tdata_t) buffer, buflen); _TIFFmemset(buffer, 0x00, 32); written += t2pWriteFile(output, (tdata_t) " 0 R \n/ID[<", 11); written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32); written += t2pWriteFile(output, (tdata_t) "><", 2); written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32); written += t2pWriteFile(output, (tdata_t) ">]\n>>\nstartxref\n", 16); buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_startxref); written += t2pWriteFile(output, (tdata_t) buffer, buflen); _TIFFmemset(buffer, 0x00, 32); written += t2pWriteFile(output, (tdata_t) "\n%%EOF\n", 7); return(written); } /* This function writes a PDF to a file given a pointer to a TIFF. The idea with using a TIFF* as output for a PDF file is that the file can be created with TIFFClientOpen for memory-mapped use within the TIFF library, and TIFFWriteEncodedStrip can be used to write compressed data to the output. The output is not actually a TIFF file, it is a PDF file. This function uses only t2pWriteFile and TIFFWriteEncodedStrip to write to the output TIFF file. When libtiff would otherwise be writing data to the output file, the write procedure of the TIFF structure is replaced with an empty implementation. The first argument to the function is an initialized and validated T2P context struct pointer. The second argument to the function is the TIFF* that is the input that has been opened for reading and no other functions have been called upon it. The third argument to the function is the TIFF* that is the output that has been opened for writing. It has to be opened so that it hasn't written any data to the output. If the output is seekable then it's OK to seek to the beginning of the file. The function only writes to the output PDF and does not seek. See the example usage in the main() function. TIFF* output = TIFFOpen("output.pdf", "w"); assert(output != NULL); if(output->tif_seekproc != NULL){ t2pSeekFile(output, (toff_t) 0, SEEK_SET); } This function returns the file size of the output PDF file. On error it returns zero and the t2p->t2p_error variable is set to T2P_ERR_ERROR. After this function completes, call t2p_free on t2p, TIFFClose on input, and TIFFClose on output. */ static tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ tsize_t written=0; ttile_t i2=0; tsize_t streamlen=0; uint16 i=0; t2p_read_tiff_init(t2p, input); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} t2p->pdf_xrefoffsets= (uint32*) _TIFFmalloc(t2p->pdf_xrefcount * sizeof(uint32) ); if(t2p->pdf_xrefoffsets==NULL){ TIFFError( TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory for t2p_write_pdf", t2p->pdf_xrefcount * (long)sizeof(uint32) ); return(written); } t2p->pdf_xrefcount=0; t2p->pdf_catalog=1; t2p->pdf_info=2; t2p->pdf_pages=3; written += t2p_write_pdf_header(t2p, output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; t2p->pdf_catalog=t2p->pdf_xrefcount; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_catalog(t2p, output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; t2p->pdf_info=t2p->pdf_xrefcount; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_info(t2p, input, output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; t2p->pdf_pages=t2p->pdf_xrefcount; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_pages(t2p, output); written += t2p_write_pdf_obj_end(output); for(t2p->pdf_page=0;t2p->pdf_pagetiff_pagecount;t2p->pdf_page++){ t2p_read_tiff_data(t2p, input); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_page(t2p->pdf_xrefcount, t2p, output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_stream_dict(0, t2p->pdf_xrefcount+1, output); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; written += t2p_write_pdf_page_content_stream(t2p, output); streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_length(streamlen, output); written += t2p_write_pdf_obj_end(output); if(t2p->tiff_transferfunctioncount != 0){ t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_transfer(t2p, output); written += t2p_write_pdf_obj_end(output); for(i=0; i < t2p->tiff_transferfunctioncount; i++){ t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_transfer_dict(t2p, output, i); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; written += t2p_write_pdf_transfer_stream(t2p, output, i); streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); } } if( (t2p->pdf_colorspace & T2P_CS_PALETTE) != 0){ t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; t2p->pdf_palettecs=t2p->pdf_xrefcount; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_stream_dict(t2p->pdf_palettesize, 0, output); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; written += t2p_write_pdf_xobject_palettecs_stream(t2p, output); streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); } if( (t2p->pdf_colorspace & T2P_CS_ICCBASED) != 0){ t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; t2p->pdf_icccs=t2p->pdf_xrefcount; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_xobject_icccs_dict(t2p, output); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; written += t2p_write_pdf_xobject_icccs_stream(t2p, output); streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); } if(t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount !=0){ for(i2=0;i2tiff_tiles[t2p->pdf_page].tiles_tilecount;i2++){ t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_xobject_stream_dict( i2+1, t2p, output); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size_tile(t2p, input, i2); written += t2p_readwrite_pdf_image_tile(t2p, input, output, i2); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_length(streamlen, output); written += t2p_write_pdf_obj_end(output); } } else { t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_dict_start(output); written += t2p_write_pdf_xobject_stream_dict( 0, t2p, output); written += t2p_write_pdf_stream_dict_end(output); written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size(t2p, input); written += t2p_readwrite_pdf_image(t2p, input, output); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} streamlen=written-streamlen; written += t2p_write_pdf_stream_end(output); written += t2p_write_pdf_obj_end(output); t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written; written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); written += t2p_write_pdf_stream_length(streamlen, output); written += t2p_write_pdf_obj_end(output); } } t2p->pdf_startxref = written; written += t2p_write_pdf_xreftable(t2p, output); written += t2p_write_pdf_trailer(t2p, output); t2p_disable(output); return(written); } /* vim: set ts=8 sts=8 sw=8 noet: */ #endif djview4-4.10.5/src/tiff2pdf.h000066400000000000000000000025561264256014000156310ustar00rootroot00000000000000/* -*- C -*- //C- ------------------------------------------------------------------- //C- DjView4 //C- Copyright (c) 2006 Leon Bottou //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, either version 2 of the license, //C- or (at your option) any later version. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- This program is distributed in the hope that it will be useful, //C- but WITHOUT ANY WARRANTY; without even the implied warranty of //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //C- GNU General Public License for more details. //C- ------------------------------------------------------------------ */ #ifndef TIFF2PDF_H # define TIFF2PDF_H # if HAVE_CONFIG_H || AUTOCONF # include "config.h" # endif # if HAVE_TIFF # include # include # include # include # include # include # ifdef TIFFLIB_VERSION # if TIFFLIB_VERSION > 20041104 # define HAVE_TIFF2PDF 1 # endif # endif # endif # if HAVE_TIFF2PDF # ifdef __cplusplus extern "C" { # endif int tiff2pdf(TIFF *input, FILE *output, int argc, const char **argv); # ifdef __cplusplus } # endif # endif /* HAVE_TIFF2PDF */ #endif /* TIFF2PDF_H */ djview4-4.10.5/src/version.h000066400000000000000000000006031264256014000156010ustar00rootroot00000000000000#ifndef VERSION_H #define VERSION_H #ifndef DJVIEW_ORG # define DJVIEW_ORG "DjVuLibre" #endif #ifndef DJVIEW_DOMAIN # define DJVIEW_DOMAIN "djvu.org" #endif #ifndef DJVIEW_APP # define DJVIEW_APP "DjView" #endif #ifndef DJVIEW_VERSION # define DJVIEW_VERSION 0x40a05 # define DJVIEW_VERSION_STR "4.10.5" # define RC_VERSION 4,10,0,0 # define RC_VERSION_STR "4,10,5,0\0" #endif #endif