From 71f6baaafaba8880aca9d7aeaa6ca3d28945f649 Mon Sep 17 00:00:00 2001 From: simon987 Date: Thu, 12 Nov 2020 16:52:36 -0500 Subject: [PATCH] antiword 0.37 original source --- .gitignore | 2 + Docs/COPYING | 342 ++++ Docs/ChangeLog | 219 ++ Docs/Emacs | 134 ++ Docs/Exmh | 14 + Docs/FAQ | 113 ++ Docs/History | 44 + Docs/Mozilla | 88 + Docs/Mutt | 24 + Docs/Netscape | 129 ++ Docs/QandA | 59 + Docs/ReadMe | 114 ++ Docs/antiword.1 | 158 ++ Docs/antiword.man | 146 ++ Docs/antiword.old.php | 34 + Docs/antiword.php | 141 ++ Docs/testdoc.doc | Bin 0 -> 23552 bytes Makefile | 97 + Resources/8859-1.txt | 303 +++ Resources/8859-10.txt | 303 +++ Resources/8859-11.txt | 299 +++ Resources/8859-13.txt | 299 +++ Resources/8859-14.txt | 301 +++ Resources/8859-15.txt | 303 +++ Resources/8859-16.txt | 299 +++ Resources/8859-2.txt | 303 +++ Resources/8859-3.txt | 296 +++ Resources/8859-4.txt | 303 +++ Resources/8859-5.txt | 303 +++ Resources/8859-6.txt | 260 +++ Resources/8859-7.txt | 302 +++ Resources/8859-8.txt | 270 +++ Resources/8859-9.txt | 307 +++ Resources/Default | 81 + Resources/Example | 80 + Resources/MacCyrillic.txt | 344 ++++ Resources/MacRoman.txt | 362 ++++ Resources/UTF-8.txt | 3 + Resources/Unicode01 | 306 +++ Resources/Unicode15 | 305 +++ Resources/cp1250.txt | 274 +++ Resources/cp1251.txt | 274 +++ Resources/cp1252.txt | 274 +++ Resources/cp437.txt | 273 +++ Resources/cp850.txt | 273 +++ Resources/cp852.txt | 273 +++ Resources/cp862.txt | 273 +++ Resources/cp864.txt | 273 +++ Resources/cp866.txt | 273 +++ Resources/fontnames | 117 ++ Resources/fontnames.russian | 43 + Resources/koi8-r.txt | 302 +++ Resources/koi8-u.txt | 303 +++ Resources/roman.txt | 1 + Unix-only/KDE1-only/Antiword.kdelnk.eu | 15 + Unix-only/KDE1-only/Antiword.kdelnk.us | 15 + Unix-only/KDE1-only/antiword.xpm | 272 +++ Unix-only/KDE1-only/kantiword.sh | 42 + Unix-only/KDE3-only/Antiword.desktop.eu | 8 + Unix-only/KDE3-only/Antiword.desktop.us | 8 + Unix-only/KDE3-only/hi32-app-antiword.png | Bin 0 -> 1510 bytes Unix-only/KDE3-only/hi48-app-antiword.png | Bin 0 -> 2285 bytes Unix-only/KDE3-only/kantiword.sh | 71 + Unix-only/KDE3-only/lo16-app-antiword.png | Bin 0 -> 330 bytes Unix-only/KDE3-only/lo32-app-antiword.png | Bin 0 -> 513 bytes Unix-only/RPM-only/antiword.spec | 49 + Unix-only/fontinfo.h | 2251 +++++++++++++++++++++ Unix-only/fontinfo.pl | 207 ++ antiword.h | 735 +++++++ asc85enc.c | 154 ++ blocklist.c | 823 ++++++++ chartrans.c | 720 +++++++ datalist.c | 374 ++++ debug.h | 117 ++ depot.c | 114 ++ dib2eps.c | 509 +++++ dib2sprt.c | 597 ++++++ doclist.c | 75 + draw.c | 1047 ++++++++++ draw.h | 46 + drawfile.c | 422 ++++ drawfile.h | 433 ++++ fail.c | 26 + fail.h | 22 + finddata.c | 154 ++ findtext.c | 289 +++ fmt_text.c | 167 ++ fontinfo.h | 2251 +++++++++++++++++++++ fontlist.c | 173 ++ fonts.c | 1018 ++++++++++ fonts_r.c | 251 +++ fonts_u.c | 305 +++ hdrftrlist.c | 371 ++++ icons.c | 96 + imgexam.c | 1044 ++++++++++ imgtrans.c | 71 + jpeg2eps.c | 74 + jpeg2sprt.c | 97 + listlist.c | 330 +++ main_ros.c | 520 +++++ main_u.c | 321 +++ misc.c | 894 ++++++++ mkfile | 30 + notes.c | 876 ++++++++ options.c | 950 +++++++++ out2window.c | 768 +++++++ output.c | 538 +++++ pdf.c | 1148 +++++++++++ pictlist.c | 109 + png2eps.c | 191 ++ png2sprt.c | 26 + postscript.c | 1171 +++++++++++ prop0.c | 489 +++++ prop2.c | 1067 ++++++++++ prop6.c | 1141 +++++++++++ prop8.c | 1496 ++++++++++++++ properties.c | 198 ++ propmod.c | 110 + riscos.c | 251 +++ rowlist.c | 117 ++ saveas.c | 387 ++++ sectlist.c | 165 ++ startup.c | 145 ++ stylelist.c | 487 +++++ stylesheet.c | 838 ++++++++ summary.c | 888 ++++++++ tabstop.c | 212 ++ text.c | 182 ++ unix.c | 45 + utf8.c | 260 +++ version.h | 37 + word2text.c | 1505 ++++++++++++++ wordconst.h | 321 +++ worddos.c | 110 + wordlib.c | 359 ++++ wordmac.c | 108 + wordole.c | 804 ++++++++ wordtypes.h | 317 +++ wordwin.c | 209 ++ xmalloc.c | 136 ++ xml.c | 1438 +++++++++++++ 141 files changed, 48223 insertions(+) create mode 100644 .gitignore create mode 100644 Docs/COPYING create mode 100644 Docs/ChangeLog create mode 100644 Docs/Emacs create mode 100644 Docs/Exmh create mode 100644 Docs/FAQ create mode 100644 Docs/History create mode 100644 Docs/Mozilla create mode 100644 Docs/Mutt create mode 100644 Docs/Netscape create mode 100644 Docs/QandA create mode 100644 Docs/ReadMe create mode 100644 Docs/antiword.1 create mode 100644 Docs/antiword.man create mode 100644 Docs/antiword.old.php create mode 100644 Docs/antiword.php create mode 100644 Docs/testdoc.doc create mode 100644 Makefile create mode 100644 Resources/8859-1.txt create mode 100644 Resources/8859-10.txt create mode 100644 Resources/8859-11.txt create mode 100644 Resources/8859-13.txt create mode 100644 Resources/8859-14.txt create mode 100644 Resources/8859-15.txt create mode 100644 Resources/8859-16.txt create mode 100644 Resources/8859-2.txt create mode 100644 Resources/8859-3.txt create mode 100644 Resources/8859-4.txt create mode 100644 Resources/8859-5.txt create mode 100644 Resources/8859-6.txt create mode 100644 Resources/8859-7.txt create mode 100644 Resources/8859-8.txt create mode 100644 Resources/8859-9.txt create mode 100644 Resources/Default create mode 100644 Resources/Example create mode 100644 Resources/MacCyrillic.txt create mode 100644 Resources/MacRoman.txt create mode 100644 Resources/UTF-8.txt create mode 100644 Resources/Unicode01 create mode 100644 Resources/Unicode15 create mode 100644 Resources/cp1250.txt create mode 100644 Resources/cp1251.txt create mode 100644 Resources/cp1252.txt create mode 100644 Resources/cp437.txt create mode 100644 Resources/cp850.txt create mode 100644 Resources/cp852.txt create mode 100644 Resources/cp862.txt create mode 100644 Resources/cp864.txt create mode 100644 Resources/cp866.txt create mode 100644 Resources/fontnames create mode 100644 Resources/fontnames.russian create mode 100644 Resources/koi8-r.txt create mode 100644 Resources/koi8-u.txt create mode 100644 Resources/roman.txt create mode 100644 Unix-only/KDE1-only/Antiword.kdelnk.eu create mode 100644 Unix-only/KDE1-only/Antiword.kdelnk.us create mode 100644 Unix-only/KDE1-only/antiword.xpm create mode 100644 Unix-only/KDE1-only/kantiword.sh create mode 100644 Unix-only/KDE3-only/Antiword.desktop.eu create mode 100644 Unix-only/KDE3-only/Antiword.desktop.us create mode 100644 Unix-only/KDE3-only/hi32-app-antiword.png create mode 100644 Unix-only/KDE3-only/hi48-app-antiword.png create mode 100644 Unix-only/KDE3-only/kantiword.sh create mode 100644 Unix-only/KDE3-only/lo16-app-antiword.png create mode 100644 Unix-only/KDE3-only/lo32-app-antiword.png create mode 100644 Unix-only/RPM-only/antiword.spec create mode 100644 Unix-only/fontinfo.h create mode 100755 Unix-only/fontinfo.pl create mode 100644 antiword.h create mode 100644 asc85enc.c create mode 100644 blocklist.c create mode 100644 chartrans.c create mode 100644 datalist.c create mode 100644 debug.h create mode 100644 depot.c create mode 100644 dib2eps.c create mode 100644 dib2sprt.c create mode 100644 doclist.c create mode 100644 draw.c create mode 100644 draw.h create mode 100644 drawfile.c create mode 100644 drawfile.h create mode 100644 fail.c create mode 100644 fail.h create mode 100644 finddata.c create mode 100644 findtext.c create mode 100644 fmt_text.c create mode 100644 fontinfo.h create mode 100644 fontlist.c create mode 100644 fonts.c create mode 100644 fonts_r.c create mode 100644 fonts_u.c create mode 100644 hdrftrlist.c create mode 100644 icons.c create mode 100644 imgexam.c create mode 100644 imgtrans.c create mode 100644 jpeg2eps.c create mode 100644 jpeg2sprt.c create mode 100644 listlist.c create mode 100644 main_ros.c create mode 100644 main_u.c create mode 100644 misc.c create mode 100644 mkfile create mode 100644 notes.c create mode 100644 options.c create mode 100644 out2window.c create mode 100644 output.c create mode 100644 pdf.c create mode 100644 pictlist.c create mode 100644 png2eps.c create mode 100644 png2sprt.c create mode 100644 postscript.c create mode 100644 prop0.c create mode 100644 prop2.c create mode 100644 prop6.c create mode 100644 prop8.c create mode 100644 properties.c create mode 100644 propmod.c create mode 100644 riscos.c create mode 100644 rowlist.c create mode 100644 saveas.c create mode 100644 sectlist.c create mode 100644 startup.c create mode 100644 stylelist.c create mode 100644 stylesheet.c create mode 100644 summary.c create mode 100644 tabstop.c create mode 100644 text.c create mode 100644 unix.c create mode 100644 utf8.c create mode 100644 version.h create mode 100644 word2text.c create mode 100644 wordconst.h create mode 100644 worddos.c create mode 100644 wordlib.c create mode 100644 wordmac.c create mode 100644 wordole.c create mode 100644 wordtypes.h create mode 100644 wordwin.c create mode 100644 xmalloc.c create mode 100644 xml.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14e54d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +antiword diff --git a/Docs/COPYING b/Docs/COPYING new file mode 100644 index 0000000..57e438a --- /dev/null +++ b/Docs/COPYING @@ -0,0 +1,342 @@ + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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 + + Appendix: 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., 675 Mass Ave, Cambridge, MA 02139, 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. + diff --git a/Docs/ChangeLog b/Docs/ChangeLog new file mode 100644 index 0000000..4bf9e5e --- /dev/null +++ b/Docs/ChangeLog @@ -0,0 +1,219 @@ +**************************************************************************** +* Changes in Antiword from versions 0.22 to 0.37 * +**************************************************************************** + +Changes 0.36 to 0.37 +-------------------- +Bug fixes: +- Bug reported by Suzanne Skinner (and others) fixed +New features: +- XML/DocBook output now contains tags +- Antiword is now based on DeskLib instead of RISC_OSLib (RISC OS only) +- Show page headers and footers (PostScript and PDF output only) +- Show text that was removed by the revisioning system +- Improved kantiword, based on information from Stefan Wiens + +Changes 0.35 to 0.36 +-------------------- +Bug fixes: +- Bug reported by Michael Minn fixed +New features: +- The default mapping file is now based on the locale (Unix/Linux) or on + the active codepage (DOS) +- A Word document can now be saved as "formatted" text. That means with things + like *bold* to show bold text, /italics/ to show italics and _undeline_ to + show underlined text are added to the plain text. Based on patches send by + Ofir Reichenberg +- Improved table parsing. Based on information supplied by Bastien Legras + and Alex de Kruijff +- A Word document can now be saved in PDF. +- First attempt to support PostScript output in the Cyrillic alphabet. Based + on work done by Alexander Belyaev +- Better support for the Cyrillic alphabet + +Changes 0.34 to 0.35 +-------------------- +Bug fixes: +- Fixed the bug in the use of the environment variable ANTIWORDHOME +New features: +- The XML/DocBook output is slightly better. +- Scale view window is closed when the main window is closed. Thanks to Tony + Moore (RISC OS only) +- More support for WinWord 1.x documents + +Changes 0.33 to 0.34 +-------------------- +Bug fixes: +- Bug in UTF-8 tables fixed +- Bug reported by Stewart Goldwater fixed +- Bug reported by Karl-Otto Linn fixed +- Fixed a bug that made DOS hang when Antiword processed a document > 8 MB. +New features: +- Better approximations for fancy characters in the output +- A Word document can now be saved as XML/DocBook. +- Linux Makefile is now closer to conventions. +- Support for Text Boxes +- An environment variable ANTIWORDHOME was added to create a more flexable + place for the fontnames file and the mapping files. +- Antiword is now Latin9 enabled. Thanks to Stefan Bellon + (RISC OS only) +- Some support for MacWord 4 and 5 documents +- More support for Word-for-DOS documents +- Support for superscripts and subscripts +- Displays slightly more images. +- Improved lists, especially in documents from Word 97 or later. + +Changes 0.32 to 0.33 +-------------------- +Bug fixes: +- Bug reported by Yannick PERRET fixed +Old features: +- The -X option is no longer supported. Replace "-X 2" by "-m 8859-2.txt" +New features: +- Slightly more accurate font translation +- Full support for WinWord 2.0 documents +- Some support for Word-for-DOS and WinWord 1.x documents +- Selective header numbering +- Implementation of stylesheets +- The system-wide directory for the mapping files was changed from + "/opt/antiword/share" to "/usr/share/antiword", in accordance with FHS, + the file-system hierarchy standard, as suggested by Anand Buddhdev + . +- Antiword now turns white text into light gray text. +- Antiword is now closer to "64-bit clean". Based on information supplied by + Duncan Haldane . + +Changes 0.31 to 0.32 +-------------------- +Bug fixes: +- Bug reported by Forrest J. Cavalier III fixed +- Bug reported by Jan ONDREJ (SAL) fixed +- Bug in dealing with RLE compressed bitmap images fixed +- Bug in image scaling fixed (RISC OS only) +New features: +- Improved leading (Unix only; PostScript version only) +- Antiword can now read from the standard input. This is based on an idea by + Matthew Miller . (Unix only) +- A white background looks much better. (RISC OS only) +- A system-wide directory for the mapping files, as suggested by Sven Geggus + and many others. (Unix only) +- Antiword can now deal with documents larger than 7 MB. + +Changes 0.30 to 0.31 +-------------------- +Bug fixes: +- Bug in the "Show hidden (by Word) text" feature fixed +- Bug reported by David Aspinwall fixed +- Bug reported by Robert Steinmetz fixed +Old features: +- The -g and -c options are no longer supported. The -c option was the default + and is now used automatically. (Unix only) +New features: +- Ability to display some of the images +- Ability to use landscape mode (Unix only; PostScript version only) +- Support for all ISO-8859 character sets plus KOI8 and some code pages + (Unix only; text version only) +- Antiword will now give a warning if the specified PostScript paper size is + unsupported. Thanks to Greg Robinson +- Changed from PostScript version 1 to version 2 +- Antiword now returns 1 if no Word document is found among the files listed + on the command line, as suggested by Jens Schleusener + . +- Takes the right margin into account +- The PostScript part now supports the AvantGarde, Bookman, Helvetica-Narrow, + NewCenturySchlbk and Palatino fonts (Unix only) +- More accurate fontnames translation table +- Initial scale factor is now configurable (RISC OS only) + +Changes 0.29 to 0.30 +-------------------- +Bug fixes: +- Bug in the generated PostScript (nocurrentpoint) fixed +- Bug reported by Keith Bamford fixed +- Bug in the chapter numbering font fixed +New features: +- Improved handling of changes in the font size on a single line. +- Some support for long file names (RISC OS only) +- Thanks to David Kanareck , Antiword can + now deal with documents made by "Word for Asian languages", but only + when these documents are written in a European language. +- Character properties "Caps" and "SmallCaps" for accented characters +- More accurate fontnames translation table. (RISC OS only) +- PostScript part now supports the Times and Helvetica fonts. (Unix only) + +Changes 0.28 to 0.29 +-------------------- +Bug fixes: +- Bug reported by Paul McCann fixed +- Character property "SmallCaps" works better now +- Bug reported by Richard Lambley fixed +- Fixed a bug in the linewidth computation (Unix only) +New features: +- A Word document can now be saved as PostScript (Unix only, Courier font only) +- Left, Center, Right and Justify alignment added for Word 97 +- Supports the Macintosh character set + +Changes 0.27 to 0.28 +-------------------- +Licence: +- Distributed under the GNU General Public License +Bug fixes: +- Bug reported by Richard Lambley has not + been fixed yet. +- Deals correctly with fancy quotes in files from a Macintosh +New features: +- Supports character properties "SmallCaps", "Caps" and "Hidden Text" +- The use of fonts and font sizes for "fast saved" documents is now supported. +- Separators between the text, the footnotes and the endnotes +- Footnotes are now numbered in Arabic numericals (1, 2, 3), endnotes are now + numbered in Roman numericals (i, ii, iii). + +Changes 0.26 to 0.27 +-------------------- +Bug fixes: +- The main title now shows the first 12 characters of the file name. +New features: +- "Fast saved" documents are now supported for Word 97. +- All tables are now supported for Word 97. +- It is now possible to scale the text. + +Changes 0.25 to 0.26 +-------------------- +Bug fixes: +- Fixed several problems with the Choices file +- Closed a small memory leak +New features: +- The use of fonts and font sizes for "full saved" documents is now supported. +- Most tables are now supported for Word 97. +- Header numbers are now supported for Word 97. + +Changes 0.24 to 0.25 +-------------------- +Bug fixes: +- Improved handling of memory shortages +- Some special tables were messed up. +New features: +- "Fast saved" documents are now supported for Word 6 and 7. +- A new option to permit Antiword to change the filetype of Word documents to + MSWord (&ae6). +- A Wordfile can now be saved as a Drawfile. +- The look and feel has been changed from editor-like to browser-like + +Changes 0.23 to 0.24 +-------------------- +Bug fixes: +- Empty paragraphs in numbered list were not always numbered correctly. +- In very complex tables some text could get lost. +New features: +- F3 is now a shortcut to the "Save as" dialogue box. +- Left, Center, Right and Justify alignment added for Word 6 and 7 +- [pic] marks the place where an image should have been. +- It is now possible to have a writeable Choices file, even when Antiword + itself is on a read-only medium. + +Changes 0.22 to 0.23 +-------------------- +New features: +- Paragraph breaks are now an option. +- Bulleted single level lists for files from Word 6 and 7 +- Numbered single level lists (some styles) for files from Word 6 and 7 diff --git a/Docs/Emacs b/Docs/Emacs new file mode 100644 index 0000000..c2d9ba1 --- /dev/null +++ b/Docs/Emacs @@ -0,0 +1,134 @@ +From: Alex Schroeder +Subject: Re: MS Word mode? +Date: Fri, 08 Nov 2002 00:40:15 +0100 + +Roger Mason writes: + +> There was a question about this recently on this forum. Look for +> undoc.el, I got it from the wiki (I think). It has worked very well for +> me to date, although I have not attempted ro read complex documents. + +Well, it makes things readable, but it is far from perfect -- it seems +to just delete any non-ascii characters, such that sometimes you will +see words such as "Alex8" where "8" is some garbage that just looked +like being part of a real word... In other words, interfacing to +something like catdoc, antiword, or wvText (included with AbiWord) +might be cool. Actually all you need is this: + +(add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word)) + +(defun no-word () + "Run antiword on the entire buffer." + (shell-command-on-region (point-min) (point-max) "antiword - " t t)) + +Alex. + +=============================================================================== + +From: Arnaldo Mandel +Subject: Re: MS Word mode? +Date: Fri, 8 Nov 2002 11:52:33 -0200 + +Alex Schroeder wrote (on Nov 8, 2002): + + > Actually all you need is this: + > + > (add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word)) + > + > (defun no-word () + > "Run antiword on the entire buffer." + > (shell-command-on-region (point-min) (point-max) "antiword - " t t)) + +On my system there are lots of filenames ending in .doc whose files +are not Word files. So I modified your function thusly + +(defun no-word () + "Run antiword on the entire buffer." + (if (string-match "Microsoft " + (shell-command-to-string (concat "file " buffer-file-name))) + (shell-command-on-region (point-min) (point-max) "antiword - " t t))) + +Works in Solaris and Linux, and should work on other unixes as well. + +am + +=============================================================================== + +From: Alex Schroeder +Subject: Re: MS Word mode? +Date: Fri, 08 Nov 2002 18:24:07 +0100 + +Arnaldo Mandel writes: + +> (defun no-word () +> "Run antiword on the entire buffer." +> (if (string-match "Microsoft " +> (shell-command-to-string (concat "file " buffer-file-name))) +> (shell-command-on-region (point-min) (point-max) "antiword - " t t))) + +Cool. I did not know about "file"... :) + +My stuff is on the wiki, btw: + +* http://www.emacswiki.org/cgi-bin/wiki.pl?AntiWord + +Alex. + +=============================================================================== + +From: Benjamin Riefenstahl +Subject: Re: emacs rmail. How to convert .doc to plain text +Date: 24 Nov 2002 18:08:22 +0100 + +Hi, + +Puff Addison writes: +> Yes, please post your Emacs integration code. + +Ok, see below. I should note that it is probably also possible to +(ab-)use jka-compr for this, which would make my two functions +obsolete. + +so long, benny + +>>>>>>> + +(defun benny-antiword-file-handler (operation &rest args) + ;; First check for the specific operations + ;; that we have special handling for. + (cond ((eq operation 'insert-file-contents) + (apply 'benny-antiword-insert-file args)) + ((eq operation 'file-writable-p) + nil) + ((eq operation 'write-region) + (error "Word documents can't be written")) + ;; Handle any operation we don't know about. + (t (let ((inhibit-file-name-handlers + (cons 'benny-antiword-file-handler + (and (eq inhibit-file-name-operation operation) + inhibit-file-name-handlers))) + (inhibit-file-name-operation operation)) + (apply operation args))))) + +(defun benny-antiword-insert-file (filename &optional visit beg end replace) + (set-buffer-modified-p nil) + (setq buffer-file-name (file-truename filename)) + (setq buffer-read-only t) + (let ((start (point)) + (inhibit-read-only t)) + (if replace (delete-region (point-min) (point-max))) + (save-excursion + (let ((coding-system-for-read 'utf-8) + (filename (encode-coding-string + buffer-file-name + (or file-name-coding-system + default-file-name-coding-system)))) + (call-process "antiword" nil t nil "-m" "UTF-8.txt" + filename)) + (list buffer-file-name (- (point) start))))) + +(setq file-name-handler-alist + (cons '("\\.doc\\'" . benny-antiword-file-handler) + file-name-handler-alist)) + +<<<<<<< diff --git a/Docs/Exmh b/Docs/Exmh new file mode 100644 index 0000000..d9da5b0 --- /dev/null +++ b/Docs/Exmh @@ -0,0 +1,14 @@ +From: Glenn Burkhardt +Subject: It's great! +Date: Wed, 22 Aug 2001 12:02:54 -0400 + +Thank you for this program. Thank you very much! Thank you immensely!! + + +P.S. I find entry helpful as a /etc/mailcap rule: + +application/msword;/usr/local/bin/antiword -t %s | less; needsterminal; \ +copiousoutput; print=antiword -p letter %s|lpr + +I completely integrates the text mode with my mailer, exmh. You might +want to include it in your documentation. diff --git a/Docs/FAQ b/Docs/FAQ new file mode 100644 index 0000000..0a15f80 --- /dev/null +++ b/Docs/FAQ @@ -0,0 +1,113 @@ +Frequently Asked Questions +========================== + +These questions and answers are mainly Linux/Unix oriented. For other +Operating Systems you may want to read the documentation provided by the +people who ported Antiword. + +Q1: How do I install Antiword? +A1: (a) Make a suitable directory such as '$HOME/src/antiword' and copy the + 'antiword.tar.gz' file to this directory. + (b) decompress: 'gunzip antiword.tar.gz' + (c) unpack: 'tar xvf antiword.tar' + (d) compile: 'make all' + (e) install: 'make install'. This will install Antiword in the $HOME/bin + directory. + (f) copy the file 'fontnames' and one or more mapping files from the + Resources directory to the $HOME/.antiword directory (note the dot + before antiword!). + NOTE: you can skip point (f) if your system administrator already copied + these files to /usr/share/antiword. + +Q2: I get the message "I can't open your mapping file (xxxx-x.txt)" +A2: This means that the mapping file has not been installed. The installation + may have to be done manually. See above answer A1, point (f). + NOTE: Antiword assumes that a file that can't be opened for reading is a + file that doesn't exist. + +Q3: How do I use Antiword? +A3: Type antiword -h and see. + +Q4: I tried "antiword -m /some/directory/8859-1.txt word.doc", but this + doesn't work. +A4: The -m option is followed by the name of a mapping file, a full pathname + won't work. + +Q5: How does Antiword deal with Word macro viruses? +A5: Antiword does not run any Word macros because it can't do so. + Therefore such a virus will not harm your computer system. + +Q6: What is the purpose of the file 'fontnames' in the '/usr/share/antiword/' + or '$HOME/.antiword' directory? +A6: This file provides a translation table from the font names used in a Word + document to the font names used by a PostScript printer. + The file 'fontnames' can be edited to match the font collection used by + your PostScript printer. + +Q7: What is 'Hidden Text'? +A7: Hidden Text is Microsoft speak for text that may or may not be shown + on the screen, subject to the user's preferences, but such text is never + printed. + +Q8: Antiword claims to support all ISO-8859 character sets, but I can't see + any of this. +A8: There is support for all ISO-8859 character sets, but only in the text + output, not in the PostScript output. + The result can only be seen if your xterm, vtterm, kvt or similar + terminal emulation program uses a font compatible with that ISO-8859 + character set. + +Q9: Which mapping file (-m option) is correct in my situation? +A9: The correct mapping file depends on the character set you need for output + in a specific language. + For Western European languages (like English, French, German) this is + 8859-1.txt. (OS/2: cp1252.txt) (DOS: cp850.txt) + For Eastern European languages (like Polish, Czech, Slovak, Croatian) this + is 8859-2.txt. (OS/2: cp1250.txt) (DOS: cp852.txt) + For Esperanto use 8859-3.txt. + For Russian use 8859-5.txt or koi8-r.txt. (OS/2: cp1251.txt) + (DOS: cp866.txt) + For Ukrainian use koi8-u.txt. + For Arabic use 8859-6.txt. (DOS: cp864.txt) + For Hebrew use 8859-8.txt. (DOS: cp862.txt) + For Thai use 8859-11.txt. + If your system supports it, you might also try UTF-8.txt. + + NOTE: UTF-8 also enables Antiword to show text in languages like Chinese, + Japanese and Korean. + +Q10: I tried UTF-8, but some documents show more garbage than text. Why? +A10: UTF-8 will only work if the document was saved by a Unicode enabled + version of Word (or if Word used ISO-8859-1 as its internal encoding). + The following versions of Word are known to be Unicode enabled: + Word 6 and Word 7 for Asian languages, all versions of Word 97, + Word 98 (Mac), Word 2000, Word 2001 (Mac) and Word 2002 (aka Word XP). + +Q11: Why can't Antiword read from stdin directly? Why use a temporary file? +A11: The information in a Word document is not stored sequentially. Therefore + the use of the "fseek" function can't be avoided. So Antiword must copy + stdin to a temporary file first and then process that file. + +Q12: Why does the XML output of Antiword sometimes contain such a strange + structure or practically no structure at all? +A12: Remember that Word is basically 'text plus appearance' and XML is + basically 'text plus structure'. If a Word document is written by a + competent person there will be a balance between appearance and structure, + but if a Word document is written by an inexperienced or incompetent + person the Word document can end up without a structure, or worse, with a + terrible structure. + Antiword can't create a structure when there is none. + +Q13: Why is the Postscript output in Cyrillic in ISO-8869-5? Nobody uses that + character set. +A13: For Cyrillic you a have: + (a) koi8 does not cover all languages that use Cyrillic, + (b) cp866, cp1251 and Mac-Cyrillic are proprietary, + (c) Unicode and UTF-8 are not supported by PostScript yet and + (d) ISO-8859-5, the character set that nobody uses. + +Q14: I have used "antiword -p a4 -m 8869-5.txt file.doc > file.ps", but I get + no Cyrillic characters. +A14: Programs like Ghostscript and Ghostview need Cyrillic enabled fonts in + order to show Cyrillic characters. A PostScript printer needs to be + Cyrillic enabled in order to show Cyrillic characters. diff --git a/Docs/History b/Docs/History new file mode 100644 index 0000000..5175df2 --- /dev/null +++ b/Docs/History @@ -0,0 +1,44 @@ +History of Antiword by (C) Adri van Os +------------------------------------ + + +The Name +-------- +The name comes from: "The antidote against people who send Microsoft(R) Word +files to everybody, because they believe that everybody runs Windows(R) and +therefore runs Word". + + +Version 0.37 (21 Oct 2005) +-------------------------- +Beta release, for evaluation by the public. + + +Known Limitations +----------------- + +1) The layout of Word documents is kept secret by Microsoft(R). Therefore + Antiword is based on information gathered from the Internet and on + guesswork. +2) Antiword doesn't show all the images included in a Word document. +3) Antiword doesn't do any hyphenation, because hyphenation is language + dependent. +4) Antiword places footnotes at the end of the text. +5) Antiword places box text after normal text and not in a box. +6) Antiword doesn't try to emulate any of Word's DTP abilities. +7) PostScript ouput will not work in combination with UTF-8. It only works in + combination with character sets ISO-8859-1, ISO-8859-2 and ISO-8859-5. +8) Antiword's error messages are not very helpful. + + +Known Bugs +---------- + +1) Antiword cannot handle encrypted documents. +2) Antiword assumes default tab stops. +3) Antiword doesn't handle frames. +4) Antiword ignores page headers and footers. +5) Antiword only handles lists in some of the styles. +6) Antiword cannot handle some types of multilevel lists. +7) Antiword assumes that all Word documents made on a Macintosh with Word + version 6 or older use the MacRoman character set. diff --git a/Docs/Mozilla b/Docs/Mozilla new file mode 100644 index 0000000..b1f1f82 --- /dev/null +++ b/Docs/Mozilla @@ -0,0 +1,88 @@ +Date: Mon, 11 Nov 2002 11:36:21 +0000 +From: Cam +Subject: Re: antiword + +Hi + +I have updated the script for the latest Mozilla with plugger, as found +in RedHat 8. This makes the default action a very quick text view of a +document, much better IMHO than starting ooffice or abiword. If users +want to edit the file they can still save as. + +Here is a slightly improved script for gnome users: + +#!/bin/bash + +tmpfile=/tmp/aw$$.txt + +lastditch=`which vi` + +editor=${EDITOR:-$lastditch} + +if [ ! -x $editor ] ; then + editor=$lastditch +fi + + +tmpfile=/tmp/aw$$.txt + +gtopts="-t antiword-helper --hide-menubar" + +antiword "$1" > $tmpfile +chmod -w $tmpfile +gnome-terminal $gtopts -x $editor $tmpfile ; chmod +w $tmpfile ; rm $tmpfile + + + +Here is the script for non-gnome users: + +#!/bin/bash + +tmpfile=/tmp/aw$$.txt + +lastditch=`which vi` + +editor=${EDITOR:-$lastditch} + +if [ ! -x $editor ] ; then + editor=$lastditch +fi + + +antiword "$1" > $tmpfile +chmod -w $tmpfile +xterm -T "antiword-helper" -e $editor $tmpfile +chmod +w $tmpfile +rm $tmpfile + + + +To use the scripts add an entry into your plugger config file +(pluggerrc, for locations check man plugger). Mine is in +/home/cxm/.netscape/pluggerrc: + +The line to add is (it has a leading tab): + + ignore_errors exits: antiword-helper "$file" + + +Here is my config file after I added the line + +application/rtf: rtf: Rich Text Format +application/x-msword: doc, dot: Microsoft Word Document +application/msword: doc, dot: Microsoft Word Document + ignore_errors exits: antiword-helper "$file" + nokill exits: oowriter "$file" + repeat swallow(AbiWord) fill: AbiWord -nosplash -geometry ++9000+9000 "$file" >/dev/null 2>/dev/null + repeat swallow(PCFileViewer) fill: sdtpcv "$file" + repeat swallow(PCFileViewer) fill: /opt/SUNWdtpcv/bin/sdtpcv +"$file" + + +Then start Mozilla / Netscape and you should be able to quickly view +word docs from the browser and as email attachments. + +Hope that helps, + +-Cam diff --git a/Docs/Mutt b/Docs/Mutt new file mode 100644 index 0000000..fdf0ef5 --- /dev/null +++ b/Docs/Mutt @@ -0,0 +1,24 @@ +From: Sven Geggus (sven@geggus.net) +Subject: Re: Word attachments in Mutt +Newsgroups: comp.mail.mutt +Date: 2001-05-16 01:21:11 PST + +Bob Zimmerman wrote: + +> I receive MS Word attachments in Mutt reguarly. Is there a way to +> read these via Mutt in a Linux/Solaris environment? (e.g. Lynx or +> some type of viewer)? + +The best M$-word to ASCII converter has to be antiword! + +Just put the following line into .mailcap: + +application/msword; antiword %s; copiousoutput + +Sven + +-- +"We just typed make" +(Stephen Lambrigh, Director of Server Product Marketing at Informix + about porting their Database to Linux) +/me is giggls@ircnet, http://geggus.net/sven/ on the Web diff --git a/Docs/Netscape b/Docs/Netscape new file mode 100644 index 0000000..022a669 --- /dev/null +++ b/Docs/Netscape @@ -0,0 +1,129 @@ +From: "Craig D. Miller" + +Hi, + +Steps to integrate antiword into NetScape 4.73 (should also work with earlier +versions). + +Programs that launch from netscape must startup an X window to display their +output (otherwise output ends up it the bit bucket on your system). I wrote the +following script to do this for antiword (and saved it as +"/usr/local/bin/xantiword": + +#!/bin/csh -f +setenv FILE $1 +setenv NEWFILE ${FILE}.xantiword +/usr/local/bin/antiword $FILE >&$NEWFILE +/usr/bin/X11/xterm -title "$FILE (MS Word)" -e /usr/bsd/more $NEWFILE +rm -f $NEWFILE + +The above script works, but may not be the best way to do it. If you come up +with a more elegant solution, then please let me know. + +Next you'll have to tell netscape to execute the "/usr/local/bin/xantiword" +script when word documents are clicked on. The easiest way to do this is to +change the /usr/local/lib/netscape/mailcap netscape configuration file. For +SGI version of netscape the following two lines are changed. For other versions +of netscape, one should find similar lines or will need to add the new lines. + +Old lines (try to run SoftWindows, which is not installed on my system): + + application/x-dos_ms_word; /usr/local/lib/netscape/swinexec %s winword; \ + description="Microsoft Word-for-Windows Document"; + application/msword; /usr/local/lib/netscape/swinexec %s winword; \ + description="Microsoft Word-for-Windows Document"; + +New lines (for antiword execution), which replace old lines on my system: + + application/x-dos_ms_word; /usr/local/bin/xantiword %s; \ + description="Microsoft Word-for-Windows Document"; + application/msword; /usr/local/bin/xantiword %s; \ + description="Microsoft Word-for-Windows Document"; + +These changes can also be made via the netscape preferences, under +Navigator/Applications, but then the changes would only be for the user that +changed them. The above change to the mailcap file affects all users, which is +what you'll usually want. + + Note that the above file paths may be different for your system. On our linux +box, a quick search DID NOT show where the mailcap for netscape was stored, but +I did find one in /etc/mailcap. I don't have time to experiment to see if this +is the same one that netscape uses. + +If you have questions then please E-mail me. + +- Craig + +=============================================================================== + +From: "Craig D. Miller" + +Hi, + +I just discovered a program called "xless". It would actually be easier to use +than my previous xterm/more solution. To use it change the +"/usr/local/bin/xantiword" script to: + +#!/bin/csh -f +setenv FILE $1 +/usr/local/bin/antiword $FILE | /usr/freeware/bin/xless \ + -title "$FILE (MS Word)" -geometry 100x60 + +Note that one also needs to have xless installed. It can be found on the +SGI Freeware Feb 1999 (or later) CD-ROM. + +- Craig + +=============================================================================== + +From: Bruno Crochet + +Hi! + +Another way to integrate antiword into netscape is to copy the following +line in your .mailcap file : + +application/msword; ns="%s"\; nf="${ns}".ps\; antiword -pa4 "${ns}" > +"${nf}"\; gv "${nf}"\; sleep 2 \; rm "${nf}" + +Bruno. + +=============================================================================== + +From: Andoni Zarate + +In order to view the file into netscape you can write the xantiword file +like this: + +#!/bin/csh -f +setenv FILE $1 +setenv NEWFILE ${FILE}.xantiword +/usr/local/bin/antiword $FILE >&$NEWFILE +netscape -remote 'openFile('$NEWFILE')' + +Andoni Zárate. + +=============================================================================== + +From: Evelyne Pinter + +I include a script for netscape to see the document with ghostview. + +#!/bin/csh -f +setenv FILE $1 +setenv NEWFILE ${FILE}.xantiword +/usr/local/bin/antiword -pa4 $FILE >&$NEWFILE +/usr/X11R6/bin/gv $NEWFILE +rm -f $NEWFILE + +In netscape the application must be called like that +"/usr/local/bin/xantiword %s" + +This is just a small change(done by Roger Luechinger) to the xantiword +you included in the distribution 0.31 + +Thanks + +SG E.M.S.P. + +=============================================================================== diff --git a/Docs/QandA b/Docs/QandA new file mode 100644 index 0000000..0b60513 --- /dev/null +++ b/Docs/QandA @@ -0,0 +1,59 @@ +Questions and Answers (RISC OS version) +======================================= + +Q1: How do I install Antiword? +A1: Copy the application-directory and all the files within it to a + suitable directory. + +Q2: How do I use Antiword? +A2: Double click on a Word document, filetype MSWord (&ae6). Or drag and drop + a file onto the Antiword icon on the iconbar. + +Q3: How does Antiword deal with Word macro viruses? +A3: Antiword does not run any Word macros because it cannot do so. + Therefore your Archimedes will not be harmed by such a virus. + +Q4: What does the 'Paragraph breaks' option do? +A4: This option controls the maximum number of characters per line in + paragraphs. If your screen is 640 pixels wide (like modes 20 and 27) + than 76 is probably best. If your screen is 800 or more pixels wide + (like mode 31) then numbers near 94 work best. You can switch this + option off if the (text only) output of Antiword will be the input to a + wordprocessor or a DTP program. + The pagebreak setting refers to the number of characters when you use + the system font. When you use an outline font only the width of that + number of characters in the system font is used. + +Q5: What does the 'Auto filetype' option do? +A5: When auto filetype is allowed, Antiword will change the filetype of + Word documents to MSWord (&ae6) + +Q6: When Antiword uses outline fonts it becomes terribly slow. What can I + do about this? +A6: When Antiword uses outline fonts it needs a large font cache. A small + font cache will make Antiword (very) slow. The larger the font cache the + better, but usually 160K or 256K will do. + +Q7: What is the purpose of the file 'FontNames' in the Choices directory? +A7: This file provides a translation table from the font names found in a + Word document to the font names used by the RISC OS font-manager. + The file 'FontNames' is can be edited to match your font collection. + Some examples are provided in the Resources directory. + +Q8: What is 'Hidden Text'? +A8: Hidden Text is Microsoft speak for text that may or may not be shown + on the screen, subject to the user's preferences, but such text is never + printed. + +Q9: After upgrading to a new version of Antiword, I found that Antiword does + not put a new _updated_ version of FontNames in !Choices. Why not? +A9: The user can change the file Fontnames to reflect the fonts available + on a specific computer. Antiword cannot be permitted to overwrite changes + made by a user. So after upgrading you should remove or rename the old + FontNames file. + +Q10: Why does Antiword freeze my computer while converting the Word document? +A10: This can happen when the Word document contains a very large image and + the image must be scaled to a much smaller size before displaying. The + delay occurs while RISC OS does the scaling, so there is not much + Antiword can do about it. diff --git a/Docs/ReadMe b/Docs/ReadMe new file mode 100644 index 0000000..5e783b1 --- /dev/null +++ b/Docs/ReadMe @@ -0,0 +1,114 @@ + ___ _ _ _ + / _ \ | | (_) | | + | |_| |_ __ | |_ ___ _____ _ __ __| | + | _ | '_ \| __| \ \ /\ / / _ \| '__/ _` | + | | | | | | | |_| |\ V V / (_) | | | (_| | + |_| |_|_| |_|\__|_| \_/\_/ \___/|_| \__,_| + +Antiword +======== + +Version 0.37 (21 Oct 2005) +-------------------------- + +Introduction +------------ + +Antiword is an application for displaying Microsoft(R) Word documents. + + +License +------- + +This program is distributed under the GNU General Public License - see the +accompanying COPYING file for more details. + + +Problems +-------- + +Any bugs found should be reported to the author with full details of how to +get the problem to occur, but don't *expect* support for a product that you +have not paid for! + +Please include Antiword's version number and version date, otherwise you +make it impossible for the author to help. + + +Thanks To +--------- + +Victor B. Wagner creator of "catdoc" +Duncan Simpson creator of "word2x" +Martin Schwartz creator of "laola" and "elser" +Caolan McNamara creator of "mswordview" +Andrew Scriven creator of "OLEdecode" +Craig Southeren creator of "nenscript" +Thomas Merz creator of "jpeg2ps" +Ulrich von Zadow creator of "paintlib" + + +Contributors +------------ + +ISO-8859-2 support by: Pawel Turnau +Character set mapping by: Dmitry Chernyak + +UTF-8 support by: Karl Koehler and + Markus Kuhn +PostScript Cyrillic by: Alexander Belyaev + + +Ports +----- + +Antiword was ported to BeOS by Pete Goodeve +Antiword was ported to OS/2 by Dave Yeo +Antiword was ported to Mac OS X by Ronaldo Nascimento +Antiword was ported to Amiga by Raffaele Pisapia +Antiword was ported to VMS by Joseph Huber +Antiword was ported to NetWare by Guenter Knauf +Antiword was ported to EPOC by Max Tomin +Antiword was ported to Zaurus PDA by Piotr Jachimczyk + +Antiword was ported to DOS by myself ;-) +Yen-Ming Lee is the maintainer of the FreeBSD version of +Antiword. + + +Acknowledgements +---------------- + +Microsoft is a registered trademark and Windows is a trademark of Microsoft +Corporation. +UNIX is a registered trademark of the X/Open Company, Ltd. +Linux is a registered trademark of Linus Torvalds. +Postscript is a trademark of Adobe Systems Incorporated. +All other trademarks are acknowledged. + + +Future Versions +--------------- + +If you have any comments, bug reports or suggestions for future versions +don't hesitate to write to me. +New versions of the program will only be available if sufficient people +are using this program. So let me know! + + +Most recent version +------------------- + +Most recent version of Antiword can be found on the author's website: +==>> http://www.winfield.demon.nl/index.html <<== +==>> http://antiword.cjb.net/ <<== + + +Author +------ + +The author can be reached by e-mail: +antiword@winfield.demon.nl +comments@antiword.cjb.net + +But PLEASE read the FAQ before you write!! diff --git a/Docs/antiword.1 b/Docs/antiword.1 new file mode 100644 index 0000000..1bae2f4 --- /dev/null +++ b/Docs/antiword.1 @@ -0,0 +1,158 @@ +.TH ANTIWORD 1 "Oct 29, 2005" "Antiword 0.37" "Linux User's Manual" +.SH NAME +antiword - show the text and images of MS Word documents +.SH SYNOPSIS +.B antiword +[ +.I options +] +.I wordfiles +.SH DESCRIPTION +.I Antiword +is an application that displays the text and the images of Microsoft Word +documents. +.br +A wordfile named - stands for a Word document read from the standard input. +.br +Only documents made by MS Word version 2 and version 6 or later are supported. +.SH OPTIONS +.TP +.BI "\-a " papersize +Output in Adobe PDF form. Printable on paper of the specified size: 10x14, +a3, a4, a5, b4, b5, executive, folio, legal, letter, note, quarto, statement +or tabloid. +.TP +.B \-f +Output in formatted text form. That means that bold text is printed like +*bold*, italics like /italics/ and underlined text as _underlined_. +.TP +.B \-h +Give a help message. +.TP +.BI "\-i " "image level" +The image level determines how images will be shown. +.RS +.TP 3 +0: +Use non-standard extensions from Ghostscript. This output may not print on +any PostScript printer, but is useful in case no hard copy is needed. It is +also useful when Ghostscript is used as a filter to print a PostScript file to +a non-PostScript printer. +.TP 3 +1: +Show no images. +.TP 3 +2: +PostScript level 2 compatible. (default) +.TP 3 +3: +PostScript level 3 compatible. (EXPERIMENTAL, Portable Network Graphics (PNG) +images are not printed correctly) +.RE +.TP +.BI "\-m " "mapping file" +This file is used to map Unicode characters to your local character set. +The default mapping file depends on the locale. +.TP +.BI "\-p " papersize +Output in PostScript form. Printable on paper of the specified size: 10x14, +a3, a4, a5, b4, b5, executive, folio, legal, letter, note, quarto, statement +or tabloid. +.TP +.B \-r +Include text removed by the revisioning system. +.TP +.B \-s +Include text with the so-called "hidden text" attribute. +.TP +.B \-t +Output in text form. (default) +.TP +.BI "\-w " width +In text mode this is the line width in characters. A value of zero puts an +entire paragraph on a line, useful when the text is to used as input for +another wordprocessor. This value is ignored in PostScript mode. +.TP +.BI "\-x " "document type definition" +Output in XML form. Currently the only document type definition is db +(for DocBook). +.TP +.B \-L +In PostScript mode: use landscape mode. +.RE +.SH FILES +.TP +Mapping files like 8859-1.txt +.br +Antiword looks for its mapping files in three directories, in the order given: +.br +(1) The directory specified by $ANTIWORDHOME +.br +(2) The directory specified by $HOME/.antiword +.br +(3) Directory /usr/share/antiword +.TP +The fontnames file +.br +Antiword will look for its fontname file in the same directories as used for the +mapping files. +.br +The fontnames file contains the translation table from font names used by MS +Word to font names used by PostScript. +.TP +NOTE: +.br +Antiword cannot tell the difference between a file that does not exist and a +file that cannot be opened for reading. +.SH ENVIRONMENT +Antiword uses the environment variable ``ANTIWORDHOME'' as the first directory +to look for its files. Antiword uses the environment variable ``HOME'' to find +the user's home directory. When in text mode it uses the variable ``COLUMNS'' +to set the width of the output (unless overridden by the -w option). + +Antiword uses the environment variables ``LC_ALL'', ``LC_CTYPE'' and ``LANG'' +(in that order) to get the current locale and uses this information to +select the default mapping file. +.SH BUGS +Antiword is far from complete. Many features are still missing. Many images are +not shown yet. Some of the images that are shown, are shown in the wrong place. +PostScript output is only available in ISO 8859-1 and ISO 8859-2. +.SH WEB SITES +The most recent released version of Antiword is always available from: +.br +http://www.winfield.demon.nl/index.html +.br +or try +.br +http://antiword.cjb.net/ +.SH AUTHOR +Adri van Os +.br +or try +.sp +R.F. Smith and +.br +Sindi Keesan +.br +contributed to this manual page. +.SH LICENSE +Antiword 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 +.SH ACKNOWLEDGEMENTS +Linux is a registered trademark of Linus Torvalds. +.br +Adobe, PDF and PostScript are trademarks of Adobe Systems Incorporated. +.br +Microsoft is a registered trademark and Windows is a trademark of Microsoft +Corporation. diff --git a/Docs/antiword.man b/Docs/antiword.man new file mode 100644 index 0000000..270b8ce --- /dev/null +++ b/Docs/antiword.man @@ -0,0 +1,146 @@ +ANTIWORD(1) Linux User's Manual ANTIWORD(1) + + + +NAME + antiword - show the text and images of MS Word documents + +SYNOPSIS + antiword [ options ] wordfiles + +DESCRIPTION + Antiword is an application that displays the text and the images of + Microsoft Word documents. + A wordfile named - stands for a Word document read from the standard + input. + Only documents made by MS Word version 2 and version 6 or later are + supported. + +OPTIONS + -a papersize + Output in Adobe PDF form. Printable on paper of the specified + size: 10x14, a3, a4, a5, b4, b5, executive, folio, legal, let- + ter, note, quarto, statement or tabloid. + + -f Output in formatted text form. That means that bold text is + printed like *bold*, italics like /italics/ and underlined text + as _underlined_. + + -h Give a help message. + + -i image level + The image level determines how images will be shown. + + 0: Use non-standard extensions from Ghostscript. This output may + not print on any PostScript printer, but is useful in case no + hard copy is needed. It is also useful when Ghostscript is + used as a filter to print a PostScript file to a non- + PostScript printer. + + 1: Show no images. + + 2: PostScript level 2 compatible. (default) + + 3: PostScript level 3 compatible. (EXPERIMENTAL, Portable Net- + work Graphics (PNG) images are not printed correctly) + + -m mapping file + This file is used to map Unicode characters to your local char- + acter set. The default mapping file depends on the locale. + + -p papersize + Output in PostScript form. Printable on paper of the specified + size: 10x14, a3, a4, a5, b4, b5, executive, folio, legal, let- + ter, note, quarto, statement or tabloid. + + -r Include text removed by the revisioning system. + + -s Include text with the so-called "hidden text" attribute. + + -t Output in text form. (default) + + -w width + In text mode this is the line width in characters. A value of + zero puts an entire paragraph on a line, useful when the text is + to used as input for another wordprocessor. This value is + ignored in PostScript mode. + + -x document type definition + Output in XML form. Currently the only document type definition + is db (for DocBook). + + -L In PostScript mode: use landscape mode. + +FILES + Mapping files like 8859-1.txt + Antiword looks for its mapping files in three directories, in + the order given: + (1) The directory specified by $ANTIWORDHOME + (2) The directory specified by $HOME/.antiword + (3) Directory /usr/share/antiword + + The fontnames file + Antiword will look for its fontname file in the same directories + as used for the mapping files. + The fontnames file contains the translation table from font + names used by MS Word to font names used by PostScript. + + NOTE: + Antiword cannot tell the difference between a file that does not + exist and a file that cannot be opened for reading. + +ENVIRONMENT + Antiword uses the environment variable ``ANTIWORDHOME'' as the first + directory to look for its files. Antiword uses the environment variable + ``HOME'' to find the user's home directory. When in text mode it uses + the variable ``COLUMNS'' to set the width of the output (unless over- + ridden by the -w option). + + Antiword uses the environment variables ``LC_ALL'', ``LC_CTYPE'' and + ``LANG'' (in that order) to get the current locale and uses this infor- + mation to select the default mapping file. + +BUGS + Antiword is far from complete. Many features are still missing. Many + images are not shown yet. Some of the images that are shown, are shown + in the wrong place. PostScript output is only available in ISO 8859-1 + and ISO 8859-2. + +WEB SITES + The most recent released version of Antiword is always available from: + http://www.winfield.demon.nl/index.html + or try + http://antiword.cjb.net/ + +AUTHOR + Adri van Os + or try + + R.F. Smith and + Sindi Keesan + contributed to this manual page. + +LICENSE + Antiword 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 MER- + CHANTABILITY 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 + +ACKNOWLEDGEMENTS + Linux is a registered trademark of Linus Torvalds. + Adobe, PDF and PostScript are trademarks of Adobe Systems Incorporated. + Microsoft is a registered trademark and Windows is a trademark of + Microsoft Corporation. + + + +Antiword 0.37 Oct 29, 2005 ANTIWORD(1) diff --git a/Docs/antiword.old.php b/Docs/antiword.old.php new file mode 100644 index 0000000..8025b24 --- /dev/null +++ b/Docs/antiword.old.php @@ -0,0 +1,34 @@ +From: Paul Southworth +Subject: antiword PHP script +Date: Thu, 24 Oct 2002 14:01:05 -0700 (PDT) + +Please find attached a trivial example of using a web form to process an +uploaded Word doc to text using antiword. Perhaps other antiword users +would find it useful. + +--Paul + + +antiword +
+ + +
+ + diff --git a/Docs/antiword.php b/Docs/antiword.php new file mode 100644 index 0000000..f30c48d --- /dev/null +++ b/Docs/antiword.php @@ -0,0 +1,141 @@ +| + +V.3: I've added escapeshellcmd to all user input that shows up directly +in exec() +*/ +switch ($_REQUEST['output']) { +case "PostScript": + $output=escapeshellcmd("-p $_REQUEST[paper]"); + break; +case "PDF": + $output=escapeshellcmd("-a $_REQUEST[paper]"); + $pdf=1; + break; +case "InLine": + $output="-t"; + break; +} +if (isset($_FILES['userfile']['name'])) { + $uploaddir = '/tmp/'; + $uploadfile = $uploaddir . $_FILES['userfile']['name']; + $userfile = $_FILES['userfile']['name']; + if (move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) { + $delims="."; + if (strstr($output,"-p")) { + $psfile=strtok($userfile,$delims).".ps"; + header("Content-Type: Application/PostScript"); + header("Content-Disposition: attachment; filename=".$psfile); + $file=escapeshellcmd($uploadfile); + $command="antiword $output $file"; + passthru($command); + unlink($uploadfile); + } elseif (strstr($output,"-a")) { + $psfile=strtok($userfile,$delims).".pdf"; + header("Content-Type: Application/PDF"); + // header("Content-Disposition: attachment; filename=".$psfile); + // $command="antiword $output $uploadfile"; + $file=escapeshellcmd($uploadfile); + $command="antiword $output $file"; + passthru($command); + unlink($uploadfile); + } else { + echo "
";
+      $file=escapeshellcmd($uploadfile);
+      $command="antiword $output $file";
+      //      echo $command;
+      //      $command="antiword $output $uploadfile";
+      passthru($command);
+      unlink($uploadfile);
+    }
+  }
+  elseif (isset($_REQUEST['url'])) {
+    echo $command;
+    $url=$_REQUEST['url'];
+    $uri=escapeshellcmd($_REQUEST['url']);
+    $delim="/";
+    $docfile=explode($delim,$uri);
+    exec("wget -O /tmp/$docfile $url");
+    if (strstr($output,"-p")) {
+      $psfile=strtok(end($docfile),".").".ps";
+      $safe=escapeshellcmd($docfile);
+      $command="antiword $output /tmp/$safe";
+      header("Content-Type: Application/PostScript");
+      header("Content-Disposition: attachment; filename=".$psfile);
+      passthru($command);
+      @@      unlink("/tmp/$docfile");
+    } elseif (strstr($output,"-a")) {
+      $psfile=strtok(end($docfile),".").".pdf";
+      $safe=escapeshellcmd($docfile);
+      $command="antiword $output /tmp/$safe";
+      header("Content-Type: Application/PDF");
+      header("Content-Disposition: attachment; filename=".$psfile);
+      passthru($command);
+@@      unlink("/tmp/$docfile");
+    } else {
+      echo "
";
+      $safe=escapeshellcmd($docfile);
+      $command="antiword $output /tmp/$safe";
+      passthru($command);
+@@      unlink("/tmp/$docfile");
+    }
+  }
+}
+if (!isset($_FILES['userfile']['name'])) {
+  ?>
+

+ This script converts a word file (most versions supported) into a +pure ASCII, a PDF or a PostScript version. Currently, only PostScript +and PDF carry images, and those images might be distorted or such. It's +based on the nice program antiword. see antiword.cjb.net for more information +about antiword. Currently, max file size is 3MiB for the upload. This +should be enough! +

Currently, I tend to end up with the ascii version being 1/100th +of the word document, and the pdf/ps versions being 1/10th of the size. +So if you're gonna send me a word document, rethink that. I'll not read +it. I'll read ascii, and probably pdf/ps too.

+

+
+ + URL:

+ Send this file:
+
Output:
+ +Papersize: +
+ +
+

This is running antiword 0.36.
+ Please drop me a note at antiword (at) bitsex.net if you have +comments for this. +


+(C)Vidar Løkken 2005 + + +| diff --git a/Docs/testdoc.doc b/Docs/testdoc.doc new file mode 100644 index 0000000000000000000000000000000000000000..3f78d7752d9fc890d4896f7a05fc37089ec3f721 GIT binary patch literal 23552 zcmeG^2V7J~^Lvesa)5|{_$Z1ZAWa1u98xtRO+hgcI1T}ULpWND1UnjtAZoxaf}&W! ziblnP*b_SNHa0U%UI2ryy5R1Eh$n7jHEATZP z(UG=@_|rIMelD#os}9&*TK6AeH7Mr?Yptn%cn#_Dp4Syq9Q0>oG2h4ifk`e@z7Ul2eOJO1@ftqAa@%(r$ULz@On{E;&NBOvUNE%0>u(1z3Me&7k zU(%GVv?(9&4lVJ8$$|t*7(q8XcCnuTm`|g^gunOZbP65suhL& zC?0A@NIPC_?c|vh%a!}L(SR~5Ivy4i zSAU=@yQI0oF*|Jm_>`?~cx%nWD-K_33T8elQI5{^PP z*rXhVdis71?@R`PM_Ju~^eUTWMU_?ajLH^pi~&q?7H~`fdYAouWs-CD@6rH%7+gs> zF@~#SpqLc1iPhAJo%XSGSHf-{56K;Dm1ZTtZ1`3X6+-w#wb>TaJZyq<1g$y+2ADx) zCW8xxQYE~AG>91PN`yxOi4_?|e253+106p+7&82bVskZ2RSsv@+!YVAAHO``+tIS_ z4s+#hF)0K(zRFzbqR+@$_nytmf%d18;w$2tL}Qe@mpi=n7-S+`L|jis5+wx%MFozM zqN1X*vXY9Lwz`_Cs#*_Ct*+WV^?Dih)H5)kOs&i)V+#`lgT90NSy*av3ZxLtI6AfovS$78#ZX z29w3+C@3l^tEfVO-5P|+V6m8N7Kej6XUu?n!sc=`jcj-dTE3x*#?!QIXXdU`GI1$C z(#`LDv#DKJ!YpMKo$k6l^m_L(>)X%Ve&C?N4vs@cy1Kc0czTWU4;VK-FlfR=ez+iF zN@P@Yq9`djB{l8a*>mR3o1eL0;o`g{OPBqWU$DGzeNpj-jU}5l@7TF(_ny5K`}Q9_ zR&~7k#K}{qFVtMDy>$7?)w)}^?=;+Pyw`O9LCdq}FJ88`y?Wh_axn-?BGw1VI>^NZ zxtMG=i>-)qF_*zMT0 z;JQtdZ4RYaWU|9zOnD9ZN}3lEd;|Gj2e~h}wJ!%e9<+PVgJJt_2iCLp+5CK(#q46U zo8Noq%w-SU>(1`m*J8MSs_DtCQ+w=Q?O7O{#$GXtQt`f-a`(E2ZtuYyCo6|BX2-vs zJb$DxMvOw$K-JS<~o$;*FPyv4>YxV9^ z*F8!OuDZB<#;PUB?M1zBPY5`8`tgsR#k)Oc&5Ou7c`K-|%0kwl8;bj0<&E0YGI;)g zT~kXljQ3}j@U0$aIgUTE=IkYMvw7ODsq=o?HnDE^lNDROsk=J5Uz*kW+#jlc%6Xfo z=($H(Gl1Ng=65*D#=)_+SY>lfpt)9jiu<_j^M9%u;$C#$W`%$GPJceJcxcKh@%iPE zXG7nw$b8)NHrBd47QCNa(<- z2e#+-yBL~=ZE#b0rKW52+*UQ#_|Vku^Qr@mS94>Fx8F@_>%ZOZ+UDjL_c!^!3g5Q0 z^>^>~;lnM?`MmLXH|+a{@8AFK)+HZFR*NKERRwr?7yrT@mI?S1+ar>D2XL~n!9 z0^yB!VZ78Q+u9f&`M;F-dc_sZjqsVSV6v`oA=&qC-E=W=O6k?sEGF5#>bh4xZ<{72 z-*HZvh{hRqE?`%}pU;44yB(F3N5x|gRbavcsZ zhmBv#C7F450kNm>#_$L!U!?jr6xtw$K3@g6Rb0EGk)H`)Sx-;TS8rcs9Ik+zppvzz zsi|dUWxpL&8U&Juc)9Wdf{s1TcM{e+=vMbw!rNlW^h>q$?zwzxneA`-!8;8Ya%#r$tEOfr4v|xpUvm>Ihh9qi z=IN#)edX7!3v#AT(0X?Fz{2m+!v`8UR+5Cgoc$Y4tor3jiaUdq*1p5du;9Rh?B2rM zO`G?Y$HcAKJlf^v$-Vt4bGNI!A?By9wl}7iGC3FBYFAv_J7~Un(q)_c$&LLk4=}GW zDZlu7#4}MrCA&ud%n$ri4VJ|Z`=1)NYBhh+FhOGb;)`cqtRDW|!AAxBdf$8cPoLj! zYj=J5(601Qda+-x^wdeo`ycWb+njaGTR7V5X|oP%a1X2d>sya1>>lA*7(A~eb?K(1 zZN7<{4)~84I@?-!aC`iY79BHP%l`8(r-ygjJ+Zn~x9Y&Q7v}CxrpsQ{JQW(wL-b6l z60YmcUeGwhiCGvkM=3jMgw^4Rcg~fZ?A4&|Ze1Lt%Q&~?smCR^AA&$E+CF~2NewSkgQA%A0bd=C_o)`7a31B%^?F^X z8{&OvLi07ZQfonedbVeIpGp_K__OYJT8e!iM&22fTxl0qxlpg(l)I4Kcz%D=lGER* zW!F+&de&^neopJr$>-J={F)WrXu7RtlYa5u!J>GE`kfDunNBoyq|Eh;lOzSyWs(xIs z?y&auP3@7KCfF%`-v)(3ET;FQBr%1!m>YInW`qF9p%kA^7 zZp(R>`CixmagT52w2jOe*x0Q{#05dLhOt|!OP3XZLfKYEXRF>>sZvt3dx3|zgK`qp=8p4m7Z_;FOG(zO8JG1Zb^;V7+ z-1;@KD;$%)8_MLZc~w?j9y>z8>)z>O{^$1<3@f-55bI$SwD5ds?#X;pagk@m8~!-G zp5{Y!_m$qTxaa<6pWaN1C(E*1hYMWu8XbmJtm2PzJMs3=>FLpHZj?^0Jo2N*drsTw zn*MfS8cp!-C0=gcuG?HfW?@_&C?@d*_)~BtJm+WPb+k>d_nF>9NesO{696}s5ElS{B6{T} zf;C$_#6Au7#F*yK9*8Q$1!_i~S{(9vDf7che;H)8{`utmQw-2szG+&Cx*3W4Qa0BcI=44|W0{K36r2vLa} z=L~iub>^^H$`E&Afv*`bmv-gQ*^t@*un{p36rl@6h)bv?f1rxR*o`VUhR`i!MJQOF z<20nmSQx-AKp#RT(F30d_i&had?+Qsoz*f2hY!{YAZ}y~xSA$GD@jmWNIdBYge?hR zN?A%xfkc=hf=_zJ+)sN8g;Y2ZJ2NsEv`i@1fl+6ODO?!GAj3?Vs&Tx1(BF^@pbzc>!Do+vql!&hl(JxQRspY@fO|r= zCIm-ZUOp)T^!I(jh0VohmoH+X0$nD{vFV&I}aJcN|=@k^rTX&lfcp|i)a zGrF{z9LY5x*MM9Dat+8eAlHCg19A=g2Q=^=PHwPi`|^*C!5)A_U z1;hd{?wrOQ-?-V;6)>9JK7jGWKoDRJz#)LO07nAGejA`OG(dF#c%R$4OdRNZC{76E zV_EEnXEn--N)C;q#wLEu2O8$90(c7(U>memxDXbwoz=nq9f_n4@-!xjpCC*WMu@0D z+yL!hWliFofldaw??+wG@#HfKEip$JbX;$^G42vay&-=x1E?d0EP0S?K&}C~2ILx$ zYe236xd!AKkZVA$0l5a`8jx$?U)Dfp_CMOU%-UaTS6b<7FJX1E8(F765Jg5&*QL%K*@xuK++_z+nJv z`!)dbB(wR^pWqQH5~PHt(YCY9hL&N-rs>fdN_0P%#{MvL#D>5C*6ZAlpavzdck~9J zGyzef7{P~r(I0_+4-9<)ur1uti8bJy0bOo~G>tU$c}({4a-Hlk&dZg~MG0w&=T~0d zqy0Zf$^*JLz;t2@z6=}K6JZB17-E)y9pGo|fe^Eyb1>#Wtcg3ZhZqlNE&x2Z+`&`f z2xaY|&J1V`JRksD0I*;5I5?4SX^bcTFwK@?lmw0;&|aL5Cp3_b`53T{75q4l7*7i# zW_D-;NBytvy8W~ds4fq34ahYh*MM9Dat+8eAlHCg19A<>H6Yi3Tm%2K2GD{-o0PWt z0He*07B2p7kN?*Zf3HV-6>Vm;7SSfh-{#TA$9%Nu@wa@m-L(PmKh>cfjn*FK<1SP^ z0DS-hfSv$oMWbbh`9^?^0Zaf)0eS=U0Wbr={C5C&4gupbfT%qDn>2ts$c3;|mjeF) z?$}L$-Qk4Pl1t<=xk9dzI#Lh&H?ET#KncY0 zQjFy#>5q36_*Vh4{t^4oC9J`Z)cJ+JBXl}p2^%;J5DL5D@f?YSBB_VGgn+jy9(J+h zK-`DsK@!6p83$e9>A`16#zPL2&Vl^3AR(5?fOrVpGoU`!!W`(D?jK78g7)!DjVoY2 z97ez${*s;3SXyQ%08!Aru2^pmcNq zCQvF4oCm;OaW^-Py%+QzLGy$ZJP9oX3ZeN%IdY)RT4)heo#)l9H4(TG$+%)jQ)bL5_=&&(YoME)P~vZ2d9(9fal8x z<~js=5CUQBMuLQ~(9&3#1<{y8oM8$(ce%_AnRbXlf_N3(Va}2kt>~n?hjFOsutFNs zg#K~Hv;O5gF_ xjnC;H_qAEd{^=*ZCK%(7d)-`xeEMO+xD_NM|1{Kryl~tx?c*Gj$Nrug_&-ix=K=r# literal 0 HcmV?d00001 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eeb2d15 --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +# +# Makefile for antiword (Linux version) +# + +CC = gcc +LD = gcc + +INSTALL = cp -f +INSTALL_PROGRAM = $(INSTALL) +INSTALL_DATA = $(INSTALL) + +# must be equal to DEBUG or NDEBUG +DB = NDEBUG +# Optimization: -O or debugging: -g +OPT = -O2 + +LDLIBS = + +CFLAGS = -Wall -pedantic $(OPT) -D$(DB) +LDFLAGS = + +OBJS =\ + main_u.o asc85enc.o blocklist.o chartrans.o datalist.o depot.o\ + dib2eps.o doclist.o fail.o finddata.o findtext.o fmt_text.o fontlist.o\ + fonts.o fonts_u.o hdrftrlist.o imgexam.o imgtrans.o jpeg2eps.o\ + listlist.o misc.o notes.o options.o out2window.o output.o pdf.o\ + pictlist.o png2eps.o postscript.o prop0.o prop2.o prop6.o prop8.o\ + properties.o propmod.o rowlist.o sectlist.o stylelist.o stylesheet.o\ + summary.o tabstop.o text.o unix.o utf8.o word2text.o worddos.o\ + wordlib.o wordmac.o wordole.o wordwin.o xmalloc.o xml.o + +PROGS =\ + antiword\ + kantiword + +LOCAL_INSTALL_DIR = $(HOME)/bin +LOCAL_RESOURCES_DIR = $(HOME)/.antiword + +GLOBAL_INSTALL_DIR = /usr/local/bin +GLOBAL_RESOURCES_DIR = /usr/share/antiword + +all: $(PROGS) + +install: all + mkdir -p $(LOCAL_INSTALL_DIR) + cp -pf $(PROGS) $(LOCAL_INSTALL_DIR) + mkdir -p $(LOCAL_RESOURCES_DIR) + cp -pf Resources/* $(LOCAL_RESOURCES_DIR) + +# NOTE: you might have to be root to do this +global_install: all +# @[ `id -u` -eq 0 ] || (echo "You must be root to do this" && false) + mkdir -p $(DESTDIR)$(GLOBAL_INSTALL_DIR) + $(INSTALL_PROGRAM) $(PROGS) $(DESTDIR)$(GLOBAL_INSTALL_DIR) + cd $(DESTDIR)$(GLOBAL_INSTALL_DIR); chmod 755 $(PROGS) + mkdir -p $(DESTDIR)$(GLOBAL_RESOURCES_DIR) + chmod 755 $(DESTDIR)$(GLOBAL_RESOURCES_DIR) + $(INSTALL_DATA) Resources/*.txt $(DESTDIR)$(GLOBAL_RESOURCES_DIR) + $(INSTALL_DATA) Resources/fontnames $(DESTDIR)$(GLOBAL_RESOURCES_DIR) + cd $(DESTDIR)$(GLOBAL_RESOURCES_DIR); chmod 644 *.txt fontnames + +# NOTE: you might have to be root to do this +global_uninstall: +# @[ `id -u` -eq 0 ] || (echo "You must be root to do this" && false) + cd $(DESTDIR)$(GLOBAL_INSTALL_DIR); rm -f $(PROGS) + -rmdir $(DESTDIR)$(GLOBAL_INSTALL_DIR) + cd $(DESTDIR)$(GLOBAL_RESOURCES_DIR); rm -f *.txt fontnames + -rmdir $(DESTDIR)$(GLOBAL_RESOURCES_DIR) + +clean: + rm -f $(OBJS) + rm -f $(PROGS) + +antiword: $(OBJS) + @rm -f $@ + $(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ + @chmod 750 $@ + +kantiword: Unix-only/KDE3-only/kantiword.sh + @rm -f $@ + echo "#!/bin/bash" > $@ + cat $? >> $@ + @chmod 750 $@ + +.c.o: + $(CC) $(CFLAGS) -c $< + +main_u.o: version.h +postscript.o: version.h +pdf.o: version.h +fonts_u.o: fontinfo.h + +fontinfo.h: Unix-only/fontinfo.h + cp -rp $? $@ + +Unix-only/fontinfo.h: Unix-only/fontinfo.pl + Unix-only/fontinfo.pl > Unix-only/fontinfo.h diff --git a/Resources/8859-1.txt b/Resources/8859-1.txt new file mode 100644 index 0000000..473ecab --- /dev/null +++ b/Resources/8859-1.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-1:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-1:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-1 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-1 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/Resources/8859-10.txt b/Resources/8859-10.txt new file mode 100644 index 0000000..374a42b --- /dev/null +++ b/Resources/8859-10.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-10:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.1 +# Table format: Format A +# Date: 1999 October 11 +# Authors: Ken Whistler +# +# Copyright (c) 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-10:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-10 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-10 order. +# +# Version history +# 1.0 version new. +# 1.1 corrected mistake in mapping of 0xA4 +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xA3 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xA4 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xA5 0x0128 # LATIN CAPITAL LETTER I WITH TILDE +0xA6 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xA7 0x00A7 # SECTION SIGN +0xA8 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xA9 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xAA 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAB 0x0166 # LATIN CAPITAL LETTER T WITH STROKE +0xAC 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xAF 0x014A # LATIN CAPITAL LETTER ENG +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xB3 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xB4 0x012B # LATIN SMALL LETTER I WITH MACRON +0xB5 0x0129 # LATIN SMALL LETTER I WITH TILDE +0xB6 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xB9 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xBA 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBB 0x0167 # LATIN SMALL LETTER T WITH STROKE +0xBC 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBD 0x2015 # HORIZONTAL BAR +0xBE 0x016B # LATIN SMALL LETTER U WITH MACRON +0xBF 0x014B # LATIN SMALL LETTER ENG +0xC0 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD2 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x0168 # LATIN CAPITAL LETTER U WITH TILDE +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF2 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x0169 # LATIN SMALL LETTER U WITH TILDE +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x0138 # LATIN SMALL LETTER KRA diff --git a/Resources/8859-11.txt b/Resources/8859-11.txt new file mode 100644 index 0000000..ab29d3d --- /dev/null +++ b/Resources/8859-11.txt @@ -0,0 +1,299 @@ +# +# Name: ISO/IEC 8859-11:2001 to Unicode +# Unicode version: 3.2 +# Table version: 1.0 +# Table format: Format A +# Date: 2002 October 7 +# Authors: Ken Whistler +# +# Copyright (c) 2002 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-11:2001 characters map into Unicode. +# +# ISO/IEC 8859-11:2001 is equivalent to TIS 620-2533 (1990) with +# the addition of 0xA0 NO-BREAK SPACE. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-11 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-11 order. +# +# Version history: +# 2002 October 7 Created +# +# Updated versions of this file may be found in: +# +# +# For any comments or problems, please use the Unicode +# web contact form at: +# http://www.unicode.org/unicode/reporting.html +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0E01 # THAI CHARACTER KO KAI +0xA2 0x0E02 # THAI CHARACTER KHO KHAI +0xA3 0x0E03 # THAI CHARACTER KHO KHUAT +0xA4 0x0E04 # THAI CHARACTER KHO KHWAI +0xA5 0x0E05 # THAI CHARACTER KHO KHON +0xA6 0x0E06 # THAI CHARACTER KHO RAKHANG +0xA7 0x0E07 # THAI CHARACTER NGO NGU +0xA8 0x0E08 # THAI CHARACTER CHO CHAN +0xA9 0x0E09 # THAI CHARACTER CHO CHING +0xAA 0x0E0A # THAI CHARACTER CHO CHANG +0xAB 0x0E0B # THAI CHARACTER SO SO +0xAC 0x0E0C # THAI CHARACTER CHO CHOE +0xAD 0x0E0D # THAI CHARACTER YO YING +0xAE 0x0E0E # THAI CHARACTER DO CHADA +0xAF 0x0E0F # THAI CHARACTER TO PATAK +0xB0 0x0E10 # THAI CHARACTER THO THAN +0xB1 0x0E11 # THAI CHARACTER THO NANGMONTHO +0xB2 0x0E12 # THAI CHARACTER THO PHUTHAO +0xB3 0x0E13 # THAI CHARACTER NO NEN +0xB4 0x0E14 # THAI CHARACTER DO DEK +0xB5 0x0E15 # THAI CHARACTER TO TAO +0xB6 0x0E16 # THAI CHARACTER THO THUNG +0xB7 0x0E17 # THAI CHARACTER THO THAHAN +0xB8 0x0E18 # THAI CHARACTER THO THONG +0xB9 0x0E19 # THAI CHARACTER NO NU +0xBA 0x0E1A # THAI CHARACTER BO BAIMAI +0xBB 0x0E1B # THAI CHARACTER PO PLA +0xBC 0x0E1C # THAI CHARACTER PHO PHUNG +0xBD 0x0E1D # THAI CHARACTER FO FA +0xBE 0x0E1E # THAI CHARACTER PHO PHAN +0xBF 0x0E1F # THAI CHARACTER FO FAN +0xC0 0x0E20 # THAI CHARACTER PHO SAMPHAO +0xC1 0x0E21 # THAI CHARACTER MO MA +0xC2 0x0E22 # THAI CHARACTER YO YAK +0xC3 0x0E23 # THAI CHARACTER RO RUA +0xC4 0x0E24 # THAI CHARACTER RU +0xC5 0x0E25 # THAI CHARACTER LO LING +0xC6 0x0E26 # THAI CHARACTER LU +0xC7 0x0E27 # THAI CHARACTER WO WAEN +0xC8 0x0E28 # THAI CHARACTER SO SALA +0xC9 0x0E29 # THAI CHARACTER SO RUSI +0xCA 0x0E2A # THAI CHARACTER SO SUA +0xCB 0x0E2B # THAI CHARACTER HO HIP +0xCC 0x0E2C # THAI CHARACTER LO CHULA +0xCD 0x0E2D # THAI CHARACTER O ANG +0xCE 0x0E2E # THAI CHARACTER HO NOKHUK +0xCF 0x0E2F # THAI CHARACTER PAIYANNOI +0xD0 0x0E30 # THAI CHARACTER SARA A +0xD1 0x0E31 # THAI CHARACTER MAI HAN-AKAT +0xD2 0x0E32 # THAI CHARACTER SARA AA +0xD3 0x0E33 # THAI CHARACTER SARA AM +0xD4 0x0E34 # THAI CHARACTER SARA I +0xD5 0x0E35 # THAI CHARACTER SARA II +0xD6 0x0E36 # THAI CHARACTER SARA UE +0xD7 0x0E37 # THAI CHARACTER SARA UEE +0xD8 0x0E38 # THAI CHARACTER SARA U +0xD9 0x0E39 # THAI CHARACTER SARA UU +0xDA 0x0E3A # THAI CHARACTER PHINTHU +0xDF 0x0E3F # THAI CURRENCY SYMBOL BAHT +0xE0 0x0E40 # THAI CHARACTER SARA E +0xE1 0x0E41 # THAI CHARACTER SARA AE +0xE2 0x0E42 # THAI CHARACTER SARA O +0xE3 0x0E43 # THAI CHARACTER SARA AI MAIMUAN +0xE4 0x0E44 # THAI CHARACTER SARA AI MAIMALAI +0xE5 0x0E45 # THAI CHARACTER LAKKHANGYAO +0xE6 0x0E46 # THAI CHARACTER MAIYAMOK +0xE7 0x0E47 # THAI CHARACTER MAITAIKHU +0xE8 0x0E48 # THAI CHARACTER MAI EK +0xE9 0x0E49 # THAI CHARACTER MAI THO +0xEA 0x0E4A # THAI CHARACTER MAI TRI +0xEB 0x0E4B # THAI CHARACTER MAI CHATTAWA +0xEC 0x0E4C # THAI CHARACTER THANTHAKHAT +0xED 0x0E4D # THAI CHARACTER NIKHAHIT +0xEE 0x0E4E # THAI CHARACTER YAMAKKAN +0xEF 0x0E4F # THAI CHARACTER FONGMAN +0xF0 0x0E50 # THAI DIGIT ZERO +0xF1 0x0E51 # THAI DIGIT ONE +0xF2 0x0E52 # THAI DIGIT TWO +0xF3 0x0E53 # THAI DIGIT THREE +0xF4 0x0E54 # THAI DIGIT FOUR +0xF5 0x0E55 # THAI DIGIT FIVE +0xF6 0x0E56 # THAI DIGIT SIX +0xF7 0x0E57 # THAI DIGIT SEVEN +0xF8 0x0E58 # THAI DIGIT EIGHT +0xF9 0x0E59 # THAI DIGIT NINE +0xFA 0x0E5A # THAI CHARACTER ANGKHANKHU +0xFB 0x0E5B # THAI CHARACTER KHOMUT + + diff --git a/Resources/8859-13.txt b/Resources/8859-13.txt new file mode 100644 index 0000000..cd11b53 --- /dev/null +++ b/Resources/8859-13.txt @@ -0,0 +1,299 @@ +# +# Name: ISO/IEC 8859-13:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-13:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-13 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-13 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x201D # RIGHT DOUBLE QUOTATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00C6 # LATIN CAPITAL LETTER AE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x201C # LEFT DOUBLE QUOTATION MARK +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x0157 # LATIN SMALL LETTER R WITH CEDILLA +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00E6 # LATIN SMALL LETTER AE +0xC0 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xC1 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC2 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC3 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xC7 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xCB 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCC 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xCD 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xCE 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xCF 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xD0 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xD9 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xDA 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xDB 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xDE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xE1 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE2 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE3 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xE7 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xEB 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xEC 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xED 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xEE 0x012B # LATIN SMALL LETTER I WITH MACRON +0xEF 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xF0 0x0161 # LATIN SMALL LETTER S WITH CARON +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xF9 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xFA 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xFB 0x016B # LATIN SMALL LETTER U WITH MACRON +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xFE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xFF 0x2019 # RIGHT SINGLE QUOTATION MARK diff --git a/Resources/8859-14.txt b/Resources/8859-14.txt new file mode 100644 index 0000000..36038f4 --- /dev/null +++ b/Resources/8859-14.txt @@ -0,0 +1,301 @@ +# +# Name: ISO/IEC 8859-14:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Markus Kuhn +# Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-14:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-14 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-14 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x1E02 # LATIN CAPITAL LETTER B WITH DOT ABOVE +0xA2 0x1E03 # LATIN SMALL LETTER B WITH DOT ABOVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xA5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xA6 0x1E0A # LATIN CAPITAL LETTER D WITH DOT ABOVE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x1E80 # LATIN CAPITAL LETTER W WITH GRAVE +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x1E82 # LATIN CAPITAL LETTER W WITH ACUTE +0xAB 0x1E0B # LATIN SMALL LETTER D WITH DOT ABOVE +0xAC 0x1EF2 # LATIN CAPITAL LETTER Y WITH GRAVE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xB0 0x1E1E # LATIN CAPITAL LETTER F WITH DOT ABOVE +0xB1 0x1E1F # LATIN SMALL LETTER F WITH DOT ABOVE +0xB2 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xB3 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xB4 0x1E40 # LATIN CAPITAL LETTER M WITH DOT ABOVE +0xB5 0x1E41 # LATIN SMALL LETTER M WITH DOT ABOVE +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x1E56 # LATIN CAPITAL LETTER P WITH DOT ABOVE +0xB8 0x1E81 # LATIN SMALL LETTER W WITH GRAVE +0xB9 0x1E57 # LATIN SMALL LETTER P WITH DOT ABOVE +0xBA 0x1E83 # LATIN SMALL LETTER W WITH ACUTE +0xBB 0x1E60 # LATIN CAPITAL LETTER S WITH DOT ABOVE +0xBC 0x1EF3 # LATIN SMALL LETTER Y WITH GRAVE +0xBD 0x1E84 # LATIN CAPITAL LETTER W WITH DIAERESIS +0xBE 0x1E85 # LATIN SMALL LETTER W WITH DIAERESIS +0xBF 0x1E61 # LATIN SMALL LETTER S WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x0174 # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x1E6A # LATIN CAPITAL LETTER T WITH DOT ABOVE +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0176 # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x0175 # LATIN SMALL LETTER W WITH CIRCUMFLEX +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x1E6B # LATIN SMALL LETTER T WITH DOT ABOVE +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0177 # LATIN SMALL LETTER Y WITH CIRCUMFLEX +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + diff --git a/Resources/8859-15.txt b/Resources/8859-15.txt new file mode 100644 index 0000000..1e31970 --- /dev/null +++ b/Resources/8859-15.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-15:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Markus Kuhn +# Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-15:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-15 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-15 order. +# +# Version history +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x20AC # EURO SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xA7 0x00A7 # SECTION SIGN +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + diff --git a/Resources/8859-16.txt b/Resources/8859-16.txt new file mode 100644 index 0000000..5353d74 --- /dev/null +++ b/Resources/8859-16.txt @@ -0,0 +1,299 @@ +# +# Name: ISO/IEC 8859-16:2001 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 2001 July 26 +# Authors: Markus Kuhn +# +# Copyright (c) 1999-2001 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-16:2001 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-16 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-16 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x20AC # EURO SIGN +0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xA7 0x00A7 # SECTION SIGN +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x0218 # LATIN CAPITAL LETTER S WITH COMMA BELOW +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xB5 0x201D # RIGHT DOUBLE QUOTATION MARK +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON +0xB9 0x010D # LATIN SMALL LETTER C WITH CARON +0xBA 0x0219 # LATIN SMALL LETTER S WITH COMMA BELOW +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xD8 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xDE 0x021A # LATIN CAPITAL LETTER T WITH COMMA BELOW +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xF8 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xFE 0x021B # LATIN SMALL LETTER T WITH COMMA BELOW +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/Resources/8859-2.txt b/Resources/8859-2.txt new file mode 100644 index 0000000..e45df25 --- /dev/null +++ b/Resources/8859-2.txt @@ -0,0 +1,303 @@ +# +# Name: ISO 8859-2:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-2:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-2 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-2 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x02D8 # BREVE +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x013D # LATIN CAPITAL LETTER L WITH CARON +0xA6 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x0164 # LATIN CAPITAL LETTER T WITH CARON +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x013E # LATIN SMALL LETTER L WITH CARON +0xB6 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x0165 # LATIN SMALL LETTER T WITH CARON +0xBC 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xBD 0x02DD # DOUBLE ACUTE ACCENT +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 # LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 # LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A # LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E # LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 # LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0158 # LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E # LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 # LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0155 # LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A # LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B # LATIN SMALL LETTER E WITH CARON +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F # LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 # LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0159 # LATIN SMALL LETTER R WITH CARON +0xF9 0x016F # LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 # LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 # DOT ABOVE diff --git a/Resources/8859-3.txt b/Resources/8859-3.txt new file mode 100644 index 0000000..9b6ac69 --- /dev/null +++ b/Resources/8859-3.txt @@ -0,0 +1,296 @@ +# +# Name: ISO/IEC 8859-3:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-3:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-3 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-3 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0126 # LATIN CAPITAL LETTER H WITH STROKE +0xA2 0x02D8 # BREVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA6 0x0124 # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xAC 0x0134 # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0127 # LATIN SMALL LETTER H WITH STROKE +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x0125 # LATIN SMALL LETTER H WITH CIRCUMFLEX +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x0131 # LATIN SMALL LETTER DOTLESS I +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x011F # LATIN SMALL LETTER G WITH BREVE +0xBC 0x0135 # LATIN SMALL LETTER J WITH CIRCUMFLEX +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xC6 0x0108 # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x011C # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x016C # LATIN CAPITAL LETTER U WITH BREVE +0xDE 0x015C # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xE6 0x0109 # LATIN SMALL LETTER C WITH CIRCUMFLEX +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x011D # LATIN SMALL LETTER G WITH CIRCUMFLEX +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x016D # LATIN SMALL LETTER U WITH BREVE +0xFE 0x015D # LATIN SMALL LETTER S WITH CIRCUMFLEX +0xFF 0x02D9 # DOT ABOVE diff --git a/Resources/8859-4.txt b/Resources/8859-4.txt new file mode 100644 index 0000000..662e698 --- /dev/null +++ b/Resources/8859-4.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-4:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-4:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-4 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-4 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0138 # LATIN SMALL LETTER KRA +0xA3 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x0128 # LATIN CAPITAL LETTER I WITH TILDE +0xA6 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xAB 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xAC 0x0166 # LATIN CAPITAL LETTER T WITH STROKE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0157 # LATIN SMALL LETTER R WITH CEDILLA +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x0129 # LATIN SMALL LETTER I WITH TILDE +0xB6 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xBB 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xBC 0x0167 # LATIN SMALL LETTER T WITH STROKE +0xBD 0x014A # LATIN CAPITAL LETTER ENG +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x014B # LATIN SMALL LETTER ENG +0xC0 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD2 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD3 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0168 # LATIN CAPITAL LETTER U WITH TILDE +0xDE 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x012B # LATIN SMALL LETTER I WITH MACRON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF2 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF3 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0169 # LATIN SMALL LETTER U WITH TILDE +0xFE 0x016B # LATIN SMALL LETTER U WITH MACRON +0xFF 0x02D9 # DOT ABOVE diff --git a/Resources/8859-5.txt b/Resources/8859-5.txt new file mode 100644 index 0000000..a7ed1ce --- /dev/null +++ b/Resources/8859-5.txt @@ -0,0 +1,303 @@ +# +# Name: ISO 8859-5:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-5:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-5 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-5 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0401 # CYRILLIC CAPITAL LETTER IO +0xA2 0x0402 # CYRILLIC CAPITAL LETTER DJE +0xA3 0x0403 # CYRILLIC CAPITAL LETTER GJE +0xA4 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xA5 0x0405 # CYRILLIC CAPITAL LETTER DZE +0xA6 0x0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xA7 0x0407 # CYRILLIC CAPITAL LETTER YI +0xA8 0x0408 # CYRILLIC CAPITAL LETTER JE +0xA9 0x0409 # CYRILLIC CAPITAL LETTER LJE +0xAA 0x040A # CYRILLIC CAPITAL LETTER NJE +0xAB 0x040B # CYRILLIC CAPITAL LETTER TSHE +0xAC 0x040C # CYRILLIC CAPITAL LETTER KJE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x040E # CYRILLIC CAPITAL LETTER SHORT U +0xAF 0x040F # CYRILLIC CAPITAL LETTER DZHE +0xB0 0x0410 # CYRILLIC CAPITAL LETTER A +0xB1 0x0411 # CYRILLIC CAPITAL LETTER BE +0xB2 0x0412 # CYRILLIC CAPITAL LETTER VE +0xB3 0x0413 # CYRILLIC CAPITAL LETTER GHE +0xB4 0x0414 # CYRILLIC CAPITAL LETTER DE +0xB5 0x0415 # CYRILLIC CAPITAL LETTER IE +0xB6 0x0416 # CYRILLIC CAPITAL LETTER ZHE +0xB7 0x0417 # CYRILLIC CAPITAL LETTER ZE +0xB8 0x0418 # CYRILLIC CAPITAL LETTER I +0xB9 0x0419 # CYRILLIC CAPITAL LETTER SHORT I +0xBA 0x041A # CYRILLIC CAPITAL LETTER KA +0xBB 0x041B # CYRILLIC CAPITAL LETTER EL +0xBC 0x041C # CYRILLIC CAPITAL LETTER EM +0xBD 0x041D # CYRILLIC CAPITAL LETTER EN +0xBE 0x041E # CYRILLIC CAPITAL LETTER O +0xBF 0x041F # CYRILLIC CAPITAL LETTER PE +0xC0 0x0420 # CYRILLIC CAPITAL LETTER ER +0xC1 0x0421 # CYRILLIC CAPITAL LETTER ES +0xC2 0x0422 # CYRILLIC CAPITAL LETTER TE +0xC3 0x0423 # CYRILLIC CAPITAL LETTER U +0xC4 0x0424 # CYRILLIC CAPITAL LETTER EF +0xC5 0x0425 # CYRILLIC CAPITAL LETTER HA +0xC6 0x0426 # CYRILLIC CAPITAL LETTER TSE +0xC7 0x0427 # CYRILLIC CAPITAL LETTER CHE +0xC8 0x0428 # CYRILLIC CAPITAL LETTER SHA +0xC9 0x0429 # CYRILLIC CAPITAL LETTER SHCHA +0xCA 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN +0xCB 0x042B # CYRILLIC CAPITAL LETTER YERU +0xCC 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN +0xCD 0x042D # CYRILLIC CAPITAL LETTER E +0xCE 0x042E # CYRILLIC CAPITAL LETTER YU +0xCF 0x042F # CYRILLIC CAPITAL LETTER YA +0xD0 0x0430 # CYRILLIC SMALL LETTER A +0xD1 0x0431 # CYRILLIC SMALL LETTER BE +0xD2 0x0432 # CYRILLIC SMALL LETTER VE +0xD3 0x0433 # CYRILLIC SMALL LETTER GHE +0xD4 0x0434 # CYRILLIC SMALL LETTER DE +0xD5 0x0435 # CYRILLIC SMALL LETTER IE +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE +0xD7 0x0437 # CYRILLIC SMALL LETTER ZE +0xD8 0x0438 # CYRILLIC SMALL LETTER I +0xD9 0x0439 # CYRILLIC SMALL LETTER SHORT I +0xDA 0x043A # CYRILLIC SMALL LETTER KA +0xDB 0x043B # CYRILLIC SMALL LETTER EL +0xDC 0x043C # CYRILLIC SMALL LETTER EM +0xDD 0x043D # CYRILLIC SMALL LETTER EN +0xDE 0x043E # CYRILLIC SMALL LETTER O +0xDF 0x043F # CYRILLIC SMALL LETTER PE +0xE0 0x0440 # CYRILLIC SMALL LETTER ER +0xE1 0x0441 # CYRILLIC SMALL LETTER ES +0xE2 0x0442 # CYRILLIC SMALL LETTER TE +0xE3 0x0443 # CYRILLIC SMALL LETTER U +0xE4 0x0444 # CYRILLIC SMALL LETTER EF +0xE5 0x0445 # CYRILLIC SMALL LETTER HA +0xE6 0x0446 # CYRILLIC SMALL LETTER TSE +0xE7 0x0447 # CYRILLIC SMALL LETTER CHE +0xE8 0x0448 # CYRILLIC SMALL LETTER SHA +0xE9 0x0449 # CYRILLIC SMALL LETTER SHCHA +0xEA 0x044A # CYRILLIC SMALL LETTER HARD SIGN +0xEB 0x044B # CYRILLIC SMALL LETTER YERU +0xEC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN +0xED 0x044D # CYRILLIC SMALL LETTER E +0xEE 0x044E # CYRILLIC SMALL LETTER YU +0xEF 0x044F # CYRILLIC SMALL LETTER YA +0xF0 0x2116 # NUMERO SIGN +0xF1 0x0451 # CYRILLIC SMALL LETTER IO +0xF2 0x0452 # CYRILLIC SMALL LETTER DJE +0xF3 0x0453 # CYRILLIC SMALL LETTER GJE +0xF4 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE +0xF5 0x0455 # CYRILLIC SMALL LETTER DZE +0xF6 0x0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0xF7 0x0457 # CYRILLIC SMALL LETTER YI +0xF8 0x0458 # CYRILLIC SMALL LETTER JE +0xF9 0x0459 # CYRILLIC SMALL LETTER LJE +0xFA 0x045A # CYRILLIC SMALL LETTER NJE +0xFB 0x045B # CYRILLIC SMALL LETTER TSHE +0xFC 0x045C # CYRILLIC SMALL LETTER KJE +0xFD 0x00A7 # SECTION SIGN +0xFE 0x045E # CYRILLIC SMALL LETTER SHORT U +0xFF 0x045F # CYRILLIC SMALL LETTER DZHE diff --git a/Resources/8859-6.txt b/Resources/8859-6.txt new file mode 100644 index 0000000..69ac7f5 --- /dev/null +++ b/Resources/8859-6.txt @@ -0,0 +1,260 @@ +# +# Name: ISO 8859-6:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-6:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-6 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-6 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# 0x30..0x39 remapped to the ASCII digits (U+0030..U+0039) instead +# of the Arabic digits (U+0660..U+0669). +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA4 0x00A4 # CURRENCY SIGN +0xAC 0x060C # ARABIC COMMA +0xAD 0x00AD # SOFT HYPHEN +0xBB 0x061B # ARABIC SEMICOLON +0xBF 0x061F # ARABIC QUESTION MARK +0xC1 0x0621 # ARABIC LETTER HAMZA +0xC2 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE +0xC3 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE +0xC4 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE +0xC5 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW +0xC6 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE +0xC7 0x0627 # ARABIC LETTER ALEF +0xC8 0x0628 # ARABIC LETTER BEH +0xC9 0x0629 # ARABIC LETTER TEH MARBUTA +0xCA 0x062A # ARABIC LETTER TEH +0xCB 0x062B # ARABIC LETTER THEH +0xCC 0x062C # ARABIC LETTER JEEM +0xCD 0x062D # ARABIC LETTER HAH +0xCE 0x062E # ARABIC LETTER KHAH +0xCF 0x062F # ARABIC LETTER DAL +0xD0 0x0630 # ARABIC LETTER THAL +0xD1 0x0631 # ARABIC LETTER REH +0xD2 0x0632 # ARABIC LETTER ZAIN +0xD3 0x0633 # ARABIC LETTER SEEN +0xD4 0x0634 # ARABIC LETTER SHEEN +0xD5 0x0635 # ARABIC LETTER SAD +0xD6 0x0636 # ARABIC LETTER DAD +0xD7 0x0637 # ARABIC LETTER TAH +0xD8 0x0638 # ARABIC LETTER ZAH +0xD9 0x0639 # ARABIC LETTER AIN +0xDA 0x063A # ARABIC LETTER GHAIN +0xE0 0x0640 # ARABIC TATWEEL +0xE1 0x0641 # ARABIC LETTER FEH +0xE2 0x0642 # ARABIC LETTER QAF +0xE3 0x0643 # ARABIC LETTER KAF +0xE4 0x0644 # ARABIC LETTER LAM +0xE5 0x0645 # ARABIC LETTER MEEM +0xE6 0x0646 # ARABIC LETTER NOON +0xE7 0x0647 # ARABIC LETTER HEH +0xE8 0x0648 # ARABIC LETTER WAW +0xE9 0x0649 # ARABIC LETTER ALEF MAKSURA +0xEA 0x064A # ARABIC LETTER YEH +0xEB 0x064B # ARABIC FATHATAN +0xEC 0x064C # ARABIC DAMMATAN +0xED 0x064D # ARABIC KASRATAN +0xEE 0x064E # ARABIC FATHA +0xEF 0x064F # ARABIC DAMMA +0xF0 0x0650 # ARABIC KASRA +0xF1 0x0651 # ARABIC SHADDA +0xF2 0x0652 # ARABIC SUKUN diff --git a/Resources/8859-7.txt b/Resources/8859-7.txt new file mode 100644 index 0000000..52c42d0 --- /dev/null +++ b/Resources/8859-7.txt @@ -0,0 +1,302 @@ +# +# Name: ISO 8859-7:1987 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO 8859-7:1987 characters map into Unicode. +# +# ISO 8859-7:1987 is equivalent to ISO-IR-126, ELOT 928, +# and ECMA 118. +# +# Format: Three tab-separated columns +# Column #1 is the ISO 8859-7 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO 8859-7 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# Remap 0xA1 to U+2018 (instead of 0x02BD) to match text of 8859-7 +# Remap 0xA2 to U+2019 (instead of 0x02BC) to match text of 8859-7 +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x2018 # LEFT SINGLE QUOTATION MARK +0xA2 0x2019 # RIGHT SINGLE QUOTATION MARK +0xA3 0x00A3 # POUND SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x2015 # HORIZONTAL BAR +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x0384 # GREEK TONOS +0xB5 0x0385 # GREEK DIALYTIKA TONOS +0xB6 0x0386 # GREEK CAPITAL LETTER ALPHA WITH TONOS +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x0388 # GREEK CAPITAL LETTER EPSILON WITH TONOS +0xB9 0x0389 # GREEK CAPITAL LETTER ETA WITH TONOS +0xBA 0x038A # GREEK CAPITAL LETTER IOTA WITH TONOS +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x038C # GREEK CAPITAL LETTER OMICRON WITH TONOS +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x038E # GREEK CAPITAL LETTER UPSILON WITH TONOS +0xBF 0x038F # GREEK CAPITAL LETTER OMEGA WITH TONOS +0xC0 0x0390 # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0xC1 0x0391 # GREEK CAPITAL LETTER ALPHA +0xC2 0x0392 # GREEK CAPITAL LETTER BETA +0xC3 0x0393 # GREEK CAPITAL LETTER GAMMA +0xC4 0x0394 # GREEK CAPITAL LETTER DELTA +0xC5 0x0395 # GREEK CAPITAL LETTER EPSILON +0xC6 0x0396 # GREEK CAPITAL LETTER ZETA +0xC7 0x0397 # GREEK CAPITAL LETTER ETA +0xC8 0x0398 # GREEK CAPITAL LETTER THETA +0xC9 0x0399 # GREEK CAPITAL LETTER IOTA +0xCA 0x039A # GREEK CAPITAL LETTER KAPPA +0xCB 0x039B # GREEK CAPITAL LETTER LAMDA +0xCC 0x039C # GREEK CAPITAL LETTER MU +0xCD 0x039D # GREEK CAPITAL LETTER NU +0xCE 0x039E # GREEK CAPITAL LETTER XI +0xCF 0x039F # GREEK CAPITAL LETTER OMICRON +0xD0 0x03A0 # GREEK CAPITAL LETTER PI +0xD1 0x03A1 # GREEK CAPITAL LETTER RHO +0xD3 0x03A3 # GREEK CAPITAL LETTER SIGMA +0xD4 0x03A4 # GREEK CAPITAL LETTER TAU +0xD5 0x03A5 # GREEK CAPITAL LETTER UPSILON +0xD6 0x03A6 # GREEK CAPITAL LETTER PHI +0xD7 0x03A7 # GREEK CAPITAL LETTER CHI +0xD8 0x03A8 # GREEK CAPITAL LETTER PSI +0xD9 0x03A9 # GREEK CAPITAL LETTER OMEGA +0xDA 0x03AA # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +0xDB 0x03AB # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +0xDC 0x03AC # GREEK SMALL LETTER ALPHA WITH TONOS +0xDD 0x03AD # GREEK SMALL LETTER EPSILON WITH TONOS +0xDE 0x03AE # GREEK SMALL LETTER ETA WITH TONOS +0xDF 0x03AF # GREEK SMALL LETTER IOTA WITH TONOS +0xE0 0x03B0 # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +0xE1 0x03B1 # GREEK SMALL LETTER ALPHA +0xE2 0x03B2 # GREEK SMALL LETTER BETA +0xE3 0x03B3 # GREEK SMALL LETTER GAMMA +0xE4 0x03B4 # GREEK SMALL LETTER DELTA +0xE5 0x03B5 # GREEK SMALL LETTER EPSILON +0xE6 0x03B6 # GREEK SMALL LETTER ZETA +0xE7 0x03B7 # GREEK SMALL LETTER ETA +0xE8 0x03B8 # GREEK SMALL LETTER THETA +0xE9 0x03B9 # GREEK SMALL LETTER IOTA +0xEA 0x03BA # GREEK SMALL LETTER KAPPA +0xEB 0x03BB # GREEK SMALL LETTER LAMDA +0xEC 0x03BC # GREEK SMALL LETTER MU +0xED 0x03BD # GREEK SMALL LETTER NU +0xEE 0x03BE # GREEK SMALL LETTER XI +0xEF 0x03BF # GREEK SMALL LETTER OMICRON +0xF0 0x03C0 # GREEK SMALL LETTER PI +0xF1 0x03C1 # GREEK SMALL LETTER RHO +0xF2 0x03C2 # GREEK SMALL LETTER FINAL SIGMA +0xF3 0x03C3 # GREEK SMALL LETTER SIGMA +0xF4 0x03C4 # GREEK SMALL LETTER TAU +0xF5 0x03C5 # GREEK SMALL LETTER UPSILON +0xF6 0x03C6 # GREEK SMALL LETTER PHI +0xF7 0x03C7 # GREEK SMALL LETTER CHI +0xF8 0x03C8 # GREEK SMALL LETTER PSI +0xF9 0x03C9 # GREEK SMALL LETTER OMEGA +0xFA 0x03CA # GREEK SMALL LETTER IOTA WITH DIALYTIKA +0xFB 0x03CB # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0xFC 0x03CC # GREEK SMALL LETTER OMICRON WITH TONOS +0xFD 0x03CD # GREEK SMALL LETTER UPSILON WITH TONOS +0xFE 0x03CE # GREEK SMALL LETTER OMEGA WITH TONOS diff --git a/Resources/8859-8.txt b/Resources/8859-8.txt new file mode 100644 index 0000000..bc8da4c --- /dev/null +++ b/Resources/8859-8.txt @@ -0,0 +1,270 @@ +# +# Name: ISO/IEC 8859-8:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.1 +# Table format: Format A +# Date: 2000-Jan-03 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-8:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-8 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-8 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# 1.1 version updates to the published 8859-8:1999, correcting +# the mapping of 0xAF and adding mappings for LRM and RLM. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00D7 # MULTIPLICATION SIGN +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00F7 # DIVISION SIGN +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xDF 0x2017 # DOUBLE LOW LINE +0xE0 0x05D0 # HEBREW LETTER ALEF +0xE1 0x05D1 # HEBREW LETTER BET +0xE2 0x05D2 # HEBREW LETTER GIMEL +0xE3 0x05D3 # HEBREW LETTER DALET +0xE4 0x05D4 # HEBREW LETTER HE +0xE5 0x05D5 # HEBREW LETTER VAV +0xE6 0x05D6 # HEBREW LETTER ZAYIN +0xE7 0x05D7 # HEBREW LETTER HET +0xE8 0x05D8 # HEBREW LETTER TET +0xE9 0x05D9 # HEBREW LETTER YOD +0xEA 0x05DA # HEBREW LETTER FINAL KAF +0xEB 0x05DB # HEBREW LETTER KAF +0xEC 0x05DC # HEBREW LETTER LAMED +0xED 0x05DD # HEBREW LETTER FINAL MEM +0xEE 0x05DE # HEBREW LETTER MEM +0xEF 0x05DF # HEBREW LETTER FINAL NUN +0xF0 0x05E0 # HEBREW LETTER NUN +0xF1 0x05E1 # HEBREW LETTER SAMEKH +0xF2 0x05E2 # HEBREW LETTER AYIN +0xF3 0x05E3 # HEBREW LETTER FINAL PE +0xF4 0x05E4 # HEBREW LETTER PE +0xF5 0x05E5 # HEBREW LETTER FINAL TSADI +0xF6 0x05E6 # HEBREW LETTER TSADI +0xF7 0x05E7 # HEBREW LETTER QOF +0xF8 0x05E8 # HEBREW LETTER RESH +0xF9 0x05E9 # HEBREW LETTER SHIN +0xFA 0x05EA # HEBREW LETTER TAV +0xFD 0x200E # LEFT-TO-RIGHT MARK +0xFE 0x200F # RIGHT-TO-LEFT MARK + diff --git a/Resources/8859-9.txt b/Resources/8859-9.txt new file mode 100644 index 0000000..22901f1 --- /dev/null +++ b/Resources/8859-9.txt @@ -0,0 +1,307 @@ +# +# Name: ISO/IEC 8859-9:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on magnetic media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-9:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-9 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-9 order. +# +# ISO/IEC 8859-9 is also equivalent to ISO-IR-148. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xDE 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x011F # LATIN SMALL LETTER G WITH BREVE +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0131 # LATIN SMALL LETTER DOTLESS I +0xFE 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + + diff --git a/Resources/Default b/Resources/Default new file mode 100644 index 0000000..c16f39a --- /dev/null +++ b/Resources/Default @@ -0,0 +1,81 @@ +# Default fontnames translation table +# uses only fonts present in the RISC OS 3 ROMs +# +# MS-Word fontname, Italic, Bold, Acorn fontname, Special +Arial, 0, 0, Homerton.Medium, 0 +Arial, 0, 1, Homerton.Bold, 0 +Arial, 1, 0, Homerton.Medium.Oblique,0 +Arial, 1, 1, Homerton.Bold.Oblique, 0 +Arial Black, 0, 0, Homerton.Medium, 0 +Arial Black, 0, 1, Homerton.Bold, 0 +Arial Black, 1, 0, Homerton.Medium.Oblique,0 +Arial Black, 1, 1, Homerton.Bold.Oblique, 0 +Arial CE, 0, 0, Homerton.Medium, 0 +Arial CE, 0, 1, Homerton.Bold, 0 +Arial CE, 1, 0, Homerton.Medium.Oblique,0 +Arial CE, 1, 1, Homerton.Bold.Oblique, 0 +Arial Narrow, 0, 0, Homerton.Medium, 0 +Arial Narrow, 0, 1, Homerton.Bold, 0 +Arial Narrow, 1, 0, Homerton.Medium.Oblique,0 +Arial Narrow, 1, 1, Homerton.Bold.Oblique, 0 +Comic Sans MS, 0, 0, Homerton.Medium, 0 +Comic Sans MS, 0, 1, Homerton.Bold, 0 +Comic Sans MS, 1, 0, Homerton.Medium.Oblique,0 +Comic Sans MS, 1, 1, Homerton.Bold.Oblique, 0 +Courier, 0, 0, Corpus.Medium, 0 +Courier, 0, 1, Corpus.Bold, 0 +Courier, 1, 0, Corpus.Medium.Oblique, 0 +Courier, 1, 1, Corpus.Bold.Oblique, 0 +Courier New, 0, 0, Corpus.Medium, 0 +Courier New, 0, 1, Corpus.Bold, 0 +Courier New, 1, 0, Corpus.Medium.Oblique, 0 +Courier New, 1, 1, Corpus.Bold.Oblique, 0 +Fixedsys, 0, 0, Corpus.Medium, 0 +Fixedsys, 0, 1, Corpus.Bold, 0 +Fixedsys, 1, 0, Corpus.Medium.Oblique, 0 +Fixedsys, 1, 1, Corpus.Bold.Oblique, 0 +Helvetica, 0, 0, Homerton.Medium, 0 +Helvetica, 0, 1, Homerton.Bold, 0 +Helvetica, 1, 0, Homerton.Medium.Oblique,0 +Helvetica, 1, 1, Homerton.Bold.Oblique, 0 +Helvetica-Narrow, 0, 0, Homerton.Medium, 0 +Helvetica-Narrow, 0, 1, Homerton.Bold, 0 +Helvetica-Narrow, 1, 0, Homerton.Medium.Oblique,0 +Helvetica-Narrow, 1, 1, Homerton.Bold.Oblique, 0 +Lucida Console, 0, 0, Corpus.Medium, 0 +Lucida Console, 0, 1, Corpus.Bold, 0 +Lucida Console, 1, 0, Corpus.Medium.Oblique, 0 +Lucida Console, 1, 1, Corpus.Bold.Oblique, 0 +Monotype.com, 0, 0, Corpus.Medium, 0 +Monotype.com, 0, 1, Corpus.Bold, 0 +Monotype.com, 1, 0, Corpus.Medium.Oblique, 0 +Monotype.com, 1, 1, Corpus.Bold.Oblique, 0 +MS Sans Serif, 0, 0, Homerton.Medium, 0 +MS Sans Serif, 0, 1, Homerton.Bold, 0 +MS Sans Serif, 1, 0, Homerton.Medium.Oblique,0 +MS Sans Serif, 1, 1, Homerton.Bold.Oblique, 0 +Swiss, 0, 0, Homerton.Medium, 0 +Swiss, 0, 1, Homerton.Bold, 0 +Swiss, 1, 0, Homerton.Medium.Oblique,0 +Swiss, 1, 1, Homerton.Bold.Oblique, 0 +Tahoma, 0, 0, Homerton.Medium, 0 +Tahoma, 0, 1, Homerton.Bold, 0 +Tahoma, 1, 0, Homerton.Medium.Oblique,0 +Tahoma, 1, 1, Homerton.Bold.Oblique, 0 +Trebuchet MS, 0, 0, Homerton.Medium, 0 +Trebuchet MS, 0, 1, Homerton.Bold, 0 +Trebuchet MS, 1, 0, Homerton.Medium.Oblique,0 +Trebuchet MS, 1, 1, Homerton.Bold.Oblique, 0 +Verdana, 0, 0, Homerton.Medium, 0 +Verdana, 0, 1, Homerton.Bold, 0 +Verdana, 1, 0, Homerton.Medium.Oblique,0 +Verdana, 1, 1, Homerton.Bold.Oblique, 0 +Univers, 0, 0, Homerton.Medium, 0 +Univers, 0, 1, Homerton.Bold, 0 +Univers, 1, 0, Homerton.Medium.Oblique,0 +Univers, 1, 1, Homerton.Bold.Oblique, 0 +# All the other fonts +*, 0, 0, Trinity.Medium, 0 +*, 0, 1, Trinity.Bold, 0 +*, 1, 0, Trinity.Medium.Italic, 0 +*, 1, 1, Trinity.Bold.Italic, 0 diff --git a/Resources/Example b/Resources/Example new file mode 100644 index 0000000..43d2ee2 --- /dev/null +++ b/Resources/Example @@ -0,0 +1,80 @@ +# An example of a fontnames translation table +# +# MS-Word fontname, Italic, Bold, Acorn fontname, Special +Arial, 0, 0, Homerton.Medium, 0 +Arial, 0, 1, Homerton.Bold, 0 +Arial, 1, 0, Homerton.Medium.Oblique,0 +Arial, 1, 1, Homerton.Bold.Oblique, 0 +Arial Black, 0, 0, Homerton.Medium, 0 +Arial Black, 0, 1, Homerton.Bold, 0 +Arial Black, 1, 0, Homerton.Medium.Oblique,0 +Arial Black, 1, 1, Homerton.Bold.Oblique, 0 +AvantGarde, 0, 0, Clare.Medium, 0 +AvantGarde, 0, 1, Clare.Demi, 0 +AvantGarde, 1, 0, Clare.Medium.Oblique, 0 +AvantGarde, 1, 1, Clare.Demi.Oblique, 0 +Bookman, 0, 0, Robinson.Light, 0 +Bookman, 0, 1, Robinson.Demi, 0 +Bookman, 1, 0, Robinson.Light.Italic, 0 +Bookman, 1, 1, Robinson.Demi.Italic, 0 +Bookman Old Style, 0, 0, Robinson.Light, 0 +Bookman Old Style, 0, 1, Robinson.Demi, 0 +Bookman Old Style, 1, 0, Robinson.Light.Italic, 0 +Bookman Old Style, 1, 1, Robinson.Demi.Italic, 0 +Courier, 0, 0, Corpus.Medium, 0 +Courier, 0, 1, Corpus.Bold, 0 +Courier, 1, 0, Corpus.Medium.Oblique, 0 +Courier, 1, 1, Corpus.Bold.Oblique, 0 +Courier New, 0, 0, Corpus.Medium, 0 +Courier New, 0, 1, Corpus.Bold, 0 +Courier New, 1, 0, Corpus.Medium.Oblique, 0 +Courier New, 1, 1, Corpus.Bold.Oblique, 0 +Fixedsys, 0, 0, Corpus.Medium, 0 +Fixedsys, 0, 1, Corpus.Bold, 0 +Fixedsys, 1, 0, Corpus.Medium.Oblique, 0 +Fixedsys, 1, 1, Corpus.Bold.Oblique, 0 +Helvetica, 0, 0, Homerton.Medium, 0 +Helvetica, 0, 1, Homerton.Bold, 0 +Helvetica, 1, 0, Homerton.Medium.Oblique,0 +Helvetica, 1, 1, Homerton.Bold.Oblique, 0 +Lucida Console, 0, 0, Corpus.Medium, 0 +Lucida Console, 0, 1, Corpus.Bold, 0 +Lucida Console, 1, 0, Corpus.Medium.Oblique, 0 +Lucida Console, 1, 1, Corpus.Bold.Oblique, 0 +Palatino, 0, 0, Pembroke.Medium, 0 +Palatino, 0, 1, Pembroke.Bold, 0 +Palatino, 1, 0, Pembroke.Medium.Italic, 0 +Palatino, 1, 1, Pembroke.Bold.Italic, 0 +Swiss, 0, 0, Homerton.Medium, 0 +Swiss, 0, 1, Homerton.Bold, 0 +Swiss, 1, 0, Homerton.Medium.Oblique,0 +Swiss, 1, 1, Homerton.Bold.Oblique, 0 +Symbol, 0, 0, Sidney, 1 +Symbol, 0, 1, Sidney, 1 +Symbol, 1, 0, Sidney, 1 +Symbol, 1, 1, Sidney, 1 +Times, 0, 0, Trinity.Medium, 0 +Times, 0, 1, Trinity.Bold, 0 +Times, 1, 0, Trinity.Medium.Italic, 0 +Times, 1, 1, Trinity.Bold.Italic, 0 +Times New Roman, 0, 0, Trinity.Medium, 0 +Times New Roman, 0, 1, Trinity.Bold, 0 +Times New Roman, 1, 0, Trinity.Medium.Italic, 0 +Times New Roman, 1, 1, Trinity.Bold.Italic, 0 +Times Roman, 0, 0, Trinity.Medium, 0 +Times Roman, 0, 1, Trinity.Bold, 0 +Times Roman, 1, 0, Trinity.Medium.Italic, 0 +Times Roman, 1, 1, Trinity.Bold.Italic, 0 +Univers, 0, 0, Homerton.Medium, 0 +Univers, 0, 1, Homerton.Bold, 0 +Univers, 1, 0, Homerton.Medium.Oblique,0 +Univers, 1, 1, Homerton.Bold.Oblique, 0 +ZapfDingbats, 0, 0, Selwyn, 2 +ZapfDingbats, 0, 1, Selwyn, 2 +ZapfDingbats, 1, 0, Selwyn, 2 +ZapfDingbats, 1, 1, Selwyn, 2 +# All the other fonts +*, 0, 0, Trinity.Medium, 0 +*, 0, 1, Trinity.Bold, 0 +*, 1, 0, Trinity.Medium.Italic, 0 +*, 1, 1, Trinity.Bold.Italic, 0 diff --git a/Resources/MacCyrillic.txt b/Resources/MacCyrillic.txt new file mode 100644 index 0000000..3e1dd1e --- /dev/null +++ b/Resources/MacCyrillic.txt @@ -0,0 +1,344 @@ +#======================================================================= +# File name: CYRILLIC.TXT +# +# Contents: Map (external version) from Mac OS Cyrillic +# character set to Unicode 2.1 through Unicode 3.2 +# +# Copyright: (c) 1995-2002 by Apple Computer, Inc., all rights +# reserved. +# +# Contact: charsets@apple.com +# +# Changes: +# +# b3,c1 2002-Dec-19 Update URLs, notes. Matches internal +# utom. +# b02 1999-Sep-22 Encoding changed for Mac OS 9.0 to merge +# with Mac OS Ukrainian and support EURO SIGN; +# Change mappings for 0xA2, 0xB6, and 0xFF. +# Update contact e-mail address. Matches +# internal utom, ufrm, and Text +# Encoding Converter version 1.5. +# n05 1998-Feb-05 Update header comments to new format; no +# mapping changes. Matches internal utom, +# ufrm, and Text Encoding Converter +# version 1.3. +# n03 1995-Apr-15 First version (after fixing some typos). +# Matches internal ufrm. +# +# Standard header: +# ---------------- +# +# Apple, the Apple logo, and Macintosh are trademarks of Apple +# Computer, Inc., registered in the United States and other countries. +# Unicode is a trademark of Unicode Inc. For the sake of brevity, +# throughout this document, "Macintosh" can be used to refer to +# Macintosh computers and "Unicode" can be used to refer to the +# Unicode standard. +# +# Apple makes no warranty or representation, either express or +# implied, with respect to these tables, their quality, accuracy, or +# fitness for a particular purpose. In no event will Apple be liable +# for direct, indirect, special, incidental, or consequential damages +# resulting from any defect or inaccuracy in this document or the +# accompanying tables. +# +# These mapping tables and character lists are subject to change. +# The latest tables should be available from the following: +# +# +# +# For general information about Mac OS encodings and these mapping +# tables, see the file "README.TXT". +# +# Format: +# ------- +# +# Three tab-separated columns; +# '#' begins a comment which continues to the end of the line. +# Column #1 is the Mac OS Cyrillic code (in hex as 0xNN) +# Column #2 is the corresponding Unicode (in hex as 0xNNNN) +# Column #3 is a comment containing the Unicode name +# +# The entries are in Mac OS Cyrillic code order. +# +# Control character mappings are not shown in this table, following +# the conventions of the standard UTC mapping tables. However, the +# Mac OS Cyrillic character set uses the standard control characters +# at 0x00-0x1F and 0x7F. +# +# Notes on Mac OS Cyrillic: +# ------------------------- +# +# This is the "Euro sign" version of Mac Cyrillic for Mac OS 9.0 and +# later. Before Mac OS 9.0, there were two separate Slavic Cyrillic +# encodings: +# +# 1. The Cyrillic currency sign variant (used for localized Russian +# and Bulgarian systems), which had the following: +# 0xA2 U+00A2 CENT SIGN +# 0xB6 U+2202 PARTIAL DIFFERENTIAL +# 0xFF U+00A4 CURRENCY SIGN +# +# 2. The Ukrainian currency sign variant (used for localized Ukrainian +# systems and the pre-9.0 Cyrillic Language Kit), which had the +# following: +# 0xA2 U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN +# 0xB6 U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN +# 0xFF U+00A4 CURRENCY SIGN +# +# This new Cyrillic Euro sign version is based on the old Ukrainian +# currency sign variant, with 0xFF changed to be EURO SIGN. +# +# The Mac OS Cyrillic encoding includes the Cyrillic letter repertoire +# of ISO 8859-5 (although not at the same code points). This covers +# most of the Slavic languages written in Cyrillic script. +# +# The Mac OS Cyrillic encoding also includes a number of characters +# needed for the Mac OS user interface and localization (e.g. +# ellipsis, bullet, copyright sign). All of the characters in Mac OS +# Cyrillic that are also in the Mac OS Roman encoding are at the +# same code point in both; this improves application compatibility. +# +# Note: There is a common Ukrainian glyph variation in which the glyph +# for CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I may or may not +# have a dot above. +# +# Unicode mapping issues and notes: +# --------------------------------- +# +# Details of mapping changes in each version: +# ------------------------------------------- +# +# Changes from version n05 to version b02: +# +# - Encoding changed for Mac OS 9.0 to merge with Mac OS Ukrainian and +# support EURO SIGN. 0xA2 changed from U+00A2 to U+0490; 0xB6 changed +# from U+2202 to U+0491; 0xFF changed from U+00A4 to U+20AC. +# +################## + +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +# +0x80 0x0410 # CYRILLIC CAPITAL LETTER A +0x81 0x0411 # CYRILLIC CAPITAL LETTER BE +0x82 0x0412 # CYRILLIC CAPITAL LETTER VE +0x83 0x0413 # CYRILLIC CAPITAL LETTER GHE +0x84 0x0414 # CYRILLIC CAPITAL LETTER DE +0x85 0x0415 # CYRILLIC CAPITAL LETTER IE +0x86 0x0416 # CYRILLIC CAPITAL LETTER ZHE +0x87 0x0417 # CYRILLIC CAPITAL LETTER ZE +0x88 0x0418 # CYRILLIC CAPITAL LETTER I +0x89 0x0419 # CYRILLIC CAPITAL LETTER SHORT I +0x8A 0x041A # CYRILLIC CAPITAL LETTER KA +0x8B 0x041B # CYRILLIC CAPITAL LETTER EL +0x8C 0x041C # CYRILLIC CAPITAL LETTER EM +0x8D 0x041D # CYRILLIC CAPITAL LETTER EN +0x8E 0x041E # CYRILLIC CAPITAL LETTER O +0x8F 0x041F # CYRILLIC CAPITAL LETTER PE +0x90 0x0420 # CYRILLIC CAPITAL LETTER ER +0x91 0x0421 # CYRILLIC CAPITAL LETTER ES +0x92 0x0422 # CYRILLIC CAPITAL LETTER TE +0x93 0x0423 # CYRILLIC CAPITAL LETTER U +0x94 0x0424 # CYRILLIC CAPITAL LETTER EF +0x95 0x0425 # CYRILLIC CAPITAL LETTER HA +0x96 0x0426 # CYRILLIC CAPITAL LETTER TSE +0x97 0x0427 # CYRILLIC CAPITAL LETTER CHE +0x98 0x0428 # CYRILLIC CAPITAL LETTER SHA +0x99 0x0429 # CYRILLIC CAPITAL LETTER SHCHA +0x9A 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN +0x9B 0x042B # CYRILLIC CAPITAL LETTER YERU +0x9C 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN +0x9D 0x042D # CYRILLIC CAPITAL LETTER E +0x9E 0x042E # CYRILLIC CAPITAL LETTER YU +0x9F 0x042F # CYRILLIC CAPITAL LETTER YA +0xA0 0x2020 # DAGGER +0xA1 0x00B0 # DEGREE SIGN +0xA2 0x0490 # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A7 # SECTION SIGN +0xA5 0x2022 # BULLET +0xA6 0x00B6 # PILCROW SIGN +0xA7 0x0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xA8 0x00AE # REGISTERED SIGN +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x2122 # TRADE MARK SIGN +0xAB 0x0402 # CYRILLIC CAPITAL LETTER DJE +0xAC 0x0452 # CYRILLIC SMALL LETTER DJE +0xAD 0x2260 # NOT EQUAL TO +0xAE 0x0403 # CYRILLIC CAPITAL LETTER GJE +0xAF 0x0453 # CYRILLIC SMALL LETTER GJE +0xB0 0x221E # INFINITY +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x2264 # LESS-THAN OR EQUAL TO +0xB3 0x2265 # GREATER-THAN OR EQUAL TO +0xB4 0x0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0xB5 0x00B5 # MICRO SIGN +0xB6 0x0491 # CYRILLIC SMALL LETTER GHE WITH UPTURN +0xB7 0x0408 # CYRILLIC CAPITAL LETTER JE +0xB8 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xB9 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE +0xBA 0x0407 # CYRILLIC CAPITAL LETTER YI +0xBB 0x0457 # CYRILLIC SMALL LETTER YI +0xBC 0x0409 # CYRILLIC CAPITAL LETTER LJE +0xBD 0x0459 # CYRILLIC SMALL LETTER LJE +0xBE 0x040A # CYRILLIC CAPITAL LETTER NJE +0xBF 0x045A # CYRILLIC SMALL LETTER NJE +0xC0 0x0458 # CYRILLIC SMALL LETTER JE +0xC1 0x0405 # CYRILLIC CAPITAL LETTER DZE +0xC2 0x00AC # NOT SIGN +0xC3 0x221A # SQUARE ROOT +0xC4 0x0192 # LATIN SMALL LETTER F WITH HOOK +0xC5 0x2248 # ALMOST EQUAL TO +0xC6 0x2206 # INCREMENT +0xC7 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC8 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC9 0x2026 # HORIZONTAL ELLIPSIS +0xCA 0x00A0 # NO-BREAK SPACE +0xCB 0x040B # CYRILLIC CAPITAL LETTER TSHE +0xCC 0x045B # CYRILLIC SMALL LETTER TSHE +0xCD 0x040C # CYRILLIC CAPITAL LETTER KJE +0xCE 0x045C # CYRILLIC SMALL LETTER KJE +0xCF 0x0455 # CYRILLIC SMALL LETTER DZE +0xD0 0x2013 # EN DASH +0xD1 0x2014 # EM DASH +0xD2 0x201C # LEFT DOUBLE QUOTATION MARK +0xD3 0x201D # RIGHT DOUBLE QUOTATION MARK +0xD4 0x2018 # LEFT SINGLE QUOTATION MARK +0xD5 0x2019 # RIGHT SINGLE QUOTATION MARK +0xD6 0x00F7 # DIVISION SIGN +0xD7 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xD8 0x040E # CYRILLIC CAPITAL LETTER SHORT U +0xD9 0x045E # CYRILLIC SMALL LETTER SHORT U +0xDA 0x040F # CYRILLIC CAPITAL LETTER DZHE +0xDB 0x045F # CYRILLIC SMALL LETTER DZHE +0xDC 0x2116 # NUMERO SIGN +0xDD 0x0401 # CYRILLIC CAPITAL LETTER IO +0xDE 0x0451 # CYRILLIC SMALL LETTER IO +0xDF 0x044F # CYRILLIC SMALL LETTER YA +0xE0 0x0430 # CYRILLIC SMALL LETTER A +0xE1 0x0431 # CYRILLIC SMALL LETTER BE +0xE2 0x0432 # CYRILLIC SMALL LETTER VE +0xE3 0x0433 # CYRILLIC SMALL LETTER GHE +0xE4 0x0434 # CYRILLIC SMALL LETTER DE +0xE5 0x0435 # CYRILLIC SMALL LETTER IE +0xE6 0x0436 # CYRILLIC SMALL LETTER ZHE +0xE7 0x0437 # CYRILLIC SMALL LETTER ZE +0xE8 0x0438 # CYRILLIC SMALL LETTER I +0xE9 0x0439 # CYRILLIC SMALL LETTER SHORT I +0xEA 0x043A # CYRILLIC SMALL LETTER KA +0xEB 0x043B # CYRILLIC SMALL LETTER EL +0xEC 0x043C # CYRILLIC SMALL LETTER EM +0xED 0x043D # CYRILLIC SMALL LETTER EN +0xEE 0x043E # CYRILLIC SMALL LETTER O +0xEF 0x043F # CYRILLIC SMALL LETTER PE +0xF0 0x0440 # CYRILLIC SMALL LETTER ER +0xF1 0x0441 # CYRILLIC SMALL LETTER ES +0xF2 0x0442 # CYRILLIC SMALL LETTER TE +0xF3 0x0443 # CYRILLIC SMALL LETTER U +0xF4 0x0444 # CYRILLIC SMALL LETTER EF +0xF5 0x0445 # CYRILLIC SMALL LETTER HA +0xF6 0x0446 # CYRILLIC SMALL LETTER TSE +0xF7 0x0447 # CYRILLIC SMALL LETTER CHE +0xF8 0x0448 # CYRILLIC SMALL LETTER SHA +0xF9 0x0449 # CYRILLIC SMALL LETTER SHCHA +0xFA 0x044A # CYRILLIC SMALL LETTER HARD SIGN +0xFB 0x044B # CYRILLIC SMALL LETTER YERU +0xFC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN +0xFD 0x044D # CYRILLIC SMALL LETTER E +0xFE 0x044E # CYRILLIC SMALL LETTER YU +0xFF 0x20AC # EURO SIGN diff --git a/Resources/MacRoman.txt b/Resources/MacRoman.txt new file mode 100644 index 0000000..b2b6723 --- /dev/null +++ b/Resources/MacRoman.txt @@ -0,0 +1,362 @@ +#======================================================================= +# File name: ROMAN.TXT +# +# Contents: Map (external version) from Mac OS Roman +# character set to Unicode 2.1 through Unicode 3.2 +# +# Copyright: (c) 1994-2002 by Apple Computer, Inc., all rights +# reserved. +# +# Contact: charsets@apple.com +# +# Changes: +# +# b4,c1 2002-Dec-19 Update URLs, notes. Matches internal +# utom. +# b03 1999-Sep-22 Update contact e-mail address. Matches +# internal utom, ufrm, and Text +# Encoding Converter version 1.5. +# b02 1998-Aug-18 Encoding changed for Mac OS 8.5; change +# mapping of 0xDB from CURRENCY SIGN to +# EURO SIGN. Matches internal utom, +# ufrm. +# n08 1998-Feb-05 Minor update to header comments +# n06 1997-Dec-14 Add warning about future changes to 0xDB +# from CURRENCY SIGN to EURO SIGN. Clarify +# some header information +# n04 1997-Dec-01 Update to match internal utom, ufrm: +# Change standard mapping for 0xBD from U+2126 +# to its canonical decomposition, U+03A9. +# n03 1995-Apr-15 First version (after fixing some typos). +# Matches internal ufrm. +# +# Standard header: +# ---------------- +# +# Apple, the Apple logo, and Macintosh are trademarks of Apple +# Computer, Inc., registered in the United States and other countries. +# Unicode is a trademark of Unicode Inc. For the sake of brevity, +# throughout this document, "Macintosh" can be used to refer to +# Macintosh computers and "Unicode" can be used to refer to the +# Unicode standard. +# +# Apple makes no warranty or representation, either express or +# implied, with respect to these tables, their quality, accuracy, or +# fitness for a particular purpose. In no event will Apple be liable +# for direct, indirect, special, incidental, or consequential damages +# resulting from any defect or inaccuracy in this document or the +# accompanying tables. +# +# These mapping tables and character lists are subject to change. +# The latest tables should be available from the following: +# +# +# +# For general information about Mac OS encodings and these mapping +# tables, see the file "README.TXT". +# +# Format: +# ------- +# +# Three tab-separated columns; +# '#' begins a comment which continues to the end of the line. +# Column #1 is the Mac OS Roman code (in hex as 0xNN) +# Column #2 is the corresponding Unicode (in hex as 0xNNNN) +# Column #3 is a comment containing the Unicode name +# +# The entries are in Mac OS Roman code order. +# +# One of these mappings requires the use of a corporate character. +# See the file "CORPCHAR.TXT" and notes below. +# +# Control character mappings are not shown in this table, following +# the conventions of the standard UTC mapping tables. However, the +# Mac OS Roman character set uses the standard control characters at +# 0x00-0x1F and 0x7F. +# +# Notes on Mac OS Roman: +# ---------------------- +# +# This character set is used for at least the following Mac OS +# localizations: U.S., British, Canadian French, French, Swiss +# French, German, Swiss German, Italian, Swiss Italian, Dutch, +# Swedish, Norwegian, Danish, Finnish, Spanish, Catalan, +# Portuguese, Brazilian, and the default International system. +# +# Variants of Mac OS Roman are used for Croatian, Icelandic, +# Turkish, Romanian, and other encodings. Separate mapping tables +# are available for these encodings. +# +# Before Mac OS 8.5, code point 0xDB was CURRENCY SIGN, and was +# mapped to U+00A4. In Mac OS 8.5 and later versions, code point +# 0xDB is changed to EURO SIGN and maps to U+20AC; the standard +# Apple fonts are updated for Mac OS 8.5 to reflect this. There is +# a "currency sign" variant of the Mac OS Roman encoding that still +# maps 0xDB to U+00A4; this can be used for older fonts. +# +# Before Mac OS 8.5, the ROM bitmap versions of the fonts Chicago, +# New York, Geneva, and Monaco did not implement the full Mac OS +# Roman character set; they only supported character codes up to +# 0xD8. The TrueType versions of these fonts have always implemented +# the full character set, as with the bitmap and TrueType versions +# of the other standard Roman fonts. +# +# In all Mac OS encodings, fonts such as Chicago which are used +# as "system" fonts (for menus, dialogs, etc.) have four glyphs +# at code points 0x11-0x14 for transient use by the Menu Manager. +# These glyphs are not intended as characters for use in normal +# text, and the associated code points are not generally +# interpreted as associated with these glyphs; they are usually +# interpreted (if at all) as the control codes DC1-DC4. +# +# Unicode mapping issues and notes: +# --------------------------------- +# +# The following corporate zone Unicode character is used in this +# mapping: +# +# 0xF8FF Apple logo +# +# NOTE: The graphic image associated with the Apple logo character +# is not authorized for use without permission of Apple, and +# unauthorized use might constitute trademark infringement. +# +# Details of mapping changes in each version: +# ------------------------------------------- +# +# Changes from version n08 to version b02: +# +# - Encoding changed for Mac OS 8.5; change mapping of 0xDB from +# CURRENCY SIGN (U+00A4) to EURO SIGN (U+20AC). +# +# Changes from version n03 to version n04: +# +# - Change mapping of 0xBD from U+2126 to its canonical +# decomposition, U+03A9. +# +################## + +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +# +0x80 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0x81 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0x82 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0x83 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0x84 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0x85 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0x86 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0x87 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0x88 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0x89 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0x8A 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0x8B 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0x8C 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0x8D 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0x8E 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0x8F 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0x90 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0x91 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0x92 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0x93 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0x94 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0x95 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0x96 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0x97 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0x98 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0x99 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0x9A 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0x9B 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0x9C 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0x9D 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0x9E 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0x9F 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xA0 0x2020 # DAGGER +0xA1 0x00B0 # DEGREE SIGN +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A7 # SECTION SIGN +0xA5 0x2022 # BULLET +0xA6 0x00B6 # PILCROW SIGN +0xA7 0x00DF # LATIN SMALL LETTER SHARP S +0xA8 0x00AE # REGISTERED SIGN +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x2122 # TRADE MARK SIGN +0xAB 0x00B4 # ACUTE ACCENT +0xAC 0x00A8 # DIAERESIS +0xAD 0x2260 # NOT EQUAL TO +0xAE 0x00C6 # LATIN CAPITAL LETTER AE +0xAF 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xB0 0x221E # INFINITY +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x2264 # LESS-THAN OR EQUAL TO +0xB3 0x2265 # GREATER-THAN OR EQUAL TO +0xB4 0x00A5 # YEN SIGN +0xB5 0x00B5 # MICRO SIGN +0xB6 0x2202 # PARTIAL DIFFERENTIAL +0xB7 0x2211 # N-ARY SUMMATION +0xB8 0x220F # N-ARY PRODUCT +0xB9 0x03C0 # GREEK SMALL LETTER PI +0xBA 0x222B # INTEGRAL +0xBB 0x00AA # FEMININE ORDINAL INDICATOR +0xBC 0x00BA # MASCULINE ORDINAL INDICATOR +0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA +0xBE 0x00E6 # LATIN SMALL LETTER AE +0xBF 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xC0 0x00BF # INVERTED QUESTION MARK +0xC1 0x00A1 # INVERTED EXCLAMATION MARK +0xC2 0x00AC # NOT SIGN +0xC3 0x221A # SQUARE ROOT +0xC4 0x0192 # LATIN SMALL LETTER F WITH HOOK +0xC5 0x2248 # ALMOST EQUAL TO +0xC6 0x2206 # INCREMENT +0xC7 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC8 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC9 0x2026 # HORIZONTAL ELLIPSIS +0xCA 0x00A0 # NO-BREAK SPACE +0xCB 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xCC 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xCD 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xCE 0x0152 # LATIN CAPITAL LIGATURE OE +0xCF 0x0153 # LATIN SMALL LIGATURE OE +0xD0 0x2013 # EN DASH +0xD1 0x2014 # EM DASH +0xD2 0x201C # LEFT DOUBLE QUOTATION MARK +0xD3 0x201D # RIGHT DOUBLE QUOTATION MARK +0xD4 0x2018 # LEFT SINGLE QUOTATION MARK +0xD5 0x2019 # RIGHT SINGLE QUOTATION MARK +0xD6 0x00F7 # DIVISION SIGN +0xD7 0x25CA # LOZENGE +0xD8 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS +0xD9 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xDA 0x2044 # FRACTION SLASH +0xDB 0x20AC # EURO SIGN +0xDC 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0xDD 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0xDE 0xFB01 # LATIN SMALL LIGATURE FI +0xDF 0xFB02 # LATIN SMALL LIGATURE FL +0xE0 0x2021 # DOUBLE DAGGER +0xE1 0x00B7 # MIDDLE DOT +0xE2 0x201A # SINGLE LOW-9 QUOTATION MARK +0xE3 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xE4 0x2030 # PER MILLE SIGN +0xE5 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xE6 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xE7 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xE8 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xE9 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xEA 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xEB 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xEC 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xED 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xEE 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xEF 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xF0 0xF8FF # Apple logo +0xF1 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xF2 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xF3 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xF4 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I +0xF6 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT +0xF7 0x02DC # SMALL TILDE +0xF8 0x00AF # MACRON +0xF9 0x02D8 # BREVE +0xFA 0x02D9 # DOT ABOVE +0xFB 0x02DA # RING ABOVE +0xFC 0x00B8 # CEDILLA +0xFD 0x02DD # DOUBLE ACUTE ACCENT +0xFE 0x02DB # OGONEK +0xFF 0x02C7 # CARON diff --git a/Resources/UTF-8.txt b/Resources/UTF-8.txt new file mode 100644 index 0000000..46431f9 --- /dev/null +++ b/Resources/UTF-8.txt @@ -0,0 +1,3 @@ +# UTF-8 to Unicode +# This file is a dummy. +# The conversion is done algorithmicly, not by a table look-up. diff --git a/Resources/Unicode01 b/Resources/Unicode01 new file mode 100644 index 0000000..7e62eca --- /dev/null +++ b/Resources/Unicode01 @@ -0,0 +1,306 @@ +# +# Name: ISO/IEC 8859-1:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-1:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-1 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-1 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +#RISC OS +# This file was changed to match RISC OS specific characters (0x80 - 0x9f) +#RISC OS +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0174 # CAPITAL W CIRCUMFLEX ACCENT +0x82 0x0175 # SMALL W CIRCUMFLEX ACCENT +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0176 # CAPITAL Y CIRCUMFLEX ACCENT +0x86 0x0177 # SMALL Y CIRCUMFLEX ACCENT +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x2026 # ELLIPSIS +0x8D 0x2122 # TRADEMARK +0x8E 0x2030 # PER MILLE SIGN +0x8F 0x2022 # BULLET +0x90 0x2018 # LEFT SINGLE QUOTE +0x91 0x2019 # RIGHT SINGLE QUOTE +0x92 0x2039 # LEFT SINGLE QUOTATION MARK +0x93 0x203A # RIGHT SINGLE QUOTATION MARK +0x94 0x201C # OPENING DOUBLE QUOTE +0x95 0x201D # CLOSING DOUBLE QUOTE +0x96 0x201E # LOW DOUBLE QUOTE +0x97 0x2013 # EN DASH +0x98 0x2014 # EM_DASH +0x99 0x2011 # NON BREAKING HYPHEN +0x9A 0x0152 # LATIN CAPITAL LIGATURE OE +0x9B 0x0153 # LATIN SMALL LIGATURE OE +0x9C 0x2020 # DAGGER +0x9D 0x2021 # DOUBLE DAGGER +0x9E 0xFB01 # Fi +0x9F 0xFB02 # Fl +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/Resources/Unicode15 b/Resources/Unicode15 new file mode 100644 index 0000000..5051a3d --- /dev/null +++ b/Resources/Unicode15 @@ -0,0 +1,305 @@ +# +# Name: ISO/IEC 8859-15:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Markus Kuhn +# Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-15:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-15 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-15 order. +# +# Version history +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +#RISC OS +# This file was changed to match RISC OS specific characters (0x80 - 0x9f) +#RISC OS +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0174 # CAPITAL W CIRCUMFLEX ACCENT +0x82 0x0175 # SMALL W CIRCUMFLEX ACCENT +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0176 # CAPITAL Y CIRCUMFLEX ACCENT +0x86 0x0177 # SMALL Y CIRCUMFLEX ACCENT +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x2026 # ELLIPSIS +0x8D 0x2122 # TRADEMARK +0x8E 0x2030 # PER MILLE SIGN +0x8F 0x2022 # BULLET +0x90 0x2018 # LEFT SINGLE QUOTE +0x91 0x2019 # RIGHT SINGLE QUOTE +0x92 0x2039 # LEFT SINGLE QUOTATION MARK +0x93 0x203A # RIGHT SINGLE QUOTATION MARK +0x94 0x201C # OPENING DOUBLE QUOTE +0x95 0x201D # CLOSING DOUBLE QUOTE +0x96 0x201E # LOW DOUBLE QUOTE +0x97 0x2013 # EN DASH +0x98 0x2014 # EM_DASH +0x99 0x2011 # NON BREAKING HYPHEN +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x2020 # DAGGER +0x9D 0x2021 # DOUBLE DAGGER +0x9E 0xFB01 # Fi +0x9F 0xFB02 # Fl +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x20AC # EURO SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xA7 0x00A7 # SECTION SIGN +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/Resources/cp1250.txt b/Resources/cp1250.txt new file mode 100644 index 0000000..aa27ca3 --- /dev/null +++ b/Resources/cp1250.txt @@ -0,0 +1,274 @@ +# +# Name: cp1250 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1250 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1250 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 #UNDEFINED +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 #UNDEFINED +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x015A #LATIN CAPITAL LETTER S WITH ACUTE +0x8D 0x0164 #LATIN CAPITAL LETTER T WITH CARON +0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +0x8F 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x015B #LATIN SMALL LETTER S WITH ACUTE +0x9D 0x0165 #LATIN SMALL LETTER T WITH CARON +0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +0x9F 0x017A #LATIN SMALL LETTER Z WITH ACUTE +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x02C7 #CARON +0xA2 0x02D8 #BREVE +0xA3 0x0141 #LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x015E #LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x017B #LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x02DB #OGONEK +0xB3 0x0142 #LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x0105 #LATIN SMALL LETTER A WITH OGONEK +0xBA 0x015F #LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x013D #LATIN CAPITAL LETTER L WITH CARON +0xBD 0x02DD #DOUBLE ACUTE ACCENT +0xBE 0x013E #LATIN SMALL LETTER L WITH CARON +0xBF 0x017C #LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 #LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 #LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 #LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C #LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A #LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E #LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 #LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 #LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x0158 #LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E #LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 #LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x0155 #LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 #LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A #LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 #LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D #LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 #LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B #LATIN SMALL LETTER E WITH CARON +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F #LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 #LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 #LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 #LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 #LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x0159 #LATIN SMALL LETTER R WITH CARON +0xF9 0x016F #LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 #LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 #LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 #DOT ABOVE diff --git a/Resources/cp1251.txt b/Resources/cp1251.txt new file mode 100644 index 0000000..f6876e6 --- /dev/null +++ b/Resources/cp1251.txt @@ -0,0 +1,274 @@ +# +# Name: cp1251 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1251 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1251 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x0402 #CYRILLIC CAPITAL LETTER DJE +0x81 0x0403 #CYRILLIC CAPITAL LETTER GJE +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0453 #CYRILLIC SMALL LETTER GJE +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x20AC #EURO SIGN +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0409 #CYRILLIC CAPITAL LETTER LJE +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x040A #CYRILLIC CAPITAL LETTER NJE +0x8D 0x040C #CYRILLIC CAPITAL LETTER KJE +0x8E 0x040B #CYRILLIC CAPITAL LETTER TSHE +0x8F 0x040F #CYRILLIC CAPITAL LETTER DZHE +0x90 0x0452 #CYRILLIC SMALL LETTER DJE +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0459 #CYRILLIC SMALL LETTER LJE +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x045A #CYRILLIC SMALL LETTER NJE +0x9D 0x045C #CYRILLIC SMALL LETTER KJE +0x9E 0x045B #CYRILLIC SMALL LETTER TSHE +0x9F 0x045F #CYRILLIC SMALL LETTER DZHE +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x040E #CYRILLIC CAPITAL LETTER SHORT U +0xA2 0x045E #CYRILLIC SMALL LETTER SHORT U +0xA3 0x0408 #CYRILLIC CAPITAL LETTER JE +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x0490 #CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x0401 #CYRILLIC CAPITAL LETTER IO +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x0407 #CYRILLIC CAPITAL LETTER YI +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x0406 #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xB3 0x0456 #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0xB4 0x0491 #CYRILLIC SMALL LETTER GHE WITH UPTURN +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x0451 #CYRILLIC SMALL LETTER IO +0xB9 0x2116 #NUMERO SIGN +0xBA 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0458 #CYRILLIC SMALL LETTER JE +0xBD 0x0405 #CYRILLIC CAPITAL LETTER DZE +0xBE 0x0455 #CYRILLIC SMALL LETTER DZE +0xBF 0x0457 #CYRILLIC SMALL LETTER YI +0xC0 0x0410 #CYRILLIC CAPITAL LETTER A +0xC1 0x0411 #CYRILLIC CAPITAL LETTER BE +0xC2 0x0412 #CYRILLIC CAPITAL LETTER VE +0xC3 0x0413 #CYRILLIC CAPITAL LETTER GHE +0xC4 0x0414 #CYRILLIC CAPITAL LETTER DE +0xC5 0x0415 #CYRILLIC CAPITAL LETTER IE +0xC6 0x0416 #CYRILLIC CAPITAL LETTER ZHE +0xC7 0x0417 #CYRILLIC CAPITAL LETTER ZE +0xC8 0x0418 #CYRILLIC CAPITAL LETTER I +0xC9 0x0419 #CYRILLIC CAPITAL LETTER SHORT I +0xCA 0x041A #CYRILLIC CAPITAL LETTER KA +0xCB 0x041B #CYRILLIC CAPITAL LETTER EL +0xCC 0x041C #CYRILLIC CAPITAL LETTER EM +0xCD 0x041D #CYRILLIC CAPITAL LETTER EN +0xCE 0x041E #CYRILLIC CAPITAL LETTER O +0xCF 0x041F #CYRILLIC CAPITAL LETTER PE +0xD0 0x0420 #CYRILLIC CAPITAL LETTER ER +0xD1 0x0421 #CYRILLIC CAPITAL LETTER ES +0xD2 0x0422 #CYRILLIC CAPITAL LETTER TE +0xD3 0x0423 #CYRILLIC CAPITAL LETTER U +0xD4 0x0424 #CYRILLIC CAPITAL LETTER EF +0xD5 0x0425 #CYRILLIC CAPITAL LETTER HA +0xD6 0x0426 #CYRILLIC CAPITAL LETTER TSE +0xD7 0x0427 #CYRILLIC CAPITAL LETTER CHE +0xD8 0x0428 #CYRILLIC CAPITAL LETTER SHA +0xD9 0x0429 #CYRILLIC CAPITAL LETTER SHCHA +0xDA 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN +0xDB 0x042B #CYRILLIC CAPITAL LETTER YERU +0xDC 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN +0xDD 0x042D #CYRILLIC CAPITAL LETTER E +0xDE 0x042E #CYRILLIC CAPITAL LETTER YU +0xDF 0x042F #CYRILLIC CAPITAL LETTER YA +0xE0 0x0430 #CYRILLIC SMALL LETTER A +0xE1 0x0431 #CYRILLIC SMALL LETTER BE +0xE2 0x0432 #CYRILLIC SMALL LETTER VE +0xE3 0x0433 #CYRILLIC SMALL LETTER GHE +0xE4 0x0434 #CYRILLIC SMALL LETTER DE +0xE5 0x0435 #CYRILLIC SMALL LETTER IE +0xE6 0x0436 #CYRILLIC SMALL LETTER ZHE +0xE7 0x0437 #CYRILLIC SMALL LETTER ZE +0xE8 0x0438 #CYRILLIC SMALL LETTER I +0xE9 0x0439 #CYRILLIC SMALL LETTER SHORT I +0xEA 0x043A #CYRILLIC SMALL LETTER KA +0xEB 0x043B #CYRILLIC SMALL LETTER EL +0xEC 0x043C #CYRILLIC SMALL LETTER EM +0xED 0x043D #CYRILLIC SMALL LETTER EN +0xEE 0x043E #CYRILLIC SMALL LETTER O +0xEF 0x043F #CYRILLIC SMALL LETTER PE +0xF0 0x0440 #CYRILLIC SMALL LETTER ER +0xF1 0x0441 #CYRILLIC SMALL LETTER ES +0xF2 0x0442 #CYRILLIC SMALL LETTER TE +0xF3 0x0443 #CYRILLIC SMALL LETTER U +0xF4 0x0444 #CYRILLIC SMALL LETTER EF +0xF5 0x0445 #CYRILLIC SMALL LETTER HA +0xF6 0x0446 #CYRILLIC SMALL LETTER TSE +0xF7 0x0447 #CYRILLIC SMALL LETTER CHE +0xF8 0x0448 #CYRILLIC SMALL LETTER SHA +0xF9 0x0449 #CYRILLIC SMALL LETTER SHCHA +0xFA 0x044A #CYRILLIC SMALL LETTER HARD SIGN +0xFB 0x044B #CYRILLIC SMALL LETTER YERU +0xFC 0x044C #CYRILLIC SMALL LETTER SOFT SIGN +0xFD 0x044D #CYRILLIC SMALL LETTER E +0xFE 0x044E #CYRILLIC SMALL LETTER YU +0xFF 0x044F #CYRILLIC SMALL LETTER YA diff --git a/Resources/cp1252.txt b/Resources/cp1252.txt new file mode 100644 index 0000000..970002d --- /dev/null +++ b/Resources/cp1252.txt @@ -0,0 +1,274 @@ +# +# Name: cp1252 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1252 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1252 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +0x8D #UNDEFINED +0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x02DC #SMALL TILDE +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x0153 #LATIN SMALL LIGATURE OE +0x9D #UNDEFINED +0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +0x9F 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x00A1 #INVERTED EXCLAMATION MARK +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x00AA #FEMININE ORDINAL INDICATOR +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x00BA #MASCULINE ORDINAL INDICATOR +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF #INVERTED QUESTION MARK +0xC0 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 #LATIN CAPITAL LETTER AE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 #LATIN CAPITAL LETTER ETH +0xD1 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE #LATIN CAPITAL LETTER THORN +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x00E0 #LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 #LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 #LATIN SMALL LETTER AE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC #LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 #LATIN SMALL LETTER ETH +0xF1 0x00F1 #LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 #LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 #LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x00F8 #LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 #LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE #LATIN SMALL LETTER THORN +0xFF 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/Resources/cp437.txt b/Resources/cp437.txt new file mode 100644 index 0000000..ae38e17 --- /dev/null +++ b/Resources/cp437.txt @@ -0,0 +1,273 @@ +# +# Name: cp437_DOSLatinUS to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp437_DOSLatinUS code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp437_DOSLatinUS order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA +0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS +0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE +0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS +0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE +0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE +0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA +0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX +0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS +0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE +0x8b 0x00ef #LATIN SMALL LETTER I WITH DIAERESIS +0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX +0x8d 0x00ec #LATIN SMALL LETTER I WITH GRAVE +0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x91 0x00e6 #LATIN SMALL LIGATURE AE +0x92 0x00c6 #LATIN CAPITAL LIGATURE AE +0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS +0x95 0x00f2 #LATIN SMALL LETTER O WITH GRAVE +0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX +0x97 0x00f9 #LATIN SMALL LETTER U WITH GRAVE +0x98 0x00ff #LATIN SMALL LETTER Y WITH DIAERESIS +0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9b 0x00a2 #CENT SIGN +0x9c 0x00a3 #POUND SIGN +0x9d 0x00a5 #YEN SIGN +0x9e 0x20a7 #PESETA SIGN +0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK +0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE +0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE +0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE +0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE +0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE +0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE +0xa6 0x00aa #FEMININE ORDINAL INDICATOR +0xa7 0x00ba #MASCULINE ORDINAL INDICATOR +0xa8 0x00bf #INVERTED QUESTION MARK +0xa9 0x2310 #REVERSED NOT SIGN +0xaa 0x00ac #NOT SIGN +0xab 0x00bd #VULGAR FRACTION ONE HALF +0xac 0x00bc #VULGAR FRACTION ONE QUARTER +0xad 0x00a1 #INVERTED EXCLAMATION MARK +0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x258c #LEFT HALF BLOCK +0xde 0x2590 #RIGHT HALF BLOCK +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x03b1 #GREEK SMALL LETTER ALPHA +0xe1 0x00df #LATIN SMALL LETTER SHARP S +0xe2 0x0393 #GREEK CAPITAL LETTER GAMMA +0xe3 0x03c0 #GREEK SMALL LETTER PI +0xe4 0x03a3 #GREEK CAPITAL LETTER SIGMA +0xe5 0x03c3 #GREEK SMALL LETTER SIGMA +0xe6 0x00b5 #MICRO SIGN +0xe7 0x03c4 #GREEK SMALL LETTER TAU +0xe8 0x03a6 #GREEK CAPITAL LETTER PHI +0xe9 0x0398 #GREEK CAPITAL LETTER THETA +0xea 0x03a9 #GREEK CAPITAL LETTER OMEGA +0xeb 0x03b4 #GREEK SMALL LETTER DELTA +0xec 0x221e #INFINITY +0xed 0x03c6 #GREEK SMALL LETTER PHI +0xee 0x03b5 #GREEK SMALL LETTER EPSILON +0xef 0x2229 #INTERSECTION +0xf0 0x2261 #IDENTICAL TO +0xf1 0x00b1 #PLUS-MINUS SIGN +0xf2 0x2265 #GREATER-THAN OR EQUAL TO +0xf3 0x2264 #LESS-THAN OR EQUAL TO +0xf4 0x2320 #TOP HALF INTEGRAL +0xf5 0x2321 #BOTTOM HALF INTEGRAL +0xf6 0x00f7 #DIVISION SIGN +0xf7 0x2248 #ALMOST EQUAL TO +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x2219 #BULLET OPERATOR +0xfa 0x00b7 #MIDDLE DOT +0xfb 0x221a #SQUARE ROOT +0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N +0xfd 0x00b2 #SUPERSCRIPT TWO +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE diff --git a/Resources/cp850.txt b/Resources/cp850.txt new file mode 100644 index 0000000..590b1af --- /dev/null +++ b/Resources/cp850.txt @@ -0,0 +1,273 @@ +# +# Name: cp850_DOSLatin1 to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp850_DOSLatin1 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp850_DOSLatin1 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA +0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS +0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE +0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS +0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE +0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE +0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA +0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX +0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS +0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE +0x8b 0x00ef #LATIN SMALL LETTER I WITH DIAERESIS +0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX +0x8d 0x00ec #LATIN SMALL LETTER I WITH GRAVE +0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x91 0x00e6 #LATIN SMALL LIGATURE AE +0x92 0x00c6 #LATIN CAPITAL LIGATURE AE +0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS +0x95 0x00f2 #LATIN SMALL LETTER O WITH GRAVE +0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX +0x97 0x00f9 #LATIN SMALL LETTER U WITH GRAVE +0x98 0x00ff #LATIN SMALL LETTER Y WITH DIAERESIS +0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9b 0x00f8 #LATIN SMALL LETTER O WITH STROKE +0x9c 0x00a3 #POUND SIGN +0x9d 0x00d8 #LATIN CAPITAL LETTER O WITH STROKE +0x9e 0x00d7 #MULTIPLICATION SIGN +0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK +0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE +0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE +0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE +0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE +0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE +0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE +0xa6 0x00aa #FEMININE ORDINAL INDICATOR +0xa7 0x00ba #MASCULINE ORDINAL INDICATOR +0xa8 0x00bf #INVERTED QUESTION MARK +0xa9 0x00ae #REGISTERED SIGN +0xaa 0x00ac #NOT SIGN +0xab 0x00bd #VULGAR FRACTION ONE HALF +0xac 0x00bc #VULGAR FRACTION ONE QUARTER +0xad 0x00a1 #INVERTED EXCLAMATION MARK +0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE +0xb6 0x00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xb7 0x00c0 #LATIN CAPITAL LETTER A WITH GRAVE +0xb8 0x00a9 #COPYRIGHT SIGN +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x00a2 #CENT SIGN +0xbe 0x00a5 #YEN SIGN +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x00e3 #LATIN SMALL LETTER A WITH TILDE +0xc7 0x00c3 #LATIN CAPITAL LETTER A WITH TILDE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x00a4 #CURRENCY SIGN +0xd0 0x00f0 #LATIN SMALL LETTER ETH +0xd1 0x00d0 #LATIN CAPITAL LETTER ETH +0xd2 0x00ca #LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xd3 0x00cb #LATIN CAPITAL LETTER E WITH DIAERESIS +0xd4 0x00c8 #LATIN CAPITAL LETTER E WITH GRAVE +0xd5 0x0131 #LATIN SMALL LETTER DOTLESS I +0xd6 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE +0xd7 0x00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xd8 0x00cf #LATIN CAPITAL LETTER I WITH DIAERESIS +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x00a6 #BROKEN BAR +0xde 0x00cc #LATIN CAPITAL LETTER I WITH GRAVE +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE +0xe1 0x00df #LATIN SMALL LETTER SHARP S +0xe2 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xe3 0x00d2 #LATIN CAPITAL LETTER O WITH GRAVE +0xe4 0x00f5 #LATIN SMALL LETTER O WITH TILDE +0xe5 0x00d5 #LATIN CAPITAL LETTER O WITH TILDE +0xe6 0x00b5 #MICRO SIGN +0xe7 0x00fe #LATIN SMALL LETTER THORN +0xe8 0x00de #LATIN CAPITAL LETTER THORN +0xe9 0x00da #LATIN CAPITAL LETTER U WITH ACUTE +0xea 0x00db #LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xeb 0x00d9 #LATIN CAPITAL LETTER U WITH GRAVE +0xec 0x00fd #LATIN SMALL LETTER Y WITH ACUTE +0xed 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE +0xee 0x00af #MACRON +0xef 0x00b4 #ACUTE ACCENT +0xf0 0x00ad #SOFT HYPHEN +0xf1 0x00b1 #PLUS-MINUS SIGN +0xf2 0x2017 #DOUBLE LOW LINE +0xf3 0x00be #VULGAR FRACTION THREE QUARTERS +0xf4 0x00b6 #PILCROW SIGN +0xf5 0x00a7 #SECTION SIGN +0xf6 0x00f7 #DIVISION SIGN +0xf7 0x00b8 #CEDILLA +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x00a8 #DIAERESIS +0xfa 0x00b7 #MIDDLE DOT +0xfb 0x00b9 #SUPERSCRIPT ONE +0xfc 0x00b3 #SUPERSCRIPT THREE +0xfd 0x00b2 #SUPERSCRIPT TWO +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE diff --git a/Resources/cp852.txt b/Resources/cp852.txt new file mode 100644 index 0000000..2f2daba --- /dev/null +++ b/Resources/cp852.txt @@ -0,0 +1,273 @@ +# +# Name: cp852_DOSLatin2 to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp852_DOSLatin2 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp852_DOSLatin2 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA +0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS +0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE +0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS +0x85 0x016f #LATIN SMALL LETTER U WITH RING ABOVE +0x86 0x0107 #LATIN SMALL LETTER C WITH ACUTE +0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA +0x88 0x0142 #LATIN SMALL LETTER L WITH STROKE +0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS +0x8a 0x0150 #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0x8b 0x0151 #LATIN SMALL LETTER O WITH DOUBLE ACUTE +0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX +0x8d 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE +0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0x8f 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE +0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x91 0x0139 #LATIN CAPITAL LETTER L WITH ACUTE +0x92 0x013a #LATIN SMALL LETTER L WITH ACUTE +0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS +0x95 0x013d #LATIN CAPITAL LETTER L WITH CARON +0x96 0x013e #LATIN SMALL LETTER L WITH CARON +0x97 0x015a #LATIN CAPITAL LETTER S WITH ACUTE +0x98 0x015b #LATIN SMALL LETTER S WITH ACUTE +0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9b 0x0164 #LATIN CAPITAL LETTER T WITH CARON +0x9c 0x0165 #LATIN SMALL LETTER T WITH CARON +0x9d 0x0141 #LATIN CAPITAL LETTER L WITH STROKE +0x9e 0x00d7 #MULTIPLICATION SIGN +0x9f 0x010d #LATIN SMALL LETTER C WITH CARON +0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE +0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE +0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE +0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE +0xa4 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK +0xa5 0x0105 #LATIN SMALL LETTER A WITH OGONEK +0xa6 0x017d #LATIN CAPITAL LETTER Z WITH CARON +0xa7 0x017e #LATIN SMALL LETTER Z WITH CARON +0xa8 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK +0xa9 0x0119 #LATIN SMALL LETTER E WITH OGONEK +0xaa 0x00ac #NOT SIGN +0xab 0x017a #LATIN SMALL LETTER Z WITH ACUTE +0xac 0x010c #LATIN CAPITAL LETTER C WITH CARON +0xad 0x015f #LATIN SMALL LETTER S WITH CEDILLA +0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE +0xb6 0x00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xb7 0x011a #LATIN CAPITAL LETTER E WITH CARON +0xb8 0x015e #LATIN CAPITAL LETTER S WITH CEDILLA +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x017b #LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xbe 0x017c #LATIN SMALL LETTER Z WITH DOT ABOVE +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x0102 #LATIN CAPITAL LETTER A WITH BREVE +0xc7 0x0103 #LATIN SMALL LETTER A WITH BREVE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x00a4 #CURRENCY SIGN +0xd0 0x0111 #LATIN SMALL LETTER D WITH STROKE +0xd1 0x0110 #LATIN CAPITAL LETTER D WITH STROKE +0xd2 0x010e #LATIN CAPITAL LETTER D WITH CARON +0xd3 0x00cb #LATIN CAPITAL LETTER E WITH DIAERESIS +0xd4 0x010f #LATIN SMALL LETTER D WITH CARON +0xd5 0x0147 #LATIN CAPITAL LETTER N WITH CARON +0xd6 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE +0xd7 0x00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xd8 0x011b #LATIN SMALL LETTER E WITH CARON +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x0162 #LATIN CAPITAL LETTER T WITH CEDILLA +0xde 0x016e #LATIN CAPITAL LETTER U WITH RING ABOVE +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE +0xe1 0x00df #LATIN SMALL LETTER SHARP S +0xe2 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xe3 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE +0xe4 0x0144 #LATIN SMALL LETTER N WITH ACUTE +0xe5 0x0148 #LATIN SMALL LETTER N WITH CARON +0xe6 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0xe7 0x0161 #LATIN SMALL LETTER S WITH CARON +0xe8 0x0154 #LATIN CAPITAL LETTER R WITH ACUTE +0xe9 0x00da #LATIN CAPITAL LETTER U WITH ACUTE +0xea 0x0155 #LATIN SMALL LETTER R WITH ACUTE +0xeb 0x0170 #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xec 0x00fd #LATIN SMALL LETTER Y WITH ACUTE +0xed 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE +0xee 0x0163 #LATIN SMALL LETTER T WITH CEDILLA +0xef 0x00b4 #ACUTE ACCENT +0xf0 0x00ad #SOFT HYPHEN +0xf1 0x02dd #DOUBLE ACUTE ACCENT +0xf2 0x02db #OGONEK +0xf3 0x02c7 #CARON +0xf4 0x02d8 #BREVE +0xf5 0x00a7 #SECTION SIGN +0xf6 0x00f7 #DIVISION SIGN +0xf7 0x00b8 #CEDILLA +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x00a8 #DIAERESIS +0xfa 0x02d9 #DOT ABOVE +0xfb 0x0171 #LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xfc 0x0158 #LATIN CAPITAL LETTER R WITH CARON +0xfd 0x0159 #LATIN SMALL LETTER R WITH CARON +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE diff --git a/Resources/cp862.txt b/Resources/cp862.txt new file mode 100644 index 0000000..e2a4f47 --- /dev/null +++ b/Resources/cp862.txt @@ -0,0 +1,273 @@ +# +# Name: cp862_DOSHebrew to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp862_DOSHebrew code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp862_DOSHebrew order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x05d0 #HEBREW LETTER ALEF +0x81 0x05d1 #HEBREW LETTER BET +0x82 0x05d2 #HEBREW LETTER GIMEL +0x83 0x05d3 #HEBREW LETTER DALET +0x84 0x05d4 #HEBREW LETTER HE +0x85 0x05d5 #HEBREW LETTER VAV +0x86 0x05d6 #HEBREW LETTER ZAYIN +0x87 0x05d7 #HEBREW LETTER HET +0x88 0x05d8 #HEBREW LETTER TET +0x89 0x05d9 #HEBREW LETTER YOD +0x8a 0x05da #HEBREW LETTER FINAL KAF +0x8b 0x05db #HEBREW LETTER KAF +0x8c 0x05dc #HEBREW LETTER LAMED +0x8d 0x05dd #HEBREW LETTER FINAL MEM +0x8e 0x05de #HEBREW LETTER MEM +0x8f 0x05df #HEBREW LETTER FINAL NUN +0x90 0x05e0 #HEBREW LETTER NUN +0x91 0x05e1 #HEBREW LETTER SAMEKH +0x92 0x05e2 #HEBREW LETTER AYIN +0x93 0x05e3 #HEBREW LETTER FINAL PE +0x94 0x05e4 #HEBREW LETTER PE +0x95 0x05e5 #HEBREW LETTER FINAL TSADI +0x96 0x05e6 #HEBREW LETTER TSADI +0x97 0x05e7 #HEBREW LETTER QOF +0x98 0x05e8 #HEBREW LETTER RESH +0x99 0x05e9 #HEBREW LETTER SHIN +0x9a 0x05ea #HEBREW LETTER TAV +0x9b 0x00a2 #CENT SIGN +0x9c 0x00a3 #POUND SIGN +0x9d 0x00a5 #YEN SIGN +0x9e 0x20a7 #PESETA SIGN +0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK +0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE +0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE +0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE +0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE +0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE +0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE +0xa6 0x00aa #FEMININE ORDINAL INDICATOR +0xa7 0x00ba #MASCULINE ORDINAL INDICATOR +0xa8 0x00bf #INVERTED QUESTION MARK +0xa9 0x2310 #REVERSED NOT SIGN +0xaa 0x00ac #NOT SIGN +0xab 0x00bd #VULGAR FRACTION ONE HALF +0xac 0x00bc #VULGAR FRACTION ONE QUARTER +0xad 0x00a1 #INVERTED EXCLAMATION MARK +0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x258c #LEFT HALF BLOCK +0xde 0x2590 #RIGHT HALF BLOCK +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x03b1 #GREEK SMALL LETTER ALPHA +0xe1 0x00df #LATIN SMALL LETTER SHARP S (GERMAN) +0xe2 0x0393 #GREEK CAPITAL LETTER GAMMA +0xe3 0x03c0 #GREEK SMALL LETTER PI +0xe4 0x03a3 #GREEK CAPITAL LETTER SIGMA +0xe5 0x03c3 #GREEK SMALL LETTER SIGMA +0xe6 0x00b5 #MICRO SIGN +0xe7 0x03c4 #GREEK SMALL LETTER TAU +0xe8 0x03a6 #GREEK CAPITAL LETTER PHI +0xe9 0x0398 #GREEK CAPITAL LETTER THETA +0xea 0x03a9 #GREEK CAPITAL LETTER OMEGA +0xeb 0x03b4 #GREEK SMALL LETTER DELTA +0xec 0x221e #INFINITY +0xed 0x03c6 #GREEK SMALL LETTER PHI +0xee 0x03b5 #GREEK SMALL LETTER EPSILON +0xef 0x2229 #INTERSECTION +0xf0 0x2261 #IDENTICAL TO +0xf1 0x00b1 #PLUS-MINUS SIGN +0xf2 0x2265 #GREATER-THAN OR EQUAL TO +0xf3 0x2264 #LESS-THAN OR EQUAL TO +0xf4 0x2320 #TOP HALF INTEGRAL +0xf5 0x2321 #BOTTOM HALF INTEGRAL +0xf6 0x00f7 #DIVISION SIGN +0xf7 0x2248 #ALMOST EQUAL TO +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x2219 #BULLET OPERATOR +0xfa 0x00b7 #MIDDLE DOT +0xfb 0x221a #SQUARE ROOT +0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N +0xfd 0x00b2 #SUPERSCRIPT TWO +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE diff --git a/Resources/cp864.txt b/Resources/cp864.txt new file mode 100644 index 0000000..b20aba5 --- /dev/null +++ b/Resources/cp864.txt @@ -0,0 +1,273 @@ +# +# Name: cp864_DOSArabic to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp864_DOSArabic code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp864_DOSArabic order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x066a #ARABIC PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x00b0 #DEGREE SIGN +0x81 0x00b7 #MIDDLE DOT +0x82 0x2219 #BULLET OPERATOR +0x83 0x221a #SQUARE ROOT +0x84 0x2592 #MEDIUM SHADE +0x85 0x2500 #FORMS LIGHT HORIZONTAL +0x86 0x2502 #FORMS LIGHT VERTICAL +0x87 0x253c #FORMS LIGHT VERTICAL AND HORIZONTAL +0x88 0x2524 #FORMS LIGHT VERTICAL AND LEFT +0x89 0x252c #FORMS LIGHT DOWN AND HORIZONTAL +0x8a 0x251c #FORMS LIGHT VERTICAL AND RIGHT +0x8b 0x2534 #FORMS LIGHT UP AND HORIZONTAL +0x8c 0x2510 #FORMS LIGHT DOWN AND LEFT +0x8d 0x250c #FORMS LIGHT DOWN AND RIGHT +0x8e 0x2514 #FORMS LIGHT UP AND RIGHT +0x8f 0x2518 #FORMS LIGHT UP AND LEFT +0x90 0x03b2 #GREEK SMALL BETA +0x91 0x221e #INFINITY +0x92 0x03c6 #GREEK SMALL PHI +0x93 0x00b1 #PLUS-OR-MINUS SIGN +0x94 0x00bd #FRACTION 1/2 +0x95 0x00bc #FRACTION 1/4 +0x96 0x2248 #ALMOST EQUAL TO +0x97 0x00ab #LEFT POINTING GUILLEMET +0x98 0x00bb #RIGHT POINTING GUILLEMET +0x99 0xfef7 #ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM +0x9a 0xfef8 #ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM +0x9b #UNDEFINED +0x9c #UNDEFINED +0x9d 0xfefb #ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM +0x9e 0xfefc #ARABIC LIGATURE LAM WITH ALEF FINAL FORM +0x9f #UNDEFINED +0xa0 0x00a0 #NON-BREAKING SPACE +0xa1 0x00ad #SOFT HYPHEN +0xa2 0xfe82 #ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM +0xa3 0x00a3 #POUND SIGN +0xa4 0x00a4 #CURRENCY SIGN +0xa5 0xfe84 #ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM +0xa6 #UNDEFINED +0xa7 #UNDEFINED +0xa8 0xfe8e #ARABIC LETTER ALEF FINAL FORM +0xa9 0xfe8f #ARABIC LETTER BEH ISOLATED FORM +0xaa 0xfe95 #ARABIC LETTER TEH ISOLATED FORM +0xab 0xfe99 #ARABIC LETTER THEH ISOLATED FORM +0xac 0x060c #ARABIC COMMA +0xad 0xfe9d #ARABIC LETTER JEEM ISOLATED FORM +0xae 0xfea1 #ARABIC LETTER HAH ISOLATED FORM +0xaf 0xfea5 #ARABIC LETTER KHAH ISOLATED FORM +0xb0 0x0660 #ARABIC-INDIC DIGIT ZERO +0xb1 0x0661 #ARABIC-INDIC DIGIT ONE +0xb2 0x0662 #ARABIC-INDIC DIGIT TWO +0xb3 0x0663 #ARABIC-INDIC DIGIT THREE +0xb4 0x0664 #ARABIC-INDIC DIGIT FOUR +0xb5 0x0665 #ARABIC-INDIC DIGIT FIVE +0xb6 0x0666 #ARABIC-INDIC DIGIT SIX +0xb7 0x0667 #ARABIC-INDIC DIGIT SEVEN +0xb8 0x0668 #ARABIC-INDIC DIGIT EIGHT +0xb9 0x0669 #ARABIC-INDIC DIGIT NINE +0xba 0xfed1 #ARABIC LETTER FEH ISOLATED FORM +0xbb 0x061b #ARABIC SEMICOLON +0xbc 0xfeb1 #ARABIC LETTER SEEN ISOLATED FORM +0xbd 0xfeb5 #ARABIC LETTER SHEEN ISOLATED FORM +0xbe 0xfeb9 #ARABIC LETTER SAD ISOLATED FORM +0xbf 0x061f #ARABIC QUESTION MARK +0xc0 0x00a2 #CENT SIGN +0xc1 0xfe80 #ARABIC LETTER HAMZA ISOLATED FORM +0xc2 0xfe81 #ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM +0xc3 0xfe83 #ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM +0xc4 0xfe85 #ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM +0xc5 0xfeca #ARABIC LETTER AIN FINAL FORM +0xc6 0xfe8b #ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM +0xc7 0xfe8d #ARABIC LETTER ALEF ISOLATED FORM +0xc8 0xfe91 #ARABIC LETTER BEH INITIAL FORM +0xc9 0xfe93 #ARABIC LETTER TEH MARBUTA ISOLATED FORM +0xca 0xfe97 #ARABIC LETTER TEH INITIAL FORM +0xcb 0xfe9b #ARABIC LETTER THEH INITIAL FORM +0xcc 0xfe9f #ARABIC LETTER JEEM INITIAL FORM +0xcd 0xfea3 #ARABIC LETTER HAH INITIAL FORM +0xce 0xfea7 #ARABIC LETTER KHAH INITIAL FORM +0xcf 0xfea9 #ARABIC LETTER DAL ISOLATED FORM +0xd0 0xfeab #ARABIC LETTER THAL ISOLATED FORM +0xd1 0xfead #ARABIC LETTER REH ISOLATED FORM +0xd2 0xfeaf #ARABIC LETTER ZAIN ISOLATED FORM +0xd3 0xfeb3 #ARABIC LETTER SEEN INITIAL FORM +0xd4 0xfeb7 #ARABIC LETTER SHEEN INITIAL FORM +0xd5 0xfebb #ARABIC LETTER SAD INITIAL FORM +0xd6 0xfebf #ARABIC LETTER DAD INITIAL FORM +0xd7 0xfec1 #ARABIC LETTER TAH ISOLATED FORM +0xd8 0xfec5 #ARABIC LETTER ZAH ISOLATED FORM +0xd9 0xfecb #ARABIC LETTER AIN INITIAL FORM +0xda 0xfecf #ARABIC LETTER GHAIN INITIAL FORM +0xdb 0x00a6 #BROKEN VERTICAL BAR +0xdc 0x00ac #NOT SIGN +0xdd 0x00f7 #DIVISION SIGN +0xde 0x00d7 #MULTIPLICATION SIGN +0xdf 0xfec9 #ARABIC LETTER AIN ISOLATED FORM +0xe0 0x0640 #ARABIC TATWEEL +0xe1 0xfed3 #ARABIC LETTER FEH INITIAL FORM +0xe2 0xfed7 #ARABIC LETTER QAF INITIAL FORM +0xe3 0xfedb #ARABIC LETTER KAF INITIAL FORM +0xe4 0xfedf #ARABIC LETTER LAM INITIAL FORM +0xe5 0xfee3 #ARABIC LETTER MEEM INITIAL FORM +0xe6 0xfee7 #ARABIC LETTER NOON INITIAL FORM +0xe7 0xfeeb #ARABIC LETTER HEH INITIAL FORM +0xe8 0xfeed #ARABIC LETTER WAW ISOLATED FORM +0xe9 0xfeef #ARABIC LETTER ALEF MAKSURA ISOLATED FORM +0xea 0xfef3 #ARABIC LETTER YEH INITIAL FORM +0xeb 0xfebd #ARABIC LETTER DAD ISOLATED FORM +0xec 0xfecc #ARABIC LETTER AIN MEDIAL FORM +0xed 0xfece #ARABIC LETTER GHAIN FINAL FORM +0xee 0xfecd #ARABIC LETTER GHAIN ISOLATED FORM +0xef 0xfee1 #ARABIC LETTER MEEM ISOLATED FORM +0xf0 0xfe7d #ARABIC SHADDA MEDIAL FORM +0xf1 0x0651 #ARABIC SHADDAH +0xf2 0xfee5 #ARABIC LETTER NOON ISOLATED FORM +0xf3 0xfee9 #ARABIC LETTER HEH ISOLATED FORM +0xf4 0xfeec #ARABIC LETTER HEH MEDIAL FORM +0xf5 0xfef0 #ARABIC LETTER ALEF MAKSURA FINAL FORM +0xf6 0xfef2 #ARABIC LETTER YEH FINAL FORM +0xf7 0xfed0 #ARABIC LETTER GHAIN MEDIAL FORM +0xf8 0xfed5 #ARABIC LETTER QAF ISOLATED FORM +0xf9 0xfef5 #ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM +0xfa 0xfef6 #ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM +0xfb 0xfedd #ARABIC LETTER LAM ISOLATED FORM +0xfc 0xfed9 #ARABIC LETTER KAF ISOLATED FORM +0xfd 0xfef1 #ARABIC LETTER YEH ISOLATED FORM +0xfe 0x25a0 #BLACK SQUARE +0xff #UNDEFINED diff --git a/Resources/cp866.txt b/Resources/cp866.txt new file mode 100644 index 0000000..94e03b0 --- /dev/null +++ b/Resources/cp866.txt @@ -0,0 +1,273 @@ +# +# Name: cp866_DOSCyrillicRussian to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell +# K.D. Chang +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp866_DOSCyrillicRussian code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp866_DOSCyrillicRussian order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x0410 #CYRILLIC CAPITAL LETTER A +0x81 0x0411 #CYRILLIC CAPITAL LETTER BE +0x82 0x0412 #CYRILLIC CAPITAL LETTER VE +0x83 0x0413 #CYRILLIC CAPITAL LETTER GHE +0x84 0x0414 #CYRILLIC CAPITAL LETTER DE +0x85 0x0415 #CYRILLIC CAPITAL LETTER IE +0x86 0x0416 #CYRILLIC CAPITAL LETTER ZHE +0x87 0x0417 #CYRILLIC CAPITAL LETTER ZE +0x88 0x0418 #CYRILLIC CAPITAL LETTER I +0x89 0x0419 #CYRILLIC CAPITAL LETTER SHORT I +0x8a 0x041a #CYRILLIC CAPITAL LETTER KA +0x8b 0x041b #CYRILLIC CAPITAL LETTER EL +0x8c 0x041c #CYRILLIC CAPITAL LETTER EM +0x8d 0x041d #CYRILLIC CAPITAL LETTER EN +0x8e 0x041e #CYRILLIC CAPITAL LETTER O +0x8f 0x041f #CYRILLIC CAPITAL LETTER PE +0x90 0x0420 #CYRILLIC CAPITAL LETTER ER +0x91 0x0421 #CYRILLIC CAPITAL LETTER ES +0x92 0x0422 #CYRILLIC CAPITAL LETTER TE +0x93 0x0423 #CYRILLIC CAPITAL LETTER U +0x94 0x0424 #CYRILLIC CAPITAL LETTER EF +0x95 0x0425 #CYRILLIC CAPITAL LETTER HA +0x96 0x0426 #CYRILLIC CAPITAL LETTER TSE +0x97 0x0427 #CYRILLIC CAPITAL LETTER CHE +0x98 0x0428 #CYRILLIC CAPITAL LETTER SHA +0x99 0x0429 #CYRILLIC CAPITAL LETTER SHCHA +0x9a 0x042a #CYRILLIC CAPITAL LETTER HARD SIGN +0x9b 0x042b #CYRILLIC CAPITAL LETTER YERU +0x9c 0x042c #CYRILLIC CAPITAL LETTER SOFT SIGN +0x9d 0x042d #CYRILLIC CAPITAL LETTER E +0x9e 0x042e #CYRILLIC CAPITAL LETTER YU +0x9f 0x042f #CYRILLIC CAPITAL LETTER YA +0xa0 0x0430 #CYRILLIC SMALL LETTER A +0xa1 0x0431 #CYRILLIC SMALL LETTER BE +0xa2 0x0432 #CYRILLIC SMALL LETTER VE +0xa3 0x0433 #CYRILLIC SMALL LETTER GHE +0xa4 0x0434 #CYRILLIC SMALL LETTER DE +0xa5 0x0435 #CYRILLIC SMALL LETTER IE +0xa6 0x0436 #CYRILLIC SMALL LETTER ZHE +0xa7 0x0437 #CYRILLIC SMALL LETTER ZE +0xa8 0x0438 #CYRILLIC SMALL LETTER I +0xa9 0x0439 #CYRILLIC SMALL LETTER SHORT I +0xaa 0x043a #CYRILLIC SMALL LETTER KA +0xab 0x043b #CYRILLIC SMALL LETTER EL +0xac 0x043c #CYRILLIC SMALL LETTER EM +0xad 0x043d #CYRILLIC SMALL LETTER EN +0xae 0x043e #CYRILLIC SMALL LETTER O +0xaf 0x043f #CYRILLIC SMALL LETTER PE +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x258c #LEFT HALF BLOCK +0xde 0x2590 #RIGHT HALF BLOCK +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x0440 #CYRILLIC SMALL LETTER ER +0xe1 0x0441 #CYRILLIC SMALL LETTER ES +0xe2 0x0442 #CYRILLIC SMALL LETTER TE +0xe3 0x0443 #CYRILLIC SMALL LETTER U +0xe4 0x0444 #CYRILLIC SMALL LETTER EF +0xe5 0x0445 #CYRILLIC SMALL LETTER HA +0xe6 0x0446 #CYRILLIC SMALL LETTER TSE +0xe7 0x0447 #CYRILLIC SMALL LETTER CHE +0xe8 0x0448 #CYRILLIC SMALL LETTER SHA +0xe9 0x0449 #CYRILLIC SMALL LETTER SHCHA +0xea 0x044a #CYRILLIC SMALL LETTER HARD SIGN +0xeb 0x044b #CYRILLIC SMALL LETTER YERU +0xec 0x044c #CYRILLIC SMALL LETTER SOFT SIGN +0xed 0x044d #CYRILLIC SMALL LETTER E +0xee 0x044e #CYRILLIC SMALL LETTER YU +0xef 0x044f #CYRILLIC SMALL LETTER YA +0xf0 0x0401 #CYRILLIC CAPITAL LETTER IO +0xf1 0x0451 #CYRILLIC SMALL LETTER IO +0xf2 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xf3 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE +0xf4 0x0407 #CYRILLIC CAPITAL LETTER YI +0xf5 0x0457 #CYRILLIC SMALL LETTER YI +0xf6 0x040e #CYRILLIC CAPITAL LETTER SHORT U +0xf7 0x045e #CYRILLIC SMALL LETTER SHORT U +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x2219 #BULLET OPERATOR +0xfa 0x00b7 #MIDDLE DOT +0xfb 0x221a #SQUARE ROOT +0xfc 0x2116 #NUMERO SIGN +0xfd 0x00a4 #CURRENCY SIGN +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE diff --git a/Resources/fontnames b/Resources/fontnames new file mode 100644 index 0000000..bb710d2 --- /dev/null +++ b/Resources/fontnames @@ -0,0 +1,117 @@ +# Default fontnames translation table +# uses only Standard PostScript (TM) fonts +# +# MS-Word fontname, Italic, Bold, PostScript fontname, Special +Arial, 0, 0, Helvetica, 0 +Arial, 0, 1, Helvetica-Bold, 0 +Arial, 1, 0, Helvetica-Oblique, 0 +Arial, 1, 1, Helvetica-BoldOblique, 0 +Arial Black, 0, 0, Helvetica, 0 +Arial Black, 0, 1, Helvetica-Bold, 0 +Arial Black, 1, 0, Helvetica-Oblique, 0 +Arial Black, 1, 1, Helvetica-BoldOblique, 0 +Arial CE, 0, 0, Helvetica, 0 +Arial CE, 0, 1, Helvetica-Bold, 0 +Arial CE, 1, 0, Helvetica-Oblique, 0 +Arial CE, 1, 1, Helvetica-BoldOblique, 0 +Arial Narrow, 0, 0, Helvetica-Narrow, 0 +Arial Narrow, 0, 1, Helvetica-Narrow-Bold, 0 +Arial Narrow, 1, 0, Helvetica-Narrow-Oblique, 0 +Arial Narrow, 1, 1, Helvetica-Narrow-BoldOblique, 0 +AvantGarde, 0, 0, AvantGarde-Book, 0 +AvantGarde, 0, 1, AvantGarde-Demi, 0 +AvantGarde, 1, 0, AvantGarde-BookOblique, 0 +AvantGarde, 1, 1, AvantGarde-DemiOblique, 0 +Bookman Old Style, 0, 0, Bookman-Light, 0 +Bookman Old Style, 0, 1, Bookman-Demi, 0 +Bookman Old Style, 1, 0, Bookman-LightItalic, 0 +Bookman Old Style, 1, 1, Bookman-DemiItalic, 0 +Century Schoolbook, 0, 0, NewCenturySchlbk-Roman, 0 +Century Schoolbook, 0, 1, NewCenturySchlbk-Bold, 0 +Century Schoolbook, 1, 0, NewCenturySchlbk-Italic, 0 +Century Schoolbook, 1, 1, NewCenturySchlbk-BoldItalic, 0 +CG Omega, 0, 0, Helvetica, 0 +CG Omega, 0, 1, Helvetica-Bold, 0 +CG Omega, 1, 0, Helvetica-Oblique, 0 +CG Omega, 1, 1, Helvetica-BoldOblique, 0 +Comic Sans MS, 0, 0, Helvetica, 0 +Comic Sans MS, 0, 1, Helvetica-Bold, 0 +Comic Sans MS, 1, 0, Helvetica-Oblique, 0 +Comic Sans MS, 1, 1, Helvetica-BoldOblique, 0 +Courier, 0, 0, Courier, 0 +Courier, 0, 1, Courier-Bold, 0 +Courier, 1, 0, Courier-Oblique, 0 +Courier, 1, 1, Courier-BoldOblique, 0 +Courier New, 0, 0, Courier, 0 +Courier New, 0, 1, Courier-Bold, 0 +Courier New, 1, 0, Courier-Oblique, 0 +Courier New, 1, 1, Courier-BoldOblique, 0 +Fixedsys, 0, 0, Courier, 0 +Fixedsys, 0, 1, Courier-Bold, 0 +Fixedsys, 1, 0, Courier-Oblique, 0 +Fixedsys, 1, 1, Courier-BoldOblique, 0 +Helvetica, 0, 0, Helvetica, 0 +Helvetica, 0, 1, Helvetica-Bold, 0 +Helvetica, 1, 0, Helvetica-Oblique, 0 +Helvetica, 1, 1, Helvetica-BoldOblique, 0 +Helvetica-Narrow, 0, 0, Helvetica-Narrow, 0 +Helvetica-Narrow, 0, 1, Helvetica-Narrow-Bold, 0 +Helvetica-Narrow, 1, 0, Helvetica-Narrow-Oblique, 0 +Helvetica-Narrow, 1, 1, Helvetica-Narrow-BoldOblique, 0 +ITC Bookman, 0, 0, Bookman-Light, 0 +ITC Bookman, 0, 1, Bookman-Demi, 0 +ITC Bookman, 1, 0, Bookman-LightItalic, 0 +ITC Bookman, 1, 1, Bookman-DemiItalic, 0 +Lucida Console, 0, 0, Courier, 0 +Lucida Console, 0, 1, Courier-Bold, 0 +Lucida Console, 1, 0, Courier-Oblique, 0 +Lucida Console, 1, 1, Courier-BoldOblique, 0 +Lucida Sans Typewriter, 0, 0, Courier, 0 +Lucida Sans Typewriter, 0, 1, Courier-Bold, 0 +Lucida Sans Typewriter, 1, 0, Courier-Oblique, 0 +Lucida Sans Typewriter, 1, 1, Courier-BoldOblique, 0 +Monotype.com, 0, 0, Courier, 0 +Monotype.com, 0, 1, Courier-Bold, 0 +Monotype.com, 1, 0, Courier-Oblique, 0 +Monotype.com, 1, 1, Courier-BoldOblique, 0 +MS Sans Serif, 0, 0, Helvetica, 0 +MS Sans Serif, 0, 1, Helvetica-Bold, 0 +MS Sans Serif, 1, 0, Helvetica-Oblique, 0 +MS Sans Serif, 1, 1, Helvetica-BoldOblique, 0 +New Century Schlbk, 0, 0, NewCenturySchlbk-Roman, 0 +New Century Schlbk, 0, 1, NewCenturySchlbk-Bold, 0 +New Century Schlbk, 1, 0, NewCenturySchlbk-Italic, 0 +New Century Schlbk, 1, 1, NewCenturySchlbk-BoldItalic, 0 +NewCenturySchlbk, 0, 0, NewCenturySchlbk-Roman, 0 +NewCenturySchlbk, 0, 1, NewCenturySchlbk-Bold, 0 +NewCenturySchlbk, 1, 0, NewCenturySchlbk-Italic, 0 +NewCenturySchlbk, 1, 1, NewCenturySchlbk-BoldItalic, 0 +Palatino, 0, 0, Palatino-Roman, 0 +Palatino, 0, 1, Palatino-Bold, 0 +Palatino, 1, 0, Palatino-Italic, 0 +Palatino, 1, 1, Palatino-BoldItalic, 0 +Swiss, 0, 0, Helvetica, 0 +Swiss, 0, 1, Helvetica-Bold, 0 +Swiss, 1, 0, Helvetica-Oblique, 0 +Swiss, 1, 1, Helvetica-BoldOblique, 0 +Tahoma, 0, 0, Helvetica, 0 +Tahoma, 0, 1, Helvetica-Bold, 0 +Tahoma, 1, 0, Helvetica-Oblique, 0 +Tahoma, 1, 1, Helvetica-BoldOblique, 0 +Trebuchet MS, 0, 0, Helvetica, 0 +Trebuchet MS, 0, 1, Helvetica-Bold, 0 +Trebuchet MS, 1, 0, Helvetica-Oblique, 0 +Trebuchet MS, 1, 1, Helvetica-BoldOblique, 0 +Univers, 0, 0, Helvetica, 0 +Univers, 0, 1, Helvetica-Bold, 0 +Univers, 1, 0, Helvetica-Oblique, 0 +Univers, 1, 1, Helvetica-BoldOblique, 0 +Verdana, 0, 0, Helvetica, 0 +Verdana, 0, 1, Helvetica-Bold, 0 +Verdana, 1, 0, Helvetica-Oblique, 0 +Verdana, 1, 1, Helvetica-BoldOblique, 0 +# All the other fonts +*, 0, 0, Times-Roman, 0 +*, 0, 1, Times-Bold, 0 +*, 1, 0, Times-Italic, 0 +*, 1, 1, Times-BoldItalic, 0 diff --git a/Resources/fontnames.russian b/Resources/fontnames.russian new file mode 100644 index 0000000..fb21c56 --- /dev/null +++ b/Resources/fontnames.russian @@ -0,0 +1,43 @@ +# Default fontnames translation table +# for Cyrillic +# +# by: Dmitry Chernyak +# +# MS-Word fontname, Italic, Bold, PostScript fontname, Special +Arial, 0, 0, ArialCyrMT, 0 +Arial, 0, 1, ArialCyrMT-Bold, 0 +Arial, 1, 0, ArialCyrMT-Italic, 0 +Arial, 1, 1, ArialCyrMT-BoldItalic, 0 +Courier, 0, 0, CourierCyrPS, 0 +Courier, 0, 1, CourierCyrPS-Bold, 0 +Courier, 1, 0, CourierCyrPS-Inclined, 0 +Courier, 1, 1, CourierCyrPS-BoldInclined, 0 +Courier New, 0, 0, CourierCyrPS, 0 +Courier New, 0, 1, CourierCyrPS-Bold, 0 +Courier New, 1, 0, CourierCyrPS-Inclined, 0 +Courier New, 1, 1, CourierCyrPS-BoldInclined, 0 +Fixedsys, 0, 0, CourierCyrPS, 0 +Fixedsys, 0, 1, CourierCyrPS-Bold, 0 +Fixedsys, 1, 0, CourierCyrPS-Inclined, 0 +Fixedsys, 1, 1, CourierCyrPS-BoldInclined, 0 +Helvetica, 0, 0, ArialCyrMT, 0 +Helvetica, 0, 1, ArialCyrMT-Bold, 0 +Helvetica, 1, 0, ArialCyrMT-Italic, 0 +Helvetica, 1, 1, ArialCyrMT-BoldItalic, 0 +Lucida Console, 0, 0, CourierCyrPS, 0 +Lucida Console, 0, 1, CourierCyrPS-Bold, 0 +Lucida Console, 1, 0, CourierCyrPS-Inclined, 0 +Lucida Console, 1, 1, CourierCyrPS-BoldInclined, 0 +Swiss, 0, 0, Helvetica, 0 +Swiss, 0, 1, Helvetica-Bold, 0 +Swiss, 1, 0, Helvetica-Oblique, 0 +Swiss, 1, 1, Helvetica-BoldOblique, 0 +Univers, 0, 0, Helvetica, 0 +Univers, 0, 1, Helvetica-Bold, 0 +Univers, 1, 0, Helvetica-Oblique, 0 +Univers, 1, 1, Helvetica-BoldOblique, 0 +# All the other fonts +*, 0, 0, TimesNRCyrMT, 0 +*, 0, 1, TimesNRCyrMT-Bold, 0 +*, 1, 0, TimesNRCyrMT-Inclined, 0 +*, 1, 1, TimesNRCyrMT-BoldInclined, 0 diff --git a/Resources/koi8-r.txt b/Resources/koi8-r.txt new file mode 100644 index 0000000..5105610 --- /dev/null +++ b/Resources/koi8-r.txt @@ -0,0 +1,302 @@ +# +# Name: KOI8-R (RFC1489) to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 18 August 1999 +# Authors: Helmut Richter +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# KOI8-R characters map into Unicode. The underlying document is the +# mapping described in RFC 1489. No statements are made as to whether +# this mapping is the same as the mapping defined as "Code Page 878" +# with some vendors. +# +# Format: Three tab-separated columns +# Column #1 is the KOI8-R code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in KOI8-R order. +# +# Version history +# 1.0 version: created. +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL +0x81 0x2502 # BOX DRAWINGS LIGHT VERTICAL +0x82 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT +0x83 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT +0x84 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT +0x85 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT +0x86 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0x87 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT +0x88 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0x89 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL +0x8A 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0x8B 0x2580 # UPPER HALF BLOCK +0x8C 0x2584 # LOWER HALF BLOCK +0x8D 0x2588 # FULL BLOCK +0x8E 0x258C # LEFT HALF BLOCK +0x8F 0x2590 # RIGHT HALF BLOCK +0x90 0x2591 # LIGHT SHADE +0x91 0x2592 # MEDIUM SHADE +0x92 0x2593 # DARK SHADE +0x93 0x2320 # TOP HALF INTEGRAL +0x94 0x25A0 # BLACK SQUARE +0x95 0x2219 # BULLET OPERATOR +0x96 0x221A # SQUARE ROOT +0x97 0x2248 # ALMOST EQUAL TO +0x98 0x2264 # LESS-THAN OR EQUAL TO +0x99 0x2265 # GREATER-THAN OR EQUAL TO +0x9A 0x00A0 # NO-BREAK SPACE +0x9B 0x2321 # BOTTOM HALF INTEGRAL +0x9C 0x00B0 # DEGREE SIGN +0x9D 0x00B2 # SUPERSCRIPT TWO +0x9E 0x00B7 # MIDDLE DOT +0x9F 0x00F7 # DIVISION SIGN +0xA0 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL +0xA1 0x2551 # BOX DRAWINGS DOUBLE VERTICAL +0xA2 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xA3 0x0451 # CYRILLIC SMALL LETTER IO +0xA4 0x2553 # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xA5 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xA6 0x2555 # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xA7 0x2556 # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xA8 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT +0xA9 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xAA 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xAB 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT +0xAC 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xAD 0x255C # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xAE 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT +0xAF 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xB0 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xB1 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xB2 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO +0xB4 0x2562 # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xB5 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xB6 0x2564 # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xB7 0x2565 # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xB8 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xB9 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xBA 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xBB 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xBC 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xBD 0x256B # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xBE 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xBF 0x00A9 # COPYRIGHT SIGN +0xC0 0x044E # CYRILLIC SMALL LETTER YU +0xC1 0x0430 # CYRILLIC SMALL LETTER A +0xC2 0x0431 # CYRILLIC SMALL LETTER BE +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE +0xC4 0x0434 # CYRILLIC SMALL LETTER DE +0xC5 0x0435 # CYRILLIC SMALL LETTER IE +0xC6 0x0444 # CYRILLIC SMALL LETTER EF +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE +0xC8 0x0445 # CYRILLIC SMALL LETTER HA +0xC9 0x0438 # CYRILLIC SMALL LETTER I +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I +0xCB 0x043A # CYRILLIC SMALL LETTER KA +0xCC 0x043B # CYRILLIC SMALL LETTER EL +0xCD 0x043C # CYRILLIC SMALL LETTER EM +0xCE 0x043D # CYRILLIC SMALL LETTER EN +0xCF 0x043E # CYRILLIC SMALL LETTER O +0xD0 0x043F # CYRILLIC SMALL LETTER PE +0xD1 0x044F # CYRILLIC SMALL LETTER YA +0xD2 0x0440 # CYRILLIC SMALL LETTER ER +0xD3 0x0441 # CYRILLIC SMALL LETTER ES +0xD4 0x0442 # CYRILLIC SMALL LETTER TE +0xD5 0x0443 # CYRILLIC SMALL LETTER U +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE +0xD7 0x0432 # CYRILLIC SMALL LETTER VE +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN +0xD9 0x044B # CYRILLIC SMALL LETTER YERU +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA +0xDC 0x044D # CYRILLIC SMALL LETTER E +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL +0xED 0x041C # CYRILLIC CAPITAL LETTER EM +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN +0xEF 0x041E # CYRILLIC CAPITAL LETTER O +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA +0xFC 0x042D # CYRILLIC CAPITAL LETTER E +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN diff --git a/Resources/koi8-u.txt b/Resources/koi8-u.txt new file mode 100644 index 0000000..61a5b40 --- /dev/null +++ b/Resources/koi8-u.txt @@ -0,0 +1,303 @@ +# +# Name: KOI8-U (RFC2319) to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 08 September 2001 +# Authors: Andriy Rysin +# +# Copyright (c) 1991-2001 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# KOI8-U characters map into Unicode. The underlying document is the +# mapping described in RFC 2319. No statements are made as to whether +# this mapping is the same as the mapping defined as "Code Page 878" +# with some vendors. +# +# Format: Three tab-separated columns +# Column #1 is the KOI8-U code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in KOI8-U order. +# +# Version history +# 1.0 version: created. +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL +0x81 0x2502 # BOX DRAWINGS LIGHT VERTICAL +0x82 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT +0x83 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT +0x84 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT +0x85 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT +0x86 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0x87 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT +0x88 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0x89 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL +0x8A 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0x8B 0x2580 # UPPER HALF BLOCK +0x8C 0x2584 # LOWER HALF BLOCK +0x8D 0x2588 # FULL BLOCK +0x8E 0x258C # LEFT HALF BLOCK +0x8F 0x2590 # RIGHT HALF BLOCK +0x90 0x2591 # LIGHT SHADE +0x91 0x2592 # MEDIUM SHADE +0x92 0x2593 # DARK SHADE +0x93 0x2320 # TOP HALF INTEGRAL +0x94 0x25A0 # BLACK SQUARE +0x95 0x2219 # BULLET OPERATOR +0x96 0x221A # SQUARE ROOT +0x97 0x2248 # ALMOST EQUAL TO +0x98 0x2264 # LESS-THAN OR EQUAL TO +0x99 0x2265 # GREATER-THAN OR EQUAL TO +0x9A 0x00A0 # NO-BREAK SPACE +0x9B 0x2321 # BOTTOM HALF INTEGRAL +0x9C 0x00B0 # DEGREE SIGN +0x9D 0x00B2 # SUPERSCRIPT TWO +0x9E 0x00B7 # MIDDLE DOT +0x9F 0x00F7 # DIVISION SIGN +0xA0 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL +0xA1 0x2551 # BOX DRAWINGS DOUBLE VERTICAL +0xA2 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xA3 0x0451 # CYRILLIC SMALL LETTER IO +0xA4 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE +0xA5 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xA6 0x0456 # CYRILLIC SMALL LETTER BELORUSSIAN-UKRAINIAN I +0xA7 0x0457 # CYRILLIC SMALL LETTER YI (UKRAINIAN) +0xA8 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT +0xA9 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xAA 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xAB 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT +0xAC 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xAD 0x0491 # CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN +0xAE 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT +0xAF 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xB0 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xB1 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xB2 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO +0xB4 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xB5 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xB6 0x0406 # CYRILLIC CAPITAL LETTER BELORUSSIAN-UKRAINIAN I +0xB7 0x0407 # CYRILLIC CAPITAL LETTER YI (UKRAINIAN) +0xB8 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xB9 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xBA 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xBB 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xBC 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xBD 0x0490 # CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN +0xBD 0x256B # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xBE 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xBF 0x00A9 # COPYRIGHT SIGN +0xC0 0x044E # CYRILLIC SMALL LETTER YU +0xC1 0x0430 # CYRILLIC SMALL LETTER A +0xC2 0x0431 # CYRILLIC SMALL LETTER BE +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE +0xC4 0x0434 # CYRILLIC SMALL LETTER DE +0xC5 0x0435 # CYRILLIC SMALL LETTER IE +0xC6 0x0444 # CYRILLIC SMALL LETTER EF +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE +0xC8 0x0445 # CYRILLIC SMALL LETTER HA +0xC9 0x0438 # CYRILLIC SMALL LETTER I +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I +0xCB 0x043A # CYRILLIC SMALL LETTER KA +0xCC 0x043B # CYRILLIC SMALL LETTER EL +0xCD 0x043C # CYRILLIC SMALL LETTER EM +0xCE 0x043D # CYRILLIC SMALL LETTER EN +0xCF 0x043E # CYRILLIC SMALL LETTER O +0xD0 0x043F # CYRILLIC SMALL LETTER PE +0xD1 0x044F # CYRILLIC SMALL LETTER YA +0xD2 0x0440 # CYRILLIC SMALL LETTER ER +0xD3 0x0441 # CYRILLIC SMALL LETTER ES +0xD4 0x0442 # CYRILLIC SMALL LETTER TE +0xD5 0x0443 # CYRILLIC SMALL LETTER U +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE +0xD7 0x0432 # CYRILLIC SMALL LETTER VE +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN +0xD9 0x044B # CYRILLIC SMALL LETTER YERU +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA +0xDC 0x044D # CYRILLIC SMALL LETTER E +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL +0xED 0x041C # CYRILLIC CAPITAL LETTER EM +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN +0xEF 0x041E # CYRILLIC CAPITAL LETTER O +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA +0xFC 0x042D # CYRILLIC CAPITAL LETTER E +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN diff --git a/Resources/roman.txt b/Resources/roman.txt new file mode 100644 index 0000000..d3ed19e --- /dev/null +++ b/Resources/roman.txt @@ -0,0 +1 @@ +#======================================================================= # FTP file name: ROMAN.TXT # # Contents: Map (external version) from Mac OS Roman # character set to Unicode 2.1 # # Copyright: (c) 1994-1999 by Apple Computer, Inc., all rights # reserved. # # Contact: charsets@apple.com # # Changes: # # b03 1999-Sep-22 Update contact e-mail address. Matches # internal utom, ufrm, and Text # Encoding Converter version 1.5. # b02 1998-Aug-18 Encoding changed for Mac OS 8.5; change # mapping of 0xDB from CURRENCY SIGN to # EURO SIGN. Matches internal utom, # ufrm. # n08 1998-Feb-05 Minor update to header comments # n06 1997-Dec-14 Add warning about future changes to 0xDB # from CURRENCY SIGN to EURO SIGN. Clarify # some header information # n04 1997-Dec-01 Update to match internal utom, ufrm: # Change standard mapping for 0xBD from U+2126 # to its canonical decomposition, U+03A9. # n03 1995-Apr-15 First version (after fixing some typos). # Matches internal ufrm. # # Standard header: # ---------------- # # Apple, the Apple logo, and Macintosh are trademarks of Apple # Computer, Inc., registered in the United States and other countries. # Unicode is a trademark of Unicode Inc. For the sake of brevity, # throughout this document, "Macintosh" can be used to refer to # Macintosh computers and "Unicode" can be used to refer to the # Unicode standard. # # Apple makes no warranty or representation, either express or # implied, with respect to these tables, their quality, accuracy, or # fitness for a particular purpose. In no event will Apple be liable # for direct, indirect, special, incidental, or consequential damages # resulting from any defect or inaccuracy in this document or the # accompanying tables. # # These mapping tables and character lists are subject to change. # The latest tables should be available from the following: # # # # # For general information about Mac OS encodings and these mapping # tables, see the file "README.TXT". # # Format: # ------- # # Three tab-separated columns; # '#' begins a comment which continues to the end of the line. # Column #1 is the Mac OS Roman code (in hex as 0xNN) # Column #2 is the corresponding Unicode (in hex as 0xNNNN) # Column #3 is a comment containing the Unicode name # # The entries are in Mac OS Roman code order. # # One of these mappings requires the use of a corporate character. # See the file "CORPCHAR.TXT" and notes below. # # Control character mappings are not shown in this table, following # the conventions of the standard UTC mapping tables. However, the # Mac OS Roman character set uses the standard control characters at # 0x00-0x1F and 0x7F. # # Notes on Mac OS Roman: # ---------------------- # # This character set is used for at least the following Mac OS # localizations: U.S., British, Canadian French, French, Swiss # French, German, Swiss German, Italian, Swiss Italian, Dutch, # Swedish, Norwegian, Danish, Finnish, Spanish, Catalan, # Portuguese, Brazilian, and the default International system. # # Variants of Mac OS Roman are used for Croatian, Icelandic, # Turkish, Romanian, and other encodings. Separate mapping tables # are available for these encodings. # # Before Mac OS 8.5, code point 0xDB was CURRENCY SIGN, and was # mapped to U+00A4. In Mac OS 8.5 and later versions, code point # 0xDB is changed to EURO SIGN and maps to U+20AC; the standard # Apple fonts are updated for Mac OS 8.5 to reflect this. There is # a "currency sign" variant of the Mac OS Roman encoding that still # maps 0xDB to U+00A4; this can be used for older fonts. # Note: U+20AC is new with Unicode 2.1; for earlier Unicode # versions, Mac OS Roman 0xDB may be mapped to private-use character # U+F8A0. # # Before Mac OS 8.5, the ROM bitmap versions of the fonts Chicago, # New York, Geneva, and Monaco did not implement the full Mac OS # Roman character set; they only supported character codes up to # 0xD8. The TrueType versions of these fonts have always implemented # the full character set, as with the bitmap and TrueType versions # of the other standard Roman fonts. # # In all Mac OS encodings, fonts such as Chicago which are used # as "system" fonts (for menus, dialogs, etc.) have four glyphs # at code points 0x11-0x14 for transient use by the Menu Manager. # These glyphs are not intended as characters for use in normal # text, and the associated code points are not generally # interpreted as associated with these glyphs; they are usually # interpreted (if at all) as the control codes DC1-DC4. # # Unicode mapping issues and notes: # --------------------------------- # # The following corporate zone Unicode character is used in this # mapping: # # 0xF8FF Apple logo # # NOTE: The graphic image associated with the Apple logo character # is not authorized for use without permission of Apple, and # unauthorized use might constitute trademark infringement. # # Details of mapping changes in each version: # ------------------------------------------- # # Changes from version n08 to version b02: # # - Encoding changed for Mac OS 8.5; change mapping of 0xDB from # CURRENCY SIGN (U+00A4) to EURO SIGN (U+20AC). # # Changes from version n03 to version n04: # # - Change mapping of 0xBD from U+2126 to its canonical # decomposition, U+03A9. # ################## 0x20 0x0020 # SPACE 0x21 0x0021 # EXCLAMATION MARK 0x22 0x0022 # QUOTATION MARK 0x23 0x0023 # NUMBER SIGN 0x24 0x0024 # DOLLAR SIGN 0x25 0x0025 # PERCENT SIGN 0x26 0x0026 # AMPERSAND 0x27 0x0027 # APOSTROPHE 0x28 0x0028 # LEFT PARENTHESIS 0x29 0x0029 # RIGHT PARENTHESIS 0x2A 0x002A # ASTERISK 0x2B 0x002B # PLUS SIGN 0x2C 0x002C # COMMA 0x2D 0x002D # HYPHEN-MINUS 0x2E 0x002E # FULL STOP 0x2F 0x002F # SOLIDUS 0x30 0x0030 # DIGIT ZERO 0x31 0x0031 # DIGIT ONE 0x32 0x0032 # DIGIT TWO 0x33 0x0033 # DIGIT THREE 0x34 0x0034 # DIGIT FOUR 0x35 0x0035 # DIGIT FIVE 0x36 0x0036 # DIGIT SIX 0x37 0x0037 # DIGIT SEVEN 0x38 0x0038 # DIGIT EIGHT 0x39 0x0039 # DIGIT NINE 0x3A 0x003A # COLON 0x3B 0x003B # SEMICOLON 0x3C 0x003C # LESS-THAN SIGN 0x3D 0x003D # EQUALS SIGN 0x3E 0x003E # GREATER-THAN SIGN 0x3F 0x003F # QUESTION MARK 0x40 0x0040 # COMMERCIAL AT 0x41 0x0041 # LATIN CAPITAL LETTER A 0x42 0x0042 # LATIN CAPITAL LETTER B 0x43 0x0043 # LATIN CAPITAL LETTER C 0x44 0x0044 # LATIN CAPITAL LETTER D 0x45 0x0045 # LATIN CAPITAL LETTER E 0x46 0x0046 # LATIN CAPITAL LETTER F 0x47 0x0047 # LATIN CAPITAL LETTER G 0x48 0x0048 # LATIN CAPITAL LETTER H 0x49 0x0049 # LATIN CAPITAL LETTER I 0x4A 0x004A # LATIN CAPITAL LETTER J 0x4B 0x004B # LATIN CAPITAL LETTER K 0x4C 0x004C # LATIN CAPITAL LETTER L 0x4D 0x004D # LATIN CAPITAL LETTER M 0x4E 0x004E # LATIN CAPITAL LETTER N 0x4F 0x004F # LATIN CAPITAL LETTER O 0x50 0x0050 # LATIN CAPITAL LETTER P 0x51 0x0051 # LATIN CAPITAL LETTER Q 0x52 0x0052 # LATIN CAPITAL LETTER R 0x53 0x0053 # LATIN CAPITAL LETTER S 0x54 0x0054 # LATIN CAPITAL LETTER T 0x55 0x0055 # LATIN CAPITAL LETTER U 0x56 0x0056 # LATIN CAPITAL LETTER V 0x57 0x0057 # LATIN CAPITAL LETTER W 0x58 0x0058 # LATIN CAPITAL LETTER X 0x59 0x0059 # LATIN CAPITAL LETTER Y 0x5A 0x005A # LATIN CAPITAL LETTER Z 0x5B 0x005B # LEFT SQUARE BRACKET 0x5C 0x005C # REVERSE SOLIDUS 0x5D 0x005D # RIGHT SQUARE BRACKET 0x5E 0x005E # CIRCUMFLEX ACCENT 0x5F 0x005F # LOW LINE 0x60 0x0060 # GRAVE ACCENT 0x61 0x0061 # LATIN SMALL LETTER A 0x62 0x0062 # LATIN SMALL LETTER B 0x63 0x0063 # LATIN SMALL LETTER C 0x64 0x0064 # LATIN SMALL LETTER D 0x65 0x0065 # LATIN SMALL LETTER E 0x66 0x0066 # LATIN SMALL LETTER F 0x67 0x0067 # LATIN SMALL LETTER G 0x68 0x0068 # LATIN SMALL LETTER H 0x69 0x0069 # LATIN SMALL LETTER I 0x6A 0x006A # LATIN SMALL LETTER J 0x6B 0x006B # LATIN SMALL LETTER K 0x6C 0x006C # LATIN SMALL LETTER L 0x6D 0x006D # LATIN SMALL LETTER M 0x6E 0x006E # LATIN SMALL LETTER N 0x6F 0x006F # LATIN SMALL LETTER O 0x70 0x0070 # LATIN SMALL LETTER P 0x71 0x0071 # LATIN SMALL LETTER Q 0x72 0x0072 # LATIN SMALL LETTER R 0x73 0x0073 # LATIN SMALL LETTER S 0x74 0x0074 # LATIN SMALL LETTER T 0x75 0x0075 # LATIN SMALL LETTER U 0x76 0x0076 # LATIN SMALL LETTER V 0x77 0x0077 # LATIN SMALL LETTER W 0x78 0x0078 # LATIN SMALL LETTER X 0x79 0x0079 # LATIN SMALL LETTER Y 0x7A 0x007A # LATIN SMALL LETTER Z 0x7B 0x007B # LEFT CURLY BRACKET 0x7C 0x007C # VERTICAL LINE 0x7D 0x007D # RIGHT CURLY BRACKET 0x7E 0x007E # TILDE # 0x80 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS 0x81 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE 0x82 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA 0x83 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE 0x84 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE 0x85 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS 0x86 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS 0x87 0x00E1 # LATIN SMALL LETTER A WITH ACUTE 0x88 0x00E0 # LATIN SMALL LETTER A WITH GRAVE 0x89 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX 0x8A 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS 0x8B 0x00E3 # LATIN SMALL LETTER A WITH TILDE 0x8C 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE 0x8D 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA 0x8E 0x00E9 # LATIN SMALL LETTER E WITH ACUTE 0x8F 0x00E8 # LATIN SMALL LETTER E WITH GRAVE 0x90 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX 0x91 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS 0x92 0x00ED # LATIN SMALL LETTER I WITH ACUTE 0x93 0x00EC # LATIN SMALL LETTER I WITH GRAVE 0x94 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX 0x95 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS 0x96 0x00F1 # LATIN SMALL LETTER N WITH TILDE 0x97 0x00F3 # LATIN SMALL LETTER O WITH ACUTE 0x98 0x00F2 # LATIN SMALL LETTER O WITH GRAVE 0x99 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX 0x9A 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS 0x9B 0x00F5 # LATIN SMALL LETTER O WITH TILDE 0x9C 0x00FA # LATIN SMALL LETTER U WITH ACUTE 0x9D 0x00F9 # LATIN SMALL LETTER U WITH GRAVE 0x9E 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX 0x9F 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS 0xA0 0x2020 # DAGGER 0xA1 0x00B0 # DEGREE SIGN 0xA2 0x00A2 # CENT SIGN 0xA3 0x00A3 # POUND SIGN 0xA4 0x00A7 # SECTION SIGN 0xA5 0x2022 # BULLET 0xA6 0x00B6 # PILCROW SIGN 0xA7 0x00DF # LATIN SMALL LETTER SHARP S 0xA8 0x00AE # REGISTERED SIGN 0xA9 0x00A9 # COPYRIGHT SIGN 0xAA 0x2122 # TRADE MARK SIGN 0xAB 0x00B4 # ACUTE ACCENT 0xAC 0x00A8 # DIAERESIS 0xAD 0x2260 # NOT EQUAL TO 0xAE 0x00C6 # LATIN CAPITAL LETTER AE 0xAF 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE 0xB0 0x221E # INFINITY 0xB1 0x00B1 # PLUS-MINUS SIGN 0xB2 0x2264 # LESS-THAN OR EQUAL TO 0xB3 0x2265 # GREATER-THAN OR EQUAL TO 0xB4 0x00A5 # YEN SIGN 0xB5 0x00B5 # MICRO SIGN 0xB6 0x2202 # PARTIAL DIFFERENTIAL 0xB7 0x2211 # N-ARY SUMMATION 0xB8 0x220F # N-ARY PRODUCT 0xB9 0x03C0 # GREEK SMALL LETTER PI 0xBA 0x222B # INTEGRAL 0xBB 0x00AA # FEMININE ORDINAL INDICATOR 0xBC 0x00BA # MASCULINE ORDINAL INDICATOR 0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA 0xBE 0x00E6 # LATIN SMALL LETTER AE 0xBF 0x00F8 # LATIN SMALL LETTER O WITH STROKE 0xC0 0x00BF # INVERTED QUESTION MARK 0xC1 0x00A1 # INVERTED EXCLAMATION MARK 0xC2 0x00AC # NOT SIGN 0xC3 0x221A # SQUARE ROOT 0xC4 0x0192 # LATIN SMALL LETTER F WITH HOOK 0xC5 0x2248 # ALMOST EQUAL TO 0xC6 0x2206 # INCREMENT 0xC7 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xC8 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0xC9 0x2026 # HORIZONTAL ELLIPSIS 0xCA 0x00A0 # NO-BREAK SPACE 0xCB 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE 0xCC 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE 0xCD 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE 0xCE 0x0152 # LATIN CAPITAL LIGATURE OE 0xCF 0x0153 # LATIN SMALL LIGATURE OE 0xD0 0x2013 # EN DASH 0xD1 0x2014 # EM DASH 0xD2 0x201C # LEFT DOUBLE QUOTATION MARK 0xD3 0x201D # RIGHT DOUBLE QUOTATION MARK 0xD4 0x2018 # LEFT SINGLE QUOTATION MARK 0xD5 0x2019 # RIGHT SINGLE QUOTATION MARK 0xD6 0x00F7 # DIVISION SIGN 0xD7 0x25CA # LOZENGE 0xD8 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS 0xD9 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS 0xDA 0x2044 # FRACTION SLASH 0xDB 0x20AC # EURO SIGN 0xDC 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0xDD 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0xDE 0xFB01 # LATIN SMALL LIGATURE FI 0xDF 0xFB02 # LATIN SMALL LIGATURE FL 0xE0 0x2021 # DOUBLE DAGGER 0xE1 0x00B7 # MIDDLE DOT 0xE2 0x201A # SINGLE LOW-9 QUOTATION MARK 0xE3 0x201E # DOUBLE LOW-9 QUOTATION MARK 0xE4 0x2030 # PER MILLE SIGN 0xE5 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX 0xE6 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX 0xE7 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE 0xE8 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS 0xE9 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE 0xEA 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE 0xEB 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX 0xEC 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS 0xED 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE 0xEE 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE 0xEF 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX 0xF0 0xF8FF # Apple logo 0xF1 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE 0xF2 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE 0xF3 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX 0xF4 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE 0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I 0xF6 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT 0xF7 0x02DC # SMALL TILDE 0xF8 0x00AF # MACRON 0xF9 0x02D8 # BREVE 0xFA 0x02D9 # DOT ABOVE 0xFB 0x02DA # RING ABOVE 0xFC 0x00B8 # CEDILLA 0xFD 0x02DD # DOUBLE ACUTE ACCENT 0xFE 0x02DB # OGONEK 0xFF 0x02C7 # CARON \ No newline at end of file diff --git a/Unix-only/KDE1-only/Antiword.kdelnk.eu b/Unix-only/KDE1-only/Antiword.kdelnk.eu new file mode 100644 index 0000000..9de8f49 --- /dev/null +++ b/Unix-only/KDE1-only/Antiword.kdelnk.eu @@ -0,0 +1,15 @@ +# KDE Config File +[KDE Desktop Entry] +Comment[C]=MS Word reader +SwallowTitle= +SwallowExec= +BinaryPattern=antiword;kantiword; +Name=Antiword +Name[C]=Antiword +MimeType= +Exec=kantiword a4 %f +Icon=antiword.xpm +TerminalOptions= +Path= +Type=Application +Terminal=0 diff --git a/Unix-only/KDE1-only/Antiword.kdelnk.us b/Unix-only/KDE1-only/Antiword.kdelnk.us new file mode 100644 index 0000000..d54c140 --- /dev/null +++ b/Unix-only/KDE1-only/Antiword.kdelnk.us @@ -0,0 +1,15 @@ +# KDE Config File +[KDE Desktop Entry] +Comment[C]=MS Word reader +SwallowTitle= +SwallowExec= +BinaryPattern=antiword;kantiword; +Name=Antiword +Name[C]=Antiword +MimeType= +Exec=kantiword letter %f +Icon=antiword.xpm +TerminalOptions= +Path= +Type=Application +Terminal=0 diff --git a/Unix-only/KDE1-only/antiword.xpm b/Unix-only/KDE1-only/antiword.xpm new file mode 100644 index 0000000..66c9cf7 --- /dev/null +++ b/Unix-only/KDE1-only/antiword.xpm @@ -0,0 +1,272 @@ +/* XPM */ +static char *antiword_48[] = { +/* width height num_colors chars_per_pixel */ +" 48 48 217 2", +/* colors */ +".. c #040204", +".# c #548a04", +".a c #840604", +".b c #4c460c", +".c c #bcc2bc", +".d c #3c0604", +".e c #b4820c", +".f c #141e04", +".g c #acaaa4", +".h c #74560c", +".i c #240604", +".j c #3c5e0c", +".k c #dca20c", +".l c #0c1204", +".m c #dce2dc", +".n c #ac060c", +".o c #543e0c", +".p c #9c720c", +".q c #3c2e0c", +".r c #848284", +".s c #e4b20c", +".t c #140204", +".u c #949694", +".v c #24320c", +".w c #b4b6b4", +".x c #5c5a5c", +".y c #741e0c", +".z c #3c3e3c", +".A c #ccd2cc", +".B c #bc920c", +".C c #ecf2ec", +".D c #746e74", +".E c #f4b20c", +".F c #1c1604", +".G c #94060c", +".H c #6c260c", +".I c #9ca29c", +".J c #5c0604", +".K c #84620c", +".L c #d40604", +".M c #5c4244", +".N c #646664", +".O c #cc9a0c", +".P c #747a74", +".Q c #f4ba0c", +".R c #0c0204", +".S c #c4cac4", +".T c #141a04", +".U c #8c8e8c", +".V c #c4bebc", +".W c #345204", +".X c #acb2ac", +".Y c #24160c", +".Z c #e4aa0c", +".0 c #e4eae4", +".1 c #544a2c", +".2 c #140e04", +".3 c #9c9e9c", +".4 c #2c2e2c", +".5 c #4c4a4c", +".6 c #f4faf4", +".7 c #a40604", +".8 c #242624", +".9 c #fcba04", +"#. c #44160c", +"## c #7c5e0c", +"#a c #14120c", +"#b c #c4020c", +"#c c #848a84", +"#d c #9c969c", +"#e c #bcbebc", +"#f c #dcdadc", +"#g c #c4920c", +"#h c #6c6e6c", +"#i c #3c363c", +"#j c #3c520c", +"#k c #7c160c", +"#l c #4c060c", +"#m c #b4aeac", +"#n c #340604", +"#o c #44720c", +"#p c #ecb20c", +"#q c #646264", +"#r c #747674", +"#s c #0c0e14", +"#t c #1c161c", +"#u c #9c0604", +"#v c #a4a2a4", +"#w c #6c0604", +"#x c #8c6a0c", +"#y c #dc0204", +"#z c #d49a0c", +"#A c #847e84", +"#B c #0c0604", +"#C c #cccac4", +"#D c #ecae0c", +"#E c #6c4e0c", +"#F c #343634", +"#G c #fcbe04", +"#H c #14160c", +"#I c #c4960c", +"#J c #040604", +"#K c #8c060c", +"#L c #c4c2c4", +"#M c #440604", +"#N c #b48a0c", +"#O c #1c1e1c", +"#P c #acaeac", +"#Q c #7c5a0c", +"#R c #3c6204", +"#S c #e4e2e4", +"#T c #542224", +"#U c #8c868c", +"#V c #1c0204", +"#W c #bcbabc", +"#X c #645e64", +"#Y c #444644", +"#Z c #d4d2d4", +"#0 c #f4f2f4", +"#1 c #0c0e0c", +"#2 c #64060c", +"#3 c #242224", +"#4 c #544e54", +"#5 c #6c666c", +"#6 c #643a0c", +"#7 c #742a0c", +"#8 c #ac7e0c", +"#9 c #342e0c", +"a. c #c48e0c", +"a# c #5c460c", +"aa c #4c3a0c", +"ab c #444244", +"ac c #7c7a7c", +"ad c #949294", +"ae c #eceaec", +"af c #342e34", +"ag c #fcfafc", +"ah c #2c262c", +"ai c #4c360c", +"aj c #6c521c", +"ak c #2c060c", +"al c #b4b2b4", +"am c #8c8a8c", +"an c #a47a0c", +"ao c #b4060c", +"ap c #442e0c", +"aq c #140e14", +"ar c #7c7674", +"as c #34560c", +"at c #e4ae0c", +"au c #4c4e4c", +"av c #a4a6a4", +"aw c #cccecc", +"ax c #745a0c", +"ay c #dca60c", +"az c #848684", +"aA c #949a94", +"aB c #b4bab4", +"aC c #5c5e5c", +"aD c #747274", +"aE c #f4b60c", +"aF c #940a0c", +"aG c #84660c", +"aH c #f4be0c", +"aI c #dcdedc", +"aJ c #3c3a3c", +"aK c #1c1a1c", +"aL c #dc0604", +"aM c #d49e0c", +"aN c #6c520c", +"aO c #c4c6c4", +"aP c #e4e6e4", +"aQ c #1c0604", +"aR c #d4d6d4", +"aS c #f4f6f4", +"aT c #545254", +"aU c #6c6a6c", +"aV c #7c7e7c", +"aW c #eceeec", +"aX c #343234", +"aY c #fcfefc", +"aZ c #2c2a2c", +"a0 c #84060c", +"a1 c #141e0c", +"a2 c #acaaac", +"a3 c #e4b214", +"a4 c #0c0a0c", +"a5 c #1c160c", +"a6 c #5c060c", +"a7 c #241e24", +"a8 c #d4060c", +"a9 c #141a0c", +"b. c #c4bec4", +"b# c #34520c", +"ba c #140e0c", +"bb c #a4060c", +"bc c #fcba0c", +"bd c #7c5e14", +"be c #141214", +"bf c #bcbec4", +"bg c #c49214", +"bh c #6c6e74", +"bi c #3c5214", +"bj c #34060c", +"bk c #9c060c", +"bl c #0c060c", +"bm c #cccacc", +"bn c #fcbe0c", +"bo c #141614", +"bp c #04060c", +"bq c #44060c", +"br c #3c620c", +"bs c #e4ae14", +"bt c #4c4e54", +"bu c #9c9a9c", +"bv c #a4a6ac", +"XX c None", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYXXXX", +"XXXXaY#WbmaYaYaYaw.waYavaIaYaYaYaYaYaW#vaSaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaY.AalaYa2#faYaYXXXX", +"XXXXaY.3.uawaY#Zbu.uaYal#SaYaYaYaYaYaP#raWaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaR#W#WaYazaOaYaYXXXX", +"XXXXaY#vaVadaWbuaV#daYaW.6aYaY#0aWaSaParaW#0aSaYaWagaS#0aY#0aW#0aYaY#0aW#0aWad#PaWaWaz#e#0aYXXXX", +"XXXXaY.3#PaW.PaP.waAaY#AawaYaS#raraBaP.PaW#P.IaYaraRaO#caY.UaraAaYaYav#r#rac#rac#r.Par.P#vaYXXXX", +"XXXXaY#v#PagaPag.w#daYaVawaRadaPaP#0aPar.U#LaWaY.PaRaO#UaY.U.XaWaY.ubm.caVaP.U#PaPaP.raBaWaYXXXX", +"XXXXaY.3#PaYaYaY.waAaY#A.Aaw#AaYaYaYaP#r#raOaYaYaraRaO#caYbm#WaOaYaVawaw.raY.u.waYaYazbmaYaYXXXX", +"XXXXaY#v.XaYaYaY#W.uaY#A.AaRbuaIaIaWaParadbfaeaY.u.SalamaY#Sav#daYaV#W#L.3aY.u#WaYaYazaOaYaYXXXX", +"XXXXaY.3#PaYaYaY.w.uaYaVawaYaS#r#r.waP#raW#P.3aYaY#v#razaY.U#raAaY#A.PavaYaY.u.waYaY#UaOaYaYXXXX", +"XXXXaYaSagaYaYaYagaSaYaSaYaYaYaSaSagaYaSaY.6agaYaYaS#L#caYagaSaSaYaSaSagaYaY.6agaYaYaSagaYaYXXXX", +"XXXXaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaY.m.x.x.xamaY.x.xam#ZaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYXXXX", +"XXXXaPaPaPaPaPaPaPaPaPaPaPawavavavbvad#FaJaKaX#v#Y#Y#h#PaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPXXXX", +"XXXX#Lb.#eb.bf.Vbfb.b.bfb.aV....a4a4#3ad.U#Y#s#1#W#WbhaKbfb.b.bf.Vbfb.#eb.bf.Vb.bf#L.V.cb.#LXXXX", +"XXXXaYaYaYaYaYaYaYaYaYaYaY#v....#rbuaV....aD#W#W#W#W#h#3aYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYaYXXXX", +"XXXXawbmawbmawbmaw#Cbm#Y.zaT#rar#i.8aJad.Ua2#W#e#W#ea2az.zal#CawbmawbmawbmawbmawbmbmbmbmbmawXXXX", +"XXXX#f#f#faIaR#fbu.N.N.5.5auaTbt.x.xaU#W#h.u#W#W#W#W#W#v...w#faIaR#f#f.X#q.N#q.N#q.N.N#P#f#fXXXX", +"XXXX#0.C#0aW.A#Z#ha7#OacaV#X#3.8.ua2bububoaDalaAbu.X#e.g#3al.m#0#0.CaI.U.T.T.Ta9#H.....U#0.CXXXX", +"XXXX#W#e#Wav....aTaAbua4..#Y#W#W#W.N..bp...Daz....az#W#W#W#3.N#W#e#Wab.v.#.#.#.##o....aD#W#eXXXX", +"XXXXaS.xbo.8#Uaz.5bobe.3#v#PalboaK#s....bgajabavav.wacaZ#W.8#s#tbo#ta4#B.lba#1.l#9aya5adaSaSXXXX", +"XXXXaRab..bebubu.5aK.D#W#rau.5....aibd#JayaN#F#W#4auaCaUbtbi.W.W.W.Wa1bja0.a.iai#8#Ga5#AaR#fXXXX", +"XXXX#ZaDafba#h.U.5#3az.waba5ai....#Q#z..ay#EaZazaJaJ.xaD..b#.j#Rbr.j.b.H.7#ybj#Q.9.9.YacawawXXXX", +"XXXXaYaY.u....aV.5....alaba#a3.R..#Q.O#Bay#E....aB#W#h.....R.R.R..#Banan.ta8#n#Q.9aH.YaAaYaYXXXX", +"XXXX#W#Wbh....aVbuaD..al#Wac#a.Q.q#Q.9.Q.9#E..............ao.Lbb.R#p.Qbcbs.R..#Q.9.9.YaD#W#eXXXX", +"XXXXaWaeaR#v...8#5#r..#F.Uac#Baa.paM.kaaat#E.f.j#R.jbras...d.G.7..#D.9.9#p....#Q.9#G.F.UaeaeXXXX", +"XXXX#S.m#SaO....aTazabblac.u.5bpax#I.O#J.K.q.T#j.W#j.W#j#E#E#7#w..#p.9.9.EaN.Fax.9#G.Yaz#S.mXXXX", +"XXXXaO#L#L.X#3bl.5amaAa4aU#P#m....#E#N.....taQ#V#V.Rba.q.9.9#Q....#D.9.9.9.9.o#x.9.Q.Y#r#LaOXXXX", +"XXXXaYaYaYaYaY.4...8bua4..ab#P.......R....a0#y#y#ybq#E.9.9.9.h.....E.9.9.9.9.9#G.9#G.Y.uaYaYXXXX", +"XXXXaObmaOaObm#3...8buaVafab#W.3ah..#O.3bu.Ma6#y#y#b#kai.9bc.Zan..#D.9.9.9.9.9.9.9.9a5araObmXXXX", +"XXXX#SaIaI#SaI.uabbe.5adaJ#3aC#W.P.NaD#W.Nah#M#y#yaLa0.Y.9.9bn.B..#D.9bc.9.9bc.9.9#G.YazaIaIXXXX", +"XXXXaWaWaWaWaWaWaD....adauaK#1#W#Wa2.UadaJ.4#T.naL#ybk#..B#p.9.Oap.E.9.9.9.9.9.9.9.Q.Y.UaW#0XXXX", +"XXXX#W#W#W#W#W#W.x.....Ubu#q#s#W#W#q....#v#Waz.Ra8#y#y#b..aM.9.9.9.9.9.9.9bc.9.9.9#G.Y#h#W#WXXXX", +"XXXXag.6ag.6ag.6aS.w..a4#5#q..#1ad.w#Pal#WaTbl.Ra8#y#y#b...OaH.9.9bc.9.9#D.2#g.9.9.9.Y.uagagXXXX", +"XXXX#Z#Z#Z#Z#Z#Z#Z#v.....Naz#X..ad#Wavab#Y.Nacac#lao#y.L#K#6.e.9.9.9.9.9#p..a..9.9#Ga5aV#Z#ZXXXX", +"XXXXaR#ZaR.AaR.A#Z.waCbpab#rad..aC.u.g#Y#Yambvar..#u#y#y#yakaG#G.9.9.9#G#D..##.O#G.9.YaV#ZaRXXXX", +"XXXXag.6.6ag.6ag.6ag.6be..#i.U#1#B.x#W#W#m.X#A#sbaaFa8#y#y#n.K#p.9bc.9.9#p....#Q.Q.sa5.uag.6XXXX", +"XXXX#e#W#W#W#W#W#W#W#Wba..#Fbubu#3.x#W#W#t..aJ#W#W#i#2#y#y#y#2ap.9.9.9.9#D....#Q.O.R..aD#W#WXXXX", +"XXXXaWaW.CaW.CaW.CaW.CaO#Yaq.4bu.8bo#Y#W.u.U.3#WaB#i.J#y#y#y#w.q.9.9.9.9#p....a5.1#LaOaIaW.CXXXX", +"XXXX#SaI#SaI#SaI#SaIaIaI#4..a4#daCah#3#e#W#e#W#W.Na7#na0#y#ybb.yaGaEbn.9#D..#Y.xaDaIaIaIaI#SXXXX", +"XXXXbmaOaObm#LaOaObmaObm.Na7a4aVadaT#Obu.wbvbubu...8#O#V#y#y#ybb..#pay.ObgaX#vaOaObmaObmaOaOXXXX", +"XXXXaYaYagaYaYaYaYaYaYagaYav....#raT....avau......al.uaQaL#y.L.n.R#pa#..beaYaYaYaYaYagaYaYaYXXXX", +"XXXX#L#L#L#L#L#L#L#L#L#L#LaV....aqa4....#ta4aXavav#W.wad#V#V#V#V..a5arava2#L#L#L#L#L#L#L#L#LXXXX", +"XXXXaP#SaP.maP#SaP.m#SaP.mbm.U.....5aV..azaA#PaP#S#S#S#f.ubuaA#daA#d.S#S#SaP.maP#SaP.maP#SaPXXXX", +"XXXXae.0aeae.0ae.0aeae.0aeaeaIaJaJ.UbmaJaRaeae.0ae.0ae.0aeae.0ae.0aeae.0ae.0ae.0ae.0ae.0aeaeXXXX", +"XXXX#e#W#W#W#W#W#W#W#W#W#W#W#e#W#W#W#W#W#W#W#W#W#W#e#Wbf#W#W#W#W#W#W#W#W#W#W#W#W#W#W#W#W#W#WXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +}; diff --git a/Unix-only/KDE1-only/kantiword.sh b/Unix-only/KDE1-only/kantiword.sh new file mode 100644 index 0000000..acbdd86 --- /dev/null +++ b/Unix-only/KDE1-only/kantiword.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Script to make drag and drop in KDE possible +#set -x +# + +if [ $# -lt 2 ] +then + exit 0 +fi + +# Determine the temp directory +if [ -d "$TMPDIR" ] && [ -w "$TMPDIR" ] +then + tmp_dir=$TMPDIR +elif [ -d "$TEMP" ] && [ -w "$TEMP" ] +then + tmp_dir=$TEMP +else + tmp_dir="/tmp" +fi +out_file=$tmp_dir"/antiword.$$.ps" +err_file=$tmp_dir"/antiword.$$.err" + +# Determine the paper size +paper_size=$1 +shift + +# Make the PostScript file +antiword -p $paper_size -i 0 "$@" 2>$err_file >$out_file +if [ $? -ne 0 ] +then + rm -f $out_file + exit 1 +fi + +# Show the PostScript file +gv $out_file -nocentre -media $paper_size + +# Clean up +rm -f $out_file $err_file +exit 0 diff --git a/Unix-only/KDE3-only/Antiword.desktop.eu b/Unix-only/KDE3-only/Antiword.desktop.eu new file mode 100644 index 0000000..58ca6df --- /dev/null +++ b/Unix-only/KDE3-only/Antiword.desktop.eu @@ -0,0 +1,8 @@ +[Desktop Entry] +BinaryPattern=kantiword;Kantiword +MimeType=application/msword +Name=Antiword +Exec=kantiword a4 "%f" +Icon=antiword +Type=Application +Terminal=0 diff --git a/Unix-only/KDE3-only/Antiword.desktop.us b/Unix-only/KDE3-only/Antiword.desktop.us new file mode 100644 index 0000000..da6aa1a --- /dev/null +++ b/Unix-only/KDE3-only/Antiword.desktop.us @@ -0,0 +1,8 @@ +[Desktop Entry] +BinaryPattern=kantiword;Kantiword +MimeType=application/msword +Name=Antiword +Exec=kantiword letter "%f" +Icon=antiword +Type=Application +Terminal=0 diff --git a/Unix-only/KDE3-only/hi32-app-antiword.png b/Unix-only/KDE3-only/hi32-app-antiword.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4f92176a76edafd358db89f10d7e9bfb7f5355 GIT binary patch literal 1510 zcmVV>IGcGYOVIUwNkl7fK6#iyr*Ky-CKp-k=A#D*7 zr6*L>W7|-&HVIHwNT^c9r3b*`02hdD9MlVP5^fwYaa5@sqTVXhL$buPYXy=tr4oly zp^B=af0RlHp%6O|dw*UJV{cr?gs4(KS=P+XoA=)L-n=)%hzS2DIDkwh#ZeUJoHc4srBcJg!vK^juD)Kla3P&e z4-O6rApj_QN;+WUx^60!I(6z4fd2k|0B6pe306;^KCOg_D3wYn5+_fdgql+g{r&w! zlt?6ke}zOMp_Y`eT1qC9!D=uKcBuhhdt_H)aBy&Cwi=+VvNkj{luRbofQW{Nhm*cM?;|54jIra#j{{gKW*Ek`Yu8lWtY)CW1r_UDE(ahUkJr5R8Dl+0)XGm% ztu_tAa2!X|w7R{4F%IT3f={GLDI<|csZ=_A`0&EQg7P{Zj{}&QnJJY@zVF9ku{OLW z1Uz#0#SYBQ&K8SBDP=euo|u?WDr5U%pA12G96+VA{+rAr$Agp-zVC-ZApqHIRynTg zx|Gs1P17_1FyM8B!9g+%hN-D3(=>$;rfGt6Xn+8801*gq4H0M%Rbk)vHQTl;l}de- zlvBOE`!_Hj0O`0l;b^r3)!p3o$a;&0pV1Q~1+t ze*#ON^DwT4%oXuuWoHzlXU==?8@T0f7Z#}W` zn6|w6{(ZqPmU#dGaOVqb-6ClRbgI?3aPapuHom8Wm6t30ZtLFZQ0*j@*Vgt!&eL) zeGkOb2*BMLu=lSsbq6#Bw6vA7!J-hERY!~oMojXqT(qiyJy7qxXl7sx!7%*0~dg;<7 zb(~OZf6}&k_wFxj+P?MCFMqiZ2O`hL=fkudbb!NWU;@koY0Vh~Bt}L?R8x{t3L(_n zDHe-;8KJ%s78rIBezn(asw_d2s|@x!0O;%W0I@?)$Zf`;9=TjjW!v}tXf&#f8L_^* za0GChq0?CKCOHqBRPQ&Bu|xCE%|SyZR^A6jtnaSx2nG&pW6Yc6oV*|h0DzZ>o+@Fj zP$;azK-YC;V`*tA91b(adU|>Uumk)j?)wZs2oh1xGdn!zu~T%Qsux&R>pvd=gb<^n zqe^mmdK!SHX+#8$pV4`T;|@nF_){AKXlZF#sigUpSq(+qr5`}adyMbvjWNep6+qxJ zKNYl~e}#JW2MFg}vE-bu{i#xqe*o73hg=K3>0AH+00(qQO+^RM2L}`h0f(yr@Bjb+ M07*qoM6N<$f=)E34gdfE literal 0 HcmV?d00001 diff --git a/Unix-only/KDE3-only/hi48-app-antiword.png b/Unix-only/KDE3-only/hi48-app-antiword.png new file mode 100644 index 0000000000000000000000000000000000000000..c0900debce3f24b545c5eb5a327fb413987c1602 GIT binary patch literal 2285 zcmWkveK^y77vI*eAJ$jG$jf-9MsjP!iWspb)GV=ErQI|wiM67Iv?R@X5~{T%mgGIw z%FIi%5bJGrQ_-6iy(p5pAGO}J>fZCmIp;d(I@h^ApL0Ifb&f{TLQT`rtg!cmSRyiYt926Cx{2t$-KFeL-51Qs`)3+7_5)>ttN zRaaKCVW=P(Xi?BmDd1=G0Ssx>swpX8(*SWfQQrw+tbwW+K!!FLsCrZs!=my5))6a_ zN_eq=lmLyr9HTG57YGWlC`hSLvf@~j)s&(8L%NSTFc+|3fM0;8)9CC(Hp>ri-GC$; z5D7q41Q@FU)elg}6kZljBos|eP7w)2{fyq-#htnwu%oc<2JkX@L4HAX7Ldb$LI9Y# z7+yM;7z4(nfJ&oQ*H&x#HQZRBtp$7mUsNiRE98tg1~-kXYXu@S;3ooIC(w>)Nq!`( z9aalNL*<6aKy_0!_GS!gNFNUAzUb&tbapbEm(82{Fh%qt>VN6o-Q4-GK@ULEAQ_Wk z0NQX(z%X!e#19$jc0kpsB1ReTfNB`%6^2`2FcuhPr%ENnusK{(6ov=`F$@3C+(z%#l{gP@Eijs!=i@o3`KFnr;V5mz+2wv+8v|{&e?n8K*bgG(Ltc zL)O?&z7cc;+7%MXs6KJYzV`!fwfl`qc>3V3@sR@`0>-}wj_xTR*N%IC`$|B54XVgM zo(;PH%_cJP;KsC%0+sgU)i^&%nTyC1nQUn@*%H=NQhwe$kY;SUy3RyUT{d6%TI5kP z)W0YpaHPCKxrlkor(;6)iQ_$B^vBd7IYhK2!gfAt>mrcuYj?ZXM63V^a?z>}?Qgp-m^Rzd*q^ACa zef^o_yIWg@tte#xo*1gU-@4YvlZ)8#qS)EyV$ipNyzns5gmY=0CG(EG{ zq|IsbMS6O)a%aZlw~yUX*Q@V8z&YW6hRdp)GB{XzV=qbcSQSaZe zDgMUaw?^uiLEt#8^r6On*|TyXGROm$l7n+|$Ov0}qL{sQSiuVWr_t?L`x9nVu$$oU zTIFW1V4^wlXvN^$p44*{Q9D`!R{4n3gVjQFtN$V~36u?tDvOA158vW*0|xrXhusF+ z6heROHq8|r)iiSzIrRqbh|g2bz?|lgkdUry4c$E4FQa~o7CBB!@((5u@(7f{w zZou!n!faZ)aZ?^8%(YJ4YSa>K=?ph#Bww+9e&2`I75~C-tvdN#?PQecoSS~uya)a- zX?Q$YYhsyO;lNm}3y95;j<$U%XS;M{&8!>!wr9!9y1wxb2j%bjicik8GY;?EGP=>Z zaW7=mf0B^XYF5$qmhEY=es1@!O;4rU1O7La_3HKVqQQ35Ax)qsB3%6Ro%U0+-S9{I ztTMz*m~&3-C4pd;k#+pzp_>kae6Jrl`|}|tLaF+k#iZG9xa}0&bN$cx4<6*b`u&_( z@A(&T)Yd2H2`7NqEEQZ^C(dO5^EJY3`_4YaF9*^$O;*xadoop&vgvwy`Wk3$t8;#z z9XBp@>2OMDpn6o{RX1^|B`G2zo-If&+MJzs!(19-DQB(a*WaN}wO78MTSF`JK@kt2 zuY9BL@5pjL@@hDU{=EIx=s0>=Ry4Qu`@>*cj(D)(Xd|-Uw(w?G+3x2H5q%-3N4aQf z?L?BFU4;LM6WVdS^N$NHl*||NtELOvI@+h_o83k)Sk1d9XRPvNn|Sw|T=IW8v1oP! zvU2$M(R-PCvEY@I5YpqjC~o5_U-!#GJ`#~JfXnvjmH5j(H0RwaJa|nZFYQ|?CoPPu zXYSjd_#cXElYL%kEIAng@b#TJ;n$C9o~JgUBb=Qqu1CAYl93mmExY?7rsNuHBAOF<>Cu5wJ8+%?| zT^{m#S>1@~PYtiJ&0FGt(h)0Q7alv>J$9!M0~cp^s>Vb z^HaleSu8c2UD&fI)Mnj9NNc(6J{IM zUvI#6XFgtFuIl%E;SkZ-Unl%DY|qi1x3wndc3Ts*-)@#o;f@4pWO(X}(a z;cuRg{1R&&e$8@xCSlf8*VGxlfDt!5BE;yP(QFGZx2sN7O@"$err_file" >"$out_file" +if [ $? -ne 0 ] +then + # Something went wrong + if [ -r "$err_file" ] && [ -s "$err_file" ] + then + konsole --caption "Error from Antword" -e less "$err_file" + fi + # Clean up + rm -f "$out_file" "$err_file" + exit 1 +fi + +# Show the PostScript file +gv "$out_file" -nocentre -media $paper_size + +# Clean up +rm -f "$out_file" "$err_file" +exit 0 diff --git a/Unix-only/KDE3-only/lo16-app-antiword.png b/Unix-only/KDE3-only/lo16-app-antiword.png new file mode 100644 index 0000000000000000000000000000000000000000..d26d00d59c76341559540261a29d7ef70736a3be GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$h5fKQ0) zojZ39A3hur5z)}lU|?XdV8H?h2ZsOu|2H%+{9h5#z`*dof#CoH!+{6}2OxQX;s2c# zK$h6wwnsn{7?Zr+T^Kr8Wj%l#&H|6fVxaZcK$vkte&rmXAbW|YuPggSb`Bvmb?J}` zEkL0zPZ!6KiaEA@oMOz19L|x-uXNu2)sHTi^K7Mlo4(VPj;Pb2UfyT?T=tk%SLL1Y znb*4Xtay09%}GnHyquaHH*@P9D+Mm$vl1J4c(OP;9NCoO6{P1}-e;Ed=t=L59m~$_ z7I&Ox`_*cZ`}@H8;){xU>dvcIObG0lqg`-7vXkXo$+RNrMf3l!@mv3&@iHIt!lvI6RWAcKLSp@G4`z<`0lp#iA0fx*d2 zX+Ds_nB?v5!qCAg>jC6&7I;J!Gca%qfiUBxyLEqng6t)pzOL*S+1W(}^tSEz-v-p< z;_2cTQZc7>66drQ1s)gAh(n8Pi~nEtQ*Bsq`LC6~;N(-wUFQ6jx|dgfHeXe{YVRHC z#`wExU%$yP=f!_{wa6%=;(BJ`I)Ar~!CkW_%&nTK6J{E;F>?Jh|M_1vJswX?es(}A zio4N()Asu1YV%V|PO&e1ogR5VV+*_N{JUy#bti0M?s|NfVE9+=c;ol0y$geaCi@sq z66)Af>F$yuQk1dTYG!@Gy2S!O9-=#6JjE4~;N+W+{=$G#1=jsAws z|NH0UEdRd>p!a*u#mvDxSC#_#93%Y9_e@! + +%description +Antiword is a free MS Word reader for Linux and RISC OS. There are ports to +BeOS, OS/2, Mac OS X, Amiga, VMS, NetWare and DOS. Antiword converts the +binary files from Word 2, 6, 7, 97, 2000 and 2002 to plain text and to +PostScript TM. +. + +%prep +# nothing to be done here + +%build +make all + +%install +rm -rf $RPM_BUILD_ROOT +install -d 555 $RPM_BUILD_ROOT/%{_prefix}/bin +install -d 555 $RPM_BUILD_ROOT/%{_prefix}/share/antiword +install -d 555 $RPM_BUILD_ROOT/%{_prefix}/share/man/man1 +install -m 555 ./antiword $RPM_BUILD_ROOT%{_prefix}/bin/antiword +install -m 555 ./kantiword $RPM_BUILD_ROOT%{_prefix}/bin/kantiword +install -m 444 ./Resources/* $RPM_BUILD_ROOT%{_prefix}/share/antiword +install -m 444 ./Docs/antiword.1 $RPM_BUILD_ROOT/%{_prefix}/share/man/man1/antiword.1 + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc Docs/* +%{_prefix}/bin/* +%{_prefix}/share/antiword/* +%{_prefix}/share/man/man1/* + diff --git a/Unix-only/fontinfo.h b/Unix-only/fontinfo.h new file mode 100644 index 0000000..8538dfa --- /dev/null +++ b/Unix-only/fontinfo.h @@ -0,0 +1,2251 @@ +/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT! */ +static const char *szFontnames[32] = { + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Palatino-Roman", + "Palatino-Bold", + "Palatino-Italic", + "Palatino-BoldItalic", + "Helvetica-Narrow", + "Helvetica-Narrow-Bold", + "Helvetica-Narrow-Oblique", + "Helvetica-Narrow-BoldOblique", + "Bookman-Light", + "Bookman-Demi", + "Bookman-LightItalic", + "Bookman-DemiItalic", + "AvantGarde-Book", + "AvantGarde-Demi", + "AvantGarde-BookOblique", + "AvantGarde-DemiOblique", + "NewCenturySchlbk-Roman", + "NewCenturySchlbk-Bold", + "NewCenturySchlbk-Italic", + "NewCenturySchlbk-BoldItalic", +}; +static unsigned short ausCharacterWidths1[32][256] = { + { /* Courier */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Times-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 408, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 564, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 278, 278, 564, 564, 564, 444, + /* 64 */ 921, 722, 667, 667, 722, 611, 556, 722, + /* 72 */ 722, 333, 389, 722, 611, 889, 722, 722, + /* 80 */ 556, 722, 667, 556, 611, 722, 722, 944, + /* 88 */ 722, 722, 611, 333, 278, 333, 469, 500, + /* 96 */ 333, 444, 500, 444, 500, 444, 333, 500, + /* 104 */ 500, 278, 278, 500, 278, 778, 500, 500, + /* 112 */ 500, 500, 333, 389, 278, 500, 500, 722, + /* 120 */ 500, 500, 444, 480, 200, 480, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1000, 350, + /* 144 */ 333, 333, 333, 333, 444, 444, 444, 500, + /* 152 */ 1000, 564, 889, 722, 500, 500, 556, 556, + /* 160 */ 250, 333, 500, 500, 500, 500, 200, 500, + /* 168 */ 333, 760, 276, 500, 564, 333, 760, 333, + /* 176 */ 400, 564, 300, 300, 333, 500, 453, 250, + /* 184 */ 333, 300, 310, 500, 750, 750, 750, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 889, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 564, + /* 216 */ 722, 722, 722, 722, 722, 722, 556, 500, + /* 224 */ 444, 444, 444, 444, 444, 444, 667, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 564, + /* 248 */ 500, 500, 500, 500, 500, 500, 500, 500, + }, + { /* Times-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 555, 500, 500, 1000, 833, 333, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 930, 722, 667, 722, 722, 667, 611, 778, + /* 72 */ 778, 389, 500, 778, 667, 944, 722, 778, + /* 80 */ 611, 778, 722, 556, 667, 722, 722, 1000, + /* 88 */ 722, 722, 667, 333, 278, 333, 581, 500, + /* 96 */ 333, 500, 556, 444, 556, 444, 333, 500, + /* 104 */ 556, 278, 333, 556, 278, 833, 556, 500, + /* 112 */ 556, 556, 444, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 394, 220, 394, 520, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 333, 333, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 570, 1000, 722, 500, 500, 556, 556, + /* 160 */ 250, 333, 500, 500, 500, 500, 220, 500, + /* 168 */ 333, 747, 300, 500, 570, 333, 747, 333, + /* 176 */ 400, 570, 300, 300, 333, 556, 540, 250, + /* 184 */ 333, 300, 330, 500, 750, 750, 750, 500, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 389, 389, 389, 389, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 570, + /* 216 */ 778, 722, 722, 722, 722, 722, 611, 556, + /* 224 */ 500, 500, 500, 500, 500, 500, 722, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 556, 500, 500, 500, 500, 500, 570, + /* 248 */ 500, 556, 556, 556, 556, 500, 556, 500, + }, + { /* Times-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 420, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 675, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 675, 675, 675, 500, + /* 64 */ 920, 611, 611, 667, 722, 611, 611, 722, + /* 72 */ 722, 333, 444, 667, 556, 833, 667, 722, + /* 80 */ 611, 722, 611, 500, 556, 722, 611, 833, + /* 88 */ 611, 556, 556, 389, 278, 389, 422, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 722, 500, 500, + /* 112 */ 500, 500, 389, 389, 278, 500, 444, 667, + /* 120 */ 444, 444, 389, 400, 275, 400, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 889, 980, 1000, 350, + /* 144 */ 333, 333, 333, 333, 556, 556, 556, 500, + /* 152 */ 889, 675, 944, 667, 500, 500, 500, 500, + /* 160 */ 250, 389, 500, 500, 500, 500, 275, 500, + /* 168 */ 333, 760, 276, 500, 675, 333, 760, 333, + /* 176 */ 400, 675, 300, 300, 333, 500, 523, 250, + /* 184 */ 333, 300, 310, 500, 750, 750, 750, 500, + /* 192 */ 611, 611, 611, 611, 611, 611, 889, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 722, 667, 722, 722, 722, 722, 722, 675, + /* 216 */ 722, 722, 722, 722, 722, 556, 611, 500, + /* 224 */ 500, 500, 500, 500, 500, 500, 667, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 675, + /* 248 */ 500, 500, 500, 500, 500, 444, 500, 444, + }, + { /* Times-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 389, 555, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 832, 667, 667, 667, 722, 667, 667, 722, + /* 72 */ 778, 389, 500, 667, 611, 889, 722, 722, + /* 80 */ 611, 722, 667, 556, 611, 722, 667, 889, + /* 88 */ 667, 611, 611, 333, 278, 333, 570, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 333, 500, + /* 104 */ 556, 278, 278, 500, 278, 778, 556, 500, + /* 112 */ 500, 500, 389, 389, 278, 556, 444, 667, + /* 120 */ 500, 444, 389, 348, 220, 348, 570, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 333, 333, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 944, 722, 500, 500, 556, 556, + /* 160 */ 250, 389, 500, 500, 500, 500, 220, 500, + /* 168 */ 333, 747, 266, 500, 606, 333, 747, 333, + /* 176 */ 400, 570, 300, 300, 333, 576, 500, 250, + /* 184 */ 333, 300, 300, 500, 750, 750, 750, 500, + /* 192 */ 667, 667, 667, 667, 667, 667, 944, 667, + /* 200 */ 667, 667, 667, 667, 389, 389, 389, 389, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 570, + /* 216 */ 722, 722, 722, 722, 722, 611, 611, 500, + /* 224 */ 500, 500, 500, 500, 500, 500, 722, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 556, 500, 500, 500, 500, 500, 570, + /* 248 */ 500, 556, 556, 556, 556, 444, 500, 444, + }, + { /* Helvetica */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 221, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 222, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 222, 221, 333, 333, 333, 333, 333, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 500, 500, + /* 160 */ 278, 333, 556, 556, 556, 556, 260, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 351, 351, 333, 556, 537, 278, + /* 184 */ 333, 351, 365, 556, 869, 869, 869, 611, + /* 192 */ 667, 667, 667, 667, 667, 667, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 666, 666, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 500, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 611, 556, 556, 556, 556, 500, 555, 500, + }, + { /* Helvetica-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 278, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 278, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 280, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 351, 351, 333, 611, 556, 278, + /* 184 */ 333, 351, 365, 556, 869, 869, 869, 611, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 556, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 611, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Helvetica-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 222, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 222, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 222, 222, 333, 333, 333, 333, 333, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 500, 500, + /* 160 */ 278, 333, 556, 556, 556, 556, 260, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 390, 390, 333, 556, 537, 278, + /* 184 */ 333, 390, 365, 556, 947, 947, 947, 611, + /* 192 */ 667, 667, 667, 667, 667, 667, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 500, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 611, 556, 556, 556, 556, 500, 556, 500, + }, + { /* Helvetica-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 278, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 278, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 280, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 444, 444, 333, 611, 556, 278, + /* 184 */ 333, 444, 365, 556, 1055, 1055, 1055, 611, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 556, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 611, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Palatino-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 371, 500, 500, 840, 778, 278, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 606, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 611, 709, 774, 611, 556, 763, + /* 72 */ 832, 337, 333, 726, 611, 946, 831, 786, + /* 80 */ 604, 786, 668, 525, 613, 778, 722, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 500, 553, 444, 611, 479, 333, 556, + /* 104 */ 582, 291, 234, 556, 291, 883, 582, 546, + /* 112 */ 601, 560, 395, 424, 326, 603, 565, 834, + /* 120 */ 516, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 979, 1144, 606, + /* 144 */ 278, 278, 331, 331, 500, 500, 500, 500, + /* 152 */ 1000, 606, 998, 827, 500, 500, 605, 608, + /* 160 */ 250, 278, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 333, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 603, 628, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 444, + /* 192 */ 778, 778, 778, 778, 778, 778, 944, 709, + /* 200 */ 611, 611, 611, 611, 337, 337, 337, 337, + /* 208 */ 774, 831, 786, 786, 786, 786, 786, 606, + /* 216 */ 833, 778, 778, 778, 778, 667, 604, 556, + /* 224 */ 500, 500, 500, 500, 500, 500, 758, 444, + /* 232 */ 479, 479, 479, 479, 287, 287, 287, 287, + /* 240 */ 546, 582, 546, 546, 546, 546, 546, 606, + /* 248 */ 556, 603, 603, 603, 603, 556, 601, 556, + }, + { /* Palatino-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 402, 500, 500, 889, 833, 278, + /* 40 */ 333, 333, 444, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 667, 722, 833, 611, 556, 833, + /* 72 */ 833, 389, 389, 778, 611, 1000, 833, 833, + /* 80 */ 611, 833, 722, 611, 667, 778, 778, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 500, 611, 444, 611, 500, 389, 556, + /* 104 */ 611, 333, 333, 611, 333, 889, 611, 556, + /* 112 */ 611, 611, 389, 444, 333, 611, 556, 833, + /* 120 */ 500, 556, 500, 310, 606, 310, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 998, 1000, 606, + /* 144 */ 278, 278, 389, 389, 500, 500, 500, 500, + /* 152 */ 1000, 606, 1000, 833, 500, 500, 611, 611, + /* 160 */ 250, 278, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 438, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 611, 641, 250, + /* 184 */ 333, 300, 488, 500, 750, 750, 750, 444, + /* 192 */ 778, 778, 778, 778, 778, 778, 1000, 722, + /* 200 */ 611, 611, 611, 611, 389, 389, 389, 389, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 778, 778, 778, 778, 667, 611, 611, + /* 224 */ 500, 500, 500, 500, 500, 500, 778, 444, + /* 232 */ 500, 500, 500, 500, 333, 333, 333, 333, + /* 240 */ 556, 611, 556, 556, 556, 556, 556, 606, + /* 248 */ 556, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Palatino-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 778, 278, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 500, + /* 64 */ 747, 722, 611, 667, 778, 611, 556, 722, + /* 72 */ 778, 333, 333, 667, 556, 944, 778, 778, + /* 80 */ 611, 778, 667, 556, 611, 778, 722, 944, + /* 88 */ 722, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 444, 463, 407, 500, 389, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 778, 556, 444, + /* 112 */ 500, 463, 389, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 500, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 1028, 669, 500, 500, 528, 545, + /* 160 */ 250, 333, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 333, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 556, 500, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 500, + /* 192 */ 722, 722, 722, 722, 722, 722, 941, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 778, 778, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 778, 778, 778, 778, 667, 611, 500, + /* 224 */ 444, 444, 444, 444, 444, 444, 638, 407, + /* 232 */ 389, 389, 389, 389, 278, 278, 278, 278, + /* 240 */ 444, 556, 444, 444, 444, 444, 444, 606, + /* 248 */ 444, 556, 556, 556, 556, 500, 500, 500, + }, + { /* Palatino-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 833, 278, + /* 40 */ 333, 333, 444, 606, 250, 389, 250, 315, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 833, 722, 667, 685, 778, 611, 556, 778, + /* 72 */ 778, 389, 389, 722, 611, 944, 778, 833, + /* 80 */ 667, 833, 722, 556, 611, 778, 667, 1000, + /* 88 */ 722, 611, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 556, 537, 444, 556, 444, 333, 500, + /* 104 */ 556, 333, 333, 556, 333, 833, 556, 556, + /* 112 */ 556, 537, 389, 444, 389, 556, 556, 833, + /* 120 */ 500, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 944, 778, 556, 556, 611, 611, + /* 160 */ 250, 333, 500, 500, 500, 500, 606, 556, + /* 168 */ 333, 747, 333, 500, 606, 389, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 556, 556, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 944, 685, + /* 200 */ 611, 611, 611, 611, 389, 389, 389, 389, + /* 208 */ 778, 778, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 778, 778, 778, 778, 611, 667, 556, + /* 224 */ 556, 556, 556, 556, 556, 556, 738, 444, + /* 232 */ 444, 444, 444, 444, 333, 333, 333, 333, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 606, + /* 248 */ 556, 556, 556, 556, 556, 556, 556, 556, + }, + { /* Helvetica-Narrow */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 182, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 182, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 182, 182, 273, 273, 273, 273, 273, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 410, 410, + /* 160 */ 228, 273, 456, 456, 456, 456, 213, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 456, 440, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 547, 547, 547, 547, 547, 547, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 410, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 501, 456, 456, 456, 456, 410, 456, 410, + }, + { /* Helvetica-Narrow-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 228, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 228, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 228, 228, 273, 273, 410, 410, 410, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 501, 501, + /* 160 */ 228, 273, 456, 456, 456, 456, 230, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 501, 456, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 592, 592, 592, 592, 592, 592, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 456, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 501, 501, 501, 501, 501, 456, 501, 456, + }, + { /* Helvetica-Narrow-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 182, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 182, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 182, 182, 273, 273, 273, 273, 273, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 410, 410, + /* 160 */ 228, 273, 456, 456, 456, 456, 213, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 456, 440, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 547, 547, 547, 547, 547, 547, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 410, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 501, 456, 456, 456, 456, 410, 456, 410, + }, + { /* Helvetica-Narrow-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 228, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 228, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 228, 228, 273, 273, 410, 410, 410, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 501, 501, + /* 160 */ 228, 273, 456, 456, 456, 456, 230, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 501, 456, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 592, 592, 592, 592, 592, 592, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 456, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 501, 501, 501, 501, 501, 456, 501, 456, + }, + { /* Bookman-Light */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 320, 300, 380, 620, 620, 900, 800, 220, + /* 40 */ 300, 300, 440, 600, 320, 400, 320, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 320, 320, 600, 600, 600, 540, + /* 64 */ 820, 680, 740, 740, 800, 720, 640, 800, + /* 72 */ 800, 340, 600, 720, 600, 920, 740, 800, + /* 80 */ 620, 820, 720, 660, 620, 780, 700, 960, + /* 88 */ 720, 640, 640, 300, 600, 300, 600, 500, + /* 96 */ 220, 580, 620, 520, 620, 520, 320, 540, + /* 104 */ 660, 300, 300, 620, 300, 940, 660, 560, + /* 112 */ 620, 580, 440, 520, 380, 680, 520, 780, + /* 120 */ 560, 540, 480, 280, 600, 280, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1280, 460, + /* 144 */ 220, 220, 240, 240, 400, 400, 400, 500, + /* 152 */ 1000, 600, 1240, 900, 540, 540, 620, 620, + /* 160 */ 320, 300, 620, 620, 620, 620, 600, 520, + /* 168 */ 420, 740, 420, 360, 600, 400, 740, 440, + /* 176 */ 400, 600, 372, 372, 340, 680, 600, 320, + /* 184 */ 320, 372, 420, 360, 930, 930, 930, 540, + /* 192 */ 680, 680, 680, 680, 680, 680, 1260, 740, + /* 200 */ 720, 720, 720, 720, 340, 340, 340, 340, + /* 208 */ 800, 740, 800, 800, 800, 800, 800, 600, + /* 216 */ 800, 780, 780, 780, 780, 640, 620, 660, + /* 224 */ 580, 580, 580, 580, 580, 580, 860, 520, + /* 232 */ 520, 520, 520, 520, 300, 300, 300, 300, + /* 240 */ 560, 660, 560, 560, 560, 560, 560, 600, + /* 248 */ 560, 680, 680, 680, 680, 540, 620, 540, + }, + { /* Bookman-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 360, 420, 660, 660, 940, 800, 320, + /* 40 */ 320, 320, 460, 600, 340, 360, 340, 600, + /* 48 */ 660, 660, 660, 660, 660, 660, 660, 660, + /* 56 */ 660, 660, 340, 340, 600, 600, 600, 660, + /* 64 */ 820, 720, 720, 740, 780, 720, 680, 780, + /* 72 */ 820, 400, 640, 800, 640, 940, 740, 800, + /* 80 */ 660, 800, 780, 660, 700, 740, 720, 940, + /* 88 */ 780, 700, 640, 300, 600, 300, 600, 500, + /* 96 */ 320, 580, 600, 580, 640, 580, 380, 580, + /* 104 */ 680, 360, 340, 660, 340, 1000, 680, 620, + /* 112 */ 640, 620, 460, 520, 460, 660, 600, 800, + /* 120 */ 600, 620, 560, 320, 600, 320, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1360, 460, + /* 144 */ 320, 320, 220, 220, 540, 540, 540, 500, + /* 152 */ 1000, 600, 1220, 940, 440, 380, 740, 740, + /* 160 */ 340, 360, 660, 660, 660, 660, 600, 600, + /* 168 */ 500, 740, 400, 400, 600, 360, 740, 460, + /* 176 */ 400, 600, 396, 396, 400, 660, 800, 340, + /* 184 */ 360, 396, 400, 400, 990, 990, 990, 660, + /* 192 */ 720, 720, 720, 720, 720, 720, 1140, 740, + /* 200 */ 720, 720, 720, 720, 400, 400, 400, 400, + /* 208 */ 780, 740, 800, 800, 800, 800, 800, 600, + /* 216 */ 800, 740, 740, 740, 740, 700, 660, 660, + /* 224 */ 580, 580, 580, 580, 580, 580, 880, 580, + /* 232 */ 580, 580, 580, 580, 360, 360, 360, 360, + /* 240 */ 620, 680, 620, 620, 620, 620, 620, 600, + /* 248 */ 620, 660, 660, 660, 660, 620, 640, 620, + }, + { /* Bookman-LightItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 300, 320, 360, 620, 620, 800, 820, 280, + /* 40 */ 280, 280, 440, 600, 300, 320, 300, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 300, 300, 600, 600, 600, 540, + /* 64 */ 780, 700, 720, 720, 740, 680, 620, 760, + /* 72 */ 800, 320, 560, 720, 580, 860, 720, 760, + /* 80 */ 600, 780, 700, 640, 600, 720, 680, 960, + /* 88 */ 700, 660, 580, 260, 600, 260, 600, 500, + /* 96 */ 280, 620, 600, 480, 640, 540, 340, 560, + /* 104 */ 620, 280, 280, 600, 280, 880, 620, 540, + /* 112 */ 600, 560, 400, 540, 340, 620, 540, 880, + /* 120 */ 540, 600, 520, 360, 600, 380, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1180, 460, + /* 144 */ 280, 280, 180, 180, 440, 440, 480, 500, + /* 152 */ 1000, 600, 1180, 900, 620, 620, 640, 660, + /* 160 */ 300, 320, 620, 620, 620, 620, 600, 620, + /* 168 */ 420, 740, 440, 300, 600, 320, 740, 440, + /* 176 */ 400, 600, 372, 372, 320, 620, 620, 300, + /* 184 */ 320, 372, 400, 300, 930, 930, 930, 540, + /* 192 */ 700, 700, 700, 700, 700, 700, 1220, 720, + /* 200 */ 680, 680, 680, 680, 320, 320, 320, 320, + /* 208 */ 740, 720, 760, 760, 760, 760, 760, 600, + /* 216 */ 760, 720, 720, 720, 720, 660, 600, 620, + /* 224 */ 620, 620, 620, 620, 620, 620, 880, 480, + /* 232 */ 540, 540, 540, 540, 280, 280, 280, 280, + /* 240 */ 540, 620, 540, 540, 540, 540, 540, 600, + /* 248 */ 540, 620, 620, 620, 620, 600, 600, 600, + }, + { /* Bookman-DemiItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 320, 380, 680, 680, 880, 980, 320, + /* 40 */ 260, 260, 460, 600, 340, 280, 340, 360, + /* 48 */ 680, 680, 680, 680, 680, 680, 680, 680, + /* 56 */ 680, 680, 340, 340, 620, 600, 620, 620, + /* 64 */ 780, 720, 720, 700, 760, 720, 660, 760, + /* 72 */ 800, 380, 620, 780, 640, 860, 740, 760, + /* 80 */ 640, 760, 740, 700, 700, 740, 660, 1000, + /* 88 */ 740, 660, 680, 260, 580, 260, 620, 500, + /* 96 */ 320, 680, 600, 560, 680, 560, 420, 620, + /* 104 */ 700, 380, 320, 700, 380, 960, 680, 600, + /* 112 */ 660, 620, 500, 540, 440, 680, 540, 860, + /* 120 */ 620, 600, 560, 300, 620, 300, 620, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 940, 1360, 360, + /* 144 */ 320, 320, 220, 220, 520, 520, 520, 500, + /* 152 */ 1000, 600, 1180, 920, 420, 420, 820, 820, + /* 160 */ 340, 320, 680, 680, 680, 680, 620, 620, + /* 168 */ 520, 780, 440, 380, 620, 280, 780, 480, + /* 176 */ 400, 600, 408, 408, 340, 680, 680, 340, + /* 184 */ 360, 408, 440, 380, 1020, 1020, 1020, 620, + /* 192 */ 720, 720, 720, 720, 720, 720, 1140, 700, + /* 200 */ 720, 720, 720, 720, 380, 380, 380, 380, + /* 208 */ 760, 740, 760, 760, 760, 760, 760, 600, + /* 216 */ 760, 740, 740, 740, 740, 660, 640, 660, + /* 224 */ 680, 680, 680, 680, 680, 680, 880, 560, + /* 232 */ 560, 560, 560, 560, 380, 380, 380, 380, + /* 240 */ 600, 680, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 680, 680, 680, 680, 600, 660, 600, + }, + { /* AvantGarde-Book */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 351, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 351, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1174, 606, + /* 144 */ 351, 351, 251, 251, 502, 484, 502, 500, + /* 152 */ 1000, 606, 1194, 1137, 553, 553, 487, 485, + /* 160 */ 277, 295, 554, 554, 554, 554, 672, 615, + /* 168 */ 369, 747, 369, 425, 606, 332, 747, 485, + /* 176 */ 400, 606, 332, 332, 375, 608, 564, 277, + /* 184 */ 324, 332, 369, 425, 831, 831, 831, 591, + /* 192 */ 740, 740, 740, 740, 740, 740, 992, 813, + /* 200 */ 536, 536, 536, 536, 226, 226, 226, 226, + /* 208 */ 790, 740, 869, 869, 869, 869, 869, 606, + /* 216 */ 868, 655, 655, 655, 655, 592, 592, 554, + /* 224 */ 683, 683, 683, 683, 683, 683, 1157, 647, + /* 232 */ 650, 650, 650, 650, 200, 200, 200, 200, + /* 240 */ 655, 610, 655, 655, 655, 655, 655, 606, + /* 248 */ 653, 608, 608, 608, 608, 536, 682, 536, + }, + { /* AvantGarde-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 280, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 280, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1280, 600, + /* 144 */ 280, 280, 240, 240, 480, 480, 480, 500, + /* 152 */ 1000, 600, 1060, 1080, 560, 560, 520, 520, + /* 160 */ 280, 280, 560, 560, 560, 560, 600, 560, + /* 168 */ 500, 740, 360, 460, 600, 420, 740, 420, + /* 176 */ 400, 600, 336, 336, 420, 576, 600, 280, + /* 184 */ 340, 336, 360, 460, 840, 840, 840, 560, + /* 192 */ 740, 740, 740, 740, 740, 740, 900, 780, + /* 200 */ 520, 520, 520, 520, 280, 280, 280, 280, + /* 208 */ 742, 740, 840, 840, 840, 840, 840, 600, + /* 216 */ 840, 640, 640, 640, 640, 620, 560, 600, + /* 224 */ 660, 660, 660, 660, 660, 660, 1080, 640, + /* 232 */ 640, 640, 640, 640, 240, 240, 240, 240, + /* 240 */ 640, 600, 640, 640, 640, 640, 640, 600, + /* 248 */ 660, 600, 600, 600, 600, 580, 660, 580, + }, + { /* AvantGarde-BookOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 351, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 351, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1174, 606, + /* 144 */ 351, 351, 251, 251, 502, 484, 502, 500, + /* 152 */ 1000, 606, 1194, 1137, 553, 553, 487, 485, + /* 160 */ 277, 295, 554, 554, 554, 554, 672, 615, + /* 168 */ 369, 747, 369, 425, 606, 332, 747, 485, + /* 176 */ 400, 606, 332, 332, 375, 608, 564, 277, + /* 184 */ 324, 332, 369, 425, 831, 831, 831, 591, + /* 192 */ 740, 740, 740, 740, 740, 740, 992, 813, + /* 200 */ 536, 536, 536, 536, 226, 226, 226, 226, + /* 208 */ 790, 740, 869, 869, 869, 869, 869, 606, + /* 216 */ 868, 655, 655, 655, 655, 592, 592, 554, + /* 224 */ 683, 683, 683, 683, 683, 683, 1157, 647, + /* 232 */ 650, 650, 650, 650, 200, 200, 200, 200, + /* 240 */ 655, 610, 655, 655, 655, 655, 655, 606, + /* 248 */ 653, 608, 608, 608, 608, 536, 682, 536, + }, + { /* AvantGarde-DemiOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 280, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 280, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1280, 600, + /* 144 */ 280, 280, 240, 240, 480, 480, 480, 500, + /* 152 */ 1000, 600, 1060, 1080, 560, 560, 520, 520, + /* 160 */ 280, 280, 560, 560, 560, 560, 600, 560, + /* 168 */ 500, 740, 360, 460, 600, 420, 740, 420, + /* 176 */ 400, 600, 336, 336, 420, 576, 600, 280, + /* 184 */ 340, 336, 360, 460, 840, 840, 840, 560, + /* 192 */ 740, 740, 740, 740, 740, 740, 900, 780, + /* 200 */ 520, 520, 520, 520, 280, 280, 280, 280, + /* 208 */ 742, 740, 840, 840, 840, 840, 840, 600, + /* 216 */ 840, 640, 640, 640, 640, 620, 560, 600, + /* 224 */ 660, 660, 660, 660, 660, 660, 1080, 640, + /* 232 */ 640, 640, 640, 640, 240, 240, 240, 240, + /* 240 */ 640, 600, 640, 640, 640, 640, 640, 600, + /* 248 */ 660, 600, 600, 600, 600, 580, 660, 580, + }, + { /* NewCenturySchlbk-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 296, 389, 556, 556, 833, 815, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 737, 722, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 556, 778, 667, 944, 815, 778, + /* 80 */ 667, 778, 722, 630, 667, 815, 722, 981, + /* 88 */ 704, 704, 611, 333, 606, 333, 606, 500, + /* 96 */ 204, 556, 556, 444, 574, 500, 333, 537, + /* 104 */ 611, 315, 296, 593, 315, 889, 611, 500, + /* 112 */ 574, 556, 444, 463, 389, 611, 537, 778, + /* 120 */ 537, 537, 481, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 204, 204, 259, 259, 389, 389, 389, 556, + /* 152 */ 1000, 606, 1000, 833, 500, 500, 611, 611, + /* 160 */ 278, 296, 556, 556, 556, 556, 606, 500, + /* 168 */ 333, 737, 334, 426, 606, 333, 737, 333, + /* 176 */ 400, 606, 333, 333, 333, 611, 606, 278, + /* 184 */ 333, 333, 300, 426, 834, 834, 834, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 722, 722, 722, 722, 407, 407, 407, 407, + /* 208 */ 778, 815, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 815, 815, 815, 815, 704, 667, 574, + /* 224 */ 556, 556, 556, 556, 556, 556, 796, 444, + /* 232 */ 500, 500, 500, 500, 315, 315, 315, 315, + /* 240 */ 500, 611, 500, 500, 500, 500, 500, 606, + /* 248 */ 500, 611, 611, 611, 611, 537, 574, 537, + }, + { /* NewCenturySchlbk-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 296, 333, 574, 574, 833, 852, 241, + /* 40 */ 389, 389, 500, 606, 278, 333, 278, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 278, 278, 606, 606, 606, 500, + /* 64 */ 747, 759, 778, 778, 833, 759, 722, 833, + /* 72 */ 870, 444, 648, 815, 722, 981, 833, 833, + /* 80 */ 759, 833, 815, 667, 722, 833, 759, 981, + /* 88 */ 722, 722, 667, 389, 606, 389, 606, 500, + /* 96 */ 241, 611, 648, 556, 667, 574, 389, 611, + /* 104 */ 685, 370, 352, 667, 352, 963, 685, 611, + /* 112 */ 667, 648, 519, 500, 426, 685, 611, 889, + /* 120 */ 611, 611, 537, 389, 606, 389, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 241, 241, 333, 333, 481, 481, 481, 500, + /* 152 */ 1000, 606, 1000, 907, 500, 500, 685, 685, + /* 160 */ 287, 296, 574, 574, 574, 574, 606, 500, + /* 168 */ 333, 747, 367, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 344, 344, 333, 685, 747, 278, + /* 184 */ 333, 344, 367, 500, 861, 861, 861, 500, + /* 192 */ 759, 759, 759, 759, 759, 759, 981, 778, + /* 200 */ 759, 759, 759, 759, 444, 444, 444, 444, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 833, 833, 833, 833, 722, 759, 611, + /* 224 */ 611, 611, 611, 611, 611, 611, 870, 556, + /* 232 */ 574, 574, 574, 574, 370, 370, 370, 370, + /* 240 */ 611, 685, 611, 611, 611, 611, 611, 606, + /* 248 */ 611, 685, 685, 685, 685, 611, 667, 611, + }, + { /* NewCenturySchlbk-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 400, 556, 556, 833, 852, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 606, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 747, 704, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 611, 741, 667, 944, 815, 778, + /* 80 */ 667, 778, 741, 667, 685, 815, 704, 926, + /* 88 */ 704, 685, 667, 333, 606, 333, 606, 500, + /* 96 */ 204, 574, 556, 444, 611, 444, 333, 537, + /* 104 */ 611, 333, 315, 556, 333, 889, 611, 500, + /* 112 */ 574, 556, 444, 444, 352, 611, 519, 778, + /* 120 */ 500, 500, 463, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 950, 1000, 606, + /* 144 */ 204, 204, 333, 333, 389, 389, 389, 500, + /* 152 */ 1000, 606, 981, 778, 500, 500, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 606, 500, + /* 168 */ 333, 747, 422, 426, 606, 333, 747, 333, + /* 176 */ 400, 606, 333, 333, 333, 611, 650, 278, + /* 184 */ 333, 333, 372, 426, 834, 834, 834, 444, + /* 192 */ 704, 704, 704, 704, 704, 704, 870, 722, + /* 200 */ 722, 722, 722, 722, 407, 407, 407, 407, + /* 208 */ 778, 815, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 815, 815, 815, 815, 685, 667, 556, + /* 224 */ 574, 574, 574, 574, 574, 574, 722, 444, + /* 232 */ 444, 444, 444, 444, 333, 333, 333, 333, + /* 240 */ 500, 611, 500, 500, 500, 500, 500, 606, + /* 248 */ 500, 611, 611, 611, 611, 500, 574, 500, + }, + { /* NewCenturySchlbk-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 333, 400, 574, 574, 889, 889, 259, + /* 40 */ 407, 407, 500, 606, 287, 333, 287, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 287, 287, 606, 606, 606, 481, + /* 64 */ 747, 741, 759, 759, 833, 741, 704, 815, + /* 72 */ 870, 444, 667, 778, 704, 944, 852, 833, + /* 80 */ 741, 833, 796, 685, 722, 833, 741, 944, + /* 88 */ 741, 704, 704, 407, 606, 407, 606, 500, + /* 96 */ 259, 667, 611, 537, 667, 519, 389, 611, + /* 104 */ 685, 389, 370, 648, 389, 944, 685, 574, + /* 112 */ 648, 630, 519, 481, 407, 685, 556, 833, + /* 120 */ 574, 519, 519, 407, 606, 407, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 950, 1167, 606, + /* 144 */ 259, 259, 278, 278, 481, 481, 481, 500, + /* 152 */ 1000, 606, 963, 852, 500, 500, 685, 685, + /* 160 */ 287, 333, 574, 574, 574, 574, 606, 500, + /* 168 */ 333, 747, 412, 481, 606, 333, 747, 333, + /* 176 */ 400, 606, 344, 344, 333, 685, 650, 287, + /* 184 */ 333, 344, 356, 481, 861, 861, 861, 481, + /* 192 */ 741, 741, 741, 741, 741, 741, 889, 759, + /* 200 */ 741, 741, 741, 741, 444, 444, 444, 444, + /* 208 */ 833, 852, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 833, 833, 833, 833, 704, 741, 574, + /* 224 */ 667, 667, 667, 667, 667, 667, 815, 537, + /* 232 */ 519, 519, 519, 519, 389, 389, 389, 389, + /* 240 */ 574, 685, 574, 574, 574, 574, 574, 606, + /* 248 */ 574, 685, 685, 685, 685, 519, 648, 519, + }, +}; +static unsigned short ausCharacterWidths2[32][256] = { + { /* Courier */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 740, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Times-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 408, 500, 500, 833, 778, 180, + /* 40 */ 333, 333, 500, 564, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 278, 278, 564, 564, 564, 444, + /* 64 */ 921, 722, 667, 667, 722, 611, 556, 722, + /* 72 */ 722, 333, 389, 722, 611, 889, 722, 722, + /* 80 */ 556, 722, 667, 556, 611, 722, 722, 944, + /* 88 */ 722, 722, 611, 333, 278, 333, 469, 500, + /* 96 */ 333, 444, 500, 444, 500, 444, 333, 500, + /* 104 */ 500, 278, 278, 500, 278, 778, 500, 500, + /* 112 */ 500, 500, 333, 389, 278, 500, 500, 722, + /* 120 */ 500, 500, 444, 480, 200, 480, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 611, 500, 611, 556, 500, + /* 168 */ 333, 556, 556, 611, 611, 333, 611, 611, + /* 176 */ 333, 444, 333, 278, 333, 348, 389, 333, + /* 184 */ 333, 389, 389, 278, 444, 333, 444, 444, + /* 192 */ 667, 722, 722, 722, 722, 611, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 722, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 564, + /* 216 */ 667, 722, 722, 722, 722, 722, 611, 500, + /* 224 */ 333, 444, 444, 444, 444, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 600, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 564, + /* 248 */ 333, 500, 500, 500, 500, 500, 278, 333, + }, + { /* Times-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 555, 500, 500, 1000, 833, 278, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 930, 722, 667, 722, 722, 667, 611, 778, + /* 72 */ 778, 389, 500, 778, 667, 944, 722, 778, + /* 80 */ 611, 778, 722, 556, 667, 722, 722, 1000, + /* 88 */ 722, 722, 667, 333, 278, 333, 581, 500, + /* 96 */ 333, 500, 556, 444, 556, 444, 333, 500, + /* 104 */ 556, 278, 333, 556, 278, 833, 556, 500, + /* 112 */ 556, 556, 444, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 394, 220, 394, 520, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 667, 500, 667, 556, 500, + /* 168 */ 333, 556, 556, 667, 667, 333, 667, 667, + /* 176 */ 333, 500, 333, 278, 333, 396, 389, 333, + /* 184 */ 333, 389, 389, 400, 444, 333, 444, 444, + /* 192 */ 722, 722, 722, 722, 722, 667, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 389, 389, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 570, + /* 216 */ 722, 722, 722, 722, 722, 722, 667, 556, + /* 224 */ 444, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 665, + /* 240 */ 556, 556, 556, 500, 500, 500, 500, 570, + /* 248 */ 444, 556, 556, 556, 556, 500, 333, 333, + }, + { /* Times-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 420, 500, 500, 833, 778, 214, + /* 40 */ 333, 333, 500, 675, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 675, 675, 675, 500, + /* 64 */ 920, 611, 611, 667, 722, 611, 611, 722, + /* 72 */ 722, 333, 444, 667, 556, 833, 667, 722, + /* 80 */ 611, 722, 611, 500, 556, 722, 611, 833, + /* 88 */ 611, 556, 556, 389, 278, 389, 422, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 722, 500, 500, + /* 112 */ 500, 500, 389, 389, 278, 500, 444, 667, + /* 120 */ 444, 444, 389, 400, 275, 400, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 611, 333, 556, 500, 556, 500, 500, + /* 168 */ 333, 500, 500, 556, 556, 333, 556, 556, + /* 176 */ 333, 500, 333, 278, 333, 278, 389, 333, + /* 184 */ 333, 389, 389, 278, 389, 333, 389, 389, + /* 192 */ 611, 611, 611, 611, 611, 556, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 722, + /* 208 */ 722, 667, 667, 722, 722, 722, 722, 675, + /* 216 */ 611, 722, 722, 722, 722, 556, 556, 500, + /* 224 */ 389, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 521, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 675, + /* 248 */ 389, 500, 500, 500, 500, 444, 278, 333, + }, + { /* Times-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 389, 555, 500, 500, 833, 778, 278, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 832, 667, 667, 667, 722, 667, 667, 722, + /* 72 */ 778, 389, 500, 667, 611, 889, 722, 722, + /* 80 */ 611, 722, 667, 556, 611, 722, 667, 889, + /* 88 */ 667, 611, 611, 333, 278, 333, 570, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 333, 500, + /* 104 */ 556, 278, 278, 500, 278, 778, 556, 500, + /* 112 */ 500, 500, 389, 389, 278, 556, 444, 667, + /* 120 */ 500, 444, 389, 348, 220, 348, 570, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 667, 333, 611, 500, 611, 556, 500, + /* 168 */ 333, 556, 556, 611, 611, 333, 611, 611, + /* 176 */ 333, 500, 333, 278, 333, 382, 389, 333, + /* 184 */ 333, 389, 389, 345, 389, 333, 389, 389, + /* 192 */ 667, 667, 667, 667, 667, 611, 667, 667, + /* 200 */ 667, 667, 667, 667, 667, 389, 389, 722, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 570, + /* 216 */ 667, 722, 722, 722, 722, 611, 611, 500, + /* 224 */ 389, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 600, + /* 240 */ 500, 556, 556, 500, 500, 500, 500, 570, + /* 248 */ 389, 556, 556, 556, 556, 444, 278, 333, + }, + { /* Helvetica */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 191, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 333, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 667, 333, 556, 556, 556, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 222, 333, 292, 500, 333, + /* 184 */ 333, 500, 500, 308, 500, 333, 500, 500, + /* 192 */ 722, 667, 667, 667, 667, 556, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 666, 611, 611, + /* 224 */ 333, 556, 556, 556, 556, 222, 500, 500, + /* 232 */ 500, 556, 556, 556, 556, 278, 278, 635, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 333, 556, 556, 556, 556, 500, 278, 333, + }, + { /* Helvetica-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 238, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 333, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 611, 556, 611, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 278, 333, 369, 556, 333, + /* 184 */ 333, 556, 556, 385, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 389, 556, 556, 556, 556, 278, 556, 556, + /* 232 */ 556, 556, 556, 556, 556, 278, 278, 707, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Helvetica-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 191, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 333, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 667, 333, 556, 556, 556, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 222, 333, 307, 500, 333, + /* 184 */ 333, 500, 500, 319, 500, 333, 500, 500, + /* 192 */ 722, 667, 667, 667, 667, 556, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 333, 556, 556, 556, 556, 222, 500, 500, + /* 232 */ 500, 556, 556, 556, 556, 278, 278, 650, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 333, 556, 556, 556, 556, 500, 278, 333, + }, + { /* Helvetica-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 238, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 333, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 611, 556, 611, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 278, 333, 384, 556, 333, + /* 184 */ 333, 556, 556, 404, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 389, 556, 556, 556, 556, 278, 556, 556, + /* 232 */ 556, 556, 556, 556, 556, 278, 278, 722, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Palatino-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 371, 500, 500, 840, 778, 208, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 606, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 611, 709, 774, 611, 556, 763, + /* 72 */ 832, 337, 333, 726, 611, 946, 831, 786, + /* 80 */ 604, 786, 668, 525, 613, 778, 722, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 500, 553, 444, 611, 479, 333, 556, + /* 104 */ 582, 291, 234, 556, 291, 883, 582, 546, + /* 112 */ 601, 560, 395, 424, 326, 603, 565, 834, + /* 120 */ 516, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 778, 333, 611, 500, 611, 525, 500, + /* 168 */ 333, 525, 525, 613, 667, 333, 667, 667, + /* 176 */ 333, 500, 313, 291, 333, 375, 424, 333, + /* 184 */ 333, 424, 424, 375, 500, 380, 500, 500, + /* 192 */ 668, 778, 778, 778, 778, 611, 709, 709, + /* 200 */ 709, 611, 611, 611, 611, 337, 337, 774, + /* 208 */ 774, 831, 831, 786, 786, 786, 786, 606, + /* 216 */ 668, 778, 778, 778, 778, 667, 613, 556, + /* 224 */ 395, 500, 500, 500, 500, 291, 444, 444, + /* 232 */ 444, 479, 479, 479, 479, 287, 287, 671, + /* 240 */ 611, 582, 582, 546, 546, 546, 546, 606, + /* 248 */ 395, 603, 603, 603, 603, 556, 326, 250, + }, + { /* Palatino-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 402, 500, 500, 889, 833, 227, + /* 40 */ 333, 333, 444, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 667, 722, 833, 611, 556, 833, + /* 72 */ 833, 389, 389, 778, 611, 1000, 833, 833, + /* 80 */ 611, 833, 722, 611, 667, 778, 778, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 500, 611, 444, 611, 500, 389, 556, + /* 104 */ 611, 333, 333, 611, 333, 889, 611, 556, + /* 112 */ 611, 611, 389, 444, 333, 611, 556, 833, + /* 120 */ 500, 556, 500, 310, 606, 310, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 778, 333, 611, 500, 611, 611, 500, + /* 168 */ 333, 611, 611, 667, 667, 333, 667, 667, + /* 176 */ 333, 500, 333, 333, 333, 433, 444, 333, + /* 184 */ 333, 444, 444, 402, 500, 333, 500, 500, + /* 192 */ 722, 778, 778, 778, 778, 611, 722, 722, + /* 200 */ 722, 611, 611, 611, 611, 389, 389, 833, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 722, 778, 778, 778, 778, 667, 667, 611, + /* 224 */ 389, 500, 500, 500, 500, 333, 444, 444, + /* 232 */ 444, 500, 500, 500, 500, 333, 333, 711, + /* 240 */ 611, 611, 611, 556, 556, 556, 556, 606, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Palatino-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 778, 333, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 500, + /* 64 */ 747, 722, 611, 667, 778, 611, 556, 722, + /* 72 */ 778, 333, 333, 667, 556, 944, 778, 778, + /* 80 */ 611, 778, 667, 556, 611, 778, 722, 944, + /* 88 */ 722, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 444, 463, 407, 500, 389, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 778, 556, 444, + /* 112 */ 500, 463, 389, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 556, 500, 556, 556, 500, + /* 168 */ 333, 556, 556, 611, 667, 333, 667, 667, + /* 176 */ 333, 444, 333, 278, 333, 346, 389, 333, + /* 184 */ 333, 389, 389, 361, 444, 333, 444, 444, + /* 192 */ 667, 722, 722, 722, 722, 556, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 778, + /* 208 */ 778, 778, 778, 778, 778, 778, 778, 606, + /* 216 */ 667, 778, 778, 778, 778, 667, 611, 500, + /* 224 */ 389, 444, 444, 444, 444, 278, 407, 407, + /* 232 */ 407, 389, 389, 389, 389, 278, 278, 577, + /* 240 */ 500, 556, 556, 444, 444, 444, 444, 606, + /* 248 */ 389, 556, 556, 556, 556, 500, 333, 333, + }, + { /* Palatino-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 833, 250, + /* 40 */ 333, 333, 444, 606, 250, 389, 250, 315, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 833, 722, 667, 685, 778, 611, 556, 778, + /* 72 */ 778, 389, 389, 722, 611, 944, 778, 833, + /* 80 */ 667, 833, 722, 556, 611, 778, 667, 1000, + /* 88 */ 722, 611, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 556, 537, 444, 556, 444, 333, 500, + /* 104 */ 556, 333, 333, 556, 333, 833, 556, 556, + /* 112 */ 556, 537, 389, 444, 389, 556, 556, 833, + /* 120 */ 500, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 611, 500, 611, 556, 556, + /* 168 */ 333, 556, 556, 611, 667, 389, 667, 667, + /* 176 */ 556, 556, 333, 333, 333, 429, 444, 333, + /* 184 */ 333, 444, 444, 389, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 685, 685, + /* 200 */ 685, 611, 611, 611, 611, 389, 389, 778, + /* 208 */ 778, 778, 778, 833, 833, 833, 833, 606, + /* 216 */ 722, 778, 778, 778, 778, 611, 611, 556, + /* 224 */ 389, 556, 556, 556, 556, 333, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 333, 333, 667, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 606, + /* 248 */ 389, 556, 556, 556, 556, 556, 389, 333, + }, + { /* Helvetica-Narrow */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 157, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 273, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 547, 273, 456, 456, 456, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 182, 273, 212, 410, 273, + /* 184 */ 273, 410, 410, 248, 410, 273, 410, 410, + /* 192 */ 592, 547, 547, 547, 547, 456, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 273, 456, 456, 456, 456, 182, 410, 410, + /* 232 */ 410, 456, 456, 456, 456, 228, 228, 496, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 273, 456, 456, 456, 456, 410, 228, 273, + }, + { /* Helvetica-Narrow-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 195, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 273, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 592, 273, 501, 456, 501, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 228, 273, 280, 456, 273, + /* 184 */ 273, 456, 456, 338, 410, 273, 410, 410, + /* 192 */ 592, 592, 592, 592, 592, 501, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 319, 456, 456, 456, 456, 228, 456, 456, + /* 232 */ 456, 456, 456, 456, 456, 228, 228, 561, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 319, 501, 501, 501, 501, 456, 273, 273, + }, + { /* Helvetica-Narrow-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 157, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 273, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 547, 273, 456, 456, 456, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 182, 273, 217, 410, 273, + /* 184 */ 273, 410, 410, 254, 410, 273, 410, 410, + /* 192 */ 592, 547, 547, 547, 547, 456, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 273, 456, 456, 456, 456, 182, 410, 410, + /* 232 */ 410, 456, 456, 456, 456, 228, 228, 503, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 273, 456, 456, 456, 456, 410, 228, 273, + }, + { /* Helvetica-Narrow-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 195, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 273, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 592, 273, 501, 456, 501, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 228, 273, 283, 456, 273, + /* 184 */ 273, 456, 456, 312, 410, 273, 410, 410, + /* 192 */ 592, 592, 592, 592, 592, 501, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 319, 456, 456, 456, 456, 228, 456, 456, + /* 232 */ 456, 456, 456, 456, 456, 228, 228, 561, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 319, 501, 501, 501, 501, 456, 273, 273, + }, + { /* Bookman-Light */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 320, 300, 380, 620, 620, 900, 800, 220, + /* 40 */ 300, 300, 440, 600, 320, 400, 320, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 320, 320, 600, 600, 600, 540, + /* 64 */ 820, 680, 740, 740, 800, 720, 640, 800, + /* 72 */ 800, 340, 600, 720, 600, 920, 740, 800, + /* 80 */ 620, 820, 720, 660, 620, 780, 700, 960, + /* 88 */ 720, 640, 640, 300, 600, 300, 600, 500, + /* 96 */ 340, 580, 620, 520, 620, 520, 320, 540, + /* 104 */ 660, 300, 300, 620, 300, 940, 660, 560, + /* 112 */ 620, 580, 440, 520, 380, 680, 520, 780, + /* 120 */ 560, 540, 480, 280, 600, 280, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 320, 680, 460, 600, 620, 600, 660, 520, + /* 168 */ 420, 660, 660, 620, 640, 400, 640, 640, + /* 176 */ 320, 580, 320, 320, 340, 336, 520, 420, + /* 184 */ 320, 520, 520, 380, 480, 380, 480, 480, + /* 192 */ 720, 680, 680, 680, 680, 600, 740, 740, + /* 200 */ 740, 720, 720, 720, 720, 340, 340, 800, + /* 208 */ 800, 740, 740, 800, 800, 800, 800, 600, + /* 216 */ 720, 780, 780, 780, 780, 640, 620, 660, + /* 224 */ 440, 580, 580, 580, 580, 300, 520, 520, + /* 232 */ 520, 520, 520, 520, 520, 300, 300, 620, + /* 240 */ 620, 660, 660, 560, 560, 560, 560, 600, + /* 248 */ 440, 680, 680, 680, 680, 540, 380, 260, + }, + { /* Bookman-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 360, 420, 660, 660, 940, 800, 240, + /* 40 */ 320, 320, 460, 600, 340, 360, 340, 600, + /* 48 */ 660, 660, 660, 660, 660, 660, 660, 660, + /* 56 */ 660, 660, 340, 340, 600, 600, 600, 660, + /* 64 */ 820, 720, 720, 740, 780, 720, 680, 780, + /* 72 */ 820, 400, 640, 800, 640, 940, 740, 800, + /* 80 */ 660, 800, 780, 660, 700, 740, 720, 940, + /* 88 */ 780, 700, 640, 300, 600, 300, 600, 500, + /* 96 */ 400, 580, 600, 580, 640, 580, 380, 580, + /* 104 */ 680, 360, 340, 660, 340, 1000, 680, 620, + /* 112 */ 640, 620, 460, 520, 460, 660, 600, 800, + /* 120 */ 600, 620, 560, 320, 600, 320, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 340, 720, 500, 640, 660, 640, 660, 600, + /* 168 */ 500, 660, 660, 700, 640, 360, 640, 640, + /* 176 */ 340, 580, 320, 340, 400, 430, 520, 500, + /* 184 */ 360, 520, 520, 470, 560, 440, 560, 560, + /* 192 */ 780, 720, 720, 720, 720, 640, 740, 740, + /* 200 */ 740, 720, 720, 720, 720, 400, 400, 780, + /* 208 */ 780, 740, 740, 800, 800, 800, 800, 600, + /* 216 */ 780, 740, 740, 740, 740, 700, 700, 660, + /* 224 */ 460, 580, 580, 580, 580, 340, 580, 580, + /* 232 */ 580, 580, 580, 580, 580, 360, 360, 720, + /* 240 */ 640, 680, 680, 620, 620, 620, 620, 600, + /* 248 */ 460, 660, 660, 660, 660, 620, 460, 320, + }, + { /* Bookman-LightItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 300, 320, 360, 620, 620, 800, 820, 200, + /* 40 */ 280, 280, 440, 600, 300, 320, 300, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 300, 300, 600, 600, 600, 540, + /* 64 */ 780, 700, 720, 720, 740, 680, 620, 760, + /* 72 */ 800, 320, 560, 720, 580, 860, 720, 760, + /* 80 */ 600, 780, 700, 640, 600, 720, 680, 960, + /* 88 */ 700, 660, 580, 260, 600, 260, 600, 500, + /* 96 */ 340, 620, 600, 480, 640, 540, 340, 560, + /* 104 */ 620, 280, 280, 600, 280, 880, 620, 540, + /* 112 */ 600, 560, 400, 540, 340, 620, 540, 880, + /* 120 */ 540, 600, 520, 360, 600, 380, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 300, 700, 440, 580, 620, 580, 640, 620, + /* 168 */ 420, 640, 640, 600, 580, 320, 580, 580, + /* 176 */ 300, 620, 260, 340, 320, 380, 540, 440, + /* 184 */ 320, 540, 540, 340, 520, 340, 520, 520, + /* 192 */ 700, 700, 700, 700, 700, 580, 720, 720, + /* 200 */ 720, 680, 680, 680, 680, 320, 320, 740, + /* 208 */ 740, 720, 720, 760, 760, 760, 760, 600, + /* 216 */ 700, 720, 720, 720, 720, 660, 600, 620, + /* 224 */ 400, 620, 620, 620, 620, 280, 480, 480, + /* 232 */ 480, 540, 540, 540, 540, 280, 280, 730, + /* 240 */ 640, 620, 620, 540, 540, 540, 540, 600, + /* 248 */ 400, 620, 620, 620, 620, 600, 340, 260, + }, + { /* Bookman-DemiItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 320, 380, 680, 680, 880, 980, 180, + /* 40 */ 260, 260, 460, 600, 340, 280, 340, 360, + /* 48 */ 680, 680, 680, 680, 680, 680, 680, 680, + /* 56 */ 680, 680, 340, 340, 620, 600, 620, 620, + /* 64 */ 780, 720, 720, 700, 760, 720, 660, 760, + /* 72 */ 800, 380, 620, 780, 640, 860, 740, 760, + /* 80 */ 640, 760, 740, 700, 700, 740, 660, 1000, + /* 88 */ 740, 660, 680, 260, 580, 260, 620, 500, + /* 96 */ 380, 680, 600, 560, 680, 560, 420, 620, + /* 104 */ 700, 380, 320, 700, 380, 960, 680, 600, + /* 112 */ 660, 620, 500, 540, 440, 680, 540, 860, + /* 120 */ 620, 600, 560, 300, 620, 300, 620, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 340, 720, 460, 640, 680, 640, 700, 620, + /* 168 */ 520, 700, 700, 700, 680, 280, 680, 680, + /* 176 */ 360, 680, 320, 380, 340, 509, 540, 480, + /* 184 */ 360, 540, 540, 520, 560, 560, 560, 560, + /* 192 */ 740, 720, 720, 720, 720, 640, 700, 700, + /* 200 */ 700, 720, 720, 720, 720, 380, 380, 760, + /* 208 */ 760, 740, 740, 760, 760, 760, 760, 600, + /* 216 */ 740, 740, 740, 740, 740, 660, 700, 660, + /* 224 */ 500, 680, 680, 680, 680, 380, 560, 560, + /* 232 */ 560, 560, 560, 560, 560, 380, 380, 810, + /* 240 */ 680, 680, 680, 600, 600, 600, 600, 600, + /* 248 */ 500, 680, 680, 680, 680, 600, 440, 380, + }, + { /* AvantGarde-Book */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 198, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 378, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 277, 740, 453, 517, 554, 462, 498, 615, + /* 168 */ 369, 498, 498, 426, 480, 332, 480, 480, + /* 176 */ 332, 683, 302, 300, 375, 245, 388, 502, + /* 184 */ 324, 388, 388, 339, 425, 552, 425, 425, + /* 192 */ 607, 740, 740, 740, 740, 462, 813, 813, + /* 200 */ 813, 536, 536, 536, 536, 226, 226, 744, + /* 208 */ 790, 740, 740, 869, 869, 869, 869, 606, + /* 216 */ 607, 655, 655, 655, 655, 592, 426, 554, + /* 224 */ 301, 683, 683, 683, 683, 200, 647, 647, + /* 232 */ 647, 650, 650, 650, 650, 200, 200, 725, + /* 240 */ 685, 610, 610, 655, 655, 655, 655, 606, + /* 248 */ 301, 608, 608, 608, 608, 536, 339, 222, + }, + { /* AvantGarde-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 220, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 420, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 280, 740, 480, 480, 560, 440, 520, 560, + /* 168 */ 500, 520, 520, 420, 500, 420, 500, 500, + /* 176 */ 360, 660, 340, 320, 420, 330, 440, 540, + /* 184 */ 340, 440, 440, 369, 460, 700, 460, 460, + /* 192 */ 580, 740, 740, 740, 740, 440, 780, 780, + /* 200 */ 780, 520, 520, 520, 520, 280, 280, 700, + /* 208 */ 742, 740, 740, 840, 840, 840, 840, 600, + /* 216 */ 580, 640, 640, 640, 640, 620, 420, 600, + /* 224 */ 320, 660, 660, 660, 660, 240, 640, 640, + /* 232 */ 640, 640, 640, 640, 640, 240, 240, 754, + /* 240 */ 660, 600, 600, 640, 640, 640, 640, 600, + /* 248 */ 320, 600, 600, 600, 600, 580, 300, 280, + }, + { /* AvantGarde-BookOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 198, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 378, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 277, 740, 453, 517, 554, 462, 498, 615, + /* 168 */ 369, 498, 498, 426, 480, 332, 480, 480, + /* 176 */ 332, 683, 302, 300, 375, 231, 388, 502, + /* 184 */ 324, 388, 388, 339, 425, 552, 425, 425, + /* 192 */ 607, 740, 740, 740, 740, 462, 813, 813, + /* 200 */ 813, 536, 536, 536, 536, 226, 226, 744, + /* 208 */ 790, 740, 740, 869, 869, 869, 869, 606, + /* 216 */ 607, 655, 655, 655, 655, 592, 426, 554, + /* 224 */ 301, 683, 683, 683, 683, 200, 647, 647, + /* 232 */ 647, 650, 650, 650, 650, 200, 200, 714, + /* 240 */ 685, 610, 610, 655, 655, 655, 655, 606, + /* 248 */ 301, 608, 608, 608, 608, 536, 339, 222, + }, + { /* AvantGarde-DemiOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 220, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 420, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 280, 740, 480, 480, 560, 440, 520, 560, + /* 168 */ 500, 520, 520, 420, 500, 420, 500, 500, + /* 176 */ 360, 660, 340, 320, 420, 326, 440, 540, + /* 184 */ 340, 440, 440, 364, 460, 700, 460, 460, + /* 192 */ 580, 740, 740, 740, 740, 440, 780, 780, + /* 200 */ 780, 520, 520, 520, 520, 280, 280, 700, + /* 208 */ 742, 740, 740, 840, 840, 840, 840, 600, + /* 216 */ 580, 640, 640, 640, 640, 620, 420, 600, + /* 224 */ 320, 660, 660, 660, 660, 240, 640, 640, + /* 232 */ 640, 640, 640, 640, 640, 240, 240, 752, + /* 240 */ 660, 600, 600, 640, 640, 640, 640, 600, + /* 248 */ 320, 600, 600, 600, 600, 580, 300, 280, + }, + { /* NewCenturySchlbk-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 296, 389, 556, 556, 833, 815, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 737, 722, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 556, 778, 667, 944, 815, 778, + /* 80 */ 667, 778, 722, 630, 667, 815, 722, 981, + /* 88 */ 704, 704, 611, 333, 606, 333, 606, 500, + /* 96 */ 333, 556, 556, 444, 574, 500, 333, 537, + /* 104 */ 611, 315, 296, 593, 315, 889, 611, 500, + /* 112 */ 574, 556, 444, 463, 389, 611, 537, 778, + /* 120 */ 537, 537, 481, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 667, 556, 667, 630, 500, + /* 168 */ 333, 630, 630, 667, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 315, 333, 339, 463, 333, + /* 184 */ 333, 463, 463, 389, 481, 333, 481, 481, + /* 192 */ 722, 722, 722, 722, 722, 667, 722, 722, + /* 200 */ 722, 722, 722, 722, 722, 407, 407, 778, + /* 208 */ 778, 815, 815, 778, 778, 778, 778, 606, + /* 216 */ 722, 815, 815, 815, 815, 704, 667, 574, + /* 224 */ 444, 556, 556, 556, 556, 315, 444, 444, + /* 232 */ 444, 500, 500, 500, 500, 315, 315, 606, + /* 240 */ 574, 611, 611, 500, 500, 500, 500, 606, + /* 248 */ 444, 611, 611, 611, 611, 537, 389, 333, + }, + { /* NewCenturySchlbk-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 296, 333, 574, 574, 833, 852, 241, + /* 40 */ 389, 389, 500, 606, 278, 333, 278, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 278, 278, 606, 606, 606, 500, + /* 64 */ 747, 759, 778, 778, 833, 759, 722, 833, + /* 72 */ 870, 444, 648, 815, 722, 981, 833, 833, + /* 80 */ 759, 833, 815, 667, 722, 833, 759, 981, + /* 88 */ 722, 722, 667, 389, 606, 389, 606, 500, + /* 96 */ 333, 611, 648, 556, 667, 574, 389, 611, + /* 104 */ 685, 370, 352, 667, 352, 963, 685, 611, + /* 112 */ 667, 648, 519, 500, 426, 685, 611, 889, + /* 120 */ 611, 611, 537, 389, 606, 389, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 287, 759, 333, 722, 574, 722, 667, 500, + /* 168 */ 333, 667, 667, 722, 667, 333, 667, 667, + /* 176 */ 333, 611, 333, 352, 333, 436, 500, 333, + /* 184 */ 333, 500, 500, 446, 537, 333, 537, 537, + /* 192 */ 815, 759, 759, 759, 759, 722, 778, 778, + /* 200 */ 778, 759, 759, 759, 759, 444, 444, 833, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 815, 833, 833, 833, 833, 722, 722, 611, + /* 224 */ 519, 611, 611, 611, 611, 352, 556, 556, + /* 232 */ 556, 574, 574, 574, 574, 370, 370, 747, + /* 240 */ 667, 685, 685, 611, 611, 611, 611, 606, + /* 248 */ 519, 685, 685, 685, 685, 611, 426, 333, + }, + { /* NewCenturySchlbk-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 400, 556, 556, 833, 852, 278, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 606, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 747, 704, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 611, 741, 667, 944, 815, 778, + /* 80 */ 667, 778, 741, 667, 685, 815, 704, 926, + /* 88 */ 704, 685, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 574, 556, 444, 611, 444, 333, 537, + /* 104 */ 611, 333, 315, 556, 333, 889, 611, 500, + /* 112 */ 574, 556, 444, 444, 352, 611, 519, 778, + /* 120 */ 500, 500, 463, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 704, 333, 667, 556, 667, 667, 500, + /* 168 */ 333, 667, 667, 685, 667, 333, 667, 667, + /* 176 */ 333, 574, 333, 333, 333, 359, 444, 333, + /* 184 */ 333, 444, 444, 368, 463, 333, 463, 463, + /* 192 */ 741, 704, 704, 704, 704, 667, 722, 722, + /* 200 */ 722, 722, 722, 722, 722, 407, 407, 778, + /* 208 */ 778, 815, 815, 778, 778, 778, 778, 606, + /* 216 */ 741, 815, 815, 815, 815, 685, 685, 556, + /* 224 */ 444, 574, 574, 574, 574, 333, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 333, 333, 651, + /* 240 */ 611, 611, 611, 500, 500, 500, 500, 606, + /* 248 */ 444, 611, 611, 611, 611, 500, 352, 333, + }, + { /* NewCenturySchlbk-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 333, 400, 574, 574, 889, 889, 287, + /* 40 */ 407, 407, 500, 606, 287, 333, 287, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 287, 287, 606, 606, 606, 481, + /* 64 */ 747, 741, 759, 759, 833, 741, 704, 815, + /* 72 */ 870, 444, 667, 778, 704, 944, 852, 833, + /* 80 */ 741, 833, 796, 685, 722, 833, 741, 944, + /* 88 */ 741, 704, 704, 407, 606, 407, 606, 500, + /* 96 */ 333, 667, 611, 537, 667, 519, 389, 611, + /* 104 */ 685, 389, 370, 648, 389, 944, 685, 574, + /* 112 */ 648, 630, 519, 481, 407, 685, 556, 833, + /* 120 */ 574, 519, 519, 407, 606, 407, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 287, 741, 333, 704, 574, 704, 685, 500, + /* 168 */ 333, 685, 685, 722, 704, 333, 704, 704, + /* 176 */ 333, 667, 333, 389, 333, 486, 481, 333, + /* 184 */ 333, 481, 481, 483, 519, 333, 519, 519, + /* 192 */ 796, 741, 741, 741, 741, 704, 759, 759, + /* 200 */ 759, 741, 741, 741, 741, 444, 444, 833, + /* 208 */ 833, 852, 852, 833, 833, 833, 833, 606, + /* 216 */ 796, 833, 833, 833, 833, 704, 722, 574, + /* 224 */ 519, 667, 667, 667, 667, 389, 537, 537, + /* 232 */ 537, 519, 519, 519, 519, 389, 389, 780, + /* 240 */ 667, 685, 685, 574, 574, 574, 574, 606, + /* 248 */ 519, 685, 685, 685, 685, 519, 407, 333, + }, +}; +#if 0 /* Until this array is needed */ +static int aiUnderlineInfo[32][2] = { + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -151, 50 }, + { -155, 69 }, + { -151, 50 }, + { -111, 69 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -125, 60 }, + { -125, 60 }, + { -125, 60 }, + { -125, 60 }, + { -96, 58 }, + { -93, 90 }, + { -96, 58 }, + { -93, 90 }, + { -104, 61 }, + { -103, 90 }, + { -102, 42 }, + { -102, 54 }, +}; +#endif /* 0 */ diff --git a/Unix-only/fontinfo.pl b/Unix-only/fontinfo.pl new file mode 100755 index 0000000..d117c8d --- /dev/null +++ b/Unix-only/fontinfo.pl @@ -0,0 +1,207 @@ +#! /usr/bin/perl -w +# +# Generate the fontinformation tables for the required fonts (Linux version) +# + +@charnames1 = ( +"ellipsis", "trademark", "perthousand", "bullet", +"quoteleft", "quoteright", "guilsinglleft", "guilsinglright", +"quotedblleft", "quotedblright", "quotedblbase", "endash", "emdash", +"minus", "OE", "oe", "dagger", "daggerdbl", "fi", "fl", +"space", "exclamdown", "cent", "sterling", "currency", +"yen", "brokenbar", "section", "dieresis", "copyright", +"ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", +"macron", "degree", "plusminus", "twosuperior", "threesuperior", +"acute", "mu", "paragraph", "periodcentered", "cedilla", +"onesuperior", "ordmasculine", "guillemotright", "onequarter", +"onehalf", "threequarters", "questiondown", "Agrave", "Aacute", +"Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", +"Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", +"Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", +"Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", +"Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", +"germandbls", "agrave", "aacute", "acircumflex", "atilde", +"adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", +"ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", +"idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", +"otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", +"ucircumflex", "udieresis", "yacute", "thorn", "ydieresis" +); + +@charnames2 = ( +"space", "Aogonek", "breve", "Lslash", "currency", "Lcaron", +"Sacute", "section", "dieresis", "Scaron", "Scedilla", +"Tcaron", "Zacute", "hyphen", "Zcaron", "Zdotaccent", "ring", +"aogonek", "ogonek", "lslash", "acute", "lcaron", "sacute", +"caron", "cedilla", "scaron", "scedilla", "tcaron", +"zacute", "hungarumlaut", "zcaron", "zdotaccent", "Racute", +"Aacute", "Acircumflex", "Abreve", "Adieresis", "Lacute", +"Cacute", "Ccedilla", "Ccaron", "Eacute", "Eogonek", +"Edieresis", "Ecaron", "Iacute", "Icircumflex", "Dcaron", +"Dslash", "Nacute", "Ncaron", "Oacute", "Ocircumflex", +"Ohungarumlaut", "Odieresis", "multiply", "Rcaron", "Uring", +"Uacute", "Uhungarumlaut", "Udieresis", "Yacute", "Tcommaaccent", +"germandbls", "racute", "aacute", "acircumflex", "abreve", +"adieresis", "lacute", "cacute", "ccedilla", "ccaron", "eacute", +"eogonek", "edieresis", "ecaron", "iacute", "icircumflex", +"dcaron", "dmacron", "nacute", "ncaron", "oacute", "ocircumflex", +"ohungarumlaut", "odieresis", "divide", "rcaron", "uring", +"uacute", "uhungarumlaut", "udieresis", "yacute", "tcommaaccent", +"dotaccent" +); + +$gs_dir1 = '/usr/share/ghostscript/fonts'; +$gs_dir2 = '/usr/share/ghostscript/fonts2'; + +@fontnames = ( +"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", +"Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", +"Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", +"Palatino-Roman", "Palatino-Bold", "Palatino-Italic", "Palatino-BoldItalic", +"Helvetica-Narrow", "Helvetica-Narrow-Bold", "Helvetica-Narrow-Oblique", "Helvetica-Narrow-BoldOblique", +"Bookman-Light", "Bookman-Demi", "Bookman-LightItalic", "Bookman-DemiItalic", +"AvantGarde-Book", "AvantGarde-Demi", "AvantGarde-BookOblique", "AvantGarde-DemiOblique", +"NewCenturySchlbk-Roman", "NewCenturySchlbk-Bold", "NewCenturySchlbk-Italic", "NewCenturySchlbk-BoldItalic", +); + +@files = ( +"n022003l.afm", "n022004l.afm", "n022023l.afm", "n022024l.afm", +"n021003l.afm", "n021004l.afm", "n021023l.afm", "n021024l.afm", +"n019003l.afm", "n019004l.afm", "n019023l.afm", "n019024l.afm", +"p052003l.afm", "p052004l.afm", "p052023l.afm", "p052024l.afm", +"n019043l.afm", "n019044l.afm", "n019063l.afm", "n019064l.afm", +"b018012l.afm", "b018015l.afm", "b018032l.afm", "b018035l.afm", +"a010013l.afm", "a010015l.afm", "a010033l.afm", "a010035l.afm", +"c059013l.afm", "c059016l.afm", "c059033l.afm", "c059036l.afm", +); + + +# Generate the array with the fontnames +sub generate_fontnames +{ + printf STDOUT "static const char *szFontnames[%d] = {\n", $#fontnames + 1; + for ($n = 0; $n <= $#fontnames; $n++) { + printf STDOUT "\t\"%s\",\n", $fontnames[$n]; + } + printf STDOUT "};\n"; +} + +# Generate the array with the character widths +sub generate_character_widths +{ + my ($char_set, $gs_dir, @charnames) = @_; + my ($n, $i, $file, $name, $start); + my (@a, @charwidth); + + if ($char_set == 1) { + $start = 140; + } else { + $start = 160; + } + printf STDOUT "static unsigned short ausCharacterWidths%d[%d][256] = {\n", $char_set, $#files + 1; + for ($n = 0; $n <= $#files; $n++) { + $file = $files[$n]; + $name = $fontnames[$n]; + open(F_IN, "<$gs_dir/$file") || die "Cannot open $gs_dir/$file"; + printf STDOUT "\t{\t/* %s */\n", $name; + while () { + chop(); + @a = split(/\s+/); + if ($a[0] eq 'UnderlinePosition') { + $underlineposition[$n] = $a[1]; + } elsif ($a[0] eq 'UnderlineThickness') { + #printf STDERR "%d %d\n", $a[0], $a[1]; + $underlinethickness[$n] = $a[1]; + } elsif ($a[0] eq 'C' && $a[2] eq ';' && $a[3] eq 'WX') { + #printf STDERR "%d %d %s\n", $a[1], $a[4], $a[7]; + if (($a[1] < 0 || $a[1] >= 129) && defined($a[7])) { + for ($i = 0; $i <= $#charnames; $i++) { + if ($charnames[$i] eq $a[7]) { + $charwidth[$start + $i] = $a[4]; + last; + } + } + } + if ($a[1] >= 0 && $a[1] <= 128 && !defined($charwidth[$a[1]])) { + $charwidth[$a[1]] = $a[4]; + } + } + if (defined($a[7])) { + for ($i = 0; $i <= $#charnames; $i++) { + if ($charnames[$i] eq $a[7]) { + $charwidth[$start + $i] = $a[4]; + last; + } + } + } + } + close(F_IN); + + # Set the width of the control characters zero + for ($i = 0; $i < 32; $i++) { + $charwidth[$i] = 0; + } + # Set the width of the unused characters to zero + for ($i = 127; $i < $start; $i++) { + $charwidth[$i] = 0; + } + + # Print the results + for ($i = 0; $i < 256; $i += 8) { + printf STDOUT "\t/* %3d */ ", $i; + for ($j = 0; $j < 8; $j++) { + if (!defined($charwidth[$i + $j])) { + printf STDERR "%d:%s: character %3d is undefined\n", $char_set, $name, $i + $j; + $charwidth[$i + $j] = 0; + } + printf STDOUT "%5d,", $charwidth[$i + $j]; + } + printf STDOUT "\n"; + } + printf STDOUT "\t},\n"; + undef @charwidth; + } + printf STDOUT "};\n"; +} + +# Generate the array with the underline information +sub generate_underline_information +{ + printf STDOUT "#if 0 /* Until this array is needed */\n"; + + printf STDOUT "static int aiUnderlineInfo[%d][2] = {\n", $#fontnames + 1; + for ($n = 0; $n <= $#fontnames; $n++) { + if (!defined($underlineposition[$n])) { + $underlineposition[$n] = 0; + } + if (!defined($underlinethickness[$n])) { + $underlinethickness[$n] = 0; + } + printf STDOUT "\t{ %d, %d },\n", $underlineposition[$n], $underlinethickness[$n]; + } + printf STDOUT "};\n"; + + printf STDOUT "#endif /* 0 */\n"; +} + + +# main() + +if ($#fontnames != $#files) { + die "The fontnames-array and the files-array are of unequel length"; +} +if ($#charnames1 != 255 - 140) { + die "The charname1 table length is $#charnames1"; +} +if ($#charnames2 != 255 - 160) { + die "The charname2 table length is $#charnames2"; +} + +printf STDOUT "/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT! */\n"; + +&generate_fontnames(); +&generate_character_widths(1, $gs_dir1, @charnames1); +&generate_character_widths(2, $gs_dir2, @charnames2); +&generate_underline_information(); + +exit 0; diff --git a/antiword.h b/antiword.h new file mode 100644 index 0000000..3f4aad5 --- /dev/null +++ b/antiword.h @@ -0,0 +1,735 @@ +/* + * antiword.h + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Generic include file for project 'Antiword' + */ + +#if !defined(__antiword_h) +#define __antiword_h 1 + +#if defined(DEBUG) == defined(NDEBUG) +#error Exactly one of the DEBUG and NDEBUG flags MUST be set +#endif /* DEBUG == NDEBUG */ + +#include +#include +#if defined(__riscos) +#include "DeskLib:Font.h" +#include "DeskLib:Wimp.h" +#include "Desklib:Window.h" +#include "drawfile.h" +#define window_ANY event_ANY +#define icon_ANY event_ANY +#else +#include +#endif /* __riscos */ +#include "wordconst.h" +#include "wordtypes.h" +#include "fail.h" +#include "debug.h" + +/* Constants */ +#if !defined(PATH_MAX) + #if defined(__riscos) + #define PATH_MAX 255 + #else + #if defined(MAXPATHLEN) + #define PATH_MAX MAXPATHLEN + #else + #define PATH_MAX 1024 + #endif /* MAXPATHLEN */ + #endif /* __riscos */ +#endif /* !PATH_MAX */ + +#if !defined(CHAR_BIT) +#define CHAR_BIT 8 +#endif /* CHAR_BIT */ + +#if !defined(TIME_T_MIN) +#define TIME_T_MIN ((time_t)0 < (time_t)-1 ?\ + (time_t)0 :\ + (time_t)1 << (sizeof(time_t) * CHAR_BIT - 1)) +#endif /* TIMER_T_MIN */ + +#if !defined(TIME_T_MAX) +#if defined(__TURBOC__) /* Turbo C chokes on the subtraction below */ +#define TIME_T_MAX (LONG_MAX) +#else /* All others */ +#define TIME_T_MAX (~(time_t)0 - TIME_T_MIN) +#endif /* __TURBOC__ */ +#endif /* TIME_T_MAX */ + +#if !defined(SIZE_T_MAX) +#define SIZE_T_MAX (~(size_t)0) +#endif /* SIZE_T_MAX */ + +#if defined(__riscos) +#define FILE_SEPARATOR "." +#elif defined(__dos) || defined(__CYGMING__) +#define FILE_SEPARATOR "\\" +#else /* All others */ +#define FILE_SEPARATOR "/" +#endif /* __riscos */ + +/* PNG chunk names */ +#define PNG_CN_IDAT 0x49444154 +#define PNG_CN_IEND 0x49454e44 +#define PNG_CN_IHDR 0x49484452 +#define PNG_CN_PLTE 0x504c5445 + +/* The screen width */ +#define MIN_SCREEN_WIDTH 45 +#define DEFAULT_SCREEN_WIDTH 76 +#define MAX_SCREEN_WIDTH 145 + +#if defined(__riscos) +/* The scale factors as percentages */ +#define MIN_SCALE_FACTOR 25 +#define DEFAULT_SCALE_FACTOR 100 +#define MAX_SCALE_FACTOR 400 + +/* Filetypes */ +#define FILETYPE_MSWORD 0xae6 +#define FILETYPE_DRAW 0xaff +#define FILETYPE_JPEG 0xc85 +#define FILETYPE_POSCRIPT 0xff5 +#define FILETYPE_SPRITE 0xff9 +#define FILETYPE_TEXT 0xfff + +/* The button numbers in the choices window */ +#define CHOICES_DEFAULT_BUTTON 3 +#define CHOICES_SAVE_BUTTON 2 +#define CHOICES_CANCEL_BUTTON 1 +#define CHOICES_APPLY_BUTTON 0 +#define CHOICES_BREAK_BUTTON 6 +#define CHOICES_BREAK_WRITEABLE 7 +#define CHOICES_BREAK_UP_BUTTON 8 +#define CHOICES_BREAK_DOWN_BUTTON 9 +#define CHOICES_NO_BREAK_BUTTON 11 +#define CHOICES_AUTOFILETYPE_BUTTON 14 +#define CHOICES_HIDDEN_TEXT_BUTTON 22 +#define CHOICES_WITH_IMAGES_BUTTON 17 +#define CHOICES_NO_IMAGES_BUTTON 18 +#define CHOICES_TEXTONLY_BUTTON 19 +#define CHOICES_SCALE_WRITEABLE 25 +#define CHOICES_SCALE_UP_BUTTON 26 +#define CHOICES_SCALE_DOWN_BUTTON 27 + +/* The button numbers in the scale view window */ +#define SCALE_CANCEL_BUTTON 1 +#define SCALE_SCALE_BUTTON 0 +#define SCALE_SCALE_WRITEABLE 3 +#define SCALE_50_PCT 5 +#define SCALE_75_PCT 6 +#define SCALE_100_PCT 7 +#define SCALE_150_PCT 8 + +/* Save menu fields */ +#define SAVEMENU_SCALEVIEW 0 +#define SAVEMENU_SAVEDRAW 1 +#define SAVEMENU_SAVETEXT 2 +#else +/* Margins for the PostScript version */ +#define PS_LEFT_MARGIN (72 * 640L) +#define PS_RIGHT_MARGIN (48 * 640L) +#define PS_TOP_MARGIN (72 * 640L) +#define PS_BOTTOM_MARGIN (72 * 640L) +#endif /* __riscos */ + +/* Macros */ +#define STREQ(x,y) (*(x) == *(y) && strcmp(x,y) == 0) +#define STRNEQ(x,y,n) (*(x) == *(y) && strncmp(x,y,n) == 0) +#if defined(__dos) || defined(__EMX__) +#define STRCEQ(x,y) (stricmp(x,y) == 0) +#else +#define STRCEQ(x,y) (strcasecmp(x,y) == 0) +#endif /* __dos or __EMX__ */ +#define elementsof(a) (sizeof(a) / sizeof(a[0])) +#define odd(x) (((x)&0x01)!=0) +#define ROUND4(x) (((x)+3)&~0x03) +#define ROUND128(x) (((x)+127)&~0x7f) +#define BIT(x) (1UL << (x)) +#if !defined(max) +#define max(x,y) ((x)>(y)?(x):(y)) +#endif /* !max */ +#if !defined(min) +#define min(x,y) ((x)<(y)?(x):(y)) +#endif /* !min */ + +#if defined(__riscos) +/* The name of the table font */ +#define TABLE_FONT "Corpus.Medium" +/* Names of the default fonts */ +#define FONT_MONOSPACED_PLAIN "Corpus.Medium" +#define FONT_MONOSPACED_BOLD "Corpus.Bold" +#define FONT_MONOSPACED_ITALIC "Corpus.Medium.Oblique" +#define FONT_MONOSPACED_BOLDITALIC "Corpus.Bold.Oblique" +#define FONT_SERIF_PLAIN "Trinity.Medium" +#define FONT_SERIF_BOLD "Trinity.Bold" +#define FONT_SERIF_ITALIC "Trinity.Medium.Italic" +#define FONT_SERIF_BOLDITALIC "Trinity.Bold.Italic" +#define FONT_SANS_SERIF_PLAIN "Homerton.Medium" +#define FONT_SANS_SERIF_BOLD "Homerton.Bold" +#define FONT_SANS_SERIF_ITALIC "Homerton.Medium.Oblique" +#define FONT_SANS_SERIF_BOLDITALIC "Homerton.Bold.Oblique" +#else +/* The name of the table font */ +#define TABLE_FONT "Courier" +/* Names of the default fonts */ +#define FONT_MONOSPACED_PLAIN "Courier" +#define FONT_MONOSPACED_BOLD "Courier-Bold" +#define FONT_MONOSPACED_ITALIC "Courier-Oblique" +#define FONT_MONOSPACED_BOLDITALIC "Courier-BoldOblique" +#define FONT_SERIF_PLAIN "Times-Roman" +#define FONT_SERIF_BOLD "Times-Bold" +#define FONT_SERIF_ITALIC "Times-Italic" +#define FONT_SERIF_BOLDITALIC "Times-BoldItalic" +#define FONT_SANS_SERIF_PLAIN "Helvetica" +#define FONT_SANS_SERIF_BOLD "Helvetica-Bold" +#define FONT_SANS_SERIF_ITALIC "Helvetica-Oblique" +#define FONT_SANS_SERIF_BOLDITALIC "Helvetica-BoldOblique" +/* The name of the antiword directories and the font information file */ +#if defined(__dos) +#define GLOBAL_ANTIWORD_DIR "C:\\antiword" +#define ANTIWORD_DIR "antiword" +#define FONTNAMES_FILE "fontname.txt" +#elif defined(__amigaos) +#define GLOBAL_ANTIWORD_DIR "SYS:.antiword" +#define ANTIWORD_DIR ".antiword" +#define FONTNAMES_FILE "fontnames" +#elif defined(N_PLAT_NLM) +#define GLOBAL_ANTIWORD_DIR "SYS:/antiword" +#define ANTIWORD_DIR "antiword" +#define FONTNAMES_FILE "fontname.txt" +#elif defined(__vms) +#define GLOBAL_ANTIWORD_DIR "/usr/share/antiword" +#define ANTIWORD_DIR "antiword" +#define FONTNAMES_FILE "fontnames" +#elif defined(__BEOS__) +#define GLOBAL_ANTIWORD_DIR "/boot/home/config/apps/antiword" +#define ANTIWORD_DIR "antiword" +#define FONTNAMES_FILE "fontnames" +#elif defined(__CYGMING__) +#define GLOBAL_ANTIWORD_DIR "C:\\antiword" +#define ANTIWORD_DIR "antiword" +#define FONTNAMES_FILE "fontnames" +#elif defined(__Plan9__) +#define GLOBAL_ANTIWORD_DIR "/sys/lib/antiword" +#define ANTIWORD_DIR "lib/antiword" +#define FONTNAMES_FILE "fontnames" +#elif defined(__sun__) +#define GLOBAL_ANTIWORD_DIR "/usr/local/share/antiword" +#define ANTIWORD_DIR ".antiword" +#define FONTNAMES_FILE "fontnames" +#else /* All others */ +#define GLOBAL_ANTIWORD_DIR "/usr/share/antiword" +#define ANTIWORD_DIR ".antiword" +#define FONTNAMES_FILE "fontnames" +#endif /* __dos */ +/* The names of grouped mapping files */ + /* ASCII */ +#define MAPPING_FILE_CP437 "cp437.txt" + /* Latin1 */ +#define MAPPING_FILE_8859_1 "8859-1.txt" + /* Latin2 */ +#define MAPPING_FILE_8859_2 "8859-2.txt" +#define MAPPING_FILE_CP852 "cp852.txt" +#define MAPPING_FILE_CP1250 "cp1250.txt" + /* Cyrillic */ +#define MAPPING_FILE_8859_5 "8859-5.txt" +#define MAPPING_FILE_KOI8_R "koi8-r.txt" +#define MAPPING_FILE_KOI8_U "koi8-u.txt" +#define MAPPING_FILE_CP866 "cp866.txt" +#define MAPPING_FILE_CP1251 "cp1251.txt" + /* Latin9 */ +#define MAPPING_FILE_8859_15 "8859-15.txt" + /* UTF-8 */ +#define MAPPING_FILE_UTF_8 "UTF-8.txt" +#endif /* __riscos */ + +/* Prototypes */ + +/* asc85enc.c */ +extern void vASCII85EncodeByte(FILE *, int); +extern void vASCII85EncodeArray(FILE *, FILE *, size_t); +extern void vASCII85EncodeFile(FILE *, FILE *, size_t); +/* blocklist.c */ +extern void vDestroyTextBlockList(void); +extern BOOL bAdd2TextBlockList(const text_block_type *); +extern void vSplitBlockList(FILE *, ULONG, ULONG, ULONG, ULONG, ULONG, + ULONG, ULONG, ULONG, BOOL); +extern BOOL bExistsHdrFtr(void); +extern BOOL bExistsTextBox(void); +extern BOOL bExistsHdrTextBox(void); +extern USHORT usNextChar(FILE *, list_id_enum, ULONG *, ULONG *, USHORT *); +extern USHORT usToHdrFtrPosition(FILE *, ULONG); +extern USHORT usToFootnotePosition(FILE *, ULONG); +extern ULONG ulCharPos2FileOffsetX(ULONG, list_id_enum *); +extern ULONG ulCharPos2FileOffset(ULONG); +extern ULONG ulHdrFtrOffset2CharPos(ULONG); +extern ULONG ulGetSeqNumber(ULONG); +#if defined(__riscos) +extern ULONG ulGetDocumentLength(void); +#endif /* __riscos */ +/* chartrans.c */ +extern UCHAR ucGetBulletCharacter(conversion_type, encoding_type); +extern UCHAR ucGetNbspCharacter(void); +extern BOOL bReadCharacterMappingTable(FILE *); +extern ULONG ulTranslateCharacters(USHORT, ULONG, int, conversion_type, + encoding_type, BOOL); +extern ULONG ulToUpper(ULONG); +/* datalist.c */ +extern void vDestroyDataBlockList(void); +extern BOOL bAdd2DataBlockList(const data_block_type *); +extern ULONG ulGetDataOffset(FILE *); +extern BOOL bSetDataOffset(FILE *, ULONG); +extern int iNextByte(FILE *); +extern USHORT usNextWord(FILE *); +extern ULONG ulNextLong(FILE *); +extern USHORT usNextWordBE(FILE *); +extern ULONG ulNextLongBE(FILE *); +extern size_t tSkipBytes(FILE *, size_t); +extern ULONG ulDataPos2FileOffset(ULONG); +/* depot.c */ +extern void vDestroySmallBlockList(void); +extern BOOL bCreateSmallBlockList(ULONG, const ULONG *, size_t); +extern ULONG ulDepotOffset(ULONG, size_t); +/* dib2eps & dib2sprt.c */ +extern BOOL bTranslateDIB(diagram_type *, + FILE *, ULONG, const imagedata_type *); +#if defined(__dos) +/* dos.c */ +extern int iGetCodepage(void); +#endif /* __dos */ +/* doclist.c */ +extern void vDestroyDocumentInfoList(void); +extern void vCreateDocumentInfoList(const document_block_type *); +extern UCHAR ucGetDopHdrFtrSpecification(void); +/* draw.c & output.c */ +extern BOOL bAddDummyImage(diagram_type *, const imagedata_type *); +extern diagram_type *pCreateDiagram(const char *, const char *); +extern void vPrologue2(diagram_type *, int); +extern void vMove2NextLine(diagram_type *, drawfile_fontref, USHORT); +extern void vSubstring2Diagram(diagram_type *, + char *, size_t, long, UCHAR, USHORT, + drawfile_fontref, USHORT, USHORT); +extern void vStartOfParagraph1(diagram_type *, long); +extern void vStartOfParagraph2(diagram_type *); +extern void vEndOfParagraph(diagram_type *, drawfile_fontref, USHORT, long); +extern void vEndOfPage(diagram_type *, long, BOOL); +extern void vSetHeaders(diagram_type *, USHORT); +extern void vStartOfList(diagram_type *, UCHAR, BOOL); +extern void vEndOfList(diagram_type *); +extern void vStartOfListItem(diagram_type *, BOOL); +extern void vEndOfTable(diagram_type *); +extern BOOL bAddTableRow(diagram_type *, char **, int, + const short *, UCHAR); +#if defined(__riscos) +extern BOOL bDestroyDiagram(event_pollblock *, void *); +extern void vImage2Diagram(diagram_type *, const imagedata_type *, + UCHAR *, size_t); +extern BOOL bVerifyDiagram(diagram_type *); +extern void vShowDiagram(diagram_type *); +extern void vMainButtonClick(mouse_block *); +extern BOOL bMainKeyPressed(event_pollblock *, void *); +extern BOOL bMainEventHandler(event_pollblock *, void *); +extern BOOL bRedrawMainWindow(event_pollblock *, void *); +extern BOOL bScaleOpenAction(event_pollblock *, void *); +extern void vSetTitle(diagram_type *); +extern void vScaleButtonClick(mouse_block *, diagram_type *); +extern BOOL bScaleKeyPressed(event_pollblock *, void *); +extern BOOL bScaleEventHandler(event_pollblock *, void *); +#else +extern void vImagePrologue(diagram_type *, const imagedata_type *); +extern void vImageEpilogue(diagram_type *); +extern void vDestroyDiagram(diagram_type *); +#endif /* __riscos */ +/* finddata.c */ +extern BOOL bAddDataBlocks(ULONG , ULONG, ULONG, const ULONG *, size_t); +extern BOOL bGet6DocumentData(FILE *, ULONG, + const ULONG *, size_t, const UCHAR *); +/* findtext.c */ +extern BOOL bAddTextBlocks(ULONG , ULONG, BOOL, + USHORT, ULONG, const ULONG *, size_t); +extern BOOL bGet6DocumentText(FILE *, BOOL, ULONG, + const ULONG *, size_t, const UCHAR *); +extern BOOL bGet8DocumentText(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +/* fmt_text.c */ +extern void vPrologueFMT(diagram_type *, const options_type *); +extern void vSubstringFMT(diagram_type *, const char *, size_t, long, + USHORT); +/* fontlist.c */ +extern void vDestroyFontInfoList(void); +extern void vCorrectFontValues(font_block_type *); +extern void vAdd2FontInfoList(const font_block_type *); +extern const font_block_type *pGetNextFontInfoListItem( + const font_block_type *); +/* fonts.c */ +extern int iGetFontByNumber(UCHAR, USHORT); +extern const char *szGetOurFontname(int); +extern int iFontname2Fontnumber(const char *, USHORT); +extern void vCreate0FontTable(void); +extern void vCreate2FontTable(FILE *, int, const UCHAR *); +extern void vCreate6FontTable(FILE *, ULONG, + const ULONG *, size_t, const UCHAR *); +extern void vCreate8FontTable(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vDestroyFontTable(void); +extern const font_table_type *pGetNextFontTableRecord( + const font_table_type *); +extern size_t tGetFontTableLength(void); +extern void vCorrectFontTable(conversion_type, encoding_type); +extern long lComputeSpaceWidth(drawfile_fontref, USHORT); +/* fonts_r.c & fonts_u.c */ +extern FILE *pOpenFontTableFile(void); +extern void vCloseFont(void); +extern drawfile_fontref tOpenFont(UCHAR, USHORT, USHORT); +extern drawfile_fontref tOpenTableFont(USHORT); +extern long lComputeStringWidth(const char *, size_t, drawfile_fontref, USHORT); +extern size_t tCountColumns(const char *, size_t); +extern size_t tGetCharacterLength(const char *); +/* fonts_u.c */ +#if !defined(__riscos) +extern const char *szGetFontname(drawfile_fontref); +#endif /* !__riscos */ +/* hdrftrlist.c */ +extern void vDestroyHdrFtrInfoList(void); +extern void vCreat8HdrFtrInfoList(const ULONG *, size_t); +extern void vCreat6HdrFtrInfoList(const ULONG *, size_t); +extern void vCreat2HdrFtrInfoList(const ULONG *, size_t); +extern const hdrftr_block_type *pGetHdrFtrInfo(int, BOOL, BOOL, BOOL); +extern void vPrepareHdrFtrText(FILE *); +#if defined(__riscos) +/* icons.c */ +extern void vUpdateIcon(window_handle, icon_block *); +extern void vUpdateRadioButton(window_handle, icon_handle, BOOL); +extern void vUpdateWriteable(window_handle, icon_handle, const char *); +extern void vUpdateWriteableNumber(window_handle, icon_handle, int); +#endif /* __riscos */ +/* imgexam.c */ +extern image_info_enum eExamineImage(FILE *, ULONG, imagedata_type *); +/* imgtrans */ +extern BOOL bTranslateImage(diagram_type *, + FILE *, BOOL, ULONG, const imagedata_type *); +/* jpeg2eps.c & jpeg2spr.c */ +extern BOOL bTranslateJPEG(diagram_type *, + FILE *, ULONG, size_t, const imagedata_type *); +/* listlist.c */ +extern void vDestroyListInfoList(void); +extern void vBuildLfoList(const UCHAR *, size_t); +extern void vAdd2ListInfoList(ULONG, USHORT, UCHAR, + const list_block_type *); +extern const list_block_type *pGetListInfo(USHORT, UCHAR); +extern USHORT usGetListValue(int, int, const style_block_type *); +/* misc.c */ +#if !defined(__riscos) +extern const char *szGetHomeDirectory(void); +extern const char *szGetAntiwordDirectory(void); +#endif /* !__riscos */ +extern long lGetFilesize(const char *); +#if defined(DEBUG) +extern void vPrintBlock(const char *, int, const UCHAR *, size_t); +extern void vPrintUnicode(const char *, int, const UCHAR *, size_t); +extern BOOL bCheckDoubleLinkedList(output_type *); +#endif /* DEBUG */ +extern BOOL bReadBytes(UCHAR *, size_t, ULONG, FILE *); +extern BOOL bReadBuffer(FILE *, ULONG, const ULONG *, size_t, size_t, + UCHAR *, ULONG, size_t); +extern ULONG ulColor2Color(UCHAR); +extern output_type *pSplitList(output_type *); +extern size_t tNumber2Roman(UINT, BOOL, char *); +extern size_t tNumber2Alpha(UINT, BOOL, char *); +extern char *unincpy(char *, const UCHAR *, size_t); +extern size_t unilen(const UCHAR *); +extern const char *szBasename(const char *); +extern long lComputeLeading(USHORT); +extern size_t tUcs2Utf8(ULONG, char *, size_t); +extern void vGetBulletValue(conversion_type, encoding_type, char *, size_t); +extern BOOL bAllZero(const UCHAR *, size_t); +extern BOOL bGetNormalizedCodeset(char *, size_t, BOOL *); +extern const char *szGetDefaultMappingFile(void); +extern time_t tConvertDTTM(ULONG); +/* notes.c */ +extern void vDestroyNotesInfoLists(void); +extern void vGetNotesInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *, int); +extern void vPrepareFootnoteText(FILE *); +extern const char *szGetFootnootText(UINT); +extern notetype_enum eGetNotetype(ULONG); +/* options.c */ +extern int iReadOptions(int, char **); +extern void vGetOptions(options_type *); +#if defined(__riscos) +extern void vChoicesOpenAction(window_handle); +extern BOOL bChoicesMouseClick(event_pollblock *, void *); +extern BOOL bChoicesKeyPressed(event_pollblock *, void *); +#endif /* __riscos */ +/* out2window.c */ +extern void vSetLeftIndentation(diagram_type *, long); +extern void vAlign2Window(diagram_type *, output_type *, + long, UCHAR); +extern void vJustify2Window(diagram_type *, output_type *, + long, long, UCHAR); +extern void vResetStyles(void); +extern size_t tStyle2Window(char *, size_t, const style_block_type *, + const section_block_type *); +extern void vTableRow2Window(diagram_type *, output_type *, + const row_block_type *, conversion_type, int); +/* pdf.c */ +extern void vCreateInfoDictionary(diagram_type *, int); +extern void vProloguePDF(diagram_type *, + const char *, const options_type *); +extern void vEpiloguePDF(diagram_type *); +extern void vImageProloguePDF(diagram_type *, const imagedata_type *); +extern void vImageEpiloguePDF(diagram_type *); +extern BOOL bAddDummyImagePDF(diagram_type *, const imagedata_type *); +extern void vAddFontsPDF(diagram_type *); +extern void vMove2NextLinePDF(diagram_type *, USHORT); +extern void vSubstringPDF(diagram_type *, + char *, size_t, long, UCHAR, USHORT, + drawfile_fontref, USHORT, USHORT); +extern void vStartOfParagraphPDF(diagram_type *, long); +extern void vEndOfParagraphPDF(diagram_type *, USHORT, long); +extern void vEndOfPagePDF(diagram_type *, BOOL); +/* pictlist.c */ +extern void vDestroyPictInfoList(void); +extern void vAdd2PictInfoList(const picture_block_type *); +extern ULONG ulGetPictInfoListItem(ULONG); +/* png2eps.c & png2spr.c */ +extern BOOL bTranslatePNG(diagram_type *, + FILE *, ULONG, size_t, const imagedata_type *); +/* postscript.c */ +extern void vProloguePS(diagram_type *, + const char *, const char *, const options_type *); +extern void vEpiloguePS(diagram_type *); +extern void vImageProloguePS(diagram_type *, const imagedata_type *); +extern void vImageEpiloguePS(diagram_type *); +extern BOOL bAddDummyImagePS(diagram_type *, const imagedata_type *); +extern void vAddFontsPS(diagram_type *); +extern void vMove2NextLinePS(diagram_type *, USHORT); +extern void vSubstringPS(diagram_type *, + char *, size_t, long, UCHAR, USHORT, + drawfile_fontref, USHORT, USHORT); +extern void vStartOfParagraphPS(diagram_type *, long); +extern void vEndOfParagraphPS(diagram_type *, USHORT, long); +extern void vEndOfPagePS(diagram_type *, BOOL); +/* prop0.c */ +extern void vGet0DopInfo(FILE *, const UCHAR *); +extern void vGet0SepInfo(FILE *, const UCHAR *); +extern void vGet0PapInfo(FILE *, const UCHAR *); +extern void vGet0ChrInfo(FILE *, const UCHAR *); +/* prop2.c */ +extern void vGet2DopInfo(FILE *, const UCHAR *); +extern void vGet2SepInfo(FILE *, const UCHAR *); +extern void vGet2HdrFtrInfo(FILE *, const UCHAR *); +extern row_info_enum eGet2RowInfo(int, + const UCHAR *, int, row_block_type *); +extern void vGet2StyleInfo(int, + const UCHAR *, int, style_block_type *); +extern void vGet2PapInfo(FILE *, const UCHAR *); +extern void vGet1FontInfo(int, + const UCHAR *, size_t, font_block_type *); +extern void vGet2FontInfo(int, + const UCHAR *, size_t, font_block_type *); +extern void vGet2ChrInfo(FILE *, int, const UCHAR *); +/* prop6.c */ +extern void vGet6DopInfo(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +extern void vGet6SepInfo(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +extern void vGet6HdrFtrInfo(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +extern row_info_enum eGet6RowInfo(int, + const UCHAR *, int, row_block_type *); +extern void vGet6StyleInfo(int, + const UCHAR *, int, style_block_type *); +extern void vGet6PapInfo(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +extern void vGet6FontInfo(int, USHORT, + const UCHAR *, int, font_block_type *); +extern void vGet6ChrInfo(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +/* prop8.c */ +extern void vGet8DopInfo(FILE *, const pps_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vGet8SepInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vGet8HdrFtrInfo(FILE *, const pps_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern row_info_enum eGet8RowInfo(int, + const UCHAR *, int, row_block_type *); +extern void vGet8StyleInfo(int, + const UCHAR *, int, style_block_type *); +extern void vGet8LstInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vGet8PapInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vGet8FontInfo(int, USHORT, + const UCHAR *, int, font_block_type *); +extern void vGet8ChrInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +/* properties.c */ +extern void vGetPropertyInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *, int); +extern row_info_enum ePropMod2RowInfo(USHORT, int); +/* propmod.c */ +extern void vDestroyPropModList(void); +extern void vAdd2PropModList(const UCHAR *); +extern const UCHAR *aucReadPropModListItem(USHORT); +/* rowlist.c */ +extern void vDestroyRowInfoList(void); +extern void vAdd2RowInfoList(const row_block_type *); +extern const row_block_type *pGetNextRowInfoListItem(void); +/* riscos.c */ +#if defined(__riscos) +extern int iGetFiletype(const char *); +extern void vSetFiletype(const char *, int); +extern BOOL bMakeDirectory(const char *); +extern int iReadCurrentAlphabetNumber(void); +extern int iGetRiscOsVersion(void); +extern BOOL bDrawRenderDiag360(void *, size_t, + window_redrawblock *, double, os_error *); +#if defined(DEBUG) +extern BOOL bGetJpegInfo(UCHAR *, size_t); +#endif /* DEBUG */ +#endif /* __riscos */ +/* saveas.c */ +#if defined(__riscos) +extern BOOL bSaveTextfile(event_pollblock *, void *); +extern BOOL bSaveDrawfile(event_pollblock *, void *); +#endif /* __riscos */ +/* sectlist.c */ +extern void vDestroySectionInfoList(void); +extern void vAdd2SectionInfoList(const section_block_type *, ULONG); +extern void vGetDefaultSection(section_block_type *); +extern void vDefault2SectionInfoList(ULONG); +extern const section_block_type * + pGetSectionInfo(const section_block_type *, ULONG); +extern size_t tGetNumberOfSections(void); +extern UCHAR ucGetSepHdrFtrSpecification(size_t); +/* stylelist.c */ +extern void vDestroyStyleInfoList(void); +extern level_type_enum eGetNumType(UCHAR); +extern void vCorrectStyleValues(style_block_type *); +extern void vAdd2StyleInfoList(const style_block_type *); +extern const style_block_type *pGetNextStyleInfoListItem( + const style_block_type *); +extern const style_block_type *pGetNextTextStyle(const style_block_type *); +extern USHORT usGetIstd(ULONG); +extern BOOL bStyleImpliesList(const style_block_type *, int); +/* stylesheet.c */ +extern void vDestroyStylesheetList(void); +extern USHORT usStc2istd(UCHAR); +extern void vGet2Stylesheet(FILE *, int, const UCHAR *); +extern void vGet6Stylesheet(FILE *, ULONG, const ULONG *, size_t, + const UCHAR *); +extern void vGet8Stylesheet(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vFillStyleFromStylesheet(USHORT, style_block_type *); +extern void vFillFontFromStylesheet(USHORT, font_block_type *); +/* summary.c */ +extern void vDestroySummaryInfo(void); +extern void vSet0SummaryInfo(FILE *, const UCHAR *); +extern void vSet2SummaryInfo(FILE *, int, const UCHAR *); +extern void vSet6SummaryInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern void vSet8SummaryInfo(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *); +extern const char *szGetTitle(void); +extern const char *szGetSubject(void); +extern const char *szGetAuthor(void); +extern const char *szGetLastSaveDtm(void); +extern const char *szGetModDate(void); +extern const char *szGetCreationDate(void); +extern const char *szGetCompany(void); +extern const char *szGetLanguage(void); +/* tabstop.c */ +extern void vSetDefaultTabWidth(FILE *, const pps_info_type *, + const ULONG *, size_t, const ULONG *, size_t, + const UCHAR *, int); +extern long lGetDefaultTabWidth(void); +/* text.c */ +extern void vPrologueTXT(diagram_type *, const options_type *); +extern void vEpilogueTXT(FILE *); +extern void vMove2NextLineTXT(diagram_type *); +extern void vSubstringTXT(diagram_type *, const char *, size_t, long); +extern void vStartOfParagraphTXT(diagram_type *, long); +extern void vEndOfParagraphTXT(diagram_type *, long); +extern void vEndOfPageTXT(diagram_type *, long); +/* unix.c */ +extern void werr(int, const char *, ...); +#if !defined(__riscos) +extern void Hourglass_On(void); +extern void Hourglass_Off(void); +#endif /* !__riscos */ +/* utf8.c */ +#if !defined(__riscos) +extern long utf8_strwidth(const char *, size_t); +extern int utf8_chrlength(const char *); +extern BOOL is_locale_utf8(void); +#endif /* !__riscos */ +/* word2text.c */ +extern BOOL bOutputContainsText(const output_type *); +extern BOOL bWordDecryptor(FILE *, long, diagram_type *); +extern output_type *pHdrFtrDecryptor(FILE *, ULONG, ULONG); +extern char *szFootnoteDecryptor(FILE *, ULONG, ULONG); +/* worddos.c */ +extern int iInitDocumentDOS(FILE *, long); +/* wordlib.c */ +extern BOOL bIsWordForDosFile(FILE *, long); +extern BOOL bIsRtfFile(FILE *); +extern BOOL bIsWordPerfectFile(FILE *); +extern BOOL bIsWinWord12File(FILE *, long); +extern BOOL bIsMacWord45File(FILE *); +extern int iGuessVersionNumber(FILE *, long); +extern int iGetVersionNumber(const UCHAR *); +extern BOOL bIsOldMacFile(void); +extern int iInitDocument(FILE *, long); +extern void vFreeDocument(void); +/* wordmac.c */ +extern int iInitDocumentMAC(FILE *, long); +/* wordole.c */ +extern int iInitDocumentOLE(FILE *, long); +/* wordwin.c */ +extern int iInitDocumentWIN(FILE *, long); +/* xmalloc.c */ +extern void *xmalloc(size_t); +extern void *xcalloc(size_t, size_t); +extern void *xrealloc(void *, size_t); +extern char *xstrdup(const char *); +extern void *xfree(void *); +/* xml.c */ +extern void vCreateBookIntro(diagram_type *, int); +extern void vPrologueXML(diagram_type *, const options_type *); +extern void vEpilogueXML(diagram_type *); +extern void vMove2NextLineXML(diagram_type *); +extern void vSubstringXML(diagram_type *, + const char *, size_t, long, USHORT); +extern void vStartOfParagraphXML(diagram_type *, UINT); +extern void vEndOfParagraphXML(diagram_type *, UINT); +extern void vEndOfPageXML(diagram_type *); +extern void vSetHeadersXML(diagram_type *, USHORT); +extern void vStartOfListXML(diagram_type *, UCHAR, BOOL); +extern void vEndOfListXML(diagram_type *); +extern void vStartOfListItemXML(diagram_type *, BOOL); +extern void vEndOfTableXML(diagram_type *); +extern void vAddTableRowXML(diagram_type *, char **, int, + const short *, UCHAR); + +#endif /* __antiword_h */ diff --git a/asc85enc.c b/asc85enc.c new file mode 100644 index 0000000..8ff6bc8 --- /dev/null +++ b/asc85enc.c @@ -0,0 +1,154 @@ +/* + * asc85enc.c + * Copyright (C) 2000-2003 A.J. van Os; Released under GPL + * + * Description: + * Functions to for ASCII 85 encoding + * + *==================================================================== + * This part of the software is based on: + * asc85ec.c - ASCII85 and Hex encoding for PostScript Level 2 and PDF + * Copyright (C) 1994-99 Thomas Merz (tm@muc.de) + *==================================================================== + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include "antiword.h" + +static const ULONG aulPower85[5] = { + 1UL, 85UL, 85UL * 85, 85UL * 85 * 85, 85UL * 85 * 85 * 85, +}; +static int iOutBytes = 0; /* Number of characters in an output line */ +static char cCharPrev = '\0'; + +/* + * Two percent characters at the start of a line will cause trouble + * with some post-processing software. In order to avoid this, we + * simply insert a line break if we encounter two percent characters + * at the start of the line. Of course, this rather simplistic + * algorithm may lead to a large line count in pathological cases, + * but the chance for hitting such a case is very small, and even + * so it's only a cosmetic flaw and not a functional restriction. + */ + +/* + * vOutputByte - output one byte + */ +static void +vOutputByte(ULONG ulChar, FILE *pOutFile) +{ + if (iOutBytes == 1 && cCharPrev == '%' && ulChar == (ULONG)'%') { + if (putc('\n', pOutFile) != EOF) { + iOutBytes = 0; + } + } + if (putc((int)ulChar, pOutFile) == EOF) { + return; + } + iOutBytes++; + if (iOutBytes > 63) { + if (putc('\n', pOutFile) != EOF) { + iOutBytes = 0; + } + } + cCharPrev = (char)ulChar; +} /* end of vOutputByte */ + +/* + * vASCII85EncodeByte - ASCII 85 encode a byte + */ +void +vASCII85EncodeByte(FILE *pOutFile, int iByte) +{ + static ULONG ulBuffer[4] = { 0, 0, 0, 0 }; + static int iInBuffer = 0; + ULONG ulValue, ulTmp; + int iIndex; + + fail(pOutFile == NULL); + fail(iInBuffer < 0); + fail(iInBuffer > 3); + + if (iByte == EOF) { + /* End Of File, time to clean up */ + if (iInBuffer > 0 && iInBuffer < 4) { + /* Encode the remaining bytes */ + ulValue = 0; + for (iIndex = iInBuffer - 1; iIndex >= 0; iIndex--) { + ulValue |= + ulBuffer[iIndex] << (8 * (3 - iIndex)); + } + for (iIndex = 4; iIndex >= 4 - iInBuffer; iIndex--) { + ulTmp = ulValue / aulPower85[iIndex]; + vOutputByte(ulTmp + '!', pOutFile); + ulValue -= ulTmp * aulPower85[iIndex]; + } + } + /* Add the End Of Data marker */ + (void)putc('~', pOutFile); + (void)putc('>', pOutFile); + (void)putc('\n', pOutFile); + /* Reset the control variables */ + iInBuffer = 0; + iOutBytes = 0; + cCharPrev = '\0'; + return; + } + + ulBuffer[iInBuffer] = (ULONG)iByte & 0xff; + iInBuffer++; + + if (iInBuffer >= 4) { + ulValue = (ulBuffer[0] << 24) | (ulBuffer[1] << 16) | + (ulBuffer[2] << 8) | ulBuffer[3]; + if (ulValue == 0) { + vOutputByte((ULONG)'z', pOutFile); /* Shortcut for 0 */ + } else { + for (iIndex = 4; iIndex >= 0; iIndex--) { + ulTmp = ulValue / aulPower85[iIndex]; + vOutputByte(ulTmp + '!', pOutFile); + ulValue -= ulTmp * aulPower85[iIndex]; + } + } + /* Reset the buffer */ + iInBuffer = 0; + } +} /* end of vASCII85EncodeByte */ + +/* + * vASCII85EncodeArray - ASCII 85 encode a byte array + */ +void +vASCII85EncodeArray(FILE *pInFile, FILE *pOutFile, size_t tLength) +{ + size_t tCount; + int iByte; + + fail(pInFile == NULL); + fail(pOutFile == NULL); + + DBG_DEC(tLength); + + for (tCount = 0; tCount < tLength; tCount++) { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + break; + } + vASCII85EncodeByte(pOutFile, iByte); + } +} /* end of vASCII85EncodeArray */ + +/* + * vASCII85EncodeFile - ASCII 85 encode part of a file + */ +void +vASCII85EncodeFile(FILE *pInFile, FILE *pOutFile, size_t tLength) +{ + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(tLength == 0); + + vASCII85EncodeArray(pInFile, pOutFile, tLength); + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vASCII85EncodeFile */ diff --git a/blocklist.c b/blocklist.c new file mode 100644 index 0000000..c847c27 --- /dev/null +++ b/blocklist.c @@ -0,0 +1,823 @@ +/* + * blocklist.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy the lists of Word "text" blocks + */ + +#include +#include "antiword.h" + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct list_mem_tag { + text_block_type tInfo; + struct list_mem_tag *pNext; +} list_mem_type; + +typedef struct readinfo_tag { + list_mem_type *pBlockCurrent; + ULONG ulBlockOffset; + size_t tByteNext; + UCHAR aucBlock[BIG_BLOCK_SIZE]; +} readinfo_type; + +/* Variables to describe the start of the block lists */ +static list_mem_type *pTextAnchor = NULL; +static list_mem_type *pFootnoteAnchor = NULL; +static list_mem_type *pHdrFtrAnchor = NULL; +static list_mem_type *pMacroAnchor = NULL; +static list_mem_type *pAnnotationAnchor = NULL; +static list_mem_type *pEndnoteAnchor = NULL; +static list_mem_type *pTextBoxAnchor = NULL; +static list_mem_type *pHdrTextBoxAnchor = NULL; +/* Variable needed to build the block list */ +static list_mem_type *pBlockLast = NULL; +/* Variable needed to read the block lists */ +static readinfo_type tOthers = { NULL, 0, 0, }; +static readinfo_type tHdrFtr = { NULL, 0, 0, }; +static readinfo_type tFootnote = { NULL, 0, 0, }; + + +/* + * pFreeOneList - free a text block list + * + * Will always return NULL + */ +static list_mem_type * +pFreeOneList(list_mem_type *pAnchor) +{ + list_mem_type *pCurr, *pNext; + + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + return NULL; +} /* end of pFreeOneList */ + +/* + * vDestroyTextBlockList - destroy the text block lists + */ +void +vDestroyTextBlockList(void) +{ + DBG_MSG("vDestroyTextBlockList"); + + /* Free the lists one by one */ + pTextAnchor = pFreeOneList(pTextAnchor); + pFootnoteAnchor = pFreeOneList(pFootnoteAnchor); + pHdrFtrAnchor = pFreeOneList(pHdrFtrAnchor); + pMacroAnchor = pFreeOneList(pMacroAnchor); + pAnnotationAnchor = pFreeOneList(pAnnotationAnchor); + pEndnoteAnchor = pFreeOneList(pEndnoteAnchor); + pTextBoxAnchor = pFreeOneList(pTextBoxAnchor); + pHdrTextBoxAnchor = pFreeOneList(pHdrTextBoxAnchor); + /* Reset all the controle variables */ + pBlockLast = NULL; + tOthers.pBlockCurrent = NULL; + tHdrFtr.pBlockCurrent = NULL; + tFootnote.pBlockCurrent = NULL; +} /* end of vDestroyTextBlockList */ + +/* + * bAdd2TextBlockList - add an element to the text block list + * + * returns: TRUE when successful, otherwise FALSE + */ +BOOL +bAdd2TextBlockList(const text_block_type *pTextBlock) +{ + list_mem_type *pListMember; + + fail(pTextBlock == NULL); + fail(pTextBlock->ulFileOffset == FC_INVALID); + fail(pTextBlock->ulCharPos == CP_INVALID); + fail(pTextBlock->ulLength == 0); + fail(pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength)); + + NO_DBG_MSG("bAdd2TextBlockList"); + NO_DBG_HEX(pTextBlock->ulFileOffset); + NO_DBG_HEX(pTextBlock->ulCharPos); + NO_DBG_HEX(pTextBlock->ulLength); + NO_DBG_DEC(pTextBlock->bUsesUnicode); + NO_DBG_DEC(pTextBlock->usPropMod); + + if (pTextBlock->ulFileOffset == FC_INVALID || + pTextBlock->ulCharPos == CP_INVALID || + pTextBlock->ulLength == 0 || + (pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength))) { + werr(0, "Software (textblock) error"); + return FALSE; + } + /* + * Check for continuous blocks of the same character size and + * the same properties modifier + */ + if (pBlockLast != NULL && + pBlockLast->tInfo.ulFileOffset + + pBlockLast->tInfo.ulLength == pTextBlock->ulFileOffset && + pBlockLast->tInfo.ulCharPos + + pBlockLast->tInfo.ulLength == pTextBlock->ulCharPos && + pBlockLast->tInfo.bUsesUnicode == pTextBlock->bUsesUnicode && + pBlockLast->tInfo.usPropMod == pTextBlock->usPropMod) { + /* These are continous blocks */ + pBlockLast->tInfo.ulLength += pTextBlock->ulLength; + return TRUE; + } + /* Make a new block */ + pListMember = xmalloc(sizeof(list_mem_type)); + /* Add the block to the list */ + pListMember->tInfo = *pTextBlock; + pListMember->pNext = NULL; + if (pTextAnchor == NULL) { + pTextAnchor = pListMember; + } else { + fail(pBlockLast == NULL); + pBlockLast->pNext = pListMember; + } + pBlockLast = pListMember; + return TRUE; +} /* end of bAdd2TextBlockList */ + +/* + * vSpitList - Split the list in two + */ +static void +vSpitList(list_mem_type **ppAnchorCurr, list_mem_type **ppAnchorNext, + ULONG ulListLen) +{ + list_mem_type *pCurr; + long lCharsToGo, lBytesTooFar; + + fail(ppAnchorCurr == NULL); + fail(ppAnchorNext == NULL); + fail(ulListLen > (ULONG)LONG_MAX); + + pCurr = NULL; + lCharsToGo = (long)ulListLen; + lBytesTooFar = -1; + if (ulListLen != 0) { + DBG_DEC(ulListLen); + for (pCurr = *ppAnchorCurr; + pCurr != NULL; + pCurr = pCurr->pNext) { + NO_DBG_DEC(pCurr->tInfo.ulLength); + fail(pCurr->tInfo.ulLength == 0); + fail(pCurr->tInfo.ulLength > (ULONG)LONG_MAX); + if (pCurr->tInfo.bUsesUnicode) { + fail(odd(pCurr->tInfo.ulLength)); + lCharsToGo -= (long)(pCurr->tInfo.ulLength / 2); + if (lCharsToGo < 0) { + lBytesTooFar = -2 * lCharsToGo; + } + } else { + lCharsToGo -= (long)pCurr->tInfo.ulLength; + if (lCharsToGo < 0) { + lBytesTooFar = -lCharsToGo; + } + } + if (lCharsToGo <= 0) { + break; + } + } + } +/* Split the list */ + if (ulListLen == 0) { + /* Current blocklist is empty */ + *ppAnchorNext = *ppAnchorCurr; + *ppAnchorCurr = NULL; + } else if (pCurr == NULL) { + /* No blocks for the next list */ + *ppAnchorNext = NULL; + } else if (lCharsToGo == 0) { + /* Move the integral number of blocks to the next list */ + *ppAnchorNext = pCurr->pNext; + pCurr->pNext = NULL; + } else { + /* Split the part current block list, part next block list */ + DBG_DEC(lBytesTooFar); + fail(lBytesTooFar <= 0); + *ppAnchorNext = xmalloc(sizeof(list_mem_type)); + DBG_HEX(pCurr->tInfo.ulFileOffset); + (*ppAnchorNext)->tInfo.ulFileOffset = + pCurr->tInfo.ulFileOffset + + pCurr->tInfo.ulLength - + lBytesTooFar; + DBG_HEX((*ppAnchorNext)->tInfo.ulFileOffset); + DBG_HEX(pCurr->tInfo.ulCharPos); + (*ppAnchorNext)->tInfo.ulCharPos = + pCurr->tInfo.ulCharPos + + pCurr->tInfo.ulLength - + lBytesTooFar; + DBG_HEX((*ppAnchorNext)->tInfo.ulCharPos); + (*ppAnchorNext)->tInfo.ulLength = (ULONG)lBytesTooFar; + pCurr->tInfo.ulLength -= (ULONG)lBytesTooFar; + (*ppAnchorNext)->tInfo.bUsesUnicode = pCurr->tInfo.bUsesUnicode; + (*ppAnchorNext)->tInfo.usPropMod = pCurr->tInfo.usPropMod; + /* Move the integral number of blocks to the next list */ + (*ppAnchorNext)->pNext = pCurr->pNext; + pCurr->pNext = NULL; + } +} /* end of vSpitList */ + +#if defined(DEBUG) || defined(__riscos) +/* + * ulComputeListLength - compute the length of a list + * + * returns the list length in characters + */ +static ULONG +ulComputeListLength(const list_mem_type *pAnchor) +{ + const list_mem_type *pCurr; + ULONG ulTotal; + + ulTotal = 0; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + fail(pCurr->tInfo.ulLength == 0); + if (pCurr->tInfo.bUsesUnicode) { + fail(odd(pCurr->tInfo.ulLength)); + ulTotal += pCurr->tInfo.ulLength / 2; + } else { + ulTotal += pCurr->tInfo.ulLength; + } + } + return ulTotal; +} /* end of ulComputeListLength */ +#endif /* DEBUG || __riscos */ + +#if defined(DEBUG) +/* + * vCheckList - check the number of bytes in a block list + */ +static void +vCheckList(const list_mem_type *pAnchor, ULONG ulListLen, char *szMsg) +{ + ULONG ulTotal; + + ulTotal = ulComputeListLength(pAnchor); + DBG_DEC(ulTotal); + if (ulTotal != ulListLen) { + DBG_DEC(ulListLen); + werr(1, szMsg); + } +} /* end of vCheckList */ +#endif /* DEBUG */ + +/* + * bIsEmptyBox - check to see if the given text box is empty + */ +static BOOL +bIsEmptyBox(FILE *pFile, const list_mem_type *pAnchor) +{ + const list_mem_type *pCurr; + size_t tIndex, tSize; + UCHAR *aucBuffer; + char cChar; + + fail(pFile == NULL); + + if (pAnchor == NULL) { + return TRUE; + } + + aucBuffer = NULL; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + fail(pCurr->tInfo.ulLength == 0); + tSize = (size_t)pCurr->tInfo.ulLength; +#if defined(__dos) && !defined(__DJGPP__) + if (pCurr->tInfo.ulLength > 0xffffUL) { + tSize = 0xffff; + } +#endif /* __dos && !__DJGPP__ */ + fail(aucBuffer != NULL); + aucBuffer = xmalloc(tSize); + if (!bReadBytes(aucBuffer, tSize, + pCurr->tInfo.ulFileOffset, pFile)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + for (tIndex = 0; tIndex < tSize; tIndex++) { + cChar = (char)aucBuffer[tIndex]; + switch (cChar) { + case '\0': case '\r': case '\n': + case '\f': case '\t': case '\v': + case ' ': + break; + default: + aucBuffer = xfree(aucBuffer); + return FALSE; + } + } + aucBuffer = xfree(aucBuffer); + } + fail(aucBuffer != NULL); + return TRUE; +} /* end of bIsEmptyBox */ + +/* + * vSplitBlockList - split the block list in the various parts + * + * Split the blocklist in a Text block list, a Footnote block list, a + * HeaderFooter block list, a Macro block list, an Annotation block list, + * an Endnote block list, a TextBox list and a HeaderTextBox list. + * + * NOTE: + * The various ul*Len input parameters are given in characters, but the + * length of the blocks are in bytes. + */ +void +vSplitBlockList(FILE *pFile, ULONG ulTextLen, ULONG ulFootnoteLen, + ULONG ulHdrFtrLen, ULONG ulMacroLen, ULONG ulAnnotationLen, + ULONG ulEndnoteLen, ULONG ulTextBoxLen, ULONG ulHdrTextBoxLen, + BOOL bMustExtend) +{ + list_mem_type *apAnchors[8]; + list_mem_type *pGarbageAnchor, *pCurr; + size_t tIndex; + + DBG_MSG("vSplitBlockList"); + + pGarbageAnchor = NULL; + + DBG_MSG_C(ulTextLen != 0, "Text block list"); + vSpitList(&pTextAnchor, &pFootnoteAnchor, ulTextLen); + DBG_MSG_C(ulFootnoteLen != 0, "Footnote block list"); + vSpitList(&pFootnoteAnchor, &pHdrFtrAnchor, ulFootnoteLen); + DBG_MSG_C(ulHdrFtrLen != 0, "Header/Footer block list"); + vSpitList(&pHdrFtrAnchor, &pMacroAnchor, ulHdrFtrLen); + DBG_MSG_C(ulMacroLen != 0, "Macro block list"); + vSpitList(&pMacroAnchor, &pAnnotationAnchor, ulMacroLen); + DBG_MSG_C(ulAnnotationLen != 0, "Annotation block list"); + vSpitList(&pAnnotationAnchor, &pEndnoteAnchor, ulAnnotationLen); + DBG_MSG_C(ulEndnoteLen != 0, "Endnote block list"); + vSpitList(&pEndnoteAnchor, &pTextBoxAnchor, ulEndnoteLen); + DBG_MSG_C(ulTextBoxLen != 0, "Textbox block list"); + vSpitList(&pTextBoxAnchor, &pHdrTextBoxAnchor, ulTextBoxLen); + DBG_MSG_C(ulHdrTextBoxLen != 0, "HeaderTextbox block list"); + vSpitList(&pHdrTextBoxAnchor, &pGarbageAnchor, ulHdrTextBoxLen); + + /* Free the garbage block list, this should not be needed */ + DBG_DEC_C(pGarbageAnchor != NULL, pGarbageAnchor->tInfo.ulLength); + pGarbageAnchor = pFreeOneList(pGarbageAnchor); + +#if defined(DEBUG) + vCheckList(pTextAnchor, ulTextLen, "Software error (Text)"); + vCheckList(pFootnoteAnchor, ulFootnoteLen, "Software error (Footnote)"); + vCheckList(pHdrFtrAnchor, ulHdrFtrLen, "Software error (Hdr/Ftr)"); + vCheckList(pMacroAnchor, ulMacroLen, "Software error (Macro)"); + vCheckList(pAnnotationAnchor, ulAnnotationLen, + "Software error (Annotation)"); + vCheckList(pEndnoteAnchor, ulEndnoteLen, "Software error (Endnote)"); + vCheckList(pTextBoxAnchor, ulTextBoxLen, "Software error (TextBox)"); + vCheckList(pHdrTextBoxAnchor, ulHdrTextBoxLen, + "Software error (HdrTextBox)"); +#endif /* DEBUG */ + + /* Remove the list if the text box is empty */ + if (bIsEmptyBox(pFile, pTextBoxAnchor)) { + pTextBoxAnchor = pFreeOneList(pTextBoxAnchor); + } + if (bIsEmptyBox(pFile, pHdrTextBoxAnchor)) { + pHdrTextBoxAnchor = pFreeOneList(pHdrTextBoxAnchor); + } + + if (!bMustExtend) { + return; + } + /* + * All blocks (except the last one) must have a length that + * is a multiple of the Big Block Size + */ + + apAnchors[0] = pTextAnchor; + apAnchors[1] = pFootnoteAnchor; + apAnchors[2] = pHdrFtrAnchor; + apAnchors[3] = pMacroAnchor; + apAnchors[4] = pAnnotationAnchor; + apAnchors[5] = pEndnoteAnchor; + apAnchors[6] = pTextBoxAnchor; + apAnchors[7] = pHdrTextBoxAnchor; + + for (tIndex = 0; tIndex < elementsof(apAnchors); tIndex++) { + for (pCurr = apAnchors[tIndex]; + pCurr != NULL; + pCurr = pCurr->pNext) { + if (pCurr->pNext != NULL && + pCurr->tInfo.ulLength % BIG_BLOCK_SIZE != 0) { + DBG_DEC(tIndex); + DBG_HEX(pCurr->tInfo.ulFileOffset); + DBG_HEX(pCurr->tInfo.ulCharPos); + DBG_DEC(pCurr->tInfo.ulLength); + pCurr->tInfo.ulLength /= BIG_BLOCK_SIZE; + pCurr->tInfo.ulLength++; + pCurr->tInfo.ulLength *= BIG_BLOCK_SIZE; + DBG_DEC(pCurr->tInfo.ulLength); + } + } + } +} /* end of vSplitBlockList */ + +#if defined(__riscos) +/* + * ulGetDocumentLength - get the total character length of the printable lists + * + * returns: The total number of characters + */ +ULONG +ulGetDocumentLength(void) +{ + long ulTotal; + + DBG_MSG("ulGetDocumentLength"); + + ulTotal = ulComputeListLength(pTextAnchor); + ulTotal += ulComputeListLength(pFootnoteAnchor); + ulTotal += ulComputeListLength(pEndnoteAnchor); + ulTotal += ulComputeListLength(pTextBoxAnchor); + ulTotal += ulComputeListLength(pHdrTextBoxAnchor); + DBG_DEC(ulTotal); + return ulTotal; +} /* end of ulGetDocumentLength */ +#endif /* __riscos */ + +#if 0 +/* + * bExistsHdrFtr - are there headers and/or footers? + */ +BOOL +bExistsHdrFtr(void) +{ + return pHdrFtrAnchor != NULL && + pHdrFtrAnchor->tInfo.ulLength != 0; +} /* end of bExistsHdrFtr */ +#endif + +/* + * bExistsTextBox - is there a text box? + */ +BOOL +bExistsTextBox(void) +{ + return pTextBoxAnchor != NULL && + pTextBoxAnchor->tInfo.ulLength != 0; +} /* end of bExistsTextBox */ + +/* + * bExistsHdrTextBox - is there a header text box? + */ +BOOL +bExistsHdrTextBox(void) +{ + return pHdrTextBoxAnchor != NULL && + pHdrTextBoxAnchor->tInfo.ulLength != 0; +} /* end of bExistsHdrTextBox */ + +/* + * usGetNextByte - get the next byte from the specified block list + */ +static USHORT +usGetNextByte(FILE *pFile, readinfo_type *pInfoCurrent, list_mem_type *pAnchor, + ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod) +{ + ULONG ulReadOff; + size_t tReadLen; + + fail(pInfoCurrent == NULL); + + if (pInfoCurrent->pBlockCurrent == NULL || + pInfoCurrent->tByteNext >= sizeof(pInfoCurrent->aucBlock) || + pInfoCurrent->ulBlockOffset + pInfoCurrent->tByteNext >= + pInfoCurrent->pBlockCurrent->tInfo.ulLength) { + if (pInfoCurrent->pBlockCurrent == NULL) { + /* First block, first part */ + pInfoCurrent->pBlockCurrent = pAnchor; + pInfoCurrent->ulBlockOffset = 0; + } else if (pInfoCurrent->ulBlockOffset + + sizeof(pInfoCurrent->aucBlock) < + pInfoCurrent->pBlockCurrent->tInfo.ulLength) { + /* Same block, next part */ + pInfoCurrent->ulBlockOffset += + sizeof(pInfoCurrent->aucBlock); + } else { + /* Next block, first part */ + pInfoCurrent->pBlockCurrent = + pInfoCurrent->pBlockCurrent->pNext; + pInfoCurrent->ulBlockOffset = 0; + } + if (pInfoCurrent->pBlockCurrent == NULL) { + /* Past the last part of the last block */ + return (USHORT)EOF; + } + tReadLen = (size_t) + (pInfoCurrent->pBlockCurrent->tInfo.ulLength - + pInfoCurrent->ulBlockOffset); + if (tReadLen > sizeof(pInfoCurrent->aucBlock)) { + tReadLen = sizeof(pInfoCurrent->aucBlock); + } + ulReadOff = pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset + + pInfoCurrent->ulBlockOffset; + if (!bReadBytes(pInfoCurrent->aucBlock, + tReadLen, ulReadOff, pFile)) { + /* Don't read from this list any longer */ + pInfoCurrent->pBlockCurrent = NULL; + return (USHORT)EOF; + } + pInfoCurrent->tByteNext = 0; + } + if (pulFileOffset != NULL) { + *pulFileOffset = + pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset + + pInfoCurrent->ulBlockOffset + + pInfoCurrent->tByteNext; + } + if (pulCharPos != NULL) { + *pulCharPos = + pInfoCurrent->pBlockCurrent->tInfo.ulCharPos + + pInfoCurrent->ulBlockOffset + + pInfoCurrent->tByteNext; + } + if (pusPropMod != NULL) { + *pusPropMod = pInfoCurrent->pBlockCurrent->tInfo.usPropMod; + } + return (USHORT)pInfoCurrent->aucBlock[pInfoCurrent->tByteNext++]; +} /* end of usGetNextByte */ + + +/* + * usGetNextChar - get the next character from the specified block list + */ +static USHORT +usGetNextChar(FILE *pFile, list_id_enum eListID, + ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod) +{ + readinfo_type *pReadinfo; + list_mem_type *pAnchor; + USHORT usLSB, usMSB; + + switch (eListID) { + case text_list: + pReadinfo = &tOthers; + pAnchor = pTextAnchor; + break; + case footnote_list: + pReadinfo = &tFootnote; + pAnchor = pFootnoteAnchor; + break; + case hdrftr_list: + pReadinfo = &tHdrFtr; + pAnchor = pHdrFtrAnchor; + break; + case endnote_list: + pReadinfo = &tOthers; + pAnchor = pEndnoteAnchor; + break; + case textbox_list: + pReadinfo = &tOthers; + pAnchor = pTextBoxAnchor; + break; + case hdrtextbox_list: + pReadinfo = &tOthers; + pAnchor = pHdrTextBoxAnchor; + break; + default: + DBG_DEC(eListID); + return (USHORT)EOF; + } + + usLSB = usGetNextByte(pFile, pReadinfo, pAnchor, + pulFileOffset, pulCharPos, pusPropMod); + if (usLSB == (USHORT)EOF) { + return (USHORT)EOF; + } + fail(pReadinfo->pBlockCurrent == NULL); + + if (pReadinfo->pBlockCurrent->tInfo.bUsesUnicode) { + usMSB = usGetNextByte(pFile, + pReadinfo, pAnchor, NULL, NULL, NULL); + } else { + usMSB = 0x00; + } + if (usMSB == (USHORT)EOF) { + DBG_MSG("usGetNextChar: Unexpected EOF"); + DBG_HEX_C(pulFileOffset != NULL, *pulFileOffset); + DBG_HEX_C(pulCharPos != NULL, *pulCharPos); + return (USHORT)EOF; + } + return (usMSB << 8) | usLSB; +} /* end of usGetNextChar */ + +/* + * usNextChar - get the next character from the given block list + */ +USHORT +usNextChar(FILE *pFile, list_id_enum eListID, + ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod) +{ + USHORT usRetVal; + + fail(pFile == NULL); + + usRetVal = usGetNextChar(pFile, eListID, + pulFileOffset, pulCharPos, pusPropMod); + if (usRetVal == (USHORT)EOF) { + if (pulFileOffset != NULL) { + *pulFileOffset = FC_INVALID; + } + if (pulCharPos != NULL) { + *pulCharPos = CP_INVALID; + } + if (pusPropMod != NULL) { + *pusPropMod = IGNORE_PROPMOD; + } + } + return usRetVal; +} /* end of usNextChar */ + +/* + * usToHdrFtrPosition - Go to a character position in header/foorter list + * + * Returns the character found on the specified character position + */ +USHORT +usToHdrFtrPosition(FILE *pFile, ULONG ulCharPos) +{ + ULONG ulCharPosCurr; + USHORT usChar; + + tHdrFtr.pBlockCurrent = NULL; /* To reset the header/footer list */ + do { + usChar = usNextChar(pFile, + hdrftr_list, NULL, &ulCharPosCurr, NULL); + } while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos); + return usChar; +} /* end of usToHdrFtrPosition */ + +/* + * usToFootnotePosition - Go to a character position in footnote list + * + * Returns the character found on the specified character position + */ +USHORT +usToFootnotePosition(FILE *pFile, ULONG ulCharPos) +{ + ULONG ulCharPosCurr; + USHORT usChar; + + tFootnote.pBlockCurrent = NULL; /* To reset the footnote list */ + do { + usChar = usNextChar(pFile, + footnote_list, NULL, &ulCharPosCurr, NULL); + } while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos); + return usChar; +} /* end of usToFootnotePosition */ + +/* + * Convert a character position to an offset in the file. + * Logical to physical offset. + * + * Returns: FC_INVALID: in case of error + * otherwise: the computed file offset + */ +ULONG +ulCharPos2FileOffsetX(ULONG ulCharPos, list_id_enum *peListID) +{ + static list_id_enum eListIDs[8] = { + text_list, footnote_list, hdrftr_list, + macro_list, annotation_list, endnote_list, + textbox_list, hdrtextbox_list, + }; + list_mem_type *apAnchors[8]; + list_mem_type *pCurr; + list_id_enum eListGuess; + ULONG ulBestGuess; + size_t tIndex; + + fail(peListID == NULL); + + if (ulCharPos == CP_INVALID) { + *peListID = no_list; + return FC_INVALID; + } + + apAnchors[0] = pTextAnchor; + apAnchors[1] = pFootnoteAnchor; + apAnchors[2] = pHdrFtrAnchor; + apAnchors[3] = pMacroAnchor; + apAnchors[4] = pAnnotationAnchor; + apAnchors[5] = pEndnoteAnchor; + apAnchors[6] = pTextBoxAnchor; + apAnchors[7] = pHdrTextBoxAnchor; + + eListGuess = no_list; /* Best guess is no list */ + ulBestGuess = FC_INVALID; /* Best guess is "file offset not found" */ + + for (tIndex = 0; tIndex < elementsof(apAnchors); tIndex++) { + for (pCurr = apAnchors[tIndex]; + pCurr != NULL; + pCurr = pCurr->pNext) { + if (ulCharPos == pCurr->tInfo.ulCharPos + + pCurr->tInfo.ulLength && + pCurr->pNext != NULL) { + /* + * The character position is one beyond this + * block, so we guess it's the first byte of + * the next block (if there is a next block) + */ + eListGuess= eListIDs[tIndex]; + ulBestGuess = pCurr->pNext->tInfo.ulFileOffset; + } + + if (ulCharPos < pCurr->tInfo.ulCharPos || + ulCharPos >= pCurr->tInfo.ulCharPos + + pCurr->tInfo.ulLength) { + /* Character position is not in this block */ + continue; + } + + /* The character position is in the current block */ + *peListID = eListIDs[tIndex]; + return pCurr->tInfo.ulFileOffset + + ulCharPos - pCurr->tInfo.ulCharPos; + } + } + /* Passed beyond the end of the last list */ + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulBestGuess); + *peListID = eListGuess; + return ulBestGuess; +} /* end of ulCharPos2FileOffsetX */ + +/* + * Convert a character position to an offset in the file. + * Logical to physical offset. + * + * Returns: FC_INVALID: in case of error + * otherwise: the computed file offset + */ +ULONG +ulCharPos2FileOffset(ULONG ulCharPos) +{ + list_id_enum eListID; + + return ulCharPos2FileOffsetX(ulCharPos, &eListID); +} /* end of ulCharPos2FileOffset */ + +/* + * Convert an offset in the header/footer list to a character position. + * + * Returns: CP_INVALID: in case of error + * otherwise: the computed character position + */ +ULONG +ulHdrFtrOffset2CharPos(ULONG ulHdrFtrOffset) +{ + list_mem_type *pCurr; + ULONG ulOffset; + + ulOffset = ulHdrFtrOffset; + for (pCurr = pHdrFtrAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (ulOffset >= pCurr->tInfo.ulLength) { + /* The offset is not in this block */ + ulOffset -= pCurr->tInfo.ulLength; + continue; + } + return pCurr->tInfo.ulCharPos + ulOffset; + } + return CP_INVALID; +} /* end of ulHdrFtrOffset2CharPos */ + +/* + * Get the sequence number beloning to the given file offset + * + * Returns the sequence number + */ +ULONG +ulGetSeqNumber(ULONG ulFileOffset) +{ + list_mem_type *pCurr; + ULONG ulSeq; + + if (ulFileOffset == FC_INVALID) { + return FC_INVALID; + } + + ulSeq = 0; + for (pCurr = pTextAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (ulFileOffset >= pCurr->tInfo.ulFileOffset && + ulFileOffset < pCurr->tInfo.ulFileOffset + + pCurr->tInfo.ulLength) { + /* The file offset is within the current textblock */ + return ulSeq + ulFileOffset - pCurr->tInfo.ulFileOffset; + } + ulSeq += pCurr->tInfo.ulLength; + } + return FC_INVALID; +} /* end of ulGetSeqNumber */ diff --git a/chartrans.c b/chartrans.c new file mode 100644 index 0000000..5edaae9 --- /dev/null +++ b/chartrans.c @@ -0,0 +1,720 @@ +/* + * chartrans.c + * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Translate Word characters to local representation + */ + +#include +#include +#include +#if defined(__STDC_ISO_10646__) +#include +#endif /* __STDC_ISO_10646__ */ +#include "antiword.h" + +static const USHORT usCp850[] = { /* DOS implementation of Latin1 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static const USHORT usCp1250[] = { /* Windows implementation of Latin2 */ + 0x20ac, 0x003f, 0x201a, 0x003f, 0x201e, 0x2026, 0x2020, 0x2021, + 0x003f, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + 0x003f, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x003f, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, +}; + +static const USHORT usCp1251[] = { /* Windows implementation of Cyrillic */ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x00f3, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, +}; + +static const USHORT usCp1252[] = { /* Windows implementation of Latin1 */ + 0x20ac, 0x003f, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x003f, 0x017d, 0x003f, + 0x003f, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x003f, 0x017e, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, +}; + +static const USHORT usMacRoman[] = { /* Apple implementation of Latin1 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0x003f, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; + +static const USHORT usPrivateArea[] = { + 0x0020, 0x0021, 0x2200, 0x0023, 0x2203, 0x0025, 0x0026, 0x220d, + 0x0028, 0x0029, 0x2217, 0x002b, 0x002c, 0x2212, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x2019, 0x003e, 0x003f, + 0x201d, 0x201c, 0x0392, 0x03a7, 0x0394, 0x0395, 0x03a6, 0x0393, + 0x0397, 0x0399, 0x03d1, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, + 0x03a0, 0x0398, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03c2, 0x03a9, + 0x039e, 0x03a8, 0x0396, 0x005b, 0x2234, 0x005d, 0x22a5, 0x005f, + 0x003f, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3, + 0x03b7, 0x03b9, 0x03d5, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf, + 0x03c0, 0x03b8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03d6, 0x03c9, + 0x03be, 0x03c8, 0x03b6, 0x007b, 0x007c, 0x007d, 0x223c, 0x003f, + 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, + 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, + 0x003f, 0x003f, 0x003f, 0x2022, 0x003f, 0x003f, 0x003f, 0x003f, + 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, + 0x20ac, 0x03d2, 0x2032, 0x2264, 0x2044, 0x221e, 0x0192, 0x2663, + 0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, + 0x00b0, 0x00b1, 0x2033, 0x2265, 0x00d7, 0x221d, 0x2202, 0x2022, + 0x00f7, 0x2260, 0x2261, 0x2248, 0x2026, 0x007c, 0x23af, 0x21b5, + 0x2135, 0x2111, 0x211c, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229, + 0x222a, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209, + 0x2220, 0x2207, 0x00ae, 0x00a9, 0x2122, 0x220f, 0x221a, 0x22c5, + 0x00ac, 0x2227, 0x2228, 0x21d4, 0x21d0, 0x21d1, 0x21d2, 0x21d3, + 0x22c4, 0x3008, 0x00ae, 0x00a9, 0x2122, 0x2211, 0x239b, 0x239c, + 0x239d, 0x23a1, 0x23a2, 0x23a3, 0x23a7, 0x23a8, 0x23a9, 0x23aa, + 0x003f, 0x3009, 0x222b, 0x2320, 0x23ae, 0x2321, 0x239e, 0x239f, + 0x23a0, 0x23a4, 0x23a5, 0x23a6, 0x23ab, 0x23ac, 0x23ad, 0x003f, +}; + +typedef struct char_table_tag { + UCHAR ucLocal; + USHORT usUnicode; +} char_table_type; + +static char_table_type atCharTable[256]; +static size_t tNextPosFree = 0; + + +/* + * iCompare - compare two records + * + * Compares two records. For use by qsort(3C) and bsearch(3C). + * + * returns -1 if rec1 < rec2, 0 if rec1 == rec2, 1 if rec1 > rec2 + */ +static int +iCompare(const void *pvRecord1, const void *pvRecord2) +{ + USHORT usUnicode1, usUnicode2; + + usUnicode1 = ((char_table_type *)pvRecord1)->usUnicode; + usUnicode2 = ((char_table_type *)pvRecord2)->usUnicode; + + if (usUnicode1 < usUnicode2) { + return -1; + } + if (usUnicode1 > usUnicode2) { + return 1; + } + return 0; +} /* end of iCompare */ + +/* + * pGetCharTableRecord - get the character table record + * + * returns a pointer to the record when found, otherwise NULL + */ +static const char_table_type * +pGetCharTableRecord(USHORT usUnicode) +{ + char_table_type tKey; + + if (tNextPosFree == 0) { + return NULL; + } + tKey.usUnicode = usUnicode; + tKey.ucLocal = 0; + return (char_table_type *)bsearch(&tKey, + atCharTable, + tNextPosFree, sizeof(atCharTable[0]), + iCompare); +} /* end of pGetCharTableRecord */ + +/* + * ucGetBulletCharacter - get the local representation of the bullet + */ +UCHAR +ucGetBulletCharacter(conversion_type eConversionType, encoding_type eEncoding) +{ +#if defined(__riscos) + return 0x8f; +#else + const char_table_type *pRec; + + fail(eEncoding == encoding_utf_8); + + if (eEncoding == encoding_latin_1 && + (eConversionType == conversion_ps || + eConversionType == conversion_pdf)) { + /* Ugly, but it makes the PostScript and PDF look better */ + return (UCHAR)143; + } + if (eConversionType != conversion_text && + eConversionType != conversion_fmt_text) { + pRec = pGetCharTableRecord(UNICODE_BULLET); + if (pRec != NULL) { + return pRec->ucLocal; + } + pRec = pGetCharTableRecord(UNICODE_BULLET_OPERATOR); + if (pRec != NULL) { + return pRec->ucLocal; + } + pRec = pGetCharTableRecord(UNICODE_MIDDLE_DOT); + if (pRec != NULL) { + return pRec->ucLocal; + } + } + return (UCHAR)'.'; +#endif /* __riscos */ +} /* end of ucGetBulletCharacter */ + +/* + * ucGetNbspCharacter - get the local representation of the non-breaking space + */ +UCHAR +ucGetNbspCharacter(void) +{ + const char_table_type *pRec; + + pRec = pGetCharTableRecord(0x00a0); /* Unicode non-breaking space */ + if (pRec == NULL) { + DBG_MSG("Non-breaking space record not found"); + /* No value found, use the best guess */ + return (UCHAR)0xa0; + } + return pRec->ucLocal; +} /* end of ucGetNbspCharacter */ + +/* + * bReadCharacterMappingTable - read the mapping table + * + * Read the character mapping table from file and have the contents sorted + * + * returns TRUE if successful, otherwise FALSE + */ +BOOL +bReadCharacterMappingTable(FILE *pFile) +{ + char *pcTmp; + ULONG ulUnicode; + UINT uiLocal; + int iFields; + char szLine[81]; + + if (pFile == NULL) { + return FALSE; + } + + /* Clean the table first */ + (void)memset(atCharTable, 0, sizeof(atCharTable)); + + /* Fill the table */ + while (fgets(szLine, (int)sizeof(szLine), pFile)) { + if (szLine[0] == '#' || + szLine[0] == '\r' || + szLine[0] == '\n') { + /* Comment or empty line */ + continue; + } + iFields = sscanf(szLine, "%x %lx %*s", &uiLocal, &ulUnicode); + if (iFields != 2) { + pcTmp = strchr(szLine, '\r'); + if (pcTmp != NULL) { + *pcTmp = '\0'; + } + pcTmp = strchr(szLine, '\n'); + if (pcTmp != NULL) { + *pcTmp = '\0'; + } + werr(0, "Syntax error in: '%s'", szLine); + continue; + } + if (uiLocal > 0xff || ulUnicode > 0xffff) { + werr(0, "Syntax error in: '%02x %04lx'", + uiLocal, ulUnicode); + continue; + } + /* Store only the relevant entries */ + if (uiLocal != ulUnicode || uiLocal >= 0x80) { + atCharTable[tNextPosFree].ucLocal = (UCHAR)uiLocal; + atCharTable[tNextPosFree].usUnicode = (USHORT)ulUnicode; + tNextPosFree++; + } + if (tNextPosFree >= elementsof(atCharTable)) { + werr(0, "Too many entries in the character mapping " + "file. Ignoring the rest."); + break; + } + } + + if (tNextPosFree != 0) { + DBG_HEX(atCharTable[0].usUnicode); + DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode); + + qsort(atCharTable, + tNextPosFree, sizeof(atCharTable[0]), + iCompare); + + DBG_HEX(atCharTable[0].usUnicode); + DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode); + } + + return TRUE; +} /* end of bReadCharacterMappingTable */ + +/* + * ulTranslateCharacters - Translate characters to local representation + * + * Translate all characters to local representation + * + * returns the translated character + */ +ULONG +ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion, + conversion_type eConversionType, encoding_type eEncoding, + BOOL bUseMacCharSet) +{ + const char_table_type *pTmp; + const USHORT *usCharSet; + + usCharSet = NULL; + if (bUseMacCharSet) { + /* Macintosh character set */ + usCharSet = usMacRoman; + } else if (iWordVersion == 0) { + /* DOS character set */ + usCharSet = usCp850; + } else { + /* Windows character set */ + switch (eEncoding) { + case encoding_latin_2: + usCharSet = usCp1250; + break; + case encoding_cyrillic: + usCharSet = usCp1251; + break; + case encoding_latin_1: + default: + usCharSet = usCp1252; + break; + } + } + fail(usCharSet == NULL); + if (usChar >= 0x80 && usChar <= 0x9f) { + /* Translate implementation defined characters */ + usChar = usCharSet[usChar - 0x80]; + } else if (iWordVersion < 8 && usChar >= 0xa0 && usChar <= 0xff) { + /* Translate old character set to Unixcode */ + usChar = usCharSet[usChar - 0x80]; + } + + /* Microsoft Unicode to real Unicode */ + if (usChar >= 0xf020 && usChar <= 0xf0ff) { + DBG_HEX_C(usPrivateArea[usChar - 0xf020] == 0x003f, usChar); + usChar = usPrivateArea[usChar - 0xf020]; + } + + /* Characters with a special meaning in Word */ + switch (usChar) { + case IGNORE_CHARACTER: + case FOOTNOTE_SEPARATOR: + case FOOTNOTE_CONTINUATION: + case ANNOTATION: + case FRAME: + case LINE_FEED: + case WORD_SOFT_HYPHEN: + case UNICODE_HYPHENATION_POINT: + return IGNORE_CHARACTER; + case PICTURE: + case TABLE_SEPARATOR: + case TAB: + case HARD_RETURN: + case PAGE_BREAK: + case PAR_END: + case COLUMN_FEED: + return (ULONG)usChar; + case FOOTNOTE_OR_ENDNOTE: + NO_DBG_HEX(ulFileOffset); + switch (eGetNotetype(ulFileOffset)) { + case notetype_is_footnote: + return FOOTNOTE_CHAR; + case notetype_is_endnote: + return ENDNOTE_CHAR; + default: + return UNKNOWN_NOTE_CHAR; + } + case WORD_UNBREAKABLE_JOIN: + return (ULONG)OUR_UNBREAKABLE_JOIN; + default: + break; + } + + if (eEncoding != encoding_utf_8) { + /* Latin characters in an oriental text */ + if (usChar >= 0xff01 && usChar <= 0xff5e) { + usChar -= 0xfee0; + } + } + + if (eEncoding == encoding_latin_1 && + (eConversionType == conversion_ps || + eConversionType == conversion_pdf)) { + /* Ugly, but it makes the PostScript and PDF look better */ + switch (usChar) { + case UNICODE_ELLIPSIS: + return 140; + case UNICODE_TRADEMARK_SIGN: + return 141; + case UNICODE_PER_MILLE_SIGN: + return 142; + case UNICODE_BULLET: + case UNICODE_BULLET_OPERATOR: + case UNICODE_BLACK_CLUB_SUIT: + return 143; + case UNICODE_LEFT_SINGLE_QMARK: + return 144; + case UNICODE_RIGHT_SINGLE_QMARK: + return 145; + case UNICODE_SINGLE_LEFT_ANGLE_QMARK: + return 146; + case UNICODE_SINGLE_RIGHT_ANGLE_QMARK: + return 147; + case UNICODE_LEFT_DOUBLE_QMARK: + return 148; + case UNICODE_RIGHT_DOUBLE_QMARK: + return 149; + case UNICODE_DOUBLE_LOW_9_QMARK: + return 150; + case UNICODE_EN_DASH: + return 151; + case UNICODE_EM_DASH: + return 152; + case UNICODE_MINUS_SIGN: + return 153; + case UNICODE_CAPITAL_LIGATURE_OE: + return 154; + case UNICODE_SMALL_LIGATURE_OE: + return 155; + case UNICODE_DAGGER: + return 156; + case UNICODE_DOUBLE_DAGGER: + return 157; + case UNICODE_SMALL_LIGATURE_FI: + return 158; + case UNICODE_SMALL_LIGATURE_FL: + return 159; + default: + break; + } + } + + if (eConversionType == conversion_pdf) { + if (eEncoding == encoding_latin_1) { + switch (usChar) { + case UNICODE_EURO_SIGN: + return 128; + default: + break; + } + } else if (eEncoding == encoding_latin_2) { + switch (usChar) { + case UNICODE_CAPITAL_D_WITH_STROKE: + case UNICODE_SMALL_D_WITH_STROKE: + return 0x3f; + default: + break; + } + } + } + + if (usChar < 0x80) { + /* US ASCII */ + if (usChar < 0x20 || usChar == 0x7f) { + /* Ignore control characters */ + DBG_HEX(usChar); + DBG_FIXME(); + return IGNORE_CHARACTER; + } + return (ULONG)usChar; + } + + if (eEncoding == encoding_utf_8) { + /* No need to convert Unicode characters */ + return (ULONG)usChar; + } + + /* Unicode to local representation */ + pTmp = pGetCharTableRecord(usChar); + if (pTmp != NULL) { + DBG_HEX_C(usChar >= 0x7f && usChar <= 0x9f, usChar); + return (ULONG)pTmp->ucLocal; + } + + /* Fancy characters to simple US ASCII */ + switch (usChar) { + case UNICODE_SMALL_F_HOOK: + return (ULONG)'f'; + case UNICODE_GREEK_CAPITAL_CHI: + return (ULONG)'X'; + case UNICODE_GREEK_SMALL_UPSILON: + return (ULONG)'v'; + case UNICODE_MODIFIER_CIRCUMFLEX: + case UNICODE_UPWARDS_ARROW: + return (ULONG)'^'; + case UNICODE_SMALL_TILDE: + case UNICODE_TILDE_OPERATOR: + return (ULONG)'~'; + case UNICODE_EN_QUAD: + case UNICODE_EM_QUAD: + case UNICODE_EN_SPACE: + case UNICODE_EM_SPACE: + case UNICODE_THREE_PER_EM_SPACE: + case UNICODE_FOUR_PER_EM_SPACE: + case UNICODE_SIX_PER_EM_SPACE: + case UNICODE_FIGURE_SPACE: + case UNICODE_PUNCTUATION_SPACE: + case UNICODE_THIN_SPACE: + case UNICODE_NARROW_NO_BREAK_SPACE: + case UNICODE_LIGHT_SHADE: + case UNICODE_MEDIUM_SHADE: + case UNICODE_DARK_SHADE: + return (ULONG)' '; + case UNICODE_LEFT_DOUBLE_QMARK: + case UNICODE_RIGHT_DOUBLE_QMARK: + case UNICODE_DOUBLE_LOW_9_QMARK: + case UNICODE_DOUBLE_HIGH_REV_9_QMARK: + case UNICODE_DOUBLE_PRIME: + return (ULONG)'"'; + case UNICODE_LEFT_SINGLE_QMARK: + case UNICODE_RIGHT_SINGLE_QMARK: + case UNICODE_SINGLE_LOW_9_QMARK: + case UNICODE_SINGLE_HIGH_REV_9_QMARK: + case UNICODE_PRIME: + return (ULONG)'\''; + case UNICODE_HYPHEN: + case UNICODE_NON_BREAKING_HYPHEN: + case UNICODE_FIGURE_DASH: + case UNICODE_EN_DASH: + case UNICODE_EM_DASH: + case UNICODE_HORIZONTAL_BAR: + case UNICODE_MINUS_SIGN: + case UNICODE_BD_LIGHT_HORIZONTAL: + case UNICODE_BD_DOUBLE_HORIZONTAL: + return (ULONG)'-'; + case UNICODE_DOUBLE_VERTICAL_LINE: + case UNICODE_BD_LIGHT_VERTICAL: + case UNICODE_BD_DOUBLE_VERTICAL: + return (ULONG)'|'; + case UNICODE_DOUBLE_LOW_LINE: + return (ULONG)'_'; + case UNICODE_DAGGER: + return (ULONG)'+'; + case UNICODE_DOUBLE_DAGGER: + return (ULONG)'#'; + case UNICODE_BULLET: + case UNICODE_BULLET_OPERATOR: + case UNICODE_BLACK_CLUB_SUIT: + return (ULONG)ucGetBulletCharacter(eConversionType, eEncoding); + case UNICODE_ONE_DOT_LEADER: + case UNICODE_TWO_DOT_LEADER: + return (ULONG)'.'; + case UNICODE_ELLIPSIS: +#if defined(__riscos) + return (ULONG)OUR_ELLIPSIS; +#else + if (ulFileOffset == 0) { + return (ULONG)OUR_ELLIPSIS; + } + return UNICODE_ELLIPSIS; +#endif /* __riscos */ + case UNICODE_DOUBLE_LEFT_ANGLE_QMARK: + case UNICODE_TRIANGULAR_BULLET: + case UNICODE_SINGLE_LEFT_ANGLE_QMARK: + case UNICODE_LEFTWARDS_ARROW: + return (ULONG)'<'; + case UNICODE_DOUBLE_RIGHT_ANGLE_QMARK: + case UNICODE_SINGLE_RIGHT_ANGLE_QMARK: + case UNICODE_RIGHTWARDS_ARROW: + return (ULONG)'>'; + case UNICODE_UNDERTIE: + return (ULONG)'-'; + case UNICODE_N_ARY_SUMMATION: + return (ULONG)'S'; + case UNICODE_EURO_SIGN: + return (ULONG)'E'; + case UNICODE_CIRCLE: + case UNICODE_SQUARE: + return (ULONG)'O'; + case UNICODE_DIAMOND: + return (ULONG)OUR_DIAMOND; + case UNICODE_NUMERO_SIGN: + return (ULONG)'N'; + case UNICODE_KELVIN_SIGN: + return (ULONG)'K'; + case UNICODE_DOWNWARDS_ARROW: + return (ULONG)'v'; + case UNICODE_FRACTION_SLASH: + case UNICODE_DIVISION_SLASH: + return (ULONG)'/'; + case UNICODE_ASTERISK_OPERATOR: + return (ULONG)'*'; + case UNICODE_RATIO: + return (ULONG)':'; + case UNICODE_BD_LIGHT_DOWN_RIGHT: + case UNICODE_BD_LIGHT_DOWN_AND_LEFT: + case UNICODE_BD_LIGHT_UP_AND_RIGHT: + case UNICODE_BD_LIGHT_UP_AND_LEFT: + case UNICODE_BD_LIGHT_VERTICAL_AND_RIGHT: + case UNICODE_BD_LIGHT_VERTICAL_AND_LEFT: + case UNICODE_BD_LIGHT_DOWN_AND_HORIZONTAL: + case UNICODE_BD_LIGHT_UP_AND_HORIZONTAL: + case UNICODE_BD_LIGHT_VERTICAL_AND_HORIZONTAL: + case UNICODE_BD_DOUBLE_DOWN_AND_RIGHT: + case UNICODE_BD_DOUBLE_DOWN_AND_LEFT: + case UNICODE_BD_DOUBLE_UP_AND_RIGHT: + case UNICODE_BD_DOUBLE_UP_AND_LEFT: + case UNICODE_BD_DOUBLE_VERTICAL_AND_RIGHT: + case UNICODE_BD_DOUBLE_VERTICAL_AND_LEFT: + case UNICODE_BD_DOUBLE_DOWN_AND_HORIZONTAL: + case UNICODE_BD_DOUBLE_UP_AND_HORIZONTAL: + case UNICODE_BD_DOUBLE_VERTICAL_AND_HORIZONTAL: + case UNICODE_BLACK_SQUARE: + return (ULONG)'+'; + case UNICODE_HAIR_SPACE: + case UNICODE_ZERO_WIDTH_SPACE: + case UNICODE_ZERO_WIDTH_NON_JOINER: + case UNICODE_ZERO_WIDTH_JOINER: + case UNICODE_LEFT_TO_RIGHT_MARK: + case UNICODE_RIGHT_TO_LEFT_MARK: + case UNICODE_LEFT_TO_RIGHT_EMBEDDING: + case UNICODE_RIGHT_TO_LEFT_EMBEDDING: + case UNICODE_POP_DIRECTIONAL_FORMATTING: + case UNICODE_LEFT_TO_RIGHT_OVERRIDE: + case UNICODE_RIGHT_TO_LEFT_OVERRIDE: + case UNICODE_ZERO_WIDTH_NO_BREAK_SPACE: + return IGNORE_CHARACTER; + default: + break; + } + + if (usChar == UNICODE_TRADEMARK_SIGN) { + /* + * No local representation, it doesn't look like anything in + * US-ASCII and a question mark does more harm than good. + */ + return IGNORE_CHARACTER; + } + + if (usChar >= 0xa0 && usChar <= 0xff) { + /* Before Word 97, Word did't use Unicode */ + return (ULONG)usChar; + } + + DBG_HEX_C(usChar < 0x3000 || usChar >= 0xd800, ulFileOffset); + DBG_HEX_C(usChar < 0x3000 || usChar >= 0xd800, usChar); + DBG_MSG_C(usChar >= 0xe000 && usChar < 0xf900, "Private Use Area"); + + /* Untranslated Unicode character */ + return 0x3f; +} /* end of ulTranslateCharacters */ + +/* + * ulToUpper - convert letter to upper case + * + * This function converts a letter to upper case. Unlike toupper(3) this + * function is independent from the settings of locale. This comes in handy + * for people who have to read Word documents in more than one language or + * contain more than one language. + * + * returns the converted letter, or ulChar if the conversion was not possible. + */ +ULONG +ulToUpper(ULONG ulChar) +{ + if (ulChar < 0x80) { + /* US ASCII: use standard function */ + return (ULONG)toupper((int)ulChar); + } + if (ulChar >= 0xe0 && ulChar <= 0xfe && ulChar != 0xf7) { + /* + * Lower case accented characters + * 0xf7 is Division sign; 0xd7 is Multiplication sign + * 0xff is y with diaeresis; 0xdf is Sharp s + */ + return ulChar & ~0x20; + } +#if defined(__STDC_ISO_10646__) + /* + * If this is ISO C99 and all locales have wchar_t = ISO 10646 + * (e.g., glibc 2.2 or newer), then use standard function + */ + if (ulChar > 0xff) { + return (ULONG)towupper((wint_t)ulChar); + } +#endif /* __STDC_ISO_10646__ */ + return ulChar; +} /* end of ulToUpper */ diff --git a/datalist.c b/datalist.c new file mode 100644 index 0000000..564f469 --- /dev/null +++ b/datalist.c @@ -0,0 +1,374 @@ +/* + * datalist.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Build, read and destroy a list of Word data blocks + */ + +#include +#include +#include "antiword.h" + +#if defined(__riscos) +#define EIO 42 +#endif /* __riscos */ + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct data_mem_tag { + data_block_type tInfo; + struct data_mem_tag *pNext; +} data_mem_type; + +/* Variable to describe the start of the data block list */ +static data_mem_type *pAnchor = NULL; +/* Variable needed to read the data block list */ +static data_mem_type *pBlockLast = NULL; +/* Variable needed to read the data block list */ +static data_mem_type *pBlockCurrent = NULL; +static ULONG ulBlockOffset = 0; +static size_t tByteNext = 0; +/* Last block read */ +static UCHAR aucBlock[BIG_BLOCK_SIZE]; + + +/* + * vDestroyDataBlockList - destroy the data block list + */ +void +vDestroyDataBlockList(void) +{ + data_mem_type *pCurr, *pNext; + + DBG_MSG("vDestroyDataBlockList"); + + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all the control variables */ + pBlockLast = NULL; + pBlockCurrent = NULL; + ulBlockOffset = 0; + tByteNext = 0; +} /* end of vDestroyDataBlockList */ + +/* + * bAdd2DataBlockList - add an element to the data block list + * + * Returns TRUE when successful, otherwise FALSE + */ +BOOL +bAdd2DataBlockList(const data_block_type *pDataBlock) +{ + data_mem_type *pListMember; + + fail(pDataBlock == NULL); + fail(pDataBlock->ulFileOffset == FC_INVALID); + fail(pDataBlock->ulDataPos == CP_INVALID); + fail(pDataBlock->ulLength == 0); + + NO_DBG_MSG("bAdd2DataBlockList"); + NO_DBG_HEX(pDataBlock->ulFileOffset); + NO_DBG_HEX(pDataBlock->ulDataPos); + NO_DBG_HEX(pDataBlock->ulLength); + + if (pDataBlock->ulFileOffset == FC_INVALID || + pDataBlock->ulDataPos == CP_INVALID || + pDataBlock->ulLength == 0) { + werr(0, "Software (datablock) error"); + return FALSE; + } + /* Check for continuous blocks */ + if (pBlockLast != NULL && + pBlockLast->tInfo.ulFileOffset + + pBlockLast->tInfo.ulLength == pDataBlock->ulFileOffset && + pBlockLast->tInfo.ulDataPos + + pBlockLast->tInfo.ulLength == pDataBlock->ulDataPos) { + /* These are continous blocks */ + pBlockLast->tInfo.ulLength += pDataBlock->ulLength; + return TRUE; + } + /* Make a new block */ + pListMember = xmalloc(sizeof(data_mem_type)); + /* Add the block to the data list */ + pListMember->tInfo = *pDataBlock; + pListMember->pNext = NULL; + if (pAnchor == NULL) { + pAnchor = pListMember; + } else { + fail(pBlockLast == NULL); + pBlockLast->pNext = pListMember; + } + pBlockLast = pListMember; + return TRUE; +} /* end of bAdd2DataBlockList */ + +/* + * ulGetDataOffset - get the offset in the data block list + * + * Get the fileoffset the current position in the data block list + */ +ULONG +ulGetDataOffset(FILE *pFile) +{ + return pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset + tByteNext; +} /* end of ulGetDataOffset */ + +/* + * bSetDataOffset - set the offset in the data block list + * + * Make the given fileoffset the current position in the data block list + */ +BOOL +bSetDataOffset(FILE *pFile, ULONG ulFileOffset) +{ + data_mem_type *pCurr; + size_t tReadLen; + + DBG_HEX(ulFileOffset); + + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (ulFileOffset < pCurr->tInfo.ulFileOffset || + ulFileOffset >= pCurr->tInfo.ulFileOffset + + pCurr->tInfo.ulLength) { + /* The file offset is not in this block */ + continue; + } + /* Compute the maximum number of bytes to read */ + tReadLen = (size_t)(pCurr->tInfo.ulFileOffset + + pCurr->tInfo.ulLength - + ulFileOffset); + /* Compute the real number of bytes to read */ + if (tReadLen > sizeof(aucBlock)) { + tReadLen = sizeof(aucBlock); + } + /* Read the bytes */ + if (!bReadBytes(aucBlock, tReadLen, ulFileOffset, pFile)) { + return FALSE; + } + /* Set the control variables */ + pBlockCurrent = pCurr; + ulBlockOffset = ulFileOffset - pCurr->tInfo.ulFileOffset; + tByteNext = 0; + return TRUE; + } + return FALSE; +} /* end of bSetDataOffset */ + +/* + * iNextByte - get the next byte from the data block list + */ +int +iNextByte(FILE *pFile) +{ + ULONG ulReadOff; + size_t tReadLen; + + fail(pBlockCurrent == NULL); + + if (tByteNext >= sizeof(aucBlock) || + ulBlockOffset + tByteNext >= pBlockCurrent->tInfo.ulLength) { + if (ulBlockOffset + sizeof(aucBlock) < + pBlockCurrent->tInfo.ulLength) { + /* Same block, next part */ + ulBlockOffset += sizeof(aucBlock); + } else { + /* Next block, first part */ + pBlockCurrent = pBlockCurrent->pNext; + ulBlockOffset = 0; + } + if (pBlockCurrent == NULL) { + /* Past the last part of the last block */ + errno = EIO; + return EOF; + } + tReadLen = (size_t) + (pBlockCurrent->tInfo.ulLength - ulBlockOffset); + if (tReadLen > sizeof(aucBlock)) { + tReadLen = sizeof(aucBlock); + } + ulReadOff = pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset; + if (!bReadBytes(aucBlock, tReadLen, ulReadOff, pFile)) { + errno = EIO; + return EOF; + } + tByteNext = 0; + } + return (int)aucBlock[tByteNext++]; +} /* end of iNextByte */ + +/* + * usNextWord - get the next word from the data block list + * + * Read a two byte value in Little Endian order, that means MSB last + * + * All return values can be valid so errno is set in case of error + */ +USHORT +usNextWord(FILE *pFile) +{ + USHORT usLSB, usMSB; + + usLSB = (USHORT)iNextByte(pFile); + if (usLSB == (USHORT)EOF) { + errno = EIO; + return (USHORT)EOF; + } + usMSB = (USHORT)iNextByte(pFile); + if (usMSB == (USHORT)EOF) { + DBG_MSG("usNextWord: Unexpected EOF"); + errno = EIO; + return (USHORT)EOF; + } + return (usMSB << 8) | usLSB; +} /* end of usNextWord */ + +/* + * ulNextLong - get the next long from the data block list + * + * Read a four byte value in Little Endian order, that means MSW last + * + * All return values can be valid so errno is set in case of error + */ +ULONG +ulNextLong(FILE *pFile) +{ + ULONG ulLSW, ulMSW; + + ulLSW = (ULONG)usNextWord(pFile); + if (ulLSW == (ULONG)EOF) { + errno = EIO; + return (ULONG)EOF; + } + ulMSW = (ULONG)usNextWord(pFile); + if (ulMSW == (ULONG)EOF) { + DBG_MSG("ulNextLong: Unexpected EOF"); + errno = EIO; + return (ULONG)EOF; + } + return (ulMSW << 16) | ulLSW; +} /* end of ulNextLong */ + +/* + * usNextWordBE - get the next two byte value + * + * Read a two byte value in Big Endian order, that means MSB first + * + * All return values can be valid so errno is set in case of error + */ +USHORT +usNextWordBE(FILE *pFile) +{ + USHORT usLSB, usMSB; + + usMSB = (USHORT)iNextByte(pFile); + if (usMSB == (USHORT)EOF) { + errno = EIO; + return (USHORT)EOF; + } + usLSB = (USHORT)iNextByte(pFile); + if (usLSB == (USHORT)EOF) { + DBG_MSG("usNextWordBE: Unexpected EOF"); + errno = EIO; + return (USHORT)EOF; + } + return (usMSB << 8) | usLSB; +} /* end of usNextWordBE */ + +/* + * ulNextLongBE - get the next four byte value + * + * Read a four byte value in Big Endian order, that means MSW first + * + * All return values can be valid so errno is set in case of error + */ +ULONG +ulNextLongBE(FILE *pFile) +{ + ULONG ulLSW, ulMSW; + + ulMSW = (ULONG)usNextWordBE(pFile); + if (ulMSW == (ULONG)EOF) { + errno = EIO; + return (ULONG)EOF; + } + ulLSW = (ULONG)usNextWordBE(pFile); + if (ulLSW == (ULONG)EOF) { + DBG_MSG("ulNextLongBE: Unexpected EOF"); + errno = EIO; + return (ULONG)EOF; + } + return (ulMSW << 16) | ulLSW; +} /* end of ulNextLongBE */ + +/* + * tSkipBytes - skip over the given number of bytes + * + * Returns the number of skipped bytes + */ +size_t +tSkipBytes(FILE *pFile, size_t tToSkip) +{ + size_t tToGo, tMaxMove, tMove; + + fail(pFile == NULL); + fail(pBlockCurrent == NULL); + + tToGo = tToSkip; + while (tToGo != 0) { + /* Goto the end of the current block */ + tMaxMove = min(sizeof(aucBlock) - tByteNext, + (size_t)(pBlockCurrent->tInfo.ulLength - + ulBlockOffset - tByteNext)); + tMove = min(tMaxMove, tToGo); + tByteNext += tMove; + tToGo -= tMove; + if (tToGo != 0) { + /* Goto the next block */ + if (iNextByte(pFile) == EOF) { + return tToSkip - tToGo; + } + tToGo--; + } + } + return tToSkip; +} /* end of tSkipBytes */ + +/* + * Translate a data position to an offset in the file. + * Logical to physical offset. + * + * Returns: FC_INVALID: in case of error + * otherwise: the computed file offset + */ +ULONG +ulDataPos2FileOffset(ULONG ulDataPos) +{ + data_mem_type *pCurr; + + fail(ulDataPos == CP_INVALID); + + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (ulDataPos < pCurr->tInfo.ulDataPos || + ulDataPos >= pCurr->tInfo.ulDataPos + + pCurr->tInfo.ulLength) { + /* The data offset is not in this block, try the next */ + continue; + } + /* The data offset is in the current block */ + return pCurr->tInfo.ulFileOffset + + ulDataPos - + pCurr->tInfo.ulDataPos; + } + /* Passed beyond the end of the list */ + DBG_HEX_C(ulDataPos != 0, ulDataPos); + return FC_INVALID; +} /* end of ulDataPos2FileOffset */ diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..4dee4d4 --- /dev/null +++ b/debug.h @@ -0,0 +1,117 @@ +/* + * debug.h + * Copyright (C) 1998-2005 A.J. van Os; Released under GPL + * + * Description: + * Macro's for debuging. + */ + +#if !defined(__debug_h) +#define __debug_h 1 + +#include +#include + +#if defined(DEBUG) + +#define DBG_MSG(t) (void)fprintf(stderr,\ + "%s[%3d]: %.240s\n",\ + __FILE__, __LINE__, (t)) + +#define DBG_STRN(t,m) (void)fprintf(stderr,\ + "%s[%3d]: %d '%.*s'\n",\ + __FILE__, __LINE__,\ + (int)(m), (int)(m), (const char *)(t)) + +#define DBG_CHR(m) (void)fprintf(stderr,\ + "%s[%3d]: "#m" = %3d 0x%02x '%c'\n",\ + __FILE__, __LINE__,\ + (int)(m), (unsigned int)(unsigned char)(m),\ + isprint((int)(unsigned char)(m))?(char)(m):' ') + +#define DBG_DEC(m) (void)fprintf(stderr,\ + "%s[%3d]: "#m" = %ld\n",\ + __FILE__, __LINE__, (long)(m)) + +#define DBG_HEX(m) (void)fprintf(stderr,\ + "%s[%3d]: "#m" = 0x%02lx\n",\ + __FILE__, __LINE__, (unsigned long)(m)) + +#define DBG_FLT(m) (void)fprintf(stderr,\ + "%s[%3d]: "#m" = %.3f\n",\ + __FILE__, __LINE__, (double)(m)) + +#define DBG_FIXME() (void)fprintf(stderr,\ + "%s[%3d]: FIXME\n",\ + __FILE__, __LINE__) + +#define DBG_PRINT_BLOCK(b,m) vPrintBlock(__FILE__, __LINE__,(b),(m)) +#define DBG_UNICODE(t) vPrintUnicode(__FILE__, __LINE__,\ + (const UCHAR *)(t),unilen(t)) +#define DBG_UNICODE_N(t,m) vPrintUnicode(__FILE__, __LINE__,\ + (const UCHAR *)(t),(m)) + +#define DBG_MSG_C(c,t) do { if (c) DBG_MSG(t); } while(0) +#define DBG_STRN_C(c,t,m) do { if (c) DBG_STRN(t,m); } while(0) +#define DBG_CHR_C(c,m) do { if (c) DBG_CHR(m); } while(0) +#define DBG_DEC_C(c,m) do { if (c) DBG_DEC(m); } while(0) +#define DBG_HEX_C(c,m) do { if (c) DBG_HEX(m); } while(0) +#define DBG_FLT_C(c,m) do { if (c) DBG_FLT(m); } while(0) + +#else + +#define DBG_MSG(t) /* EMPTY */ +#define DBG_STRN(t,m) /* EMPTY */ +#define DBG_CHR(m) /* EMPTY */ +#define DBG_DEC(m) /* EMPTY */ +#define DBG_HEX(m) /* EMPTY */ +#define DBG_FLT(m) /* EMPTY */ + +#define DBG_FIXME() /* EMPTY */ +#define DBG_PRINT_BLOCK(b,m) /* EMPTY */ +#define DBG_UNICODE(t) /* EMPTY */ +#define DBG_UNICODE_N(t,m) /* EMPTY */ + +#define DBG_MSG_C(c,t) /* EMPTY */ +#define DBG_STRN_C(c,t,m) /* EMPTY */ +#define DBG_CHR_C(c,m) /* EMPTY */ +#define DBG_DEC_C(c,m) /* EMPTY */ +#define DBG_HEX_C(c,m) /* EMPTY */ +#define DBG_FLT_C(c,m) /* EMPTY */ + +#endif /* DEBUG */ + +#define NO_DBG_MSG(t) /* EMPTY */ +#define NO_DBG_STRN(t,m) /* EMPTY */ +#define NO_DBG_CHR(m) /* EMPTY */ +#define NO_DBG_DEC(m) /* EMPTY */ +#define NO_DBG_HEX(m) /* EMPTY */ +#define NO_DBG_FLT(m) /* EMPTY */ + +#define NO_DBG_PRINT_BLOCK(b,m) /* EMPTY */ +#define NO_DBG_UNICODE(t) /* EMPTY */ +#define NO_DBG_UNICODE_N(t,m) /* EMPTY */ + +#define NO_DBG_MSG_C(c,t) /* EMPTY */ +#define NO_DBG_STRN_C(c,t,m) /* EMPTY */ +#define NO_DBG_CHR_C(c,m) /* EMPTY */ +#define NO_DBG_DEC_C(c,m) /* EMPTY */ +#define NO_DBG_HEX_C(c,m) /* EMPTY */ +#define NO_DBG_FLT_C(c,m) /* EMPTY */ + +#if defined(TRACE) + +#define TRACE_MSG(t) do {\ + (void)fprintf(stderr,\ + "%s[%3d]: TRACE:%.40s\n",\ + __FILE__, __LINE__, (t));\ + (void)fflush(stderr);\ + } while(0) + +#else + +#define TRACE_MSG(t) /* EMPTY */ + +#endif /* TRACE */ + +#endif /* !__debug_h */ diff --git a/depot.c b/depot.c new file mode 100644 index 0000000..295c39d --- /dev/null +++ b/depot.c @@ -0,0 +1,114 @@ +/* + * depot.c + * Copyright (C) 1998-2002 A.J. van Os; Released under GPL + * + * Description: + * Functions to compute the depot offset + */ + +#include "antiword.h" + +#define SIZE_RATIO (BIG_BLOCK_SIZE/SMALL_BLOCK_SIZE) + +static ULONG *aulSmallBlockList = NULL; +static size_t tSmallBlockListLen = 0; + + +/* + * vDestroySmallBlockList - destroy the small block list + */ +void +vDestroySmallBlockList(void) +{ + DBG_MSG("vDestroySmallBlockList"); + + aulSmallBlockList = xfree(aulSmallBlockList); + tSmallBlockListLen = 0; +} /* end of vDestroySmalBlockList */ + +/* + * vCreateSmallBlockList - create the small block list + * + * returns: TRUE when successful, otherwise FALSE + */ +BOOL +bCreateSmallBlockList(ULONG ulStartblock, const ULONG *aulBBD, size_t tBBDLen) +{ + ULONG ulTmp; + size_t tSize; + int iIndex; + + fail(aulSmallBlockList != NULL); + fail(tSmallBlockListLen != 0); + fail(ulStartblock > MAX_BLOCKNUMBER && ulStartblock != END_OF_CHAIN); + fail(aulBBD == NULL); + fail(tBBDLen == 0); + + /* Find the length of the small block list */ + for (tSmallBlockListLen = 0, ulTmp = ulStartblock; + tSmallBlockListLen < tBBDLen && ulTmp != END_OF_CHAIN; + tSmallBlockListLen++, ulTmp = aulBBD[ulTmp]) { + if (ulTmp >= (ULONG)tBBDLen) { + DBG_DEC(ulTmp); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + } + DBG_DEC(tSmallBlockListLen); + + if (tSmallBlockListLen == 0) { + /* There is no small block list */ + fail(ulStartblock != END_OF_CHAIN); + aulSmallBlockList = NULL; + return TRUE; + } + + /* Create the small block list */ + tSize = tSmallBlockListLen * sizeof(ULONG); + aulSmallBlockList = xmalloc(tSize); + for (iIndex = 0, ulTmp = ulStartblock; + iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN; + iIndex++, ulTmp = aulBBD[ulTmp]) { + if (ulTmp >= (ULONG)tBBDLen) { + DBG_DEC(ulTmp); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + aulSmallBlockList[iIndex] = ulTmp; + NO_DBG_DEC(aulSmallBlockList[iIndex]); + } + return TRUE; +} /* end of bCreateSmallBlockList */ + +/* + * ulDepotOffset - get the depot offset the block list + */ +ULONG +ulDepotOffset(ULONG ulIndex, size_t tBlockSize) +{ + ULONG ulTmp; + size_t tTmp; + + fail(ulIndex >= ULONG_MAX / BIG_BLOCK_SIZE); + + switch (tBlockSize) { + case BIG_BLOCK_SIZE: + return (ulIndex + 1) * BIG_BLOCK_SIZE; + case SMALL_BLOCK_SIZE: + tTmp = (size_t)(ulIndex / SIZE_RATIO); + ulTmp = ulIndex % SIZE_RATIO; + if (aulSmallBlockList == NULL || + tTmp >= tSmallBlockListLen) { + DBG_HEX(aulSmallBlockList); + DBG_DEC(tSmallBlockListLen); + DBG_DEC(tTmp); + return 0; + } + return ((aulSmallBlockList[tTmp] + 1) * SIZE_RATIO + + ulTmp) * SMALL_BLOCK_SIZE; + default: + DBG_DEC(tBlockSize); + DBG_FIXME(); + return 0; + } +} /* end of ulDepotOffset */ diff --git a/dib2eps.c b/dib2eps.c new file mode 100644 index 0000000..2673d38 --- /dev/null +++ b/dib2eps.c @@ -0,0 +1,509 @@ +/* + * dib2eps.c + * Copyright (C) 2000-2003 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate dib pictures into eps + * + *================================================================ + * This part of the software is based on: + * The Windows Bitmap Decoder Class part of paintlib + * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow + *================================================================ + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include "antiword.h" + + +/* + * vDecode1bpp - decode an uncompressed 1 bit per pixel image + */ +static void +vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + size_t tPadding; + int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse; + + DBG_MSG("vDecode1bpp"); + + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + iEighthWidth = (pImg->iWidth + 7) / 8; + tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth); + + for (iY = 0; iY < pImg->iHeight; iY++) { + for (iX = 0; iX < iEighthWidth; iX++) { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) { + iUse = pImg->iWidth % 8; + } else { + iUse = 8; + } + for (iN = 0; iN < iUse; iN++) { + switch (iN) { + case 0: iTmp = (iByte & 0x80) / 128; break; + case 1: iTmp = (iByte & 0x40) / 64; break; + case 2: iTmp = (iByte & 0x20) / 32; break; + case 3: iTmp = (iByte & 0x10) / 16; break; + case 4: iTmp = (iByte & 0x08) / 8; break; + case 5: iTmp = (iByte & 0x04) / 4; break; + case 6: iTmp = (iByte & 0x02) / 2; break; + case 7: iTmp = (iByte & 0x01); break; + default: iTmp = 0; break; + } + vASCII85EncodeByte(pOutFile, iTmp); + } + } + (void)tSkipBytes(pInFile, tPadding); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecode1bpp */ + +/* + * vDecode4bpp - decode an uncompressed 4 bits per pixel image + */ +static void +vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + size_t tPadding; + int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse; + + DBG_MSG("vDecode4bpp"); + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + iHalfWidth = (pImg->iWidth + 1) / 2; + tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth); + + for (iY = 0; iY < pImg->iHeight; iY++) { + for (iX = 0; iX < iHalfWidth; iX++) { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) { + iUse = 1; + } else { + iUse = 2; + } + for (iN = 0; iN < iUse; iN++) { + if (odd(iN)) { + iTmp = iByte & 0x0f; + } else { + iTmp = (iByte & 0xf0) / 16; + } + vASCII85EncodeByte(pOutFile, iTmp); + } + } + (void)tSkipBytes(pInFile, tPadding); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecode4bpp */ + +/* + * vDecode8bpp - decode an uncompressed 8 bits per pixel image + */ +static void +vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + size_t tPadding; + int iX, iY, iByte; + + DBG_MSG("vDecode8bpp"); + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth); + + for (iY = 0; iY < pImg->iHeight; iY++) { + for (iX = 0; iX < pImg->iWidth; iX++) { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + vASCII85EncodeByte(pOutFile, iByte); + } + (void)tSkipBytes(pInFile, tPadding); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecode8bpp */ + +/* + * vDecode24bpp - decode an uncompressed 24 bits per pixel image + */ +static void +vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + size_t tPadding; + int iX, iY, iBlue, iGreen, iRed, iTripleWidth; + + DBG_MSG("vDecode24bpp"); + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(!pImg->bColorImage); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + iTripleWidth = pImg->iWidth * 3; + tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth); + + for (iY = 0; iY < pImg->iHeight; iY++) { + for (iX = 0; iX < pImg->iWidth; iX++) { + /* Change from BGR order to RGB order */ + iBlue = iNextByte(pInFile); + if (iBlue == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + iGreen = iNextByte(pInFile); + if (iGreen == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + iRed = iNextByte(pInFile); + if (iRed == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + vASCII85EncodeByte(pOutFile, iRed); + vASCII85EncodeByte(pOutFile, iGreen); + vASCII85EncodeByte(pOutFile, iBlue); + } + (void)tSkipBytes(pInFile, tPadding); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecode24bpp */ + +/* + * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image + */ +static void +vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + int iX, iY, iByte, iTmp, iRunLength, iRun; + BOOL bEOF, bEOL; + + DBG_MSG("vDecodeRle4"); + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + bEOF = FALSE; + + for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) { + bEOL = FALSE; + iX = 0; + while (!bEOL) { + iRunLength = iNextByte(pInFile); + if (iRunLength == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iRunLength != 0) { + /* + * Encoded packet: + * RunLength pixels, all the "same" value + */ + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + for (iRun = 0; iRun < iRunLength; iRun++) { + if (odd(iRun)) { + iTmp = iByte & 0x0f; + } else { + iTmp = (iByte & 0xf0) / 16; + } + if (iX < pImg->iWidth) { + vASCII85EncodeByte(pOutFile, iTmp); + } + iX++; + } + continue; + } + /* Literal or escape */ + iRunLength = iNextByte(pInFile); + if (iRunLength == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iRunLength == 0) { /* End of line escape */ + bEOL = TRUE; + } else if (iRunLength == 1) { /* End of file escape */ + bEOF = TRUE; + bEOL = TRUE; + } else if (iRunLength == 2) { /* Delta escape */ + DBG_MSG("RLE4: encountered delta escape"); + bEOF = TRUE; + bEOL = TRUE; + } else { /* Literal packet */ + iByte = 0; + for (iRun = 0; iRun < iRunLength; iRun++) { + if (odd(iRun)) { + iTmp = iByte & 0x0f; + } else { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + iTmp = (iByte & 0xf0) / 16; + } + if (iX < pImg->iWidth) { + vASCII85EncodeByte(pOutFile, iTmp); + } + iX++; + } + /* Padding if the number of bytes is odd */ + if (odd((iRunLength + 1) / 2)) { + (void)tSkipBytes(pInFile, 1); + } + } + } + DBG_DEC_C(iX != pImg->iWidth, iX); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecodeRle4 */ + +/* + * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image + */ +static void +vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + int iX, iY, iByte, iRunLength, iRun; + BOOL bEOF, bEOL; + + DBG_MSG("vDecodeRle8"); + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + bEOF = FALSE; + + for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) { + bEOL = FALSE; + iX = 0; + while (!bEOL) { + iRunLength = iNextByte(pInFile); + if (iRunLength == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iRunLength != 0) { + /* + * Encoded packet: + * RunLength pixels, all the same value + */ + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + for (iRun = 0; iRun < iRunLength; iRun++) { + if (iX < pImg->iWidth) { + vASCII85EncodeByte(pOutFile, iByte); + } + iX++; + } + continue; + } + /* Literal or escape */ + iRunLength = iNextByte(pInFile); + if (iRunLength == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iRunLength == 0) { /* End of line escape */ + bEOL = TRUE; + } else if (iRunLength == 1) { /* End of file escape */ + bEOF = TRUE; + bEOL = TRUE; + } else if (iRunLength == 2) { /* Delta escape */ + DBG_MSG("RLE8: encountered delta escape"); + bEOF = TRUE; + bEOL = TRUE; + } else { /* Literal packet */ + for (iRun = 0; iRun < iRunLength; iRun++) { + iByte = iNextByte(pInFile); + if (iByte == EOF) { + vASCII85EncodeByte(pOutFile, EOF); + return; + } + if (iX < pImg->iWidth) { + vASCII85EncodeByte(pOutFile, iByte); + } + iX++; + } + /* Padding if the number of bytes is odd */ + if (odd(iRunLength)) { + (void)tSkipBytes(pInFile, 1); + } + } + } + DBG_DEC_C(iX != pImg->iWidth, iX); + } + vASCII85EncodeByte(pOutFile, EOF); +} /* end of vDecodeRle8 */ + +/* + * vDecodeDIB - decode a dib picture + */ +static void +vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg) +{ + size_t tHeaderSize; + + fail(pInFile == NULL); + fail(pOutFile == NULL); + fail(pImg == NULL); + + /* Skip the bitmap info header */ + tHeaderSize = (size_t)ulNextLong(pInFile); + (void)tSkipBytes(pInFile, tHeaderSize - 4); + /* Skip the colortable */ + if (pImg->uiBitsPerComponent <= 8) { + (void)tSkipBytes(pInFile, + (size_t)(pImg->iColorsUsed * + ((tHeaderSize > 12) ? 4 : 3))); + } + + switch (pImg->uiBitsPerComponent) { + case 1: + fail(pImg->eCompression != compression_none); + vDecode1bpp(pInFile, pOutFile, pImg); + break; + case 4: + fail(pImg->eCompression != compression_none && + pImg->eCompression != compression_rle4); + if (pImg->eCompression == compression_rle4) { + vDecodeRle4(pInFile, pOutFile, pImg); + } else { + vDecode4bpp(pInFile, pOutFile, pImg); + } + break; + case 8: + fail(pImg->eCompression != compression_none && + pImg->eCompression != compression_rle8); + if (pImg->eCompression == compression_rle8) { + vDecodeRle8(pInFile, pOutFile, pImg); + } else { + vDecode8bpp(pInFile, pOutFile, pImg); + } + break; + case 24: + fail(pImg->eCompression != compression_none); + vDecode24bpp(pInFile, pOutFile, pImg); + break; + default: + DBG_DEC(pImg->uiBitsPerComponent); + break; + } +} /* end of vDecodeDIB */ + +#if defined(DEBUG) +/* + * vCopy2File + */ +static void +vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen) +{ + static int iPicCounter = 0; + FILE *pOutFile; + size_t tIndex; + int iTmp; + char szFilename[30]; + + if (!bSetDataOffset(pInFile, ulFileOffset)) { + return; + } + + sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter); + pOutFile = fopen(szFilename, "wb"); + if (pOutFile == NULL) { + return; + } + /* Turn a dib into a bmp by adding a fake 14 byte header */ + (void)putc('B', pOutFile); + (void)putc('M', pOutFile); + for (iTmp = 0; iTmp < 12; iTmp++) { + if (putc(0, pOutFile) == EOF) { + break; + } + } + for (tIndex = 0; tIndex < tPictureLen; tIndex++) { + iTmp = iNextByte(pInFile); + if (putc(iTmp, pOutFile) == EOF) { + break; + } + } + (void)fclose(pOutFile); +} /* end of vCopy2File */ +#endif /* DEBUG */ + +/* + * bTranslateDIB - translate a DIB picture + * + * This function translates a picture from dib to eps + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslateDIB(diagram_type *pDiag, FILE *pInFile, + ULONG ulFileOffset, const imagedata_type *pImg) +{ +#if defined(DEBUG) + fail(pImg->tPosition > pImg->tLength); + vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition); +#endif /* DEBUG */ + + /* Seek to start position of DIB data */ + if (!bSetDataOffset(pInFile, ulFileOffset)) { + return FALSE; + } + + vImagePrologue(pDiag, pImg); + vDecodeDIB(pInFile, pDiag->pOutFile, pImg); + vImageEpilogue(pDiag); + + return TRUE; +} /* end of bTranslateDIB */ diff --git a/dib2sprt.c b/dib2sprt.c new file mode 100644 index 0000000..b8fc364 --- /dev/null +++ b/dib2sprt.c @@ -0,0 +1,597 @@ +/* + * dib2sprt.c + * Copyright (C) 2000-2003 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate dib pictures into sprites + */ + +#include +#include +#include "DeskLib:Error.h" +#include "DeskLib:Sprite.h" +#include "antiword.h" + +#if 0 /* defined(DEBUG) */ +static int iPicCounter = 0; +#endif /* DEBUG */ + + +/* + * iGetByteWidth - compute the number of bytes needed for a row of pixels + */ +static int +iGetByteWidth(const imagedata_type *pImg) +{ + switch (pImg->uiBitsPerComponent) { + case 1: + return (pImg->iWidth + 31) / 32 * sizeof(int); + case 4: + return (pImg->iWidth + 7) / 8 * sizeof(int); + case 8: + case 24: + return (pImg->iWidth + 3) / 4 * sizeof(int); + default: + DBG_DEC(pImg->uiBitsPerComponent); + return 0; + } +} /* end of iGetByteWidth */ + +/* + * pCreateBlankSprite - Create a blank sprite. + * + * Create a blank sprite and add a palette if needed + * + * returns a pointer to the sprite when successful, otherwise NULL + */ +static sprite_areainfo * +pCreateBlankSprite(const imagedata_type *pImg, size_t *pSize) +{ + sprite_areainfo *pArea; + UCHAR *pucTmp; + size_t tSize; + screen_modeval uMode; + int iIndex, iPaletteEntries; + + TRACE_MSG("pCreateBlankSprite"); + + fail(pImg == NULL); + fail(pSize == NULL); + + switch (pImg->uiBitsPerComponent) { + case 1: + uMode.screen_mode = 18; + iPaletteEntries = 2; + break; + case 4: + uMode.screen_mode = 20; + iPaletteEntries = 16; + break; + case 8: + case 24: + uMode.screen_mode = 21; + iPaletteEntries = 0; + break; + default: + DBG_DEC(pImg->uiBitsPerComponent); + return NULL; + } + fail(iPaletteEntries < 0 || iPaletteEntries > 16); + + /* Get memory for the sprite */ + tSize = sizeof(sprite_areainfo) + + Sprite_MemorySize(pImg->iWidth, pImg->iHeight, uMode, + iPaletteEntries > 0 ? sprite_HASPAL : sprite_HASNOMASKPAL); + DBG_DEC(tSize); + pArea = xmalloc(tSize); + + /* Initialise sprite area */ + pArea->areasize = tSize; + pArea->numsprites = 0; + pArea->firstoffset = sizeof(sprite_areainfo); + pArea->freeoffset = sizeof(sprite_areainfo); + + /* Create a blank sprite */ + Error_CheckFatal(Sprite_Create(pArea, "wordimage", + iPaletteEntries > 0 ? 1 : 0, + pImg->iWidth, pImg->iHeight, uMode)); + + /* Add the palette */ + pucTmp = (UCHAR *)pArea + pArea->firstoffset + sizeof(sprite_header); + for (iIndex = 0; iIndex < iPaletteEntries; iIndex++) { + /* First color */ + *pucTmp++ = 0; + *pucTmp++ = pImg->aucPalette[iIndex][0]; + *pucTmp++ = pImg->aucPalette[iIndex][1]; + *pucTmp++ = pImg->aucPalette[iIndex][2]; + /* Second color */ + *pucTmp++ = 0; + *pucTmp++ = pImg->aucPalette[iIndex][0]; + *pucTmp++ = pImg->aucPalette[iIndex][1]; + *pucTmp++ = pImg->aucPalette[iIndex][2]; + } + + *pSize = tSize; + return pArea; +} /* end of pCreateBlankSprite */ + +/* + * iReduceColor - reduce from 24 bit to 8 bit color + * + * Reduce 24 bit true colors to RISC OS default 256 color palette + * + * returns the resulting color + */ +static int +iReduceColor(int iRed, int iGreen, int iBlue) +{ + int iResult; + + iResult = (iBlue & 0x80) ? 0x80 : 0; + iResult |= (iGreen & 0x80) ? 0x40 : 0; + iResult |= (iGreen & 0x40) ? 0x20 : 0; + iResult |= (iRed & 0x80) ? 0x10 : 0; + iResult |= (iBlue & 0x40) ? 0x08 : 0; + iResult |= (iRed & 0x40) ? 0x04 : 0; + iResult |= ((iRed | iGreen | iBlue) & 0x20) ? 0x02 : 0; + iResult |= ((iRed | iGreen | iBlue) & 0x10) ? 0x01 : 0; + return iResult; +} /* end of iReduceColor */ + +/* + * vDecode1bpp - decode an uncompressed 1 bit per pixel image + */ +static void +vDecode1bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iByteWidth, iOffset, iTmp, iEighthWidth, iPadding; + UCHAR ucTmp; + + DBG_MSG("vDecode1bpp"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2); + + iByteWidth = iGetByteWidth(pImg); + + iEighthWidth = (pImg->iWidth + 7) / 8; + iPadding = ROUND4(iEighthWidth) - iEighthWidth; + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + for (iX = 0; iX < iEighthWidth; iX++) { + iTmp = iNextByte(pFile); + if (iTmp == EOF) { + return; + } + /* Reverse the bit order */ + ucTmp = (iTmp & BIT(0)) ? (UCHAR)BIT(7) : 0; + ucTmp |= (iTmp & BIT(1)) ? (UCHAR)BIT(6) : 0; + ucTmp |= (iTmp & BIT(2)) ? (UCHAR)BIT(5) : 0; + ucTmp |= (iTmp & BIT(3)) ? (UCHAR)BIT(4) : 0; + ucTmp |= (iTmp & BIT(4)) ? (UCHAR)BIT(3) : 0; + ucTmp |= (iTmp & BIT(5)) ? (UCHAR)BIT(2) : 0; + ucTmp |= (iTmp & BIT(6)) ? (UCHAR)BIT(1) : 0; + ucTmp |= (iTmp & BIT(7)) ? (UCHAR)BIT(0) : 0; + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = ucTmp; + } + (void)tSkipBytes(pFile, iPadding); + } +} /* end of vDecode1bpp */ + +/* + * vDecode4bpp - decode an uncompressed 4 bits per pixel image + */ +static void +vDecode4bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth, iPadding; + UCHAR ucTmp; + + DBG_MSG("vDecode4bpp"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); + + iByteWidth = iGetByteWidth(pImg); + + iHalfWidth = (pImg->iWidth + 1) / 2; + iPadding = ROUND4(iHalfWidth) - iHalfWidth; + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + for (iX = 0; iX < iHalfWidth; iX++) { + iTmp = iNextByte(pFile); + if (iTmp == EOF) { + return; + } + /* Reverse the nibble order */ + ucTmp = (iTmp & 0xf0) >> 4; + ucTmp |= (iTmp & 0x0f) << 4; + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = ucTmp; + } + (void)tSkipBytes(pFile, iPadding); + } +} /* end of vDecode4bpp */ + +/* + * vDecode8bpp - decode an uncompressed 8 bits per pixel image + */ +static void +vDecode8bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iByteWidth, iOffset, iIndex, iPadding; + + DBG_MSG("vDecode8bpp"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); + + iByteWidth = iGetByteWidth(pImg); + + iPadding = ROUND4(pImg->iWidth) - pImg->iWidth; + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + for (iX = 0; iX < pImg->iWidth; iX++) { + iIndex = iNextByte(pFile); + if (iIndex == EOF) { + return; + } + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = iReduceColor( + pImg->aucPalette[iIndex][0], + pImg->aucPalette[iIndex][1], + pImg->aucPalette[iIndex][2]); + } + (void)tSkipBytes(pFile, iPadding); + } +} /* end of vDecode8bpp */ + +/* + * vDecode24bpp - decode an uncompressed 24 bits per pixel image + */ +static void +vDecode24bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iTripleWidth, iByteWidth, iOffset, iPadding; + int iRed, iGreen, iBlue; + + DBG_MSG("vDecode24bpp"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + + iByteWidth = iGetByteWidth(pImg); + + iTripleWidth = pImg->iWidth * 3; + iPadding = ROUND4(iTripleWidth) - iTripleWidth; + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + for (iX = 0; iX < pImg->iWidth; iX++) { + iBlue = iNextByte(pFile); + if (iBlue == EOF) { + return; + } + iGreen = iNextByte(pFile); + if (iGreen == EOF) { + return; + } + iRed = iNextByte(pFile); + if (iRed == EOF) { + return; + } + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = + iReduceColor(iRed, iGreen, iBlue); + } + (void)tSkipBytes(pFile, iPadding); + } +} /* end of vDecode24bpp */ + +/* + * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image + */ +static void +vDecodeRle4(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth; + int iRun, iRunLength, iHalfRun; + BOOL bEOL; + UCHAR ucTmp; + + DBG_MSG("vDecodeRle4"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + iByteWidth = iGetByteWidth(pImg); + iHalfWidth = (pImg->iWidth + 1) / 2; + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + bEOL = FALSE; + iX = 0; + while (!bEOL) { + iRunLength = iNextByte(pFile); + if (iRunLength == EOF) { + return; + } + if (iRunLength != 0) { + /* + * Encoded packet: + * RunLength pixels, all the "same" value + */ + iTmp = iNextByte(pFile); + if (iTmp == EOF) { + return; + } + /* Reverse the nibble order */ + ucTmp = (iTmp & 0xf0) >> 4; + ucTmp |= (iTmp & 0x0f) << 4; + iHalfRun = (iRunLength + 1) / 2; + for (iRun = 0; iRun < iHalfRun; iRun++) { + if (iX < iHalfWidth) { + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = ucTmp; + } + iX++; + } + continue; + } + /* Literal or escape */ + iRunLength = iNextByte(pFile); + if (iRunLength == EOF) { + return; + } + if (iRunLength == 0) { /* End of line escape */ + bEOL = TRUE; + } else if (iRunLength == 1) { /* End of file escape */ + return; + } else if (iRunLength == 2) { /* Delta escape */ + DBG_MSG("RLE4: encountered delta escape"); + return; + } else { /* Literal packet */ + iHalfRun = (iRunLength + 1) / 2; + for (iRun = 0; iRun < iHalfRun; iRun++) { + iTmp = iNextByte(pFile); + if (iTmp == EOF) { + return; + } + /* Reverse the nibble order */ + ucTmp = (iTmp & 0xf0) >> 4; + ucTmp |= (iTmp & 0x0f) << 4; + if (iX < iHalfWidth) { + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = ucTmp; + } + iX++; + } + /* Padding if the number of bytes is odd */ + if (odd(iHalfRun)) { + (void)tSkipBytes(pFile, 1); + } + } + } + DBG_DEC_C(iX != iHalfWidth, iX); + } +} /* end of vDecodeRle4 */ + +/* + * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image + */ +static void +vDecodeRle8(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +{ + int iX, iY, iRun, iRunLength, iOffset, iIndex, iByteWidth; + BOOL bEOL; + + DBG_MSG("vDecodeRle8"); + + fail(pFile == NULL); + fail(pucData == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + + iByteWidth = iGetByteWidth(pImg); + + for (iY = pImg->iHeight - 1; iY >= 0; iY--) { + bEOL = FALSE; + iX = 0; + while (!bEOL) { + iRunLength = iNextByte(pFile); + if (iRunLength == EOF) { + return; + } + if (iRunLength != 0) { + /* + * Encoded packet: + * RunLength pixels, all the same value + */ + iIndex = iNextByte(pFile); + if (iIndex == EOF) { + return; + } + for (iRun = 0; iRun < iRunLength; iRun++) { + if (iX < pImg->iWidth) { + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = + iReduceColor( + pImg->aucPalette[iIndex][0], + pImg->aucPalette[iIndex][1], + pImg->aucPalette[iIndex][2]); + } + iX++; + } + continue; + } + /* Literal or escape */ + iRunLength = iNextByte(pFile); + if (iRunLength == EOF) { + return; + } + if (iRunLength == 0) { /* End of line escape */ + bEOL = TRUE; + } else if (iRunLength == 1) { /* End of file escape */ + return; + } else if (iRunLength == 2) { /* Delta escape */ + DBG_MSG("RLE8: encountered delta escape"); + return; + } else { /* Literal packet */ + for (iRun = 0; iRun < iRunLength; iRun++) { + iIndex = iNextByte(pFile); + if (iIndex == EOF) { + return; + } + if (iX < pImg->iWidth) { + iOffset = iY * iByteWidth + iX; + *(pucData + iOffset) = + iReduceColor( + pImg->aucPalette[iIndex][0], + pImg->aucPalette[iIndex][1], + pImg->aucPalette[iIndex][2]); + } + iX++; + } + /* Padding if the number of bytes is odd */ + if (odd(iRunLength)) { + (void)tSkipBytes(pFile, 1); + } + } + } + DBG_DEC_C(iX != pImg->iWidth, iX); + } +} /* end of vDecodeRle8 */ + +#if 0 /* defined(DEBUG) */ +static void +vCopy2File(UCHAR *pucSprite, size_t tSpriteSize) +{ + FILE *pOutFile; + int iIndex; + char szFilename[30]; + + sprintf(szFilename, ".sprt%04d", ++iPicCounter); + pOutFile = fopen(szFilename, "wb"); + if (pOutFile == NULL) { + return; + } + DBG_MSG(szFilename); + for (iIndex = 4; iIndex < (int)tSpriteSize; iIndex++) { + if (putc(pucSprite[iIndex], pOutFile) == EOF) { + break; + } + } + (void)fclose(pOutFile); + vSetFiletype(szFilename, FILETYPE_SPRITE); +} /* end of vCopy2File */ +#endif /* DEBUG */ + +/* + * vDecodeDIB - decode a dib picture + */ +static void +vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg) +{ + sprite_areainfo *pSprite; + UCHAR *pucPalette, *pucData; + size_t tSpriteSize; + int iHeaderSize; + + /* Skip the bitmap info header */ + iHeaderSize = (int)ulNextLong(pFile); + (void)tSkipBytes(pFile, iHeaderSize - 4); + /* Skip the colortable */ + if (pImg->uiBitsPerComponent <= 8) { + (void)tSkipBytes(pFile, + pImg->iColorsUsed * ((iHeaderSize > 12) ? 4 : 3)); + } + + /* Create an blank sprite */ + pSprite = pCreateBlankSprite(pImg, &tSpriteSize); + pucPalette = (UCHAR *)pSprite + + pSprite->firstoffset + sizeof(sprite_header); + + /* Add the pixel information */ + switch (pImg->uiBitsPerComponent) { + case 1: + fail(pImg->eCompression != compression_none); + pucData = pucPalette + 2 * 8; + vDecode1bpp(pFile, pucData, pImg); + break; + case 4: + fail(pImg->eCompression != compression_none && + pImg->eCompression != compression_rle4); + pucData = pucPalette + 16 * 8; + if (pImg->eCompression == compression_rle4) { + vDecodeRle4(pFile, pucData, pImg); + } else { + vDecode4bpp(pFile, pucData, pImg); + } + break; + case 8: + fail(pImg->eCompression != compression_none && + pImg->eCompression != compression_rle8); + pucData = pucPalette + 0 * 8; + if (pImg->eCompression == compression_rle8) { + vDecodeRle8(pFile, pucData, pImg); + } else { + vDecode8bpp(pFile, pucData, pImg); + } + break; + case 24: + fail(pImg->eCompression != compression_none); + pucData = pucPalette + 0 * 8; + vDecode24bpp(pFile, pucData, pImg); + break; + default: + DBG_DEC(pImg->uiBitsPerComponent); + break; + } + +#if 0 /* defined(DEBUG) */ + vCopy2File((UCHAR *)pSprite, tSpriteSize); +#endif /* DEBUG */ + + /* Add the sprite to the Draw file */ + vImage2Diagram(pDiag, pImg, + (UCHAR *)pSprite + pSprite->firstoffset, + tSpriteSize - pSprite->firstoffset); + + /* Clean up before you leave */ + pSprite = xfree(pSprite); +} /* end of vDecodeDIB */ + +/* + * bTranslateDIB - translate a DIB picture + * + * This function translates a picture from dib to sprite + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslateDIB(diagram_type *pDiag, FILE *pFile, + ULONG ulFileOffset, const imagedata_type *pImg) +{ + /* Seek to start position of DIB data */ + if (!bSetDataOffset(pFile, ulFileOffset)) { + return FALSE; + } + + vDecodeDIB(pDiag, pFile, pImg); + + return TRUE; +} /* end of bTranslateDIB */ diff --git a/doclist.c b/doclist.c new file mode 100644 index 0000000..d4ac380 --- /dev/null +++ b/doclist.c @@ -0,0 +1,75 @@ +/* + * doclist.c + * Copyright (C) 2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy list(s) of Word document information + * + * Note: + * There is no real list there is always one document per document + */ + +#include "antiword.h" + +#define HALF_INCH 36000L /* In millipoints */ + +/* Variables needed to write the Document Information List */ +static document_block_type *pAnchor = NULL; +static document_block_type tInfo; + + +/* + * vDestroyDocumentInfoList - destroy the Document Information List + */ +void +vDestroyDocumentInfoList(void) +{ + DBG_MSG("vDestroyDocumentInfoList"); + + pAnchor = NULL; +} /* end of vDestoryDocumentInfoList */ + +/* + * vCreateDocumentInfoList - create the Document Information List + */ +void +vCreateDocumentInfoList(const document_block_type *pDocument) +{ + fail(pDocument == NULL); + fail(pAnchor != NULL); + + tInfo = *pDocument; + pAnchor = &tInfo; +} /* end of vCreateDocumentInfoList */ + +/* + * lGetDefaultTabWidth - get the default tabwidth in millipoints + */ +long +lGetDefaultTabWidth(void) +{ + long lDefaultTabWidth; + USHORT usTmp; + + if (pAnchor == NULL) { + DBG_FIXME(); + return HALF_INCH; + } + usTmp = pAnchor->usDefaultTabWidth; + lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp); + NO_DBG_DEC(lDefaultTabWidth); + return lDefaultTabWidth; +} /* end of lGetDefaultTabWidth */ + +/* + * ucGetDopHdrFtrSpecification - get the Heder/footer specification + */ +UCHAR +ucGetDopHdrFtrSpecification(void) +{ + if (pAnchor == NULL) { + DBG_FIXME(); + return 0x00; + } + return pAnchor->ucHdrFtrSpecification; +} /* end of ucGetDopHdrFtrSpecification */ diff --git a/draw.c b/draw.c new file mode 100644 index 0000000..f833d75 --- /dev/null +++ b/draw.c @@ -0,0 +1,1047 @@ +/* + * draw.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GPL + * + * Description: + * Functions to deal with the Draw format + */ + +#include +#include +#include +#include "DeskLib:KeyCodes.h" +#include "DeskLib:Error.h" +#include "DeskLib:Menu.h" +#include "DeskLib:Template.h" +#include "DeskLib:Window.h" +#include "DeskLib:EventMsg.h" +#include "flexlib:flex.h" +#include "drawfile.h" +#include "antiword.h" + +/* The work area must be a little bit larger than the diagram */ +#define WORKAREA_EXTENSION 5 +/* Diagram memory */ +#define INITIAL_SIZE 32768 /* 32k */ +#define EXTENSION_SIZE 4096 /* 4k */ +/* Main window title */ +#define WINDOW_TITLE_LEN 28 +#define FILENAME_TITLE_LEN (WINDOW_TITLE_LEN - 10) + + +#if !defined(__GNUC__) +int +flex_alloc(flex_ptr anchor, int n) +{ + void *pvTmp; + + TRACE_MSG("flex_alloc"); + + if (anchor == NULL || n < 0) { + return 0; + } + if (n == 0) { + n = 1; + } + pvTmp = malloc(n); + if (pvTmp == NULL) { + return 0; + } + *anchor = pvTmp; + return 1; +} /* end of flex_alloc */ + +void +flex_free(flex_ptr anchor) +{ + TRACE_MSG("flex_free"); + + if (anchor == NULL || *anchor == NULL) { + return; + } + free(*anchor); + *anchor = NULL; +} /* end of flex_free */ + +int +flex_extend(flex_ptr anchor, int newsize) +{ + void *pvTmp; + + TRACE_MSG("flex_extend"); + + if (anchor == NULL || newsize < 0) { + return 0; + } + if (newsize == 0) { + newsize = 1; + } + pvTmp = realloc(*anchor, newsize); + if (pvTmp == NULL) { + return 0; + } + *anchor = pvTmp; + return 1; +} /* end of flex_extend */ +#endif /* !__GNUC__ */ + +/* + * vCreateMainWindow - create the Main window + * + * remark: does not return if the Main window can't be created + */ +static window_handle +tCreateMainWindow(void) +{ + window_handle tMainWindow; + + TRACE_MSG("tCreateMainWindow"); + + tMainWindow = Window_Create("MainWindow", template_TITLEMIN); + if (tMainWindow == 0) { + werr(1, "I can't find the 'MainWindow' template"); + } + return tMainWindow; +} /* end of tCreateMainWindow */ + +/* + * vCreateScaleWindow - create the Scale view window + * + * remark: does not return if the Scale view window can't be created + */ +static window_handle +tCreateScaleWindow(void) +{ + window_handle tScaleWindow; + + TRACE_MSG("tCreateScaleWindow"); + + tScaleWindow = Window_Create("ScaleView", template_TITLEMIN); + if (tScaleWindow == 0) { + werr(1, "I can't find the 'ScaleView' template"); + } + return tScaleWindow; +} /* end of tCreateScaleWindow */ + +/* + * pCreateDiagram - create and initialize a diagram + * + * remark: does not return if the diagram can't be created + */ +diagram_type * +pCreateDiagram(const char *szTask, const char *szFilename) +{ + diagram_type *pDiag; + options_type tOptions; + window_handle tMainWindow, tScaleWindow; + wimp_box tBox; + + TRACE_MSG("pCreateDiagram"); + + fail(szTask == NULL || szTask[0] == '\0'); + + /* Create the main window */ + tMainWindow = tCreateMainWindow(); + + /* Create the scale view window */ + tScaleWindow = tCreateScaleWindow(); + + /* Get the necessary memory */ + pDiag = xmalloc(sizeof(diagram_type)); + if (flex_alloc((flex_ptr)&pDiag->tInfo.data, INITIAL_SIZE) != 1) { + werr(1, "Memory allocation failed, unable to continue"); + } + + /* Initialize the diagram */ + vGetOptions(&tOptions); + pDiag->tMainWindow = tMainWindow; + pDiag->tScaleWindow = tScaleWindow; + pDiag->iScaleFactorCurr = tOptions.iScaleFactor; + pDiag->iScaleFactorTemp = tOptions.iScaleFactor; + pDiag->tMemorySize = INITIAL_SIZE; + tBox.min.x = 0; + tBox.min.y = -(Drawfile_ScreenToDraw(32 + 3) * 8 + 1); + tBox.max.x = Drawfile_ScreenToDraw(16) * MIN_SCREEN_WIDTH + 1; + tBox.max.y = 0; + Error_CheckFatal(Drawfile_CreateDiagram(&pDiag->tInfo, + pDiag->tMemorySize, szTask, tBox)); + DBG_DEC(pDiag->tInfo.length); + pDiag->lXleft = 0; + pDiag->lYtop = 0; + strncpy(pDiag->szFilename, + szBasename(szFilename), sizeof(pDiag->szFilename) - 1); + pDiag->szFilename[sizeof(pDiag->szFilename) - 1] = '\0'; + /* Return success */ + return pDiag; +} /* end of pCreateDiagram */ + +/* + * bDestroyDiagram - remove a diagram by freeing the memory it uses + */ +BOOL +bDestroyDiagram(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + window_handle tWindow; + + TRACE_MSG("bDestroyDiagram"); + + fail(pEvent == NULL); + fail(pvReference == NULL); + + if (pEvent == NULL || pvReference == NULL) { + return FALSE; + } + + pDiag = (diagram_type *)pvReference; + + switch (pEvent->type) { + case event_CLOSE: + tWindow = pEvent->data.openblock.window; + break; + case event_KEY: + tWindow = pEvent->data.key.caret.window; + break; + default: + DBG_DEC(pEvent->type); + return FALSE; + } + if (tWindow != pDiag->tMainWindow) { + return FALSE; + } + + /* Delete the main window */ + Window_Delete(pDiag->tMainWindow); + pDiag->tMainWindow = 0; + + /* Delete the scale window */ + Window_Delete(pDiag->tScaleWindow); + pDiag->tScaleWindow = 0; + +#if defined(__GNUC__) + /* + * Remove all references to the diagram that will be free-ed + * by undoing the EventMsg_Claim's from within the Menu_Warn's + */ + while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY, + bSaveTextfile, pDiag)) + ; /* EMPTY */ + while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY, + bSaveDrawfile, pDiag)) + ; /* EMPTY */ + while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY, + bScaleOpenAction, pDiag)) + ; /* EMPTY */ +#endif /* __GNUC__ */ + + /* Free the memory */ + if (pDiag->tInfo.data != NULL && pDiag->tMemorySize != 0) { + flex_free((flex_ptr)&pDiag->tInfo.data); + } + /* Just to be on the save side */ + pDiag->tInfo.data = NULL; + pDiag->tInfo.length = 0; + pDiag->tMemorySize = 0; + + /* Destroy the diagram itself */ + pDiag = xfree(pDiag); + return TRUE; +} /* end of bDestroyDiagram */ + +/* + * vExtendDiagramSize - make sure the diagram is big enough + */ +static void +vExtendDiagramSize(diagram_type *pDiag, size_t tSize) +{ + TRACE_MSG("vExtendDiagramSize"); + + fail(pDiag == NULL || tSize % 4 != 0); + + while (pDiag->tInfo.length + tSize > pDiag->tMemorySize) { + if (flex_extend((flex_ptr)&pDiag->tInfo.data, + pDiag->tMemorySize + EXTENSION_SIZE) != 1) { + werr(1, "Memory extend failed, unable to continue"); + } + pDiag->tMemorySize += EXTENSION_SIZE; + NO_DBG_DEC(pDiag->tMemorySize); + } + TRACE_MSG("end of vExtendDiagramSize"); +} /* end of vExtendDiagramSize */ + +/* + * vPrologue2 - prologue part 2; add a font list to a diagram + */ +void +vPrologue2(diagram_type *pDiag, int iWordVersion) +{ + drawfile_object *pNew; + const font_table_type *pTmp; + char *pcTmp; + size_t tRealSize, tSize; + int iCount; + + TRACE_MSG("vPrologue2"); + + fail(pDiag == NULL); + + if (tGetFontTableLength() == 0) { + return; + } + tRealSize = offsetof(drawfile_object, data); + pTmp = NULL; + while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) { + tRealSize += 2 + strlen(pTmp->szOurFontname); + } + DBG_DEC(tRealSize); + tSize = ROUND4(tRealSize); + vExtendDiagramSize(pDiag, tSize); + pNew = xmalloc(tSize); + memset(pNew, 0, tSize); + pNew->type = drawfile_TYPE_FONT_TABLE; + pNew->size = tSize; + pcTmp = (char *)&pNew->data.font_table.font_def[0].font_ref; + iCount = 0; + pTmp = NULL; + while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) { + *pcTmp = ++iCount; + pcTmp++; + strcpy(pcTmp, pTmp->szOurFontname); + pcTmp += 1 + strlen(pTmp->szOurFontname); + } + Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo, + pDiag->tMemorySize, pNew, TRUE)); + pNew = xfree(pNew); +} /* end of vPrologue2 */ + +/* + * vSubstring2Diagram - put a sub string into a diagram + */ +void +vSubstring2Diagram(diagram_type *pDiag, + char *szString, size_t tStringLength, long lStringWidth, + UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, + USHORT usFontSize, USHORT usMaxFontSize) +{ + drawfile_object *pNew; + long lSizeX, lSizeY, lOffset, l20, lYMove; + size_t tRealSize, tSize; + + TRACE_MSG("vSubstring2Diagram"); + + fail(pDiag == NULL || szString == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE); + fail(usFontSize > usMaxFontSize); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + if (tFontRef == 0) { + lOffset = Drawfile_ScreenToDraw(2); + l20 = Drawfile_ScreenToDraw(32 + 3); + lSizeX = Drawfile_ScreenToDraw(16); + lSizeY = Drawfile_ScreenToDraw(32); + } else { + lOffset = lToBaseLine(usMaxFontSize); + l20 = lWord2DrawUnits20(usMaxFontSize); + lSizeX = lWord2DrawUnits00(usFontSize); + lSizeY = lWord2DrawUnits00(usFontSize); + } + + lYMove = 0; + + /* Up for superscript */ + if (bIsSuperscript(usFontstyle)) { + lYMove = lMilliPoints2DrawUnits((((long)usFontSize + 1) / 2) * 375); + } + /* Down for subscript */ + if (bIsSubscript(usFontstyle)) { + lYMove = -lMilliPoints2DrawUnits((long)usFontSize * 125); + } + + tRealSize = offsetof(drawfile_object, data); + tRealSize += sizeof(drawfile_text) + tStringLength; + tSize = ROUND4(tRealSize); + vExtendDiagramSize(pDiag, tSize); + pNew = xmalloc(tSize); + memset(pNew, 0, tSize); + pNew->type = drawfile_TYPE_TEXT; + pNew->size = tSize; + pNew->data.text.bbox.min.x = (int)pDiag->lXleft; + pNew->data.text.bbox.min.y = (int)(pDiag->lYtop + lYMove); + pNew->data.text.bbox.max.x = (int)(pDiag->lXleft + lStringWidth); + pNew->data.text.bbox.max.y = (int)(pDiag->lYtop + l20 + lYMove); + pNew->data.text.fill.value = (int)ulColor2Color(ucFontColor); + pNew->data.text.bg_hint.value = 0xffffff00; /* White */ + pNew->data.text.style.font_ref = tFontRef; + pNew->data.text.style.reserved[0] = 0; + pNew->data.text.style.reserved[1] = 0; + pNew->data.text.style.reserved[2] = 0; + pNew->data.text.xsize = (int)lSizeX; + pNew->data.text.ysize = (int)lSizeY; + pNew->data.text.base.x = (int)pDiag->lXleft; + pNew->data.text.base.y = (int)(pDiag->lYtop + lOffset + lYMove); + strncpy(pNew->data.text.text, szString, tStringLength); + pNew->data.text.text[tStringLength] = '\0'; + Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo, + pDiag->tMemorySize, pNew, TRUE)); + pNew = xfree(pNew); + /*draw_translateText(&pDiag->tInfo);*/ + pDiag->lXleft += lStringWidth; + TRACE_MSG("leaving vSubstring2Diagram"); +} /* end of vSubstring2Diagram */ + +/* + * vImage2Diagram - put an image into a diagram + */ +void +vImage2Diagram(diagram_type *pDiag, const imagedata_type *pImg, + UCHAR *pucImage, size_t tImageSize) +{ + drawfile_object *pNew; + long lWidth, lHeight; + size_t tRealSize, tSize; + + TRACE_MSG("vImage2Diagram"); + + fail(pDiag == NULL); + fail(pImg == NULL); + fail(pDiag->lXleft < 0); + fail(pImg->eImageType != imagetype_is_dib && + pImg->eImageType != imagetype_is_jpeg); + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled); + lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled); + DBG_DEC(lWidth); + DBG_DEC(lHeight); + + pDiag->lYtop -= lHeight; + + tRealSize = offsetof(drawfile_object, data); + switch (pImg->eImageType) { + case imagetype_is_dib: + tRealSize += sizeof(drawfile_sprite) + tImageSize; + tSize = ROUND4(tRealSize); + vExtendDiagramSize(pDiag, tSize); + pNew = xmalloc(tSize); + memset(pNew, 0, tSize); + pNew->type = drawfile_TYPE_SPRITE; + pNew->size = tSize; + pNew->data.sprite.bbox.min.x = (int)pDiag->lXleft; + pNew->data.sprite.bbox.min.y = (int)pDiag->lYtop; + pNew->data.sprite.bbox.max.x = (int)(pDiag->lXleft + lWidth); + pNew->data.sprite.bbox.max.y = (int)(pDiag->lYtop + lHeight); + memcpy(&pNew->data.sprite.header, pucImage, tImageSize); + break; + case imagetype_is_jpeg: +#if defined(DEBUG) + (void)bGetJpegInfo(pucImage, tImageSize); +#endif /* DEBUG */ + tRealSize += sizeof(drawfile_jpeg) + tImageSize; + tSize = ROUND4(tRealSize); + vExtendDiagramSize(pDiag, tSize); + pNew = xmalloc(tSize); + memset(pNew, 0, tSize); + pNew->type = drawfile_TYPE_JPEG; + pNew->size = tSize; + pNew->data.jpeg.bbox.min.x = (int)pDiag->lXleft; + pNew->data.jpeg.bbox.min.y = (int)pDiag->lYtop; + pNew->data.jpeg.bbox.max.x = (int)(pDiag->lXleft + lWidth); + pNew->data.jpeg.bbox.max.y = (int)(pDiag->lYtop + lHeight); + pNew->data.jpeg.width = (int)lWidth; + pNew->data.jpeg.height = (int)lHeight; + pNew->data.jpeg.xdpi = 90; + pNew->data.jpeg.ydpi = 90; + pNew->data.jpeg.trfm.entries[0][0] = 0x10000; + pNew->data.jpeg.trfm.entries[0][1] = 0; + pNew->data.jpeg.trfm.entries[1][0] = 0; + pNew->data.jpeg.trfm.entries[1][1] = 0x10000; + pNew->data.jpeg.trfm.entries[2][0] = (int)pDiag->lXleft; + pNew->data.jpeg.trfm.entries[2][1] = (int)pDiag->lYtop; + pNew->data.jpeg.len = tImageSize; + memcpy(pNew->data.jpeg.data, pucImage, tImageSize); + break; + default: + DBG_DEC(pImg->eImageType); + pNew = NULL; + break; + } + + Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo, + pDiag->tMemorySize, pNew, TRUE)); + pNew = xfree(pNew); + pDiag->lXleft = 0; +} /* end of vImage2Diagram */ + +/* + * bAddDummyImage - add a dummy image + * + * return TRUE when successful, otherwise FALSE + */ +BOOL +bAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg) +{ + drawfile_object *pNew; + int *piTmp; + long lWidth, lHeight; + size_t tRealSize, tSize; + + TRACE_MSG("bAddDummyImage"); + + fail(pDiag == NULL); + fail(pImg == NULL); + fail(pDiag->lXleft < 0); + + if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { + return FALSE; + } + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled); + lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled); + + pDiag->lYtop -= lHeight; + + tRealSize = offsetof(drawfile_object, data); + tRealSize += sizeof(drawfile_path) + (14 - 1) * sizeof(int); + tSize = ROUND4(tRealSize); + vExtendDiagramSize(pDiag, tSize); + pNew = xmalloc(tSize); + memset(pNew, 0, tSize); + pNew->type = drawfile_TYPE_PATH; + pNew->size = tSize; + pNew->data.path.bbox.min.x = (int)pDiag->lXleft; + pNew->data.path.bbox.min.y = (int)pDiag->lYtop; + pNew->data.path.bbox.max.x = (int)(pDiag->lXleft + lWidth); + pNew->data.path.bbox.max.y = (int)(pDiag->lYtop + lHeight); + pNew->data.path.fill.value = -1; + pNew->data.path.outline.value = 0x4d4d4d00; /* Gray 70 percent */ + pNew->data.path.width = (int)lMilliPoints2DrawUnits(500); + pNew->data.path.style.flags = 0; + pNew->data.path.style.reserved = 0; + pNew->data.path.style.cap_width = 0; + pNew->data.path.style.cap_length = 0; + piTmp = pNew->data.path.path; + *piTmp++ = drawfile_PATH_MOVE_TO; + *piTmp++ = pNew->data.path.bbox.min.x; + *piTmp++ = pNew->data.path.bbox.min.y; + *piTmp++ = drawfile_PATH_LINE_TO; + *piTmp++ = pNew->data.path.bbox.min.x; + *piTmp++ = pNew->data.path.bbox.max.y; + *piTmp++ = drawfile_PATH_LINE_TO; + *piTmp++ = pNew->data.path.bbox.max.x; + *piTmp++ = pNew->data.path.bbox.max.y; + *piTmp++ = drawfile_PATH_LINE_TO; + *piTmp++ = pNew->data.path.bbox.max.x; + *piTmp++ = pNew->data.path.bbox.min.y; + *piTmp++ = drawfile_PATH_CLOSE_LINE; + *piTmp++ = drawfile_PATH_END_PATH; + + Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo, + pDiag->tMemorySize, pNew, TRUE)); + pNew = xfree(pNew); + pDiag->lXleft = 0; + return TRUE; +} /* end of bAddDummyImage */ + +/* + * vMove2NextLine - move to the next line + */ +void +vMove2NextLine(diagram_type *pDiag, drawfile_fontref tFontRef, + USHORT usFontSize) +{ + long l20; + + TRACE_MSG("vMove2NextLine"); + + fail(pDiag == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + if (tFontRef == 0) { + l20 = Drawfile_ScreenToDraw(32 + 3); + } else { + l20 = lWord2DrawUnits20(usFontSize); + } + pDiag->lYtop -= l20; +} /* end of vMove2NextLine */ + +/* + * Create an start of paragraph (Phase 1) + */ +void +vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation) +{ + TRACE_MSG("vStartOfParagraph1"); + + fail(pDiag == NULL); + fail(lBeforeIndentation < 0); + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation); +} /* end of vStartOfParagraph1 */ + +/* + * Create an start of paragraph (Phase 2) + * DUMMY function + */ +void +vStartOfParagraph2(diagram_type *pDiag) +{ + TRACE_MSG("vStartOfParagraph2"); +} /* end of vStartOfParagraph2 */ + +/* + * Create an end of paragraph + */ +void +vEndOfParagraph(diagram_type *pDiag, + drawfile_fontref tFontRef, USHORT usFontSize, long lAfterIndentation) +{ + TRACE_MSG("vEndOfParagraph"); + + fail(pDiag == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(lAfterIndentation < 0); + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation); +} /* end of vEndOfParagraph */ + +/* + * Create an end of page + */ +void +vEndOfPage(diagram_type *pDiag, long lAfterIndentation, BOOL bNewSection) +{ + TRACE_MSG("vEndOfPage"); + + fail(pDiag == NULL); + fail(lAfterIndentation < 0); + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation); +} /* end of vEndOfPage */ + +/* + * vSetHeaders - set the headers + * DUMMY function + */ +void +vSetHeaders(diagram_type *pDiag, USHORT usIstd) +{ + TRACE_MSG("vSetHeaders"); +} /* end of vSetHeaders */ + +/* + * Create a start of list + * DUMMY function + */ +void +vStartOfList(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable) +{ + TRACE_MSG("vStartOfList"); +} /* end of vStartOfList */ + +/* + * Create an end of list + * DUMMY function + */ +void +vEndOfList(diagram_type *pDiag) +{ + TRACE_MSG("vEndOfList"); +} /* end of vEndOfList */ + +/* + * Create a start of a list item + * DUMMY function + */ +void +vStartOfListItem(diagram_type *pDiag, BOOL bNoMarks) +{ + TRACE_MSG("vStartOfListItem"); +} /* end of vStartOfListItem */ + +/* + * Create an end of a table + * DUMMY function + */ +void +vEndOfTable(diagram_type *pDiag) +{ + TRACE_MSG("vEndOfTable"); +} /* end of vEndTable */ + +/* + * Add a table row + * DUMMY function + * + * Returns TRUE when conversion type is XML + */ +BOOL +bAddTableRow(diagram_type *pDiag, char **aszColTxt, + int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo) +{ + TRACE_MSG("bAddTableRow"); + + return FALSE; +} /* end of bAddTableRow */ + +/* + * vForceRedraw - force a redraw of the main window + */ +static void +vForceRedraw(diagram_type *pDiag) +{ + window_state tWindowState; + window_redrawblock tRedraw; + int x0, y0, x1, y1; + + TRACE_MSG("vForceRedraw"); + + fail(pDiag == NULL); + + DBG_DEC(pDiag->iScaleFactorCurr); + + /* Read the size of the current diagram */ + Drawfile_QueryBox(&pDiag->tInfo, &tRedraw.rect, TRUE); + /* Adjust the size of the work area */ + x0 = tRedraw.rect.min.x * pDiag->iScaleFactorCurr / 100 - 1; + y0 = tRedraw.rect.min.y * pDiag->iScaleFactorCurr / 100 - 1; + x1 = tRedraw.rect.max.x * pDiag->iScaleFactorCurr / 100 + 1; + y1 = tRedraw.rect.max.y * pDiag->iScaleFactorCurr / 100 + 1; + /* Work area extension */ + x0 -= WORKAREA_EXTENSION; + y0 -= WORKAREA_EXTENSION; + x1 += WORKAREA_EXTENSION; + y1 += WORKAREA_EXTENSION; + Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1); + /* Widen the box slightly to be sure all the edges are drawn */ + x0 -= 5; + y0 -= 5; + x1 += 5; + y1 += 5; + /* Force the redraw */ + Window_ForceRedraw(pDiag->tMainWindow, x0, y0, x1, y1); + /* Reopen the window to show the correct size */ + Error_CheckFatal(Wimp_GetWindowState(pDiag->tMainWindow, &tWindowState)); + tWindowState.openblock.behind = -1; + Error_CheckFatal(Wimp_OpenWindow(&tWindowState.openblock)); +} /* end of vForceRedraw */ + +/* + * vShowDiagram - put the diagram on the screen + */ +void +vShowDiagram(diagram_type *pDiag) +{ + wimp_box tRect; + int x0, y0, x1, y1; + + TRACE_MSG("vShowDiagram"); + + fail(pDiag == NULL); + + Window_Show(pDiag->tMainWindow, open_NEARLAST); + Drawfile_QueryBox(&pDiag->tInfo, &tRect, TRUE); + /* Work area extension */ + x0 = tRect.min.x - WORKAREA_EXTENSION; + y0 = tRect.min.y - WORKAREA_EXTENSION; + x1 = tRect.max.x + WORKAREA_EXTENSION; + y1 = tRect.max.y + WORKAREA_EXTENSION; + Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1); + vForceRedraw(pDiag); +} /* end of vShowDiagram */ + +/* + * vMainButtonClick - handle mouse buttons clicks for the main screen + */ +void +vMainButtonClick(mouse_block *pMouse) +{ + caret_block tCaret; + window_state ws; + + TRACE_MSG("vMainButtonClick"); + + fail(pMouse == NULL); + + DBG_DEC(pMouse->button.data.select); + DBG_DEC(pMouse->button.data.adjust); + DBG_DEC(pMouse->window); + DBG_DEC(pMouse->icon); + + if (pMouse->window >= 0 && + pMouse->icon == -1 && + (pMouse->button.data.select || pMouse->button.data.adjust)) { + /* Get the input focus */ + Error_CheckFatal(Wimp_GetWindowState(pMouse->window, &ws)); + tCaret.window = pMouse->window; + tCaret.icon = -1; + tCaret.offset.x = pMouse->pos.x - ws.openblock.screenrect.min.x; + tCaret.offset.y = pMouse->pos.y - ws.openblock.screenrect.max.y; + tCaret.height = (int)BIT(25); + tCaret.index = 0; + Error_CheckFatal(Wimp_SetCaretPosition(&tCaret)); + } +} /* end of vMainButtonClick */ + +/* + * bMainKeyPressed - handle pressed keys for the main window + */ +BOOL +bMainKeyPressed(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + + TRACE_MSG("bMainKeyPressed"); + + fail(pEvent == NULL); + fail(pEvent->type != event_KEY); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + fail(pEvent->data.key.caret.window != pDiag->tMainWindow); + + + switch (pEvent->data.key.code) { + case keycode_CTRL_F2: /* Ctrl F2 */ + bDestroyDiagram(pEvent, pvReference); + break; + case keycode_F3: /* F3 */ + bSaveDrawfile(pEvent, pvReference); + break; + case keycode_SHIFT_F3: /* Shift F3 */ + bSaveTextfile(pEvent, pvReference); + break; + default: + DBG_DEC(pEvent->data.key.code); + Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code)); + } + return TRUE; +} /* end of bMainKeyPressed */ + +/* + * bRedrawMainWindow - redraw the main window + */ +BOOL +bRedrawMainWindow(event_pollblock *pEvent, void *pvReference) +{ + window_redrawblock tBlock; + diagram_type *pDiag; + drawfile_info *pInfo; + double dScaleFactor; + BOOL bMore; + + TRACE_MSG("bRedrawMainWindow"); + + fail(pEvent == NULL); + fail(pEvent->type != event_REDRAW); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + fail(pDiag->tMainWindow != pEvent->data.openblock.window); + fail(pDiag->iScaleFactorCurr < MIN_SCALE_FACTOR); + fail(pDiag->iScaleFactorCurr > MAX_SCALE_FACTOR); + + dScaleFactor = (double)pDiag->iScaleFactorCurr / 100.0; + pInfo = &pDiag->tInfo; + + tBlock.window = pEvent->data.openblock.window; + Error_CheckFatal(Wimp_RedrawWindow(&tBlock, &bMore)); + + /* If there is no real diagram just go thru the motions */ + while (bMore) { + if (pInfo->data != NULL && pInfo->length != 0) { + Error_CheckFatal(Drawfile_RenderDiagram(pInfo, + &tBlock, dScaleFactor)); + } + Error_CheckFatal(Wimp_GetRectangle(&tBlock, &bMore)); + } + return TRUE; +} /* end of bRedrawMainWindow */ + +/* + * bScaleOpenAction - action to be taken when the Scale view window opens + */ +BOOL +bScaleOpenAction(event_pollblock *pEvent, void *pvReference) +{ + window_state tWindowState; + diagram_type *pDiag; + + TRACE_MSG("bScaleOpenAction"); + + fail(pEvent == NULL); + fail(pEvent->type != event_SEND); + fail(pEvent->data.message.header.action != message_MENUWARN); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + if (menu_currentopen != pDiag->pSaveMenu || + pEvent->data.message.data.menuwarn.selection[0] != SAVEMENU_SCALEVIEW) { + return FALSE; + } + + Error_CheckFatal(Wimp_GetWindowState(pDiag->tScaleWindow, + &tWindowState)); + if (tWindowState.flags.data.open) { + /* The window is already open */ + return TRUE; + } + + DBG_MSG("vScaleOpenAction for real"); + + pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr; + vUpdateWriteableNumber(pDiag->tScaleWindow, + SCALE_SCALE_WRITEABLE, pDiag->iScaleFactorTemp); + Window_Show(pDiag->tScaleWindow, open_UNDERPOINTER); + return TRUE; +} /* end of bScaleOpenAction */ + +/* + * vSetTitle - set the title of a window + */ +void +vSetTitle(diagram_type *pDiag) +{ + char szTitle[WINDOW_TITLE_LEN]; + + TRACE_MSG("vSetTitle"); + + fail(pDiag == NULL); + fail(pDiag->szFilename[0] == '\0'); + + (void)sprintf(szTitle, "%.*s at %d%%", + FILENAME_TITLE_LEN, + pDiag->szFilename, + pDiag->iScaleFactorCurr % 1000); + if (strlen(pDiag->szFilename) > FILENAME_TITLE_LEN) { + szTitle[FILENAME_TITLE_LEN - 1] = OUR_ELLIPSIS; + } + + Window_SetTitle(pDiag->tMainWindow, szTitle); +} /* end of vSetTitle */ + +/* + * vScaleButtonClick - handle a mouse button click in the Scale view window + */ +void +vScaleButtonClick(mouse_block *pMouse, diagram_type *pDiag) +{ + BOOL bCloseWindow, bRedraw; + + TRACE_MSG("vScaleButtonClick"); + + fail(pMouse == NULL || pDiag == NULL); + fail(pMouse->window != pDiag->tScaleWindow); + + bCloseWindow = FALSE; + bRedraw = FALSE; + switch (pMouse->icon) { + case SCALE_CANCEL_BUTTON: + bCloseWindow = TRUE; + pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr; + break; + case SCALE_SCALE_BUTTON: + bCloseWindow = TRUE; + bRedraw = pDiag->iScaleFactorCurr != pDiag->iScaleFactorTemp; + pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp; + break; + case SCALE_50_PCT: + pDiag->iScaleFactorTemp = 50; + break; + case SCALE_75_PCT: + pDiag->iScaleFactorTemp = 75; + break; + case SCALE_100_PCT: + pDiag->iScaleFactorTemp = 100; + break; + case SCALE_150_PCT: + pDiag->iScaleFactorTemp = 150; + break; + default: + DBG_DEC(pMouse->icon); + break; + } + if (bCloseWindow) { + /* Close the scale window */ + Error_CheckFatal(Wimp_CloseWindow(pMouse->window)); + if (bRedraw) { + /* Redraw the main window */ + vSetTitle(pDiag); + vForceRedraw(pDiag); + } + } else { + vUpdateWriteableNumber(pMouse->window, + SCALE_SCALE_WRITEABLE, + pDiag->iScaleFactorTemp); + } +} /* end of vScaleButtonClick */ + +/* + * bScaleKeyPressed - handle pressed keys for the scale window + */ +BOOL +bScaleKeyPressed(event_pollblock *pEvent, void *pvReference) +{ + icon_block tIcon; + diagram_type *pDiag; + caret_block *pCaret; + char *pcChar; + int iTmp; + + TRACE_MSG("bScaleKeyPressed"); + + fail(pEvent == NULL); + fail(pEvent->type != event_KEY); + fail(pvReference == NULL); + + pCaret = &pEvent->data.key.caret; + pDiag = (diagram_type *)pvReference; + + fail(pEvent->data.key.caret.window != pDiag->tScaleWindow); + + DBG_DEC_C(pCaret->icon != SCALE_SCALE_WRITEABLE, pCaret->icon); + DBG_DEC_C(pCaret->icon == SCALE_SCALE_WRITEABLE, pEvent->data.key.code); + + if (pEvent->data.key.code != '\r' || + pCaret->icon != SCALE_SCALE_WRITEABLE) { + Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code)); + return TRUE; + } + + Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon)); + if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) { + werr(1, "Icon %d must be indirected text", (int)pCaret->icon); + } + iTmp = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10); + if (*pcChar != '\0' && *pcChar != '\r') { + DBG_DEC(*pcChar); + } else if (iTmp < MIN_SCALE_FACTOR) { + pDiag->iScaleFactorTemp = MIN_SCALE_FACTOR; + } else if (iTmp > MAX_SCALE_FACTOR) { + pDiag->iScaleFactorTemp = MAX_SCALE_FACTOR; + } else { + pDiag->iScaleFactorTemp = iTmp; + } + pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp; + /* Close the scale window */ + Error_CheckFatal(Wimp_CloseWindow(pCaret->window)); + /* Redraw the main window */ + vSetTitle(pDiag); + vForceRedraw(pDiag); + return TRUE; +} /* end of bScaleKeyPressed */ + diff --git a/draw.h b/draw.h new file mode 100644 index 0000000..839bbf0 --- /dev/null +++ b/draw.h @@ -0,0 +1,46 @@ +/* + * draw.h + * Copyright (C) 2001 A.J. van Os; Released under GPL + * + * Description: + * Constants and macros to deal with the Draw format + */ + +#if !defined(__draw_h) +#define __draw_h 1 + +#include "drawftypes.h" + +typedef struct draw_jpegstrhdr_tag { + draw_tagtyp tag; /* 1 word */ + draw_sizetyp size; /* 1 word */ + draw_bboxtyp bbox; /* 4 words */ + int width; /* 1 word */ + int height; /* 1 word */ + int xdpi; /* 1 word */ + int ydpi; /* 1 word */ + int trfm[6]; /* 6 words */ + int len; /* 1 word */ +} draw_jpegstrhdr; + +typedef struct draw_jpegstr_tag { + draw_tagtyp tag; /* 1 word */ + draw_sizetyp size; /* 1 word */ + draw_bboxtyp bbox; /* 4 words */ + int width; /* 1 word */ + int height; /* 1 word */ + int xdpi; /* 1 word */ + int ydpi; /* 1 word */ + int trfm[6]; /* 6 words */ + int len; /* 1 word */ + unsigned char *jpeg; +} draw_jpegstr; + +typedef union draw_imageType_tag { + draw_spristr *sprite; + draw_jpegstr *jpeg; + char *bytep; + int *wordp; +} draw_imageType; + +#endif /* !__draw_h */ diff --git a/drawfile.c b/drawfile.c new file mode 100644 index 0000000..5963644 --- /dev/null +++ b/drawfile.c @@ -0,0 +1,422 @@ +/* + * drawfile.c + * Copyright (C) 2005 A.J. van Os; Released under GPL + * + * Description: + * Functions to process with the Draw diagram + */ + +#include +#include "DeskLib:Error.h" +#include "DeskLib:SWI.h" +#include "drawfile.h" +#include "antiword.h" + +#define DRAWFILE_OBJECT_TOO_SMALL 200 +#define DRAWFILE_NO_TEXT 201 +#define DRAWFILE_BAD_CHARACTER 202 +#define DRAWFILE_SMALL_MEMORY 203 +#define DRAWFILE_PATH_WITHOUT_LINES 204 +#define DRAWFILE_BAD_PATH_TYPE 205 +#define DRAWFILE_PATH_WITHOUT_END 206 +#define DRAWFILE_BAD_SPRITE_SIZE 207 +#define DRAWFILE_BAD_JPEG_SIZE 208 +#define DRAWFILE_TOO_SMALL 209 +#define DRAWFILE_NOT_A_DRAWFILE 210 +#define DRAWFILE_OBJECT_SIZE 211 +#define DRAWFILE_MANY_FONTTABLES 212 +#define DRAWFILE_TEXT_NO_FONT 213 +#define DRAWFILE_OBJECT_UNEXPECTED 214 +#define DRAWFILE_SIZE_ERROR 215 + +typedef struct drawfile_error_tag { + int iErrorNumber; + const char *szErrorText; +} drawfile_error_type; + +static const drawfile_error_type atErrors[] = { + { DRAWFILE_OBJECT_TOO_SMALL, "Object too small"}, + { DRAWFILE_NO_TEXT, "Text object without text"}, + { DRAWFILE_BAD_CHARACTER, "Bad character in string"}, + { DRAWFILE_SMALL_MEMORY, "Not enough memory reserved"}, + { DRAWFILE_PATH_WITHOUT_LINES, "This path has no lines"}, + { DRAWFILE_BAD_PATH_TYPE, "Bad path-type in path"}, + { DRAWFILE_PATH_WITHOUT_END, "No end of path seen"}, + { DRAWFILE_BAD_SPRITE_SIZE, "Bad sprite size"}, + { DRAWFILE_BAD_JPEG_SIZE, "Bad jpeg size"}, + { DRAWFILE_TOO_SMALL, "Too small to be a drawfile"}, + { DRAWFILE_NOT_A_DRAWFILE, "Not a drawfile"}, + { DRAWFILE_OBJECT_SIZE, "Object with incorrect size"}, + { DRAWFILE_MANY_FONTTABLES, "More than one font table"}, + { DRAWFILE_TEXT_NO_FONT, "Text, but no font table seen"}, + { DRAWFILE_OBJECT_UNEXPECTED, "Unexpected object type"}, + { DRAWFILE_SIZE_ERROR, "Sizes don't match"}, +}; + + +/* + * pFillError - error number to error struct + */ +static os_error * +pFillError(int iErrorNumber) +{ + static os_error tError; + const drawfile_error_type *pTmp; + const char *szErrorText; + + szErrorText = "Unknown error"; + for (pTmp = atErrors; pTmp < atErrors + elementsof(atErrors); pTmp++) { + if (iErrorNumber == pTmp->iErrorNumber) { + szErrorText = pTmp->szErrorText; + break; + } + } + tError.errnum = iErrorNumber; + strncpy(tError.errmess, szErrorText, sizeof(tError.errmess) - 1); + tError.errmess[sizeof(tError.errmess) - 1] = '\0'; + DBG_DEC(tError.errnum); + DBG_MSG(tError.errmess); + return &tError; +} /* end of pFillError */ + +/* + * Drawfile_BBox - Find the bounding box of a diagram + */ +os_error * +Drawfile_Bbox(drawfile_bbox_flags flags, + drawfile_diagram const *diagram, + int size, + os_trfm const *trfm, + wimp_box *bbox) +{ + return SWI(5, 0, DrawFile_BBox | XOS_Bit, + flags, diagram, size, trfm, bbox); +} /* end of Drawfile_Bbox */ + +/* + * Drawfile_CreateDiagram - create an empty drawfile diagram + */ +os_error * +Drawfile_CreateDiagram(drawfile_info *pInfo, size_t tMemorySize, + const char *szCreator, wimp_box tBbox) +{ + drawfile_diagram *pDiag; + + if (tMemorySize < offsetof(drawfile_diagram, objects)) { + return pFillError(DRAWFILE_SMALL_MEMORY); + } + pDiag = (drawfile_diagram *)pInfo->data; + strncpy(pDiag->tag, "Draw", 4); + pDiag->major_version = 201; + pDiag->minor_version = 0; + strncpy(pDiag->source, szCreator, sizeof(pDiag->source)); + pDiag->bbox = tBbox; + /* Memory in use */ + pInfo->length = offsetof(drawfile_diagram, objects); + return NULL; +} /* end of Drawfile_CreateDiagram */ + +/* + * Drawfile_AppendObject - append an object to a diagram + */ +os_error * +Drawfile_AppendObject(drawfile_info *pInfo, size_t tMemorySize, + const drawfile_object *pObject, BOOL bRebind) +{ + wimp_box *pMainBbox; + const wimp_box *pBbox; + byte *pAfter; + + if (tMemorySize < pInfo->length + pObject->size) { + return pFillError(DRAWFILE_OBJECT_TOO_SMALL); + } + /* After the last object */ + pAfter = (byte *)pInfo->data + pInfo->length; + /* Copy in the new data */ + memcpy(pAfter, pObject, pObject->size); + /* Rebind if needed */ + if (bRebind) { + pMainBbox = &((drawfile_diagram *)pInfo->data)->bbox; + switch (pObject->type) { + case drawfile_TYPE_FONT_TABLE: + pBbox = NULL; + break; + case drawfile_TYPE_TEXT: + pBbox = &pObject->data.text.bbox; + break; + case drawfile_TYPE_PATH: + pBbox = &pObject->data.path.bbox; + break; + case drawfile_TYPE_SPRITE: + pBbox = &pObject->data.sprite.bbox; + break; + case drawfile_TYPE_GROUP: + pBbox = &pObject->data.group.bbox; + break; + case drawfile_TYPE_TAGGED: + pBbox = &pObject->data.tagged.bbox; + break; + case drawfile_TYPE_TEXT_AREA: + pBbox = &pObject->data.text_area.bbox; + break; + case drawfile_TYPE_TEXT_COLUMN: + pBbox = NULL; + break; + case drawfile_TYPE_OPTIONS: + pBbox = &pObject->data.options.bbox; + break; + case drawfile_TYPE_TRFM_TEXT: + pBbox = &pObject->data.trfm_text.bbox; + break; + case drawfile_TYPE_TRFM_SPRITE: + pBbox = &pObject->data.trfm_sprite.bbox; + break; + case drawfile_TYPE_JPEG: + pBbox = &pObject->data.jpeg.bbox; + break; + default: + pBbox = NULL; + break; + } + if (pBbox != NULL) { + if (pBbox->min.x < pMainBbox->min.x) { + pMainBbox->min.x = pBbox->min.x; + } + if (pBbox->min.y < pMainBbox->min.y) { + pMainBbox->min.y = pBbox->min.y; + } + if (pBbox->max.x > pMainBbox->max.x) { + pMainBbox->max.x = pBbox->max.x; + } + if (pBbox->max.y > pMainBbox->max.y) { + pMainBbox->max.y = pBbox->max.y; + } + } + } + /* Memory in use */ + pInfo->length += pObject->size; + return NULL; +} /* end of Drawfile_AppendObject */ + +/* + * Replaces the draw_render_diag function from RISC_OSLib + */ +os_error * +Drawfile_RenderDiagram(drawfile_info *pInfo, window_redrawblock *pRedraw, + double dScale) +{ + int aiTransform[6]; + + fail(pInfo == NULL); + fail(pInfo->data == NULL); + fail(pRedraw == NULL); + fail(dScale < 0.01); + + aiTransform[0] = (int)(dScale * 0x10000); + aiTransform[1] = 0; + aiTransform[2] = 0; + aiTransform[3] = (int)(dScale * 0x10000); + aiTransform[4] = (pRedraw->rect.min.x - pRedraw->scroll.x) * 256; + aiTransform[5] = (pRedraw->rect.max.y - pRedraw->scroll.y) * 256; + + return SWI(6, 0, DrawFile_Render | XOS_Bit, + 0, pInfo->data, pInfo->length, aiTransform, &pRedraw->rect, 0); +} /* end of Drawfile_RenderDiagram */ + +/* + * pVerifyText - verify a text object + */ +static os_error * +pVerifyText(const drawfile_text *pText) +{ + const unsigned char *pucTmp; + + if (pText->text[0] == '\0') { + return pFillError(DRAWFILE_NO_TEXT); + } + pucTmp = (const unsigned char *)pText->text; + while (*pucTmp != '\0') { + if (*pucTmp < 0x20 || *pucTmp == 0x7f) { + return pFillError(DRAWFILE_BAD_CHARACTER); + } + pucTmp++; + } + return NULL; +} /* end of pVerifyText */ + +/* + * pVerifyPath - verify a path object + */ +static os_error * +pVerifyPath(const drawfile_path *pPath, int iSize) +{ + const int *piTmp; + int iElements; + BOOL bLine; + + bLine = FALSE; + iElements = (iSize - offsetof(drawfile_path, path)) / 4; + + for (piTmp = pPath->path; piTmp < pPath->path + iElements; piTmp++) { + switch(*piTmp) { + case drawfile_PATH_END_PATH: + if (bLine) { + return NULL; + } + return pFillError(DRAWFILE_PATH_WITHOUT_LINES); + case drawfile_PATH_LINE_TO: + bLine = TRUE; + piTmp += 2; + break; + case drawfile_PATH_MOVE_TO: + piTmp += 2; + break; + case drawfile_PATH_CLOSE_LINE: + bLine = TRUE; + break; + default: + return pFillError(DRAWFILE_BAD_PATH_TYPE); + } + } + return pFillError(DRAWFILE_PATH_WITHOUT_END); +} /* end of pVerifyPath */ + +/* + * pVerifySprite - verify a sprite object + */ +static os_error * +pVerifySprite(const drawfile_sprite *pSprite, int iSize) +{ + iSize -= offsetof(drawfile_sprite, header); + if (iSize < pSprite->header.offset_next) { + DBG_DEC(iSize); + DBG_DEC(pSprite->header.offset_next); + return pFillError(DRAWFILE_BAD_SPRITE_SIZE); + } + return NULL; +} /* end of pVerifySprite */ + +/* + * pVerifyJpeg - verify a jpeg object + */ +static os_error * +pVerifyJpeg(const drawfile_jpeg *pJpeg, int iSize) +{ + iSize -= offsetof(drawfile_jpeg, data); + if (iSize < pJpeg->len) { + DBG_DEC(iSize); + DBG_DEC(pJpeg->len); + return pFillError(DRAWFILE_BAD_JPEG_SIZE); + } + return NULL; +} /* end of pVerifyJpeg */ + +/* + * Drawfile_VerifyDiagram - Verify the diagram generated from the Word file + * + * returns NULL if the diagram is correct + */ +os_error * +Drawfile_VerifyDiagram(drawfile_info *pInfo) +{ + drawfile_diagram *pDiag; + drawfile_object *pObj; + os_error *pError; + const char *pcTmp; + int iToGo, iFontTables; + BOOL bTypeFontTable; + + TRACE_MSG("Drawfile_VerifyDiagram"); + + fail(pInfo == NULL); + + if (pInfo->length < offsetof(drawfile_diagram, objects)) { + return pFillError(DRAWFILE_TOO_SMALL); + } + + pDiag = (drawfile_diagram *)pInfo->data; + if (strncmp(pDiag->tag, "Draw", 4) != 0 || + pDiag->major_version != 201 || + pDiag->minor_version != 0) { + return pFillError(DRAWFILE_NOT_A_DRAWFILE); + } + + iToGo = pInfo->length - offsetof(drawfile_diagram, objects); + pcTmp = (const char *)pInfo->data + offsetof(drawfile_diagram, objects); + iFontTables = 0; + bTypeFontTable = FALSE; + + while (iToGo > 0) { + pObj = (drawfile_object *)pcTmp; + if (pObj->size < 0 || pObj->size % 4 != 0) { + return pFillError(DRAWFILE_OBJECT_SIZE); + } + switch (pObj->type) { + case drawfile_TYPE_FONT_TABLE: + if (bTypeFontTable) { + return pFillError(DRAWFILE_MANY_FONTTABLES); + } + bTypeFontTable = TRUE; + break; + case drawfile_TYPE_TEXT: + if (pObj->data.text.style.font_ref != 0 && + !bTypeFontTable) { + return pFillError(DRAWFILE_TEXT_NO_FONT); + } + pError = pVerifyText(&pObj->data.text); + if (pError != NULL) { + return pError; + } + break; + case drawfile_TYPE_PATH: + pError = pVerifyPath(&pObj->data.path, + pObj->size - offsetof(drawfile_object, data)); + if (pError != NULL) { + return pError; + } + break; + case drawfile_TYPE_SPRITE: + pError = pVerifySprite(&pObj->data.sprite, + pObj->size - offsetof(drawfile_object, data)); + if (pError != NULL) { + return pError; + } + break; + case drawfile_TYPE_JPEG: + pError = pVerifyJpeg(&pObj->data.jpeg, + pObj->size - offsetof(drawfile_object, data)); + if (pError != NULL) { + return pError; + } + break; + default: + DBG_DEC(pObj->type); + return pFillError(DRAWFILE_OBJECT_UNEXPECTED); + } + pcTmp += pObj->size; + iToGo -= pObj->size; + } + if (iToGo < 0) { + return pFillError(DRAWFILE_SIZE_ERROR); + } + return NULL; +} /* end of Drawfile_VerifyDiagram */ + +/* + * Drawfile_QueryBox - Find the bounding box of a diagram + */ +void +Drawfile_QueryBox(drawfile_info *pInfo, wimp_box *pRect, BOOL bScreenUnits) +{ + fail(pInfo == NULL); + fail(pRect == NULL); + + Error_CheckFatal(Drawfile_Bbox(0, + pInfo->data, pInfo->length, NULL, pRect)); + if (bScreenUnits) { + pRect->min.x = Drawfile_DrawToScreen(pRect->min.x); + pRect->min.y = Drawfile_DrawToScreen(pRect->min.y); + pRect->max.x = Drawfile_DrawToScreen(pRect->max.x); + pRect->max.y = Drawfile_DrawToScreen(pRect->max.y); + } +} /* end of Drawfile_QueryBox */ diff --git a/drawfile.h b/drawfile.h new file mode 100644 index 0000000..c9b76db --- /dev/null +++ b/drawfile.h @@ -0,0 +1,433 @@ +/* + * drawfile.h + * Copyright (C) 2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Include file to deal with drawfiles + * + * Based on: + * C header file for DrawFile + * written by DefMod (May 4 2004) on Tue May 4 13:34:17 2004 + * Jonathan Coxhead, jonathan@doves.demon.co.uk, 21 Aug 1995 + * OSLib---efficient, type-safe, transparent, extensible, + * register-safe A P I coverage of RISC O S + * Copyright (C) 1994 Jonathan Coxhead + * + * All credit should go to him, but all the bugs are mine + */ + +#if !defined(__drawfile_h) +#define __drawfile_h + +#include "DeskLib:Sprite.h" +#include "DeskLib:Wimp.h" + +#if !defined(BOOL) +#define BOOL int +#define TRUE 1 +#define FALSE 0 +#endif /* !BOOL */ + +/********************* + * Conversion macros * + *********************/ +#define Drawfile_DrawToScreen(i) ((i) / 256) +#define Drawfile_ScreenToDraw(i) ((i) * 256) + +/********************************** + * SWI names and SWI reason codes * + **********************************/ +#define DrawFile_Render 0x45540 +#define DrawFile_BBox 0x45541 +#define DrawFile_DeclareFonts 0x45542 + +/******************** + * Type definitions * + ********************/ +typedef unsigned int bits; +typedef unsigned char byte; + +typedef byte drawfile_fontref; + +typedef byte drawfile_path_style_flags; + +typedef bits drawfile_text_flags; + +typedef bits drawfile_render_flags; + +typedef bits drawfile_declare_fonts_flags; + +typedef bits drawfile_paper_options; + +typedef bits drawfile_entry_mode; + +typedef enum { + drawfile_TYPE_FONT_TABLE = 0, + drawfile_TYPE_TEXT = 1, + drawfile_TYPE_PATH = 2, + drawfile_TYPE_SPRITE = 5, + drawfile_TYPE_GROUP = 6, + drawfile_TYPE_TAGGED = 7, + drawfile_TYPE_TEXT_AREA = 9, + drawfile_TYPE_TEXT_COLUMN = 10, + drawfile_TYPE_OPTIONS = 11, + drawfile_TYPE_TRFM_TEXT = 12, + drawfile_TYPE_TRFM_SPRITE = 13, + drawfile_TYPE_JPEG = 16 +} drawfile_type; + +typedef enum { + drawfile_PATH_END_PATH = 0, + drawfile_PATH_CONTINUATION = 1, + drawfile_PATH_MOVE_TO = 2, + drawfile_PATH_SPECIAL_MOVE_TO = 3, + drawfile_PATH_CLOSE_GAP = 4, + drawfile_PATH_CLOSE_LINE = 5, + drawfile_PATH_BEZIER_TO = 6, + drawfile_PATH_GAP_TO = 7, + drawfile_PATH_LINE_TO = 8 +} drawfile_path_type; + +typedef struct { + int start; + int element_count; + int elements [6]; +} draw_dash_pattern; + +typedef struct { + int entries [3] [2]; +} os_trfm; + +typedef struct { + void *data; + size_t length; +} drawfile_info; + +typedef struct { + drawfile_fontref font_ref; + char font_name [1]; +} drawfile_font_def; + +typedef struct { + drawfile_fontref font_ref; + byte reserved [3]; +} drawfile_text_style; + +typedef struct { + drawfile_path_style_flags flags; + byte reserved; + byte cap_width; + byte cap_length; +} drawfile_path_style; + +typedef struct { + drawfile_font_def font_def[1]; +} drawfile_font_table; + +typedef struct { + wimp_box bbox; + palette_entry fill; + palette_entry bg_hint; + drawfile_text_style style; + int xsize; + int ysize; + wimp_coord base; + char text [1]; +} drawfile_text; + +typedef struct { + wimp_box bbox; + palette_entry fill; + palette_entry outline; + int width; + drawfile_path_style style; + int path [1]; +} drawfile_path; + +typedef struct { + wimp_box bbox; + palette_entry fill; + palette_entry outline; + int width; + drawfile_path_style style; + draw_dash_pattern pattern; + int path [1]; +} drawfile_path_with_pattern; + +typedef struct { + wimp_box bbox; + sprite_header header; + byte data [1]; +} drawfile_sprite; + +typedef struct { + wimp_box bbox; + char name [12]; + int objects [1]; +} drawfile_group; + +typedef struct { + wimp_box bbox; + drawfile_type tag; + int object [1]; +} drawfile_tagged; + +typedef struct { + wimp_box box; +} drawfile_text_column; + +typedef struct { + struct { + drawfile_type type; + int size; + drawfile_text_column data; + } columns [1]; +} drawfile_text_column_list; + +typedef struct { + drawfile_type type; + int reserved [2]; + palette_entry fill; + palette_entry bg_hint; + char text [1]; +} drawfile_area_text; + +typedef struct { + wimp_box bbox; + drawfile_text_column_list header; + drawfile_area_text area_text; +} drawfile_text_area; + +typedef struct { + wimp_box bbox; + int paper_size; + drawfile_paper_options paper_options; + double grid_spacing; + int grid_division; + BOOL isometric; + BOOL auto_adjust; + BOOL show; + BOOL lock; + BOOL cm; + int zoom_mul; + int zoom_div; + BOOL zoom_lock; + BOOL toolbox; + drawfile_entry_mode entry_mode; + int undo_size; +} drawfile_options; + +typedef struct { + wimp_box bbox; + os_trfm trfm; + drawfile_text_flags flags; + palette_entry fill; + palette_entry bg_hint; + drawfile_text_style style; + int xsize; + int ysize; + wimp_coord base; + char text [1]; +} drawfile_trfm_text; + +typedef struct { + wimp_box bbox; + os_trfm trfm; + sprite_header header; + byte data [1]; +} drawfile_trfm_sprite; + +typedef struct { + wimp_box bbox; + int width; + int height; + int xdpi; + int ydpi; + os_trfm trfm; + int len; + byte data [1]; +} drawfile_jpeg; + +/* ------------------------------------------------------------------------ + * Type: drawfile_object + * + * Description: This type is used to declare pointers rather than objects + */ + +typedef struct { + drawfile_type type; + int size; + union { + drawfile_font_table font_table; + drawfile_text text; + drawfile_path path; + drawfile_path_with_pattern path_with_pattern; + drawfile_sprite sprite; + drawfile_group group; + drawfile_tagged tagged; + drawfile_text_column text_column; + drawfile_text_area text_area; + drawfile_options options; + drawfile_trfm_text trfm_text; + drawfile_trfm_sprite trfm_sprite; + drawfile_jpeg jpeg; + } data; +} drawfile_object; + +typedef struct { + char tag [4]; + int major_version; + int minor_version; + char source [12]; + wimp_box bbox; + drawfile_object objects [1]; +} drawfile_diagram; + +typedef bits drawfile_bbox_flags; + +typedef struct { + drawfile_object *object; + drawfile_diagram *diagram; + drawfile_object *font_table; + drawfile_declare_fonts_flags flags; + os_error *error; +} drawfile_declare_fonts_state; + +/************************ + * Constant definitions * + ************************/ +#define error_DRAW_FILE_NOT_DRAW 0x20C00u +#define error_DRAW_FILE_VERSION 0x20C01u +#define error_DRAW_FILE_FONT_TAB 0x20C02u +#define error_DRAW_FILE_BAD_FONT_NO 0x20C03u +#define error_DRAW_FILE_BAD_MODE 0x20C04u +#define error_DRAW_FILE_BAD_FILE 0x20C05u +#define error_DRAW_FILE_BAD_GROUP 0x20C06u +#define error_DRAW_FILE_BAD_TAG 0x20C07u +#define error_DRAW_FILE_SYNTAX 0x20C08u +#define error_DRAW_FILE_FONT_NO 0x20C09u +#define error_DRAW_FILE_AREA_VER 0x20C0Au +#define error_DRAW_FILE_NO_AREA_VER 0x20C0Bu + +#define drawfile_PATH_MITRED ((drawfile_path_style_flags) 0x0u) +#define drawfile_PATH_ROUND ((drawfile_path_style_flags) 0x1u) +#define drawfile_PATH_BEVELLED ((drawfile_path_style_flags) 0x2u) +#define drawfile_PATH_BUTT ((drawfile_path_style_flags) 0x0u) +#define drawfile_PATH_SQUARE ((drawfile_path_style_flags) 0x2u) +#define drawfile_PATH_TRIANGLE ((drawfile_path_style_flags) 0x3u) +#define drawfile_PATH_JOIN_SHIFT 0 +#define drawfile_PATH_JOIN ((drawfile_path_style_flags) 0x3u) +#define drawfile_PATH_END_SHIFT 2 +#define drawfile_PATH_END ((drawfile_path_style_flags) 0xCu) +#define drawfile_PATH_START_SHIFT 4 +#define drawfile_PATH_START ((drawfile_path_style_flags) 0x30u) +#define drawfile_PATH_WINDING_EVEN_ODD ((drawfile_path_style_flags) 0x40u) +#define drawfile_PATH_DASHED ((drawfile_path_style_flags) 0x80u) +#define drawfile_PATH_CAP_WIDTH_SHIFT 16 +#define drawfile_PATH_CAP_WIDTH ((drawfile_path_style_flags) 0xFF0000u) +#define drawfile_PATH_CAP_LENGTH_SHIFT 24 +#define drawfile_PATH_CAP_LENGTH ((drawfile_path_style_flags) 0xFF000000u) +#define drawfile_TEXT_KERN ((drawfile_text_flags) 0x1u) +#define drawfile_TEXT_RIGHT_TO_LEFT ((drawfile_text_flags) 0x2u) +#define drawfile_TEXT_UNDERLINE ((drawfile_text_flags) 0x4u) +#define drawfile_RENDER_BBOXES ((drawfile_render_flags) 0x1u) +#define drawfile_RENDER_SUPPRESS ((drawfile_render_flags) 0x2u) +#define drawfile_RENDER_GIVEN_FLATNESS ((drawfile_render_flags) 0x4u) +#define drawfile_RENDER_GIVEN_COLOUR_MAPPING ((drawfile_render_flags) 0x8u) +#define drawfile_NO_DOWNLOAD ((drawfile_declare_fonts_flags) 0x1u) +#define drawfile_PAPER_SHOW ((drawfile_paper_options) 0x1u) +#define drawfile_PAPER_LANDSCAPE ((drawfile_paper_options) 0x10u) +#define drawfile_PAPER_DEFAULT ((drawfile_paper_options) 0x100u) +#define drawfile_ENTRY_MODE_LINE ((drawfile_entry_mode) 0x1u) +#define drawfile_ENTRY_MODE_CLOSED_LINE ((drawfile_entry_mode) 0x2u) +#define drawfile_ENTRY_MODE_CURVE ((drawfile_entry_mode) 0x4u) +#define drawfile_ENTRY_MODE_CLOSED_CURVE ((drawfile_entry_mode) 0x8u) +#define drawfile_ENTRY_MODE_RECTANGLE ((drawfile_entry_mode) 0x10u) +#define drawfile_ENTRY_MODE_ELLIPSE ((drawfile_entry_mode) 0x20u) +#define drawfile_ENTRY_MODE_TEXT_LINE ((drawfile_entry_mode) 0x40u) +#define drawfile_ENTRY_MODE_SELECT ((drawfile_entry_mode) 0x80u) + +/************************* + * Function declarations * + *************************/ + +#if defined(__cplusplus) + extern "C" { +#endif /* __cplusplus */ + +/* ------------------------------------------------------------------------ + * Function: drawfile_render() + * + * Description: Calls SWI 0x45540 + * + * Input: flags - value of R0 on entry + * diagram - value of R1 on entry + * size - value of R2 on entry + * trfm - value of R3 on entry + * clip - value of R4 on entry + * flatness - value of R5 on entry + */ + +extern os_error *Drawfile_Render (drawfile_render_flags flags, + drawfile_diagram const *diagram, + int size, + os_trfm const *trfm, + wimp_box const *clip, + int flatness); + +/* ------------------------------------------------------------------------ + * Function: drawfile_bbox() + * + * Description: Calls SWI 0x45541 + * + * Input: flags - value of R0 on entry + * diagram - value of R1 on entry + * size - value of R2 on entry + * trfm - value of R3 on entry + * bbox - value of R4 on entry + */ + +extern os_error *Drawfile_Bbox (drawfile_bbox_flags flags, + drawfile_diagram const *diagram, + int size, + os_trfm const *trfm, + wimp_box *bbox); + +/* ------------------------------------------------------------------------ + * Function: Drawfile_DeclareFonts() + * + * Description: Calls SWI 0x45542 + * + * Input: flags - value of R0 on entry + * diagram - value of R1 on entry + * size - value of R2 on entry + */ + +extern os_error *Drawfile_DeclareFonts (drawfile_declare_fonts_flags flags, + drawfile_diagram const *diagram, + int size); + +/* ------------------------------------------------------------------------ + * Function: Drawfile_CreateDiagram() + * + */ + +extern os_error * Drawfile_CreateDiagram(drawfile_info *info, size_t memory, + const char *creator, wimp_box box); + +extern os_error *Drawfile_AppendObject(drawfile_info *info, size_t memory, + const drawfile_object *object, BOOL rebind); + +extern os_error *Drawfile_RenderDiagram(drawfile_info *info, + window_redrawblock *redraw, double scale); + +extern os_error *Drawfile_VerifyDiagram(drawfile_info *info); + +extern void Drawfile_QueryBox(drawfile_info *info, + wimp_box *rect, BOOL screenUnits); + +#if defined(__cplusplus) + } +#endif /* __cplusplus */ + +#endif /* __drawfile.h */ diff --git a/fail.c b/fail.c new file mode 100644 index 0000000..b6c729f --- /dev/null +++ b/fail.c @@ -0,0 +1,26 @@ +/* + * fail.c + * Copyright (C) 1998 A.J. van Os + * + * Description: + * An alternative form of assert() + */ + +#include +#include "antiword.h" + +#if !defined(NDEBUG) +void +__fail(char *szExpression, char *szFilename, int iLineNumber) +{ + if (szExpression == NULL || szFilename == NULL) { + werr(1, "Internal error: no expression"); + } +#if defined(DEBUG) + fprintf(stderr, "%s[%3d]: Internal error in '%s'\n", + szFilename, iLineNumber, szExpression); +#endif /* DEBUG */ + werr(1, "Internal error in '%s' in file %s at line %d", + szExpression, szFilename, iLineNumber); +} /* end of __fail */ +#endif /* !NDEBUG */ diff --git a/fail.h b/fail.h new file mode 100644 index 0000000..151a26a --- /dev/null +++ b/fail.h @@ -0,0 +1,22 @@ +/* + * fail.h + * Copyright (C) 1998-2000 A.J. van Os; Released under GPL + * + * Description: + * Support for an alternative form of assert() + */ + +#if !defined(__fail_h) +#define __fail_h 1 + +#undef fail + +#if defined(NDEBUG) +#define fail(e) ((void)0) +#else +#define fail(e) ((e) ? __fail(#e, __FILE__, __LINE__) : (void)0) +#endif /* NDEBUG */ + +extern void __fail(char *, char *, int); + +#endif /* __fail_h */ diff --git a/finddata.c b/finddata.c new file mode 100644 index 0000000..441030c --- /dev/null +++ b/finddata.c @@ -0,0 +1,154 @@ +/* + * finddata.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Find the blocks that contain the data of MS Word files + */ + +#include +#include +#include "antiword.h" + + +/* + * bAddDataBlocks - Add the blocks to the data block list + * + * Returns TRUE when successful, otherwise FALSE + */ +BOOL +bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength, + ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen) +{ + data_block_type tDataBlock; + ULONG ulDataPos, ulOffset, ulIndex; + long lToGo; + BOOL bSuccess; + + fail(ulTotalLength > (ULONG)LONG_MAX); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + NO_DBG_HEX(ulDataPosFirst); + NO_DBG_DEC(ulTotalLength); + + lToGo = (long)ulTotalLength; + + ulDataPos = ulDataPosFirst; + ulOffset = ulDataPosFirst; + for (ulIndex = ulStartBlock; + ulIndex != END_OF_CHAIN && lToGo > 0; + ulIndex = aulBBD[ulIndex]) { + if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) { + DBG_DEC(ulIndex); + DBG_DEC(tBBDLen); + return FALSE; + } + if (ulOffset >= BIG_BLOCK_SIZE) { + ulOffset -= BIG_BLOCK_SIZE; + continue; + } + tDataBlock.ulFileOffset = + (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset; + tDataBlock.ulDataPos = ulDataPos; + tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset, + (ULONG)lToGo); + fail(tDataBlock.ulLength > BIG_BLOCK_SIZE); + ulOffset = 0; + if (!bAdd2DataBlockList(&tDataBlock)) { + DBG_HEX(tDataBlock.ulFileOffset); + DBG_HEX(tDataBlock.ulDataPos); + DBG_DEC(tDataBlock.ulLength); + return FALSE; + } + ulDataPos += tDataBlock.ulLength; + lToGo -= (long)tDataBlock.ulLength; + } + bSuccess = lToGo == 0 || + (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN); + DBG_DEC_C(!bSuccess, lToGo); + DBG_DEC_C(!bSuccess, ulTotalLength); + DBG_DEC_C(!bSuccess, ulIndex); + return bSuccess; +} /* end of bAddDataBlocks */ + +/* + * bGet6DocumentData - make a list of the data blocks of Word 6/7 files + * + * Code for "fast saved" files. + * + * Returns TRUE when successful, otherwise FALSE + */ +BOOL +bGet6DocumentData(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginTextInfo, ulOffset, ulTotLength; + size_t tTextInfoLen; + int iIndex, iOff, iType, iLen, iPieces; + + DBG_MSG("bGet6DocumentData"); + + fail(pFile == NULL); + fail(aulBBD == NULL); + fail(aucHeader == NULL); + + ulBeginTextInfo = ulGetLong(0x160, aucHeader); + DBG_HEX(ulBeginTextInfo); + tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader); + DBG_DEC(tTextInfoLen); + + aucBuffer = xmalloc(tTextInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginTextInfo, tTextInfoLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen); + + iOff = 0; + while (iOff < (int)tTextInfoLen) { + iType = (int)ucGetByte(iOff, aucBuffer); + iOff++; + if (iType == 0) { + iOff++; + continue; + } + iLen = (int)usGetWord(iOff, aucBuffer); + iOff += 2; + if (iType == 1) { + iOff += iLen; + continue; + } + if (iType != 2) { + werr(0, "Unknown type of 'fastsaved' format"); + aucBuffer = xfree(aucBuffer); + return FALSE; + } + /* Type 2 */ + NO_DBG_DEC(iLen); + iOff += 2; + iPieces = (iLen - 4) / 12; + DBG_DEC(iPieces); + for (iIndex = 0; iIndex < iPieces; iIndex++) { + ulOffset = ulGetLong( + iOff + (iPieces + 1) * 4 + iIndex * 8 + 2, + aucBuffer); + ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4, + aucBuffer) - + ulGetLong(iOff + iIndex * 4, + aucBuffer); + if (!bAddDataBlocks(ulOffset, ulTotLength, + ulStartBlock, + aulBBD, tBBDLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + } + break; + } + aucBuffer = xfree(aucBuffer); + return TRUE; +} /* end of bGet6DocumentData */ diff --git a/findtext.c b/findtext.c new file mode 100644 index 0000000..20724a5 --- /dev/null +++ b/findtext.c @@ -0,0 +1,289 @@ +/* + * findtext.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Find the blocks that contain the text of MS Word files + */ + +#include +#include +#include "antiword.h" + + +/* + * bAddTextBlocks - Add the blocks to the text block list + * + * Returns TRUE when successful, FALSE if not + */ +BOOL +bAddTextBlocks(ULONG ulCharPosFirst, ULONG ulTotalLength, + BOOL bUsesUnicode, USHORT usPropMod, + ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen) +{ + text_block_type tTextBlock; + ULONG ulCharPos, ulOffset, ulIndex; + long lToGo; + + fail(ulTotalLength > (ULONG)LONG_MAX / 2); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + NO_DBG_HEX(ulCharPosFirst); + NO_DBG_DEC(ulTotalLength); + + if (bUsesUnicode) { + /* One character equals two bytes */ + NO_DBG_MSG("Uses Unicode"); + lToGo = (long)ulTotalLength * 2; + } else { + /* One character equals one byte */ + NO_DBG_MSG("Uses ASCII"); + lToGo = (long)ulTotalLength; + } + + ulCharPos = ulCharPosFirst; + ulOffset = ulCharPosFirst; + for (ulIndex = ulStartBlock; + ulIndex != END_OF_CHAIN && lToGo > 0; + ulIndex = aulBBD[ulIndex]) { + if (ulIndex >= (ULONG)tBBDLen) { + DBG_DEC(ulIndex); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + if (ulOffset >= BIG_BLOCK_SIZE) { + ulOffset -= BIG_BLOCK_SIZE; + continue; + } + tTextBlock.ulFileOffset = + (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset; + tTextBlock.ulCharPos = ulCharPos; + tTextBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset, + (ULONG)lToGo); + tTextBlock.bUsesUnicode = bUsesUnicode; + tTextBlock.usPropMod = usPropMod; + ulOffset = 0; + if (!bAdd2TextBlockList(&tTextBlock)) { + DBG_HEX(tTextBlock.ulFileOffset); + DBG_HEX(tTextBlock.ulCharPos); + DBG_DEC(tTextBlock.ulLength); + DBG_DEC(tTextBlock.bUsesUnicode); + DBG_DEC(tTextBlock.usPropMod); + return FALSE; + } + ulCharPos += tTextBlock.ulLength; + lToGo -= (long)tTextBlock.ulLength; + } + DBG_DEC_C(lToGo != 0, lToGo); + return lToGo == 0; +} /* end of bAddTextBlocks */ + +/* + * bGet6DocumentText - make a list of the text blocks of Word 6/7 files + * + * Code for "fast saved" files. + * + * Returns TRUE when successful, FALSE if not + */ +BOOL +bGet6DocumentText(FILE *pFile, BOOL bUsesUnicode, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginTextInfo, ulTextOffset, ulTotLength; + size_t tTextInfoLen; + int iIndex, iType, iOff, iLen, iPieces; + USHORT usPropMod; + + DBG_MSG("bGet6DocumentText"); + + fail(pFile == NULL); + fail(aulBBD == NULL); + fail(aucHeader == NULL); + + ulBeginTextInfo = ulGetLong(0x160, aucHeader); /* fcClx */ + DBG_HEX(ulBeginTextInfo); + tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader); /* lcbClx */ + DBG_DEC(tTextInfoLen); + + aucBuffer = xmalloc(tTextInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginTextInfo, tTextInfoLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen); + + iOff = 0; + while ((size_t)iOff < tTextInfoLen) { + iType = (int)ucGetByte(iOff, aucBuffer); + iOff++; + if (iType == 0) { + DBG_FIXME(); + iOff++; + continue; + } + if (iType == 1) { + iLen = (int)usGetWord(iOff, aucBuffer); + vAdd2PropModList(aucBuffer + iOff); + iOff += iLen + 2; + continue; + } + if (iType != 2) { + werr(0, "Unknown type of 'fastsaved' format"); + aucBuffer = xfree(aucBuffer); + return FALSE; + } + /* Type 2 */ + iLen = (int)usGetWord(iOff, aucBuffer); + NO_DBG_DEC(iLen); + iOff += 4; + iPieces = (iLen - 4) / 12; + DBG_DEC(iPieces); + for (iIndex = 0; iIndex < iPieces; iIndex++) { + ulTextOffset = ulGetLong( + iOff + (iPieces + 1) * 4 + iIndex * 8 + 2, + aucBuffer); + usPropMod = usGetWord( + iOff + (iPieces + 1) * 4 + iIndex * 8 + 6, + aucBuffer); + ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4, + aucBuffer) - + ulGetLong(iOff + iIndex * 4, + aucBuffer); + NO_DBG_HEX_C(usPropMod != 0, usPropMod); + if (!bAddTextBlocks(ulTextOffset, ulTotLength, + bUsesUnicode, usPropMod, + ulStartBlock, + aulBBD, tBBDLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + } + break; + } + aucBuffer = xfree(aucBuffer); + return TRUE; +} /* end of bGet6DocumentText */ + +/* + * bGet8DocumentText - make a list of the text blocks of Word 8/97 files + * + * Returns TRUE when successful, FALSE if not + */ +BOOL +bGet8DocumentText(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulTextOffset, ulBeginTextInfo; + ULONG ulTotLength, ulLen; + long lIndex, lPieces, lOff; + size_t tTextInfoLen, tBlockDepotLen, tBlockSize; + int iType, iLen; + BOOL bUsesUnicode; + USHORT usPropMod; + + DBG_MSG("bGet8DocumentText"); + + fail(pFile == NULL || pPPS == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + fail(aucHeader == NULL); + + ulBeginTextInfo = ulGetLong(0x1a2, aucHeader); /* fcClx */ + DBG_HEX(ulBeginTextInfo); + tTextInfoLen = (size_t)ulGetLong(0x1a6, aucHeader); /* lcbClx */ + DBG_DEC(tTextInfoLen); + + DBG_DEC(pPPS->tTable.ulSB); + DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + return FALSE; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tTextInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginTextInfo, tTextInfoLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen); + + lOff = 0; + while (lOff < (long)tTextInfoLen) { + iType = (int)ucGetByte(lOff, aucBuffer); + lOff++; + if (iType == 0) { + DBG_FIXME(); + lOff++; + continue; + } + if (iType == 1) { + iLen = (int)usGetWord(lOff, aucBuffer); + vAdd2PropModList(aucBuffer + lOff); + lOff += (long)iLen + 2; + continue; + } + if (iType != 2) { + werr(0, "Unknown type of 'fastsaved' format"); + aucBuffer = xfree(aucBuffer); + return FALSE; + } + /* Type 2 */ + ulLen = ulGetLong(lOff, aucBuffer); + if (ulLen < 4) { + DBG_DEC(ulLen); + return FALSE; + } + lOff += 4; + lPieces = (long)((ulLen - 4) / 12); + DBG_DEC(lPieces); + for (lIndex = 0; lIndex < lPieces; lIndex++) { + ulTextOffset = ulGetLong( + lOff + (lPieces + 1) * 4 + lIndex * 8 + 2, + aucBuffer); + usPropMod = usGetWord( + lOff + (lPieces + 1) * 4 + lIndex * 8 + 6, + aucBuffer); + ulTotLength = ulGetLong(lOff + (lIndex + 1) * 4, + aucBuffer) - + ulGetLong(lOff + lIndex * 4, + aucBuffer); + if ((ulTextOffset & BIT(30)) == 0) { + bUsesUnicode = TRUE; + } else { + bUsesUnicode = FALSE; + ulTextOffset &= ~BIT(30); + ulTextOffset /= 2; + } + NO_DBG_HEX_C(usPropMod != 0, usPropMod); + if (!bAddTextBlocks(ulTextOffset, ulTotLength, + bUsesUnicode, usPropMod, + pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen)) { + aucBuffer = xfree(aucBuffer); + return FALSE; + } + } + break; + } + aucBuffer = xfree(aucBuffer); + return TRUE; +} /* end of bGet8DocumentText */ diff --git a/fmt_text.c b/fmt_text.c new file mode 100644 index 0000000..db211e9 --- /dev/null +++ b/fmt_text.c @@ -0,0 +1,167 @@ +/* + * fmt_text.c + * Copyright (C) 2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with the Formatted Text format + * + * Based on patches send by: Ofir Reichenberg + * + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include "antiword.h" + +/* The character set */ +static encoding_type eEncoding = encoding_neutral; +/* Current vertical position information */ +static long lYtopCurr = 0; +/* Local representation of the non-breaking space */ +static UCHAR ucNbsp = 0; + + +/* + * vPrologueFMT - set options and perform the Formatted Text initialization + */ +void +vPrologueFMT(diagram_type *pDiag, const options_type *pOptions) +{ + fail(pDiag == NULL); + fail(pOptions == NULL); + + eEncoding = pOptions->eEncoding; + pDiag->lXleft = 0; + pDiag->lYtop = 0; + lYtopCurr = 0; +} /* end of vPrologueFMT */ + +/* + * vPrintFMT - print a Formatted Text string + */ +static void +vPrintFMT(FILE *pFile, + const char *szString, size_t tStringLength, USHORT usFontstyle) +{ + const UCHAR *pucByte, *pucStart, *pucLast, *pucNonSpace; + + fail(szString == NULL); + + if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { + return; + } + + if (eEncoding == encoding_utf_8) { + fprintf(pFile, "%.*s", (int)tStringLength, szString); + return; + } + + if (ucNbsp == 0) { + ucNbsp = ucGetNbspCharacter(); + DBG_HEX_C(ucNbsp != 0xa0, ucNbsp); + } + + pucStart = (UCHAR *)szString; + pucLast = pucStart + tStringLength - 1; + pucNonSpace = pucLast; + while ((*pucNonSpace == (UCHAR)' ' || *pucNonSpace == ucNbsp) && + pucNonSpace > pucStart) { + pucNonSpace--; + } + + /* 1: The spaces at the start */ + pucByte = pucStart; + while ((*pucByte == (UCHAR)' ' || *pucByte == ucNbsp) && + pucByte <= pucLast) { + (void)putc(' ', pFile); + pucByte++; + } + + if (pucByte > pucLast) { + /* There is no text, just spaces */ + return; + } + + /* 2: Start the *bold*, /italic/ and _underline_ */ + if (bIsBold(usFontstyle)) { + (void)putc('*', pFile); + } + if (bIsItalic(usFontstyle)) { + (void)putc('/', pFile); + } + if (bIsUnderline(usFontstyle)) { + (void)putc('_', pFile); + } + + /* 3: The text itself */ + while (pucByte <= pucNonSpace) { + if (*pucByte == ucNbsp) { + (void)putc(' ', pFile); + } else { + (void)putc((char)*pucByte, pFile); + } + pucByte++; + } + + /* 4: End the *bold*, /italic/ and _underline_ */ + if (bIsUnderline(usFontstyle)) { + (void)putc('_', pFile); + } + if (bIsItalic(usFontstyle)) { + (void)putc('/', pFile); + } + if (bIsBold(usFontstyle)) { + (void)putc('*', pFile); + } + + /* 5: The spaces at the end */ + while (pucByte <= pucLast) { + (void)putc(' ', pFile); + pucByte++; + } +} /* end of vPrintFMT */ + +/* + * vMoveTo - move to the given X,Y coordinates + * + * Move the current position of the given diagram to its X,Y coordinates, + * start on a new page if needed + */ +static void +vMoveTo(diagram_type *pDiag) +{ + int iCount, iNbr; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + if (pDiag->lYtop != lYtopCurr) { + iNbr = iDrawUnits2Char(pDiag->lXleft); + for (iCount = 0; iCount < iNbr; iCount++) { + (void)putc(FILLER_CHAR, pDiag->pOutFile); + } + lYtopCurr = pDiag->lYtop; + } +} /* end of vMoveTo */ + +/* + * vSubstringFMT - print a sub string + */ +void +vSubstringFMT(diagram_type *pDiag, + const char *szString, size_t tStringLength, long lStringWidth, + USHORT usFontstyle) +{ + fail(pDiag == NULL || szString == NULL); + fail(pDiag->pOutFile == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + vMoveTo(pDiag); + vPrintFMT(pDiag->pOutFile, szString, tStringLength, usFontstyle); + pDiag->lXleft += lStringWidth; +} /* end of vSubstringFMT */ diff --git a/fontinfo.h b/fontinfo.h new file mode 100644 index 0000000..8538dfa --- /dev/null +++ b/fontinfo.h @@ -0,0 +1,2251 @@ +/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT! */ +static const char *szFontnames[32] = { + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Palatino-Roman", + "Palatino-Bold", + "Palatino-Italic", + "Palatino-BoldItalic", + "Helvetica-Narrow", + "Helvetica-Narrow-Bold", + "Helvetica-Narrow-Oblique", + "Helvetica-Narrow-BoldOblique", + "Bookman-Light", + "Bookman-Demi", + "Bookman-LightItalic", + "Bookman-DemiItalic", + "AvantGarde-Book", + "AvantGarde-Demi", + "AvantGarde-BookOblique", + "AvantGarde-DemiOblique", + "NewCenturySchlbk-Roman", + "NewCenturySchlbk-Bold", + "NewCenturySchlbk-Italic", + "NewCenturySchlbk-BoldItalic", +}; +static unsigned short ausCharacterWidths1[32][256] = { + { /* Courier */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 600, 600, 600, 600, + /* 144 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 152 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Times-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 408, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 564, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 278, 278, 564, 564, 564, 444, + /* 64 */ 921, 722, 667, 667, 722, 611, 556, 722, + /* 72 */ 722, 333, 389, 722, 611, 889, 722, 722, + /* 80 */ 556, 722, 667, 556, 611, 722, 722, 944, + /* 88 */ 722, 722, 611, 333, 278, 333, 469, 500, + /* 96 */ 333, 444, 500, 444, 500, 444, 333, 500, + /* 104 */ 500, 278, 278, 500, 278, 778, 500, 500, + /* 112 */ 500, 500, 333, 389, 278, 500, 500, 722, + /* 120 */ 500, 500, 444, 480, 200, 480, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1000, 350, + /* 144 */ 333, 333, 333, 333, 444, 444, 444, 500, + /* 152 */ 1000, 564, 889, 722, 500, 500, 556, 556, + /* 160 */ 250, 333, 500, 500, 500, 500, 200, 500, + /* 168 */ 333, 760, 276, 500, 564, 333, 760, 333, + /* 176 */ 400, 564, 300, 300, 333, 500, 453, 250, + /* 184 */ 333, 300, 310, 500, 750, 750, 750, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 889, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 564, + /* 216 */ 722, 722, 722, 722, 722, 722, 556, 500, + /* 224 */ 444, 444, 444, 444, 444, 444, 667, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 564, + /* 248 */ 500, 500, 500, 500, 500, 500, 500, 500, + }, + { /* Times-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 555, 500, 500, 1000, 833, 333, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 930, 722, 667, 722, 722, 667, 611, 778, + /* 72 */ 778, 389, 500, 778, 667, 944, 722, 778, + /* 80 */ 611, 778, 722, 556, 667, 722, 722, 1000, + /* 88 */ 722, 722, 667, 333, 278, 333, 581, 500, + /* 96 */ 333, 500, 556, 444, 556, 444, 333, 500, + /* 104 */ 556, 278, 333, 556, 278, 833, 556, 500, + /* 112 */ 556, 556, 444, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 394, 220, 394, 520, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 333, 333, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 570, 1000, 722, 500, 500, 556, 556, + /* 160 */ 250, 333, 500, 500, 500, 500, 220, 500, + /* 168 */ 333, 747, 300, 500, 570, 333, 747, 333, + /* 176 */ 400, 570, 300, 300, 333, 556, 540, 250, + /* 184 */ 333, 300, 330, 500, 750, 750, 750, 500, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 389, 389, 389, 389, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 570, + /* 216 */ 778, 722, 722, 722, 722, 722, 611, 556, + /* 224 */ 500, 500, 500, 500, 500, 500, 722, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 556, 500, 500, 500, 500, 500, 570, + /* 248 */ 500, 556, 556, 556, 556, 500, 556, 500, + }, + { /* Times-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 420, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 675, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 675, 675, 675, 500, + /* 64 */ 920, 611, 611, 667, 722, 611, 611, 722, + /* 72 */ 722, 333, 444, 667, 556, 833, 667, 722, + /* 80 */ 611, 722, 611, 500, 556, 722, 611, 833, + /* 88 */ 611, 556, 556, 389, 278, 389, 422, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 722, 500, 500, + /* 112 */ 500, 500, 389, 389, 278, 500, 444, 667, + /* 120 */ 444, 444, 389, 400, 275, 400, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 889, 980, 1000, 350, + /* 144 */ 333, 333, 333, 333, 556, 556, 556, 500, + /* 152 */ 889, 675, 944, 667, 500, 500, 500, 500, + /* 160 */ 250, 389, 500, 500, 500, 500, 275, 500, + /* 168 */ 333, 760, 276, 500, 675, 333, 760, 333, + /* 176 */ 400, 675, 300, 300, 333, 500, 523, 250, + /* 184 */ 333, 300, 310, 500, 750, 750, 750, 500, + /* 192 */ 611, 611, 611, 611, 611, 611, 889, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 722, 667, 722, 722, 722, 722, 722, 675, + /* 216 */ 722, 722, 722, 722, 722, 556, 611, 500, + /* 224 */ 500, 500, 500, 500, 500, 500, 667, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 675, + /* 248 */ 500, 500, 500, 500, 500, 444, 500, 444, + }, + { /* Times-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 389, 555, 500, 500, 833, 778, 333, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 832, 667, 667, 667, 722, 667, 667, 722, + /* 72 */ 778, 389, 500, 667, 611, 889, 722, 722, + /* 80 */ 611, 722, 667, 556, 611, 722, 667, 889, + /* 88 */ 667, 611, 611, 333, 278, 333, 570, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 333, 500, + /* 104 */ 556, 278, 278, 500, 278, 778, 556, 500, + /* 112 */ 500, 500, 389, 389, 278, 556, 444, 667, + /* 120 */ 500, 444, 389, 348, 220, 348, 570, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 333, 333, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 944, 722, 500, 500, 556, 556, + /* 160 */ 250, 389, 500, 500, 500, 500, 220, 500, + /* 168 */ 333, 747, 266, 500, 606, 333, 747, 333, + /* 176 */ 400, 570, 300, 300, 333, 576, 500, 250, + /* 184 */ 333, 300, 300, 500, 750, 750, 750, 500, + /* 192 */ 667, 667, 667, 667, 667, 667, 944, 667, + /* 200 */ 667, 667, 667, 667, 389, 389, 389, 389, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 570, + /* 216 */ 722, 722, 722, 722, 722, 611, 611, 500, + /* 224 */ 500, 500, 500, 500, 500, 500, 722, 444, + /* 232 */ 444, 444, 444, 444, 278, 278, 278, 278, + /* 240 */ 500, 556, 500, 500, 500, 500, 500, 570, + /* 248 */ 500, 556, 556, 556, 556, 444, 500, 444, + }, + { /* Helvetica */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 221, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 222, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 222, 221, 333, 333, 333, 333, 333, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 500, 500, + /* 160 */ 278, 333, 556, 556, 556, 556, 260, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 351, 351, 333, 556, 537, 278, + /* 184 */ 333, 351, 365, 556, 869, 869, 869, 611, + /* 192 */ 667, 667, 667, 667, 667, 667, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 666, 666, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 500, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 611, 556, 556, 556, 556, 500, 555, 500, + }, + { /* Helvetica-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 278, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 278, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 280, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 351, 351, 333, 611, 556, 278, + /* 184 */ 333, 351, 365, 556, 869, 869, 869, 611, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 556, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 611, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Helvetica-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 222, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 222, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 222, 222, 333, 333, 333, 333, 333, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 500, 500, + /* 160 */ 278, 333, 556, 556, 556, 556, 260, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 390, 390, 333, 556, 537, 278, + /* 184 */ 333, 390, 365, 556, 947, 947, 947, 611, + /* 192 */ 667, 667, 667, 667, 667, 667, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 500, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 611, 556, 556, 556, 556, 500, 556, 500, + }, + { /* Helvetica-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 278, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 278, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 350, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 556, + /* 152 */ 1000, 584, 1000, 944, 556, 556, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 280, 556, + /* 168 */ 333, 737, 370, 556, 584, 333, 737, 333, + /* 176 */ 606, 584, 444, 444, 333, 611, 556, 278, + /* 184 */ 333, 444, 365, 556, 1055, 1055, 1055, 611, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 667, 667, 667, 667, 278, 278, 278, 278, + /* 208 */ 722, 722, 778, 778, 778, 778, 778, 584, + /* 216 */ 778, 722, 722, 722, 722, 667, 667, 611, + /* 224 */ 556, 556, 556, 556, 556, 556, 889, 556, + /* 232 */ 556, 556, 556, 556, 278, 278, 278, 278, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 611, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Palatino-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 371, 500, 500, 840, 778, 278, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 606, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 611, 709, 774, 611, 556, 763, + /* 72 */ 832, 337, 333, 726, 611, 946, 831, 786, + /* 80 */ 604, 786, 668, 525, 613, 778, 722, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 500, 553, 444, 611, 479, 333, 556, + /* 104 */ 582, 291, 234, 556, 291, 883, 582, 546, + /* 112 */ 601, 560, 395, 424, 326, 603, 565, 834, + /* 120 */ 516, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 979, 1144, 606, + /* 144 */ 278, 278, 331, 331, 500, 500, 500, 500, + /* 152 */ 1000, 606, 998, 827, 500, 500, 605, 608, + /* 160 */ 250, 278, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 333, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 603, 628, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 444, + /* 192 */ 778, 778, 778, 778, 778, 778, 944, 709, + /* 200 */ 611, 611, 611, 611, 337, 337, 337, 337, + /* 208 */ 774, 831, 786, 786, 786, 786, 786, 606, + /* 216 */ 833, 778, 778, 778, 778, 667, 604, 556, + /* 224 */ 500, 500, 500, 500, 500, 500, 758, 444, + /* 232 */ 479, 479, 479, 479, 287, 287, 287, 287, + /* 240 */ 546, 582, 546, 546, 546, 546, 546, 606, + /* 248 */ 556, 603, 603, 603, 603, 556, 601, 556, + }, + { /* Palatino-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 402, 500, 500, 889, 833, 278, + /* 40 */ 333, 333, 444, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 667, 722, 833, 611, 556, 833, + /* 72 */ 833, 389, 389, 778, 611, 1000, 833, 833, + /* 80 */ 611, 833, 722, 611, 667, 778, 778, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 500, 611, 444, 611, 500, 389, 556, + /* 104 */ 611, 333, 333, 611, 333, 889, 611, 556, + /* 112 */ 611, 611, 389, 444, 333, 611, 556, 833, + /* 120 */ 500, 556, 500, 310, 606, 310, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 998, 1000, 606, + /* 144 */ 278, 278, 389, 389, 500, 500, 500, 500, + /* 152 */ 1000, 606, 1000, 833, 500, 500, 611, 611, + /* 160 */ 250, 278, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 438, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 611, 641, 250, + /* 184 */ 333, 300, 488, 500, 750, 750, 750, 444, + /* 192 */ 778, 778, 778, 778, 778, 778, 1000, 722, + /* 200 */ 611, 611, 611, 611, 389, 389, 389, 389, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 778, 778, 778, 778, 667, 611, 611, + /* 224 */ 500, 500, 500, 500, 500, 500, 778, 444, + /* 232 */ 500, 500, 500, 500, 333, 333, 333, 333, + /* 240 */ 556, 611, 556, 556, 556, 556, 556, 606, + /* 248 */ 556, 611, 611, 611, 611, 556, 611, 556, + }, + { /* Palatino-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 778, 278, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 500, + /* 64 */ 747, 722, 611, 667, 778, 611, 556, 722, + /* 72 */ 778, 333, 333, 667, 556, 944, 778, 778, + /* 80 */ 611, 778, 667, 556, 611, 778, 722, 944, + /* 88 */ 722, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 444, 463, 407, 500, 389, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 778, 556, 444, + /* 112 */ 500, 463, 389, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 500, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 1028, 669, 500, 500, 528, 545, + /* 160 */ 250, 333, 500, 500, 500, 500, 606, 500, + /* 168 */ 333, 747, 333, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 556, 500, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 500, + /* 192 */ 722, 722, 722, 722, 722, 722, 941, 667, + /* 200 */ 611, 611, 611, 611, 333, 333, 333, 333, + /* 208 */ 778, 778, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 778, 778, 778, 778, 667, 611, 500, + /* 224 */ 444, 444, 444, 444, 444, 444, 638, 407, + /* 232 */ 389, 389, 389, 389, 278, 278, 278, 278, + /* 240 */ 444, 556, 444, 444, 444, 444, 444, 606, + /* 248 */ 444, 556, 556, 556, 556, 500, 500, 500, + }, + { /* Palatino-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 833, 278, + /* 40 */ 333, 333, 444, 606, 250, 389, 250, 315, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 833, 722, 667, 685, 778, 611, 556, 778, + /* 72 */ 778, 389, 389, 722, 611, 944, 778, 833, + /* 80 */ 667, 833, 722, 556, 611, 778, 667, 1000, + /* 88 */ 722, 611, 667, 333, 606, 333, 606, 500, + /* 96 */ 278, 556, 537, 444, 556, 444, 333, 500, + /* 104 */ 556, 333, 333, 556, 333, 833, 556, 556, + /* 112 */ 556, 537, 389, 444, 389, 556, 556, 833, + /* 120 */ 500, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 278, 278, 333, 333, 500, 500, 500, 500, + /* 152 */ 1000, 606, 944, 778, 556, 556, 611, 611, + /* 160 */ 250, 333, 500, 500, 500, 500, 606, 556, + /* 168 */ 333, 747, 333, 500, 606, 389, 747, 333, + /* 176 */ 400, 606, 300, 300, 333, 556, 556, 250, + /* 184 */ 333, 300, 333, 500, 750, 750, 750, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 944, 685, + /* 200 */ 611, 611, 611, 611, 389, 389, 389, 389, + /* 208 */ 778, 778, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 778, 778, 778, 778, 611, 667, 556, + /* 224 */ 556, 556, 556, 556, 556, 556, 738, 444, + /* 232 */ 444, 444, 444, 444, 333, 333, 333, 333, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 606, + /* 248 */ 556, 556, 556, 556, 556, 556, 556, 556, + }, + { /* Helvetica-Narrow */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 182, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 182, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 182, 182, 273, 273, 273, 273, 273, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 410, 410, + /* 160 */ 228, 273, 456, 456, 456, 456, 213, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 456, 440, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 547, 547, 547, 547, 547, 547, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 410, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 501, 456, 456, 456, 456, 410, 456, 410, + }, + { /* Helvetica-Narrow-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 228, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 228, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 228, 228, 273, 273, 410, 410, 410, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 501, 501, + /* 160 */ 228, 273, 456, 456, 456, 456, 230, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 501, 456, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 592, 592, 592, 592, 592, 592, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 456, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 501, 501, 501, 501, 501, 456, 501, 456, + }, + { /* Helvetica-Narrow-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 182, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 182, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 182, 182, 273, 273, 273, 273, 273, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 410, 410, + /* 160 */ 228, 273, 456, 456, 456, 456, 213, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 456, 440, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 547, 547, 547, 547, 547, 547, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 410, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 501, 456, 456, 456, 456, 410, 456, 410, + }, + { /* Helvetica-Narrow-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 228, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 228, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 820, 820, 820, 287, + /* 144 */ 228, 228, 273, 273, 410, 410, 410, 456, + /* 152 */ 820, 479, 820, 774, 456, 456, 501, 501, + /* 160 */ 228, 273, 456, 456, 456, 456, 230, 456, + /* 168 */ 273, 604, 303, 456, 479, 273, 604, 273, + /* 176 */ 328, 479, 273, 273, 273, 501, 456, 228, + /* 184 */ 273, 273, 299, 456, 684, 684, 684, 501, + /* 192 */ 592, 592, 592, 592, 592, 592, 820, 592, + /* 200 */ 547, 547, 547, 547, 228, 228, 228, 228, + /* 208 */ 592, 592, 638, 638, 638, 638, 638, 479, + /* 216 */ 638, 592, 592, 592, 592, 547, 547, 501, + /* 224 */ 456, 456, 456, 456, 456, 456, 729, 456, + /* 232 */ 456, 456, 456, 456, 228, 228, 228, 228, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 501, 501, 501, 501, 501, 456, 501, 456, + }, + { /* Bookman-Light */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 320, 300, 380, 620, 620, 900, 800, 220, + /* 40 */ 300, 300, 440, 600, 320, 400, 320, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 320, 320, 600, 600, 600, 540, + /* 64 */ 820, 680, 740, 740, 800, 720, 640, 800, + /* 72 */ 800, 340, 600, 720, 600, 920, 740, 800, + /* 80 */ 620, 820, 720, 660, 620, 780, 700, 960, + /* 88 */ 720, 640, 640, 300, 600, 300, 600, 500, + /* 96 */ 220, 580, 620, 520, 620, 520, 320, 540, + /* 104 */ 660, 300, 300, 620, 300, 940, 660, 560, + /* 112 */ 620, 580, 440, 520, 380, 680, 520, 780, + /* 120 */ 560, 540, 480, 280, 600, 280, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1280, 460, + /* 144 */ 220, 220, 240, 240, 400, 400, 400, 500, + /* 152 */ 1000, 600, 1240, 900, 540, 540, 620, 620, + /* 160 */ 320, 300, 620, 620, 620, 620, 600, 520, + /* 168 */ 420, 740, 420, 360, 600, 400, 740, 440, + /* 176 */ 400, 600, 372, 372, 340, 680, 600, 320, + /* 184 */ 320, 372, 420, 360, 930, 930, 930, 540, + /* 192 */ 680, 680, 680, 680, 680, 680, 1260, 740, + /* 200 */ 720, 720, 720, 720, 340, 340, 340, 340, + /* 208 */ 800, 740, 800, 800, 800, 800, 800, 600, + /* 216 */ 800, 780, 780, 780, 780, 640, 620, 660, + /* 224 */ 580, 580, 580, 580, 580, 580, 860, 520, + /* 232 */ 520, 520, 520, 520, 300, 300, 300, 300, + /* 240 */ 560, 660, 560, 560, 560, 560, 560, 600, + /* 248 */ 560, 680, 680, 680, 680, 540, 620, 540, + }, + { /* Bookman-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 360, 420, 660, 660, 940, 800, 320, + /* 40 */ 320, 320, 460, 600, 340, 360, 340, 600, + /* 48 */ 660, 660, 660, 660, 660, 660, 660, 660, + /* 56 */ 660, 660, 340, 340, 600, 600, 600, 660, + /* 64 */ 820, 720, 720, 740, 780, 720, 680, 780, + /* 72 */ 820, 400, 640, 800, 640, 940, 740, 800, + /* 80 */ 660, 800, 780, 660, 700, 740, 720, 940, + /* 88 */ 780, 700, 640, 300, 600, 300, 600, 500, + /* 96 */ 320, 580, 600, 580, 640, 580, 380, 580, + /* 104 */ 680, 360, 340, 660, 340, 1000, 680, 620, + /* 112 */ 640, 620, 460, 520, 460, 660, 600, 800, + /* 120 */ 600, 620, 560, 320, 600, 320, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1360, 460, + /* 144 */ 320, 320, 220, 220, 540, 540, 540, 500, + /* 152 */ 1000, 600, 1220, 940, 440, 380, 740, 740, + /* 160 */ 340, 360, 660, 660, 660, 660, 600, 600, + /* 168 */ 500, 740, 400, 400, 600, 360, 740, 460, + /* 176 */ 400, 600, 396, 396, 400, 660, 800, 340, + /* 184 */ 360, 396, 400, 400, 990, 990, 990, 660, + /* 192 */ 720, 720, 720, 720, 720, 720, 1140, 740, + /* 200 */ 720, 720, 720, 720, 400, 400, 400, 400, + /* 208 */ 780, 740, 800, 800, 800, 800, 800, 600, + /* 216 */ 800, 740, 740, 740, 740, 700, 660, 660, + /* 224 */ 580, 580, 580, 580, 580, 580, 880, 580, + /* 232 */ 580, 580, 580, 580, 360, 360, 360, 360, + /* 240 */ 620, 680, 620, 620, 620, 620, 620, 600, + /* 248 */ 620, 660, 660, 660, 660, 620, 640, 620, + }, + { /* Bookman-LightItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 300, 320, 360, 620, 620, 800, 820, 280, + /* 40 */ 280, 280, 440, 600, 300, 320, 300, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 300, 300, 600, 600, 600, 540, + /* 64 */ 780, 700, 720, 720, 740, 680, 620, 760, + /* 72 */ 800, 320, 560, 720, 580, 860, 720, 760, + /* 80 */ 600, 780, 700, 640, 600, 720, 680, 960, + /* 88 */ 700, 660, 580, 260, 600, 260, 600, 500, + /* 96 */ 280, 620, 600, 480, 640, 540, 340, 560, + /* 104 */ 620, 280, 280, 600, 280, 880, 620, 540, + /* 112 */ 600, 560, 400, 540, 340, 620, 540, 880, + /* 120 */ 540, 600, 520, 360, 600, 380, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 980, 1180, 460, + /* 144 */ 280, 280, 180, 180, 440, 440, 480, 500, + /* 152 */ 1000, 600, 1180, 900, 620, 620, 640, 660, + /* 160 */ 300, 320, 620, 620, 620, 620, 600, 620, + /* 168 */ 420, 740, 440, 300, 600, 320, 740, 440, + /* 176 */ 400, 600, 372, 372, 320, 620, 620, 300, + /* 184 */ 320, 372, 400, 300, 930, 930, 930, 540, + /* 192 */ 700, 700, 700, 700, 700, 700, 1220, 720, + /* 200 */ 680, 680, 680, 680, 320, 320, 320, 320, + /* 208 */ 740, 720, 760, 760, 760, 760, 760, 600, + /* 216 */ 760, 720, 720, 720, 720, 660, 600, 620, + /* 224 */ 620, 620, 620, 620, 620, 620, 880, 480, + /* 232 */ 540, 540, 540, 540, 280, 280, 280, 280, + /* 240 */ 540, 620, 540, 540, 540, 540, 540, 600, + /* 248 */ 540, 620, 620, 620, 620, 600, 600, 600, + }, + { /* Bookman-DemiItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 320, 380, 680, 680, 880, 980, 320, + /* 40 */ 260, 260, 460, 600, 340, 280, 340, 360, + /* 48 */ 680, 680, 680, 680, 680, 680, 680, 680, + /* 56 */ 680, 680, 340, 340, 620, 600, 620, 620, + /* 64 */ 780, 720, 720, 700, 760, 720, 660, 760, + /* 72 */ 800, 380, 620, 780, 640, 860, 740, 760, + /* 80 */ 640, 760, 740, 700, 700, 740, 660, 1000, + /* 88 */ 740, 660, 680, 260, 580, 260, 620, 500, + /* 96 */ 320, 680, 600, 560, 680, 560, 420, 620, + /* 104 */ 700, 380, 320, 700, 380, 960, 680, 600, + /* 112 */ 660, 620, 500, 540, 440, 680, 540, 860, + /* 120 */ 620, 600, 560, 300, 620, 300, 620, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 940, 1360, 360, + /* 144 */ 320, 320, 220, 220, 520, 520, 520, 500, + /* 152 */ 1000, 600, 1180, 920, 420, 420, 820, 820, + /* 160 */ 340, 320, 680, 680, 680, 680, 620, 620, + /* 168 */ 520, 780, 440, 380, 620, 280, 780, 480, + /* 176 */ 400, 600, 408, 408, 340, 680, 680, 340, + /* 184 */ 360, 408, 440, 380, 1020, 1020, 1020, 620, + /* 192 */ 720, 720, 720, 720, 720, 720, 1140, 700, + /* 200 */ 720, 720, 720, 720, 380, 380, 380, 380, + /* 208 */ 760, 740, 760, 760, 760, 760, 760, 600, + /* 216 */ 760, 740, 740, 740, 740, 660, 640, 660, + /* 224 */ 680, 680, 680, 680, 680, 680, 880, 560, + /* 232 */ 560, 560, 560, 560, 380, 380, 380, 380, + /* 240 */ 600, 680, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 680, 680, 680, 680, 600, 660, 600, + }, + { /* AvantGarde-Book */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 351, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 351, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1174, 606, + /* 144 */ 351, 351, 251, 251, 502, 484, 502, 500, + /* 152 */ 1000, 606, 1194, 1137, 553, 553, 487, 485, + /* 160 */ 277, 295, 554, 554, 554, 554, 672, 615, + /* 168 */ 369, 747, 369, 425, 606, 332, 747, 485, + /* 176 */ 400, 606, 332, 332, 375, 608, 564, 277, + /* 184 */ 324, 332, 369, 425, 831, 831, 831, 591, + /* 192 */ 740, 740, 740, 740, 740, 740, 992, 813, + /* 200 */ 536, 536, 536, 536, 226, 226, 226, 226, + /* 208 */ 790, 740, 869, 869, 869, 869, 869, 606, + /* 216 */ 868, 655, 655, 655, 655, 592, 592, 554, + /* 224 */ 683, 683, 683, 683, 683, 683, 1157, 647, + /* 232 */ 650, 650, 650, 650, 200, 200, 200, 200, + /* 240 */ 655, 610, 655, 655, 655, 655, 655, 606, + /* 248 */ 653, 608, 608, 608, 608, 536, 682, 536, + }, + { /* AvantGarde-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 280, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 280, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1280, 600, + /* 144 */ 280, 280, 240, 240, 480, 480, 480, 500, + /* 152 */ 1000, 600, 1060, 1080, 560, 560, 520, 520, + /* 160 */ 280, 280, 560, 560, 560, 560, 600, 560, + /* 168 */ 500, 740, 360, 460, 600, 420, 740, 420, + /* 176 */ 400, 600, 336, 336, 420, 576, 600, 280, + /* 184 */ 340, 336, 360, 460, 840, 840, 840, 560, + /* 192 */ 740, 740, 740, 740, 740, 740, 900, 780, + /* 200 */ 520, 520, 520, 520, 280, 280, 280, 280, + /* 208 */ 742, 740, 840, 840, 840, 840, 840, 600, + /* 216 */ 840, 640, 640, 640, 640, 620, 560, 600, + /* 224 */ 660, 660, 660, 660, 660, 660, 1080, 640, + /* 232 */ 640, 640, 640, 640, 240, 240, 240, 240, + /* 240 */ 640, 600, 640, 640, 640, 640, 640, 600, + /* 248 */ 660, 600, 600, 600, 600, 580, 660, 580, + }, + { /* AvantGarde-BookOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 351, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 351, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1174, 606, + /* 144 */ 351, 351, 251, 251, 502, 484, 502, 500, + /* 152 */ 1000, 606, 1194, 1137, 553, 553, 487, 485, + /* 160 */ 277, 295, 554, 554, 554, 554, 672, 615, + /* 168 */ 369, 747, 369, 425, 606, 332, 747, 485, + /* 176 */ 400, 606, 332, 332, 375, 608, 564, 277, + /* 184 */ 324, 332, 369, 425, 831, 831, 831, 591, + /* 192 */ 740, 740, 740, 740, 740, 740, 992, 813, + /* 200 */ 536, 536, 536, 536, 226, 226, 226, 226, + /* 208 */ 790, 740, 869, 869, 869, 869, 869, 606, + /* 216 */ 868, 655, 655, 655, 655, 592, 592, 554, + /* 224 */ 683, 683, 683, 683, 683, 683, 1157, 647, + /* 232 */ 650, 650, 650, 650, 200, 200, 200, 200, + /* 240 */ 655, 610, 655, 655, 655, 655, 655, 606, + /* 248 */ 653, 608, 608, 608, 608, 536, 682, 536, + }, + { /* AvantGarde-DemiOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 280, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 280, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1280, 600, + /* 144 */ 280, 280, 240, 240, 480, 480, 480, 500, + /* 152 */ 1000, 600, 1060, 1080, 560, 560, 520, 520, + /* 160 */ 280, 280, 560, 560, 560, 560, 600, 560, + /* 168 */ 500, 740, 360, 460, 600, 420, 740, 420, + /* 176 */ 400, 600, 336, 336, 420, 576, 600, 280, + /* 184 */ 340, 336, 360, 460, 840, 840, 840, 560, + /* 192 */ 740, 740, 740, 740, 740, 740, 900, 780, + /* 200 */ 520, 520, 520, 520, 280, 280, 280, 280, + /* 208 */ 742, 740, 840, 840, 840, 840, 840, 600, + /* 216 */ 840, 640, 640, 640, 640, 620, 560, 600, + /* 224 */ 660, 660, 660, 660, 660, 660, 1080, 640, + /* 232 */ 640, 640, 640, 640, 240, 240, 240, 240, + /* 240 */ 640, 600, 640, 640, 640, 640, 640, 600, + /* 248 */ 660, 600, 600, 600, 600, 580, 660, 580, + }, + { /* NewCenturySchlbk-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 296, 389, 556, 556, 833, 815, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 737, 722, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 556, 778, 667, 944, 815, 778, + /* 80 */ 667, 778, 722, 630, 667, 815, 722, 981, + /* 88 */ 704, 704, 611, 333, 606, 333, 606, 500, + /* 96 */ 204, 556, 556, 444, 574, 500, 333, 537, + /* 104 */ 611, 315, 296, 593, 315, 889, 611, 500, + /* 112 */ 574, 556, 444, 463, 389, 611, 537, 778, + /* 120 */ 537, 537, 481, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 204, 204, 259, 259, 389, 389, 389, 556, + /* 152 */ 1000, 606, 1000, 833, 500, 500, 611, 611, + /* 160 */ 278, 296, 556, 556, 556, 556, 606, 500, + /* 168 */ 333, 737, 334, 426, 606, 333, 737, 333, + /* 176 */ 400, 606, 333, 333, 333, 611, 606, 278, + /* 184 */ 333, 333, 300, 426, 834, 834, 834, 444, + /* 192 */ 722, 722, 722, 722, 722, 722, 1000, 722, + /* 200 */ 722, 722, 722, 722, 407, 407, 407, 407, + /* 208 */ 778, 815, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 815, 815, 815, 815, 704, 667, 574, + /* 224 */ 556, 556, 556, 556, 556, 556, 796, 444, + /* 232 */ 500, 500, 500, 500, 315, 315, 315, 315, + /* 240 */ 500, 611, 500, 500, 500, 500, 500, 606, + /* 248 */ 500, 611, 611, 611, 611, 537, 574, 537, + }, + { /* NewCenturySchlbk-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 296, 333, 574, 574, 833, 852, 241, + /* 40 */ 389, 389, 500, 606, 278, 333, 278, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 278, 278, 606, 606, 606, 500, + /* 64 */ 747, 759, 778, 778, 833, 759, 722, 833, + /* 72 */ 870, 444, 648, 815, 722, 981, 833, 833, + /* 80 */ 759, 833, 815, 667, 722, 833, 759, 981, + /* 88 */ 722, 722, 667, 389, 606, 389, 606, 500, + /* 96 */ 241, 611, 648, 556, 667, 574, 389, 611, + /* 104 */ 685, 370, 352, 667, 352, 963, 685, 611, + /* 112 */ 667, 648, 519, 500, 426, 685, 611, 889, + /* 120 */ 611, 611, 537, 389, 606, 389, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 1000, 1000, 606, + /* 144 */ 241, 241, 333, 333, 481, 481, 481, 500, + /* 152 */ 1000, 606, 1000, 907, 500, 500, 685, 685, + /* 160 */ 287, 296, 574, 574, 574, 574, 606, 500, + /* 168 */ 333, 747, 367, 500, 606, 333, 747, 333, + /* 176 */ 400, 606, 344, 344, 333, 685, 747, 278, + /* 184 */ 333, 344, 367, 500, 861, 861, 861, 500, + /* 192 */ 759, 759, 759, 759, 759, 759, 981, 778, + /* 200 */ 759, 759, 759, 759, 444, 444, 444, 444, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 833, 833, 833, 833, 722, 759, 611, + /* 224 */ 611, 611, 611, 611, 611, 611, 870, 556, + /* 232 */ 574, 574, 574, 574, 370, 370, 370, 370, + /* 240 */ 611, 685, 611, 611, 611, 611, 611, 606, + /* 248 */ 611, 685, 685, 685, 685, 611, 667, 611, + }, + { /* NewCenturySchlbk-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 400, 556, 556, 833, 852, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 606, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 747, 704, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 611, 741, 667, 944, 815, 778, + /* 80 */ 667, 778, 741, 667, 685, 815, 704, 926, + /* 88 */ 704, 685, 667, 333, 606, 333, 606, 500, + /* 96 */ 204, 574, 556, 444, 611, 444, 333, 537, + /* 104 */ 611, 333, 315, 556, 333, 889, 611, 500, + /* 112 */ 574, 556, 444, 444, 352, 611, 519, 778, + /* 120 */ 500, 500, 463, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 950, 1000, 606, + /* 144 */ 204, 204, 333, 333, 389, 389, 389, 500, + /* 152 */ 1000, 606, 981, 778, 500, 500, 611, 611, + /* 160 */ 278, 333, 556, 556, 556, 556, 606, 500, + /* 168 */ 333, 747, 422, 426, 606, 333, 747, 333, + /* 176 */ 400, 606, 333, 333, 333, 611, 650, 278, + /* 184 */ 333, 333, 372, 426, 834, 834, 834, 444, + /* 192 */ 704, 704, 704, 704, 704, 704, 870, 722, + /* 200 */ 722, 722, 722, 722, 407, 407, 407, 407, + /* 208 */ 778, 815, 778, 778, 778, 778, 778, 606, + /* 216 */ 778, 815, 815, 815, 815, 685, 667, 556, + /* 224 */ 574, 574, 574, 574, 574, 574, 722, 444, + /* 232 */ 444, 444, 444, 444, 333, 333, 333, 333, + /* 240 */ 500, 611, 500, 500, 500, 500, 500, 606, + /* 248 */ 500, 611, 611, 611, 611, 500, 574, 500, + }, + { /* NewCenturySchlbk-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 333, 400, 574, 574, 889, 889, 259, + /* 40 */ 407, 407, 500, 606, 287, 333, 287, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 287, 287, 606, 606, 606, 481, + /* 64 */ 747, 741, 759, 759, 833, 741, 704, 815, + /* 72 */ 870, 444, 667, 778, 704, 944, 852, 833, + /* 80 */ 741, 833, 796, 685, 722, 833, 741, 944, + /* 88 */ 741, 704, 704, 407, 606, 407, 606, 500, + /* 96 */ 259, 667, 611, 537, 667, 519, 389, 611, + /* 104 */ 685, 389, 370, 648, 389, 944, 685, 574, + /* 112 */ 648, 630, 519, 481, 407, 685, 556, 833, + /* 120 */ 574, 519, 519, 407, 606, 407, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 1000, 950, 1167, 606, + /* 144 */ 259, 259, 278, 278, 481, 481, 481, 500, + /* 152 */ 1000, 606, 963, 852, 500, 500, 685, 685, + /* 160 */ 287, 333, 574, 574, 574, 574, 606, 500, + /* 168 */ 333, 747, 412, 481, 606, 333, 747, 333, + /* 176 */ 400, 606, 344, 344, 333, 685, 650, 287, + /* 184 */ 333, 344, 356, 481, 861, 861, 861, 481, + /* 192 */ 741, 741, 741, 741, 741, 741, 889, 759, + /* 200 */ 741, 741, 741, 741, 444, 444, 444, 444, + /* 208 */ 833, 852, 833, 833, 833, 833, 833, 606, + /* 216 */ 833, 833, 833, 833, 833, 704, 741, 574, + /* 224 */ 667, 667, 667, 667, 667, 667, 815, 537, + /* 232 */ 519, 519, 519, 519, 389, 389, 389, 389, + /* 240 */ 574, 685, 574, 574, 574, 574, 574, 606, + /* 248 */ 574, 685, 685, 685, 685, 519, 648, 519, + }, +}; +static unsigned short ausCharacterWidths2[32][256] = { + { /* Courier */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Courier-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 40 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 48 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 56 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 64 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 72 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 80 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 88 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 96 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 104 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 112 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 120 */ 600, 600, 600, 600, 600, 600, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 168 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 176 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 184 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 192 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 200 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 208 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 216 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 224 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 232 */ 600, 600, 600, 600, 600, 600, 600, 740, + /* 240 */ 600, 600, 600, 600, 600, 600, 600, 600, + /* 248 */ 600, 600, 600, 600, 600, 600, 600, 600, + }, + { /* Times-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 408, 500, 500, 833, 778, 180, + /* 40 */ 333, 333, 500, 564, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 278, 278, 564, 564, 564, 444, + /* 64 */ 921, 722, 667, 667, 722, 611, 556, 722, + /* 72 */ 722, 333, 389, 722, 611, 889, 722, 722, + /* 80 */ 556, 722, 667, 556, 611, 722, 722, 944, + /* 88 */ 722, 722, 611, 333, 278, 333, 469, 500, + /* 96 */ 333, 444, 500, 444, 500, 444, 333, 500, + /* 104 */ 500, 278, 278, 500, 278, 778, 500, 500, + /* 112 */ 500, 500, 333, 389, 278, 500, 500, 722, + /* 120 */ 500, 500, 444, 480, 200, 480, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 611, 500, 611, 556, 500, + /* 168 */ 333, 556, 556, 611, 611, 333, 611, 611, + /* 176 */ 333, 444, 333, 278, 333, 348, 389, 333, + /* 184 */ 333, 389, 389, 278, 444, 333, 444, 444, + /* 192 */ 667, 722, 722, 722, 722, 611, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 722, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 564, + /* 216 */ 667, 722, 722, 722, 722, 722, 611, 500, + /* 224 */ 333, 444, 444, 444, 444, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 600, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 564, + /* 248 */ 333, 500, 500, 500, 500, 500, 278, 333, + }, + { /* Times-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 555, 500, 500, 1000, 833, 278, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 930, 722, 667, 722, 722, 667, 611, 778, + /* 72 */ 778, 389, 500, 778, 667, 944, 722, 778, + /* 80 */ 611, 778, 722, 556, 667, 722, 722, 1000, + /* 88 */ 722, 722, 667, 333, 278, 333, 581, 500, + /* 96 */ 333, 500, 556, 444, 556, 444, 333, 500, + /* 104 */ 556, 278, 333, 556, 278, 833, 556, 500, + /* 112 */ 556, 556, 444, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 394, 220, 394, 520, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 667, 500, 667, 556, 500, + /* 168 */ 333, 556, 556, 667, 667, 333, 667, 667, + /* 176 */ 333, 500, 333, 278, 333, 396, 389, 333, + /* 184 */ 333, 389, 389, 400, 444, 333, 444, 444, + /* 192 */ 722, 722, 722, 722, 722, 667, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 389, 389, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 570, + /* 216 */ 722, 722, 722, 722, 722, 722, 667, 556, + /* 224 */ 444, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 665, + /* 240 */ 556, 556, 556, 500, 500, 500, 500, 570, + /* 248 */ 444, 556, 556, 556, 556, 500, 333, 333, + }, + { /* Times-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 420, 500, 500, 833, 778, 214, + /* 40 */ 333, 333, 500, 675, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 675, 675, 675, 500, + /* 64 */ 920, 611, 611, 667, 722, 611, 611, 722, + /* 72 */ 722, 333, 444, 667, 556, 833, 667, 722, + /* 80 */ 611, 722, 611, 500, 556, 722, 611, 833, + /* 88 */ 611, 556, 556, 389, 278, 389, 422, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 722, 500, 500, + /* 112 */ 500, 500, 389, 389, 278, 500, 444, 667, + /* 120 */ 444, 444, 389, 400, 275, 400, 541, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 611, 333, 556, 500, 556, 500, 500, + /* 168 */ 333, 500, 500, 556, 556, 333, 556, 556, + /* 176 */ 333, 500, 333, 278, 333, 278, 389, 333, + /* 184 */ 333, 389, 389, 278, 389, 333, 389, 389, + /* 192 */ 611, 611, 611, 611, 611, 556, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 722, + /* 208 */ 722, 667, 667, 722, 722, 722, 722, 675, + /* 216 */ 611, 722, 722, 722, 722, 556, 556, 500, + /* 224 */ 389, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 521, + /* 240 */ 500, 500, 500, 500, 500, 500, 500, 675, + /* 248 */ 389, 500, 500, 500, 500, 444, 278, 333, + }, + { /* Times-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 389, 555, 500, 500, 833, 778, 278, + /* 40 */ 333, 333, 500, 570, 250, 333, 250, 278, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 333, 333, 570, 570, 570, 500, + /* 64 */ 832, 667, 667, 667, 722, 667, 667, 722, + /* 72 */ 778, 389, 500, 667, 611, 889, 722, 722, + /* 80 */ 611, 722, 667, 556, 611, 722, 667, 889, + /* 88 */ 667, 611, 611, 333, 278, 333, 570, 500, + /* 96 */ 333, 500, 500, 444, 500, 444, 333, 500, + /* 104 */ 556, 278, 278, 500, 278, 778, 556, 500, + /* 112 */ 500, 500, 389, 389, 278, 556, 444, 667, + /* 120 */ 500, 444, 389, 348, 220, 348, 570, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 667, 333, 611, 500, 611, 556, 500, + /* 168 */ 333, 556, 556, 611, 611, 333, 611, 611, + /* 176 */ 333, 500, 333, 278, 333, 382, 389, 333, + /* 184 */ 333, 389, 389, 345, 389, 333, 389, 389, + /* 192 */ 667, 667, 667, 667, 667, 611, 667, 667, + /* 200 */ 667, 667, 667, 667, 667, 389, 389, 722, + /* 208 */ 722, 722, 722, 722, 722, 722, 722, 570, + /* 216 */ 667, 722, 722, 722, 722, 611, 611, 500, + /* 224 */ 389, 500, 500, 500, 500, 278, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 278, 278, 600, + /* 240 */ 500, 556, 556, 500, 500, 500, 500, 570, + /* 248 */ 389, 556, 556, 556, 556, 444, 278, 333, + }, + { /* Helvetica */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 191, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 333, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 667, 333, 556, 556, 556, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 222, 333, 292, 500, 333, + /* 184 */ 333, 500, 500, 308, 500, 333, 500, 500, + /* 192 */ 722, 667, 667, 667, 667, 556, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 666, 611, 611, + /* 224 */ 333, 556, 556, 556, 556, 222, 500, 500, + /* 232 */ 500, 556, 556, 556, 556, 278, 278, 635, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 333, 556, 556, 556, 556, 500, 278, 333, + }, + { /* Helvetica-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 238, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 333, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 611, 556, 611, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 278, 333, 369, 556, 333, + /* 184 */ 333, 556, 556, 385, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 389, 556, 556, 556, 556, 278, 556, 556, + /* 232 */ 556, 556, 556, 556, 556, 278, 278, 707, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Helvetica-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 278, 355, 556, 556, 889, 667, 191, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 584, 584, 584, 556, + /* 64 */ 1015, 667, 667, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 500, 667, 556, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 278, 278, 278, 469, 556, + /* 96 */ 333, 556, 556, 500, 556, 556, 278, 556, + /* 104 */ 556, 222, 222, 500, 222, 833, 556, 556, + /* 112 */ 556, 556, 333, 500, 278, 556, 500, 722, + /* 120 */ 500, 500, 500, 334, 260, 334, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 667, 333, 556, 556, 556, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 222, 333, 307, 500, 333, + /* 184 */ 333, 500, 500, 319, 500, 333, 500, 500, + /* 192 */ 722, 667, 667, 667, 667, 556, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 333, 556, 556, 556, 556, 222, 500, 500, + /* 232 */ 500, 556, 556, 556, 556, 278, 278, 650, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 584, + /* 248 */ 333, 556, 556, 556, 556, 500, 278, 333, + }, + { /* Helvetica-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 474, 556, 556, 889, 722, 238, + /* 40 */ 333, 333, 389, 584, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 333, 333, 584, 584, 584, 611, + /* 64 */ 975, 722, 722, 722, 722, 667, 611, 778, + /* 72 */ 722, 278, 556, 722, 611, 833, 722, 778, + /* 80 */ 667, 778, 722, 667, 611, 722, 667, 944, + /* 88 */ 667, 667, 611, 333, 278, 333, 584, 556, + /* 96 */ 333, 556, 611, 556, 611, 556, 333, 611, + /* 104 */ 611, 278, 278, 556, 278, 889, 611, 611, + /* 112 */ 611, 611, 389, 556, 333, 611, 556, 778, + /* 120 */ 556, 556, 500, 389, 280, 389, 584, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 611, 556, 611, 667, 556, + /* 168 */ 333, 667, 667, 611, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 278, 333, 384, 556, 333, + /* 184 */ 333, 556, 556, 404, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 722, 722, + /* 200 */ 722, 667, 667, 667, 667, 278, 278, 722, + /* 208 */ 722, 722, 722, 778, 778, 778, 778, 584, + /* 216 */ 722, 722, 722, 722, 722, 667, 611, 611, + /* 224 */ 389, 556, 556, 556, 556, 278, 556, 556, + /* 232 */ 556, 556, 556, 556, 556, 278, 278, 722, + /* 240 */ 611, 611, 611, 611, 611, 611, 611, 584, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Palatino-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 371, 500, 500, 840, 778, 208, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 606, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 611, 709, 774, 611, 556, 763, + /* 72 */ 832, 337, 333, 726, 611, 946, 831, 786, + /* 80 */ 604, 786, 668, 525, 613, 778, 722, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 500, 553, 444, 611, 479, 333, 556, + /* 104 */ 582, 291, 234, 556, 291, 883, 582, 546, + /* 112 */ 601, 560, 395, 424, 326, 603, 565, 834, + /* 120 */ 516, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 778, 333, 611, 500, 611, 525, 500, + /* 168 */ 333, 525, 525, 613, 667, 333, 667, 667, + /* 176 */ 333, 500, 313, 291, 333, 375, 424, 333, + /* 184 */ 333, 424, 424, 375, 500, 380, 500, 500, + /* 192 */ 668, 778, 778, 778, 778, 611, 709, 709, + /* 200 */ 709, 611, 611, 611, 611, 337, 337, 774, + /* 208 */ 774, 831, 831, 786, 786, 786, 786, 606, + /* 216 */ 668, 778, 778, 778, 778, 667, 613, 556, + /* 224 */ 395, 500, 500, 500, 500, 291, 444, 444, + /* 232 */ 444, 479, 479, 479, 479, 287, 287, 671, + /* 240 */ 611, 582, 582, 546, 546, 546, 546, 606, + /* 248 */ 395, 603, 603, 603, 603, 556, 326, 250, + }, + { /* Palatino-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 278, 402, 500, 500, 889, 833, 227, + /* 40 */ 333, 333, 444, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 747, 778, 667, 722, 833, 611, 556, 833, + /* 72 */ 833, 389, 389, 778, 611, 1000, 833, 833, + /* 80 */ 611, 833, 722, 611, 667, 778, 778, 1000, + /* 88 */ 667, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 500, 611, 444, 611, 500, 389, 556, + /* 104 */ 611, 333, 333, 611, 333, 889, 611, 556, + /* 112 */ 611, 611, 389, 444, 333, 611, 556, 833, + /* 120 */ 500, 556, 500, 310, 606, 310, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 778, 333, 611, 500, 611, 611, 500, + /* 168 */ 333, 611, 611, 667, 667, 333, 667, 667, + /* 176 */ 333, 500, 333, 333, 333, 433, 444, 333, + /* 184 */ 333, 444, 444, 402, 500, 333, 500, 500, + /* 192 */ 722, 778, 778, 778, 778, 611, 722, 722, + /* 200 */ 722, 611, 611, 611, 611, 389, 389, 833, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 722, 778, 778, 778, 778, 667, 667, 611, + /* 224 */ 389, 500, 500, 500, 500, 333, 444, 444, + /* 232 */ 444, 500, 500, 500, 500, 333, 333, 711, + /* 240 */ 611, 611, 611, 556, 556, 556, 556, 606, + /* 248 */ 389, 611, 611, 611, 611, 556, 333, 333, + }, + { /* Palatino-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 778, 333, + /* 40 */ 333, 333, 389, 606, 250, 333, 250, 296, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 500, + /* 64 */ 747, 722, 611, 667, 778, 611, 556, 722, + /* 72 */ 778, 333, 333, 667, 556, 944, 778, 778, + /* 80 */ 611, 778, 667, 556, 611, 778, 722, 944, + /* 88 */ 722, 667, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 444, 463, 407, 500, 389, 278, 500, + /* 104 */ 500, 278, 278, 444, 278, 778, 556, 444, + /* 112 */ 500, 463, 389, 389, 333, 556, 500, 722, + /* 120 */ 500, 500, 444, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 556, 500, 556, 556, 500, + /* 168 */ 333, 556, 556, 611, 667, 333, 667, 667, + /* 176 */ 333, 444, 333, 278, 333, 346, 389, 333, + /* 184 */ 333, 389, 389, 361, 444, 333, 444, 444, + /* 192 */ 667, 722, 722, 722, 722, 556, 667, 667, + /* 200 */ 667, 611, 611, 611, 611, 333, 333, 778, + /* 208 */ 778, 778, 778, 778, 778, 778, 778, 606, + /* 216 */ 667, 778, 778, 778, 778, 667, 611, 500, + /* 224 */ 389, 444, 444, 444, 444, 278, 407, 407, + /* 232 */ 407, 389, 389, 389, 389, 278, 278, 577, + /* 240 */ 500, 556, 556, 444, 444, 444, 444, 606, + /* 248 */ 389, 556, 556, 556, 556, 500, 333, 333, + }, + { /* Palatino-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 250, 333, 500, 500, 500, 889, 833, 250, + /* 40 */ 333, 333, 444, 606, 250, 389, 250, 315, + /* 48 */ 500, 500, 500, 500, 500, 500, 500, 500, + /* 56 */ 500, 500, 250, 250, 606, 606, 606, 444, + /* 64 */ 833, 722, 667, 685, 778, 611, 556, 778, + /* 72 */ 778, 389, 389, 722, 611, 944, 778, 833, + /* 80 */ 667, 833, 722, 556, 611, 778, 667, 1000, + /* 88 */ 722, 611, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 556, 537, 444, 556, 444, 333, 500, + /* 104 */ 556, 333, 333, 556, 333, 833, 556, 556, + /* 112 */ 556, 537, 389, 444, 389, 556, 556, 833, + /* 120 */ 500, 556, 500, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 250, 722, 333, 611, 500, 611, 556, 556, + /* 168 */ 333, 556, 556, 611, 667, 389, 667, 667, + /* 176 */ 556, 556, 333, 333, 333, 429, 444, 333, + /* 184 */ 333, 444, 444, 389, 500, 333, 500, 500, + /* 192 */ 722, 722, 722, 722, 722, 611, 685, 685, + /* 200 */ 685, 611, 611, 611, 611, 389, 389, 778, + /* 208 */ 778, 778, 778, 833, 833, 833, 833, 606, + /* 216 */ 722, 778, 778, 778, 778, 611, 611, 556, + /* 224 */ 389, 556, 556, 556, 556, 333, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 333, 333, 667, + /* 240 */ 556, 556, 556, 556, 556, 556, 556, 606, + /* 248 */ 389, 556, 556, 556, 556, 556, 389, 333, + }, + { /* Helvetica-Narrow */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 157, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 273, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 547, 273, 456, 456, 456, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 182, 273, 212, 410, 273, + /* 184 */ 273, 410, 410, 248, 410, 273, 410, 410, + /* 192 */ 592, 547, 547, 547, 547, 456, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 273, 456, 456, 456, 456, 182, 410, 410, + /* 232 */ 410, 456, 456, 456, 456, 228, 228, 496, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 273, 456, 456, 456, 456, 410, 228, 273, + }, + { /* Helvetica-Narrow-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 195, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 273, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 592, 273, 501, 456, 501, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 228, 273, 280, 456, 273, + /* 184 */ 273, 456, 456, 338, 410, 273, 410, 410, + /* 192 */ 592, 592, 592, 592, 592, 501, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 319, 456, 456, 456, 456, 228, 456, 456, + /* 232 */ 456, 456, 456, 456, 456, 228, 228, 561, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 319, 501, 501, 501, 501, 456, 273, 273, + }, + { /* Helvetica-Narrow-Oblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 228, 291, 456, 456, 729, 547, 157, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 228, 228, 479, 479, 479, 456, + /* 64 */ 832, 547, 547, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 410, 547, 456, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 228, 228, 228, 385, 456, + /* 96 */ 273, 456, 456, 410, 456, 456, 228, 456, + /* 104 */ 456, 182, 182, 410, 182, 683, 456, 456, + /* 112 */ 456, 456, 273, 410, 228, 456, 410, 592, + /* 120 */ 410, 410, 410, 274, 213, 274, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 547, 273, 456, 456, 456, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 182, 273, 217, 410, 273, + /* 184 */ 273, 410, 410, 254, 410, 273, 410, 410, + /* 192 */ 592, 547, 547, 547, 547, 456, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 273, 456, 456, 456, 456, 182, 410, 410, + /* 232 */ 410, 456, 456, 456, 456, 228, 228, 503, + /* 240 */ 456, 456, 456, 456, 456, 456, 456, 479, + /* 248 */ 273, 456, 456, 456, 456, 410, 228, 273, + }, + { /* Helvetica-Narrow-BoldOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 228, 273, 389, 456, 456, 729, 592, 195, + /* 40 */ 273, 273, 319, 479, 228, 273, 228, 228, + /* 48 */ 456, 456, 456, 456, 456, 456, 456, 456, + /* 56 */ 456, 456, 273, 273, 479, 479, 479, 501, + /* 64 */ 800, 592, 592, 592, 592, 547, 501, 638, + /* 72 */ 592, 228, 456, 592, 501, 683, 592, 638, + /* 80 */ 547, 638, 592, 547, 501, 592, 547, 774, + /* 88 */ 547, 547, 501, 273, 228, 273, 479, 456, + /* 96 */ 273, 456, 501, 456, 501, 456, 273, 501, + /* 104 */ 501, 228, 228, 456, 228, 729, 501, 501, + /* 112 */ 501, 501, 319, 456, 273, 501, 456, 638, + /* 120 */ 456, 456, 410, 319, 230, 319, 479, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 228, 592, 273, 501, 456, 501, 547, 456, + /* 168 */ 273, 547, 547, 501, 501, 273, 501, 501, + /* 176 */ 273, 456, 273, 228, 273, 283, 456, 273, + /* 184 */ 273, 456, 456, 312, 410, 273, 410, 410, + /* 192 */ 592, 592, 592, 592, 592, 501, 592, 592, + /* 200 */ 592, 547, 547, 547, 547, 228, 228, 592, + /* 208 */ 592, 592, 592, 638, 638, 638, 638, 479, + /* 216 */ 592, 592, 592, 592, 592, 547, 501, 501, + /* 224 */ 319, 456, 456, 456, 456, 228, 456, 456, + /* 232 */ 456, 456, 456, 456, 456, 228, 228, 561, + /* 240 */ 501, 501, 501, 501, 501, 501, 501, 479, + /* 248 */ 319, 501, 501, 501, 501, 456, 273, 273, + }, + { /* Bookman-Light */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 320, 300, 380, 620, 620, 900, 800, 220, + /* 40 */ 300, 300, 440, 600, 320, 400, 320, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 320, 320, 600, 600, 600, 540, + /* 64 */ 820, 680, 740, 740, 800, 720, 640, 800, + /* 72 */ 800, 340, 600, 720, 600, 920, 740, 800, + /* 80 */ 620, 820, 720, 660, 620, 780, 700, 960, + /* 88 */ 720, 640, 640, 300, 600, 300, 600, 500, + /* 96 */ 340, 580, 620, 520, 620, 520, 320, 540, + /* 104 */ 660, 300, 300, 620, 300, 940, 660, 560, + /* 112 */ 620, 580, 440, 520, 380, 680, 520, 780, + /* 120 */ 560, 540, 480, 280, 600, 280, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 320, 680, 460, 600, 620, 600, 660, 520, + /* 168 */ 420, 660, 660, 620, 640, 400, 640, 640, + /* 176 */ 320, 580, 320, 320, 340, 336, 520, 420, + /* 184 */ 320, 520, 520, 380, 480, 380, 480, 480, + /* 192 */ 720, 680, 680, 680, 680, 600, 740, 740, + /* 200 */ 740, 720, 720, 720, 720, 340, 340, 800, + /* 208 */ 800, 740, 740, 800, 800, 800, 800, 600, + /* 216 */ 720, 780, 780, 780, 780, 640, 620, 660, + /* 224 */ 440, 580, 580, 580, 580, 300, 520, 520, + /* 232 */ 520, 520, 520, 520, 520, 300, 300, 620, + /* 240 */ 620, 660, 660, 560, 560, 560, 560, 600, + /* 248 */ 440, 680, 680, 680, 680, 540, 380, 260, + }, + { /* Bookman-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 360, 420, 660, 660, 940, 800, 240, + /* 40 */ 320, 320, 460, 600, 340, 360, 340, 600, + /* 48 */ 660, 660, 660, 660, 660, 660, 660, 660, + /* 56 */ 660, 660, 340, 340, 600, 600, 600, 660, + /* 64 */ 820, 720, 720, 740, 780, 720, 680, 780, + /* 72 */ 820, 400, 640, 800, 640, 940, 740, 800, + /* 80 */ 660, 800, 780, 660, 700, 740, 720, 940, + /* 88 */ 780, 700, 640, 300, 600, 300, 600, 500, + /* 96 */ 400, 580, 600, 580, 640, 580, 380, 580, + /* 104 */ 680, 360, 340, 660, 340, 1000, 680, 620, + /* 112 */ 640, 620, 460, 520, 460, 660, 600, 800, + /* 120 */ 600, 620, 560, 320, 600, 320, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 340, 720, 500, 640, 660, 640, 660, 600, + /* 168 */ 500, 660, 660, 700, 640, 360, 640, 640, + /* 176 */ 340, 580, 320, 340, 400, 430, 520, 500, + /* 184 */ 360, 520, 520, 470, 560, 440, 560, 560, + /* 192 */ 780, 720, 720, 720, 720, 640, 740, 740, + /* 200 */ 740, 720, 720, 720, 720, 400, 400, 780, + /* 208 */ 780, 740, 740, 800, 800, 800, 800, 600, + /* 216 */ 780, 740, 740, 740, 740, 700, 700, 660, + /* 224 */ 460, 580, 580, 580, 580, 340, 580, 580, + /* 232 */ 580, 580, 580, 580, 580, 360, 360, 720, + /* 240 */ 640, 680, 680, 620, 620, 620, 620, 600, + /* 248 */ 460, 660, 660, 660, 660, 620, 460, 320, + }, + { /* Bookman-LightItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 300, 320, 360, 620, 620, 800, 820, 200, + /* 40 */ 280, 280, 440, 600, 300, 320, 300, 600, + /* 48 */ 620, 620, 620, 620, 620, 620, 620, 620, + /* 56 */ 620, 620, 300, 300, 600, 600, 600, 540, + /* 64 */ 780, 700, 720, 720, 740, 680, 620, 760, + /* 72 */ 800, 320, 560, 720, 580, 860, 720, 760, + /* 80 */ 600, 780, 700, 640, 600, 720, 680, 960, + /* 88 */ 700, 660, 580, 260, 600, 260, 600, 500, + /* 96 */ 340, 620, 600, 480, 640, 540, 340, 560, + /* 104 */ 620, 280, 280, 600, 280, 880, 620, 540, + /* 112 */ 600, 560, 400, 540, 340, 620, 540, 880, + /* 120 */ 540, 600, 520, 360, 600, 380, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 300, 700, 440, 580, 620, 580, 640, 620, + /* 168 */ 420, 640, 640, 600, 580, 320, 580, 580, + /* 176 */ 300, 620, 260, 340, 320, 380, 540, 440, + /* 184 */ 320, 540, 540, 340, 520, 340, 520, 520, + /* 192 */ 700, 700, 700, 700, 700, 580, 720, 720, + /* 200 */ 720, 680, 680, 680, 680, 320, 320, 740, + /* 208 */ 740, 720, 720, 760, 760, 760, 760, 600, + /* 216 */ 700, 720, 720, 720, 720, 660, 600, 620, + /* 224 */ 400, 620, 620, 620, 620, 280, 480, 480, + /* 232 */ 480, 540, 540, 540, 540, 280, 280, 730, + /* 240 */ 640, 620, 620, 540, 540, 540, 540, 600, + /* 248 */ 400, 620, 620, 620, 620, 600, 340, 260, + }, + { /* Bookman-DemiItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 340, 320, 380, 680, 680, 880, 980, 180, + /* 40 */ 260, 260, 460, 600, 340, 280, 340, 360, + /* 48 */ 680, 680, 680, 680, 680, 680, 680, 680, + /* 56 */ 680, 680, 340, 340, 620, 600, 620, 620, + /* 64 */ 780, 720, 720, 700, 760, 720, 660, 760, + /* 72 */ 800, 380, 620, 780, 640, 860, 740, 760, + /* 80 */ 640, 760, 740, 700, 700, 740, 660, 1000, + /* 88 */ 740, 660, 680, 260, 580, 260, 620, 500, + /* 96 */ 380, 680, 600, 560, 680, 560, 420, 620, + /* 104 */ 700, 380, 320, 700, 380, 960, 680, 600, + /* 112 */ 660, 620, 500, 540, 440, 680, 540, 860, + /* 120 */ 620, 600, 560, 300, 620, 300, 620, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 340, 720, 460, 640, 680, 640, 700, 620, + /* 168 */ 520, 700, 700, 700, 680, 280, 680, 680, + /* 176 */ 360, 680, 320, 380, 340, 509, 540, 480, + /* 184 */ 360, 540, 540, 520, 560, 560, 560, 560, + /* 192 */ 740, 720, 720, 720, 720, 640, 700, 700, + /* 200 */ 700, 720, 720, 720, 720, 380, 380, 760, + /* 208 */ 760, 740, 740, 760, 760, 760, 760, 600, + /* 216 */ 740, 740, 740, 740, 740, 660, 700, 660, + /* 224 */ 500, 680, 680, 680, 680, 380, 560, 560, + /* 232 */ 560, 560, 560, 560, 560, 380, 380, 810, + /* 240 */ 680, 680, 680, 600, 600, 600, 600, 600, + /* 248 */ 500, 680, 680, 680, 680, 600, 440, 380, + }, + { /* AvantGarde-Book */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 198, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 378, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 277, 740, 453, 517, 554, 462, 498, 615, + /* 168 */ 369, 498, 498, 426, 480, 332, 480, 480, + /* 176 */ 332, 683, 302, 300, 375, 245, 388, 502, + /* 184 */ 324, 388, 388, 339, 425, 552, 425, 425, + /* 192 */ 607, 740, 740, 740, 740, 462, 813, 813, + /* 200 */ 813, 536, 536, 536, 536, 226, 226, 744, + /* 208 */ 790, 740, 740, 869, 869, 869, 869, 606, + /* 216 */ 607, 655, 655, 655, 655, 592, 426, 554, + /* 224 */ 301, 683, 683, 683, 683, 200, 647, 647, + /* 232 */ 647, 650, 650, 650, 650, 200, 200, 725, + /* 240 */ 685, 610, 610, 655, 655, 655, 655, 606, + /* 248 */ 301, 608, 608, 608, 608, 536, 339, 222, + }, + { /* AvantGarde-Demi */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 220, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 420, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 280, 740, 480, 480, 560, 440, 520, 560, + /* 168 */ 500, 520, 520, 420, 500, 420, 500, 500, + /* 176 */ 360, 660, 340, 320, 420, 330, 440, 540, + /* 184 */ 340, 440, 440, 369, 460, 700, 460, 460, + /* 192 */ 580, 740, 740, 740, 740, 440, 780, 780, + /* 200 */ 780, 520, 520, 520, 520, 280, 280, 700, + /* 208 */ 742, 740, 740, 840, 840, 840, 840, 600, + /* 216 */ 580, 640, 640, 640, 640, 620, 420, 600, + /* 224 */ 320, 660, 660, 660, 660, 240, 640, 640, + /* 232 */ 640, 640, 640, 640, 640, 240, 240, 754, + /* 240 */ 660, 600, 600, 640, 640, 640, 640, 600, + /* 248 */ 320, 600, 600, 600, 600, 580, 300, 280, + }, + { /* AvantGarde-BookOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 277, 295, 309, 554, 554, 775, 757, 198, + /* 40 */ 369, 369, 425, 606, 277, 332, 277, 437, + /* 48 */ 554, 554, 554, 554, 554, 554, 554, 554, + /* 56 */ 554, 554, 277, 277, 606, 606, 606, 591, + /* 64 */ 867, 740, 574, 813, 744, 536, 485, 872, + /* 72 */ 683, 226, 482, 591, 462, 919, 740, 869, + /* 80 */ 592, 871, 607, 498, 426, 655, 702, 960, + /* 88 */ 609, 592, 480, 351, 605, 351, 606, 500, + /* 96 */ 378, 683, 682, 647, 685, 650, 314, 673, + /* 104 */ 610, 200, 203, 502, 200, 938, 610, 655, + /* 112 */ 682, 682, 301, 388, 339, 608, 554, 831, + /* 120 */ 480, 536, 425, 351, 672, 351, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 277, 740, 453, 517, 554, 462, 498, 615, + /* 168 */ 369, 498, 498, 426, 480, 332, 480, 480, + /* 176 */ 332, 683, 302, 300, 375, 231, 388, 502, + /* 184 */ 324, 388, 388, 339, 425, 552, 425, 425, + /* 192 */ 607, 740, 740, 740, 740, 462, 813, 813, + /* 200 */ 813, 536, 536, 536, 536, 226, 226, 744, + /* 208 */ 790, 740, 740, 869, 869, 869, 869, 606, + /* 216 */ 607, 655, 655, 655, 655, 592, 426, 554, + /* 224 */ 301, 683, 683, 683, 683, 200, 647, 647, + /* 232 */ 647, 650, 650, 650, 650, 200, 200, 714, + /* 240 */ 685, 610, 610, 655, 655, 655, 655, 606, + /* 248 */ 301, 608, 608, 608, 608, 536, 339, 222, + }, + { /* AvantGarde-DemiOblique */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 280, 280, 360, 560, 560, 860, 680, 220, + /* 40 */ 380, 380, 440, 600, 280, 420, 280, 460, + /* 48 */ 560, 560, 560, 560, 560, 560, 560, 560, + /* 56 */ 560, 560, 280, 280, 600, 600, 600, 560, + /* 64 */ 740, 740, 580, 780, 700, 520, 480, 840, + /* 72 */ 680, 280, 480, 620, 440, 900, 740, 840, + /* 80 */ 560, 840, 580, 520, 420, 640, 700, 900, + /* 88 */ 680, 620, 500, 320, 640, 320, 600, 500, + /* 96 */ 420, 660, 660, 640, 660, 640, 280, 660, + /* 104 */ 600, 240, 260, 580, 240, 940, 600, 640, + /* 112 */ 660, 660, 320, 440, 300, 600, 560, 800, + /* 120 */ 560, 580, 460, 340, 600, 340, 600, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 280, 740, 480, 480, 560, 440, 520, 560, + /* 168 */ 500, 520, 520, 420, 500, 420, 500, 500, + /* 176 */ 360, 660, 340, 320, 420, 326, 440, 540, + /* 184 */ 340, 440, 440, 364, 460, 700, 460, 460, + /* 192 */ 580, 740, 740, 740, 740, 440, 780, 780, + /* 200 */ 780, 520, 520, 520, 520, 280, 280, 700, + /* 208 */ 742, 740, 740, 840, 840, 840, 840, 600, + /* 216 */ 580, 640, 640, 640, 640, 620, 420, 600, + /* 224 */ 320, 660, 660, 660, 660, 240, 640, 640, + /* 232 */ 640, 640, 640, 640, 640, 240, 240, 752, + /* 240 */ 660, 600, 600, 640, 640, 640, 640, 600, + /* 248 */ 320, 600, 600, 600, 600, 580, 300, 280, + }, + { /* NewCenturySchlbk-Roman */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 296, 389, 556, 556, 833, 815, 204, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 278, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 737, 722, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 556, 778, 667, 944, 815, 778, + /* 80 */ 667, 778, 722, 630, 667, 815, 722, 981, + /* 88 */ 704, 704, 611, 333, 606, 333, 606, 500, + /* 96 */ 333, 556, 556, 444, 574, 500, 333, 537, + /* 104 */ 611, 315, 296, 593, 315, 889, 611, 500, + /* 112 */ 574, 556, 444, 463, 389, 611, 537, 778, + /* 120 */ 537, 537, 481, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 722, 333, 667, 556, 667, 630, 500, + /* 168 */ 333, 630, 630, 667, 611, 333, 611, 611, + /* 176 */ 333, 556, 333, 315, 333, 339, 463, 333, + /* 184 */ 333, 463, 463, 389, 481, 333, 481, 481, + /* 192 */ 722, 722, 722, 722, 722, 667, 722, 722, + /* 200 */ 722, 722, 722, 722, 722, 407, 407, 778, + /* 208 */ 778, 815, 815, 778, 778, 778, 778, 606, + /* 216 */ 722, 815, 815, 815, 815, 704, 667, 574, + /* 224 */ 444, 556, 556, 556, 556, 315, 444, 444, + /* 232 */ 444, 500, 500, 500, 500, 315, 315, 606, + /* 240 */ 574, 611, 611, 500, 500, 500, 500, 606, + /* 248 */ 444, 611, 611, 611, 611, 537, 389, 333, + }, + { /* NewCenturySchlbk-Bold */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 296, 333, 574, 574, 833, 852, 241, + /* 40 */ 389, 389, 500, 606, 278, 333, 278, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 278, 278, 606, 606, 606, 500, + /* 64 */ 747, 759, 778, 778, 833, 759, 722, 833, + /* 72 */ 870, 444, 648, 815, 722, 981, 833, 833, + /* 80 */ 759, 833, 815, 667, 722, 833, 759, 981, + /* 88 */ 722, 722, 667, 389, 606, 389, 606, 500, + /* 96 */ 333, 611, 648, 556, 667, 574, 389, 611, + /* 104 */ 685, 370, 352, 667, 352, 963, 685, 611, + /* 112 */ 667, 648, 519, 500, 426, 685, 611, 889, + /* 120 */ 611, 611, 537, 389, 606, 389, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 287, 759, 333, 722, 574, 722, 667, 500, + /* 168 */ 333, 667, 667, 722, 667, 333, 667, 667, + /* 176 */ 333, 611, 333, 352, 333, 436, 500, 333, + /* 184 */ 333, 500, 500, 446, 537, 333, 537, 537, + /* 192 */ 815, 759, 759, 759, 759, 722, 778, 778, + /* 200 */ 778, 759, 759, 759, 759, 444, 444, 833, + /* 208 */ 833, 833, 833, 833, 833, 833, 833, 606, + /* 216 */ 815, 833, 833, 833, 833, 722, 722, 611, + /* 224 */ 519, 611, 611, 611, 611, 352, 556, 556, + /* 232 */ 556, 574, 574, 574, 574, 370, 370, 747, + /* 240 */ 667, 685, 685, 611, 611, 611, 611, 606, + /* 248 */ 519, 685, 685, 685, 685, 611, 426, 333, + }, + { /* NewCenturySchlbk-Italic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 278, 333, 400, 556, 556, 833, 852, 278, + /* 40 */ 333, 333, 500, 606, 278, 333, 278, 606, + /* 48 */ 556, 556, 556, 556, 556, 556, 556, 556, + /* 56 */ 556, 556, 278, 278, 606, 606, 606, 444, + /* 64 */ 747, 704, 722, 722, 778, 722, 667, 778, + /* 72 */ 833, 407, 611, 741, 667, 944, 815, 778, + /* 80 */ 667, 778, 741, 667, 685, 815, 704, 926, + /* 88 */ 704, 685, 667, 333, 606, 333, 606, 500, + /* 96 */ 333, 574, 556, 444, 611, 444, 333, 537, + /* 104 */ 611, 333, 315, 556, 333, 889, 611, 500, + /* 112 */ 574, 556, 444, 444, 352, 611, 519, 778, + /* 120 */ 500, 500, 463, 333, 606, 333, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 278, 704, 333, 667, 556, 667, 667, 500, + /* 168 */ 333, 667, 667, 685, 667, 333, 667, 667, + /* 176 */ 333, 574, 333, 333, 333, 359, 444, 333, + /* 184 */ 333, 444, 444, 368, 463, 333, 463, 463, + /* 192 */ 741, 704, 704, 704, 704, 667, 722, 722, + /* 200 */ 722, 722, 722, 722, 722, 407, 407, 778, + /* 208 */ 778, 815, 815, 778, 778, 778, 778, 606, + /* 216 */ 741, 815, 815, 815, 815, 685, 685, 556, + /* 224 */ 444, 574, 574, 574, 574, 333, 444, 444, + /* 232 */ 444, 444, 444, 444, 444, 333, 333, 651, + /* 240 */ 611, 611, 611, 500, 500, 500, 500, 606, + /* 248 */ 444, 611, 611, 611, 611, 500, 352, 333, + }, + { /* NewCenturySchlbk-BoldItalic */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 287, 333, 400, 574, 574, 889, 889, 287, + /* 40 */ 407, 407, 500, 606, 287, 333, 287, 278, + /* 48 */ 574, 574, 574, 574, 574, 574, 574, 574, + /* 56 */ 574, 574, 287, 287, 606, 606, 606, 481, + /* 64 */ 747, 741, 759, 759, 833, 741, 704, 815, + /* 72 */ 870, 444, 667, 778, 704, 944, 852, 833, + /* 80 */ 741, 833, 796, 685, 722, 833, 741, 944, + /* 88 */ 741, 704, 704, 407, 606, 407, 606, 500, + /* 96 */ 333, 667, 611, 537, 667, 519, 389, 611, + /* 104 */ 685, 389, 370, 648, 389, 944, 685, 574, + /* 112 */ 648, 630, 519, 481, 407, 685, 556, 833, + /* 120 */ 574, 519, 519, 407, 606, 407, 606, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 287, 741, 333, 704, 574, 704, 685, 500, + /* 168 */ 333, 685, 685, 722, 704, 333, 704, 704, + /* 176 */ 333, 667, 333, 389, 333, 486, 481, 333, + /* 184 */ 333, 481, 481, 483, 519, 333, 519, 519, + /* 192 */ 796, 741, 741, 741, 741, 704, 759, 759, + /* 200 */ 759, 741, 741, 741, 741, 444, 444, 833, + /* 208 */ 833, 852, 852, 833, 833, 833, 833, 606, + /* 216 */ 796, 833, 833, 833, 833, 704, 722, 574, + /* 224 */ 519, 667, 667, 667, 667, 389, 537, 537, + /* 232 */ 537, 519, 519, 519, 519, 389, 389, 780, + /* 240 */ 667, 685, 685, 574, 574, 574, 574, 606, + /* 248 */ 519, 685, 685, 685, 685, 519, 407, 333, + }, +}; +#if 0 /* Until this array is needed */ +static int aiUnderlineInfo[32][2] = { + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -151, 50 }, + { -155, 69 }, + { -151, 50 }, + { -111, 69 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -100, 50 }, + { -125, 60 }, + { -125, 60 }, + { -125, 60 }, + { -125, 60 }, + { -96, 58 }, + { -93, 90 }, + { -96, 58 }, + { -93, 90 }, + { -104, 61 }, + { -103, 90 }, + { -102, 42 }, + { -102, 54 }, +}; +#endif /* 0 */ diff --git a/fontlist.c b/fontlist.c new file mode 100644 index 0000000..d55efbb --- /dev/null +++ b/fontlist.c @@ -0,0 +1,173 @@ +/* + * fontlist.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy a list of Word font information + */ + +#include +#include +#include "antiword.h" + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct font_desc_tag { + font_block_type tInfo; + struct font_desc_tag *pNext; +} font_mem_type; + +/* Variables needed to write the Font Information List */ +static font_mem_type *pAnchor = NULL; +static font_mem_type *pFontLast = NULL; + + +/* + * vDestroyFontInfoList - destroy the Font Information List + */ +void +vDestroyFontInfoList(void) +{ + font_mem_type *pCurr, *pNext; + + DBG_MSG("vDestroyFontInfoList"); + + /* Free the Font Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pFontLast = NULL; +} /* end of vDestroyFontInfoList */ + +/* + * vCorrectFontValues - correct font values to values Antiword can use + */ +void +vCorrectFontValues(font_block_type *pFontBlock) +{ + UINT uiRealSize; + USHORT usRealStyle; + + uiRealSize = pFontBlock->usFontSize; + usRealStyle = pFontBlock->usFontStyle; + if (bIsSmallCapitals(pFontBlock->usFontStyle)) { + /* Small capitals become normal capitals in a smaller font */ + uiRealSize = (uiRealSize * 4 + 2) / 5; + usRealStyle &= ~FONT_SMALL_CAPITALS; + usRealStyle |= FONT_CAPITALS; + } + if (bIsSuperscript(pFontBlock->usFontStyle) || + bIsSubscript(pFontBlock->usFontStyle)) { + /* Superscript and subscript use a smaller fontsize */ + uiRealSize = (uiRealSize * 2 + 1) / 3; + } + + if (uiRealSize < MIN_FONT_SIZE) { + DBG_DEC(uiRealSize); + uiRealSize = MIN_FONT_SIZE; + } else if (uiRealSize > MAX_FONT_SIZE) { + DBG_DEC(uiRealSize); + uiRealSize = MAX_FONT_SIZE; + } + + pFontBlock->usFontSize = (USHORT)uiRealSize; + if (pFontBlock->ucFontColor == 8) { + /* White text to light gray text */ + pFontBlock->ucFontColor = 16; + } + pFontBlock->usFontStyle = usRealStyle; +} /* end of vCorrectFontValues */ + +/* + * vAdd2FontInfoList - Add an element to the Font Information List + */ +void +vAdd2FontInfoList(const font_block_type *pFontBlock) +{ + font_mem_type *pListMember; + + fail(pFontBlock == NULL); + + NO_DBG_MSG("bAdd2FontInfoList"); + + if (pFontBlock->ulFileOffset == FC_INVALID) { + /* + * This offset is really past the end of the file, + * so don't waste any memory by storing it. + */ + return; + } + + NO_DBG_HEX(pFontBlock->ulFileOffset); + NO_DBG_DEC_C(pFontBlock->ucFontNumber != 0, + pFontBlock->ucFontNumber); + NO_DBG_DEC_C(pFontBlock->usFontSize != DEFAULT_FONT_SIZE, + pFontBlock->usFontSize); + NO_DBG_DEC_C(pFontBlock->ucFontColor != 0, + pFontBlock->ucFontColor); + NO_DBG_HEX_C(pFontBlock->usFontStyle != 0x00, + pFontBlock->usFontStyle); + + if (pFontLast != NULL && + pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) { + /* + * If two consecutive fonts share the same + * offset, remember only the last font + */ + fail(pFontLast->pNext != NULL); + pFontLast->tInfo = *pFontBlock; + return; + } + + /* Create list member */ + pListMember = xmalloc(sizeof(font_mem_type)); + /* Fill the list member */ + pListMember->tInfo = *pFontBlock; + pListMember->pNext = NULL; + /* Correct the values where needed */ + vCorrectFontValues(&pListMember->tInfo); + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + } else { + fail(pFontLast == NULL); + pFontLast->pNext = pListMember; + } + pFontLast = pListMember; +} /* end of vAdd2FontInfoList */ + +/* + * Get the record that follows the given recored in the Font Information List + */ +const font_block_type * +pGetNextFontInfoListItem(const font_block_type *pCurr) +{ + const font_mem_type *pRecord; + size_t tOffset; + + if (pCurr == NULL) { + if (pAnchor == NULL) { + /* There are no records */ + return NULL; + } + /* The first record is the only one without a predecessor */ + return &pAnchor->tInfo; + } + tOffset = offsetof(font_mem_type, tInfo); + /* Many casts to prevent alignment warnings */ + pRecord = (font_mem_type *)(void *)((char *)pCurr - tOffset); + fail(pCurr != &pRecord->tInfo); + if (pRecord->pNext == NULL) { + /* The last record has no successor */ + return NULL; + } + return &pRecord->pNext->tInfo; +} /* end of pGetNextFontInfoListItem */ diff --git a/fonts.c b/fonts.c new file mode 100644 index 0000000..77fde74 --- /dev/null +++ b/fonts.c @@ -0,0 +1,1018 @@ +/* + * fonts.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with fonts (generic) + */ + +#include +#include +#include "antiword.h" + +/* Maximum line length in the font file */ +#define FONT_LINE_LENGTH 81 + +/* Pitch */ +#define PITCH_UNKNOWN 0 +#define PITCH_FIXED 1 +#define PITCH_VARIABLE 2 + +/* Font Family */ +#define FAMILY_UNKNOWN 0 +#define FAMILY_ROMAN 1 +#define FAMILY_SWISS 2 +#define FAMILY_MODERN 3 +#define FAMILY_SCRIPT 4 +#define FAMILY_DECORATIVE 5 + +/* Font Translation Table */ +static size_t tFontTableRecords = 0; +static font_table_type *pFontTable = NULL; + +/* + * Find the given font in the font table + * + * returns the index into the FontTable, -1 if not found + */ +int +iGetFontByNumber(UCHAR ucWordFontNumber, USHORT usFontStyle) +{ + int iIndex; + + for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) { + if (ucWordFontNumber == pFontTable[iIndex].ucWordFontNumber && + usFontStyle == pFontTable[iIndex].usFontStyle && + pFontTable[iIndex].szOurFontname[0] != '\0') { + return iIndex; + } + } + DBG_DEC(ucWordFontNumber); + DBG_HEX(usFontStyle); + return -1; +} /* end of iGetFontByNumber */ + +/* + * szGetOurFontname - Get our font name + * + * return our font name from the given index, NULL if not found + */ +const char * +szGetOurFontname(int iIndex) +{ + if (iIndex < 0 || iIndex >= (int)tFontTableRecords) { + return NULL; + } + return pFontTable[iIndex].szOurFontname; +} /* end of szGetOurFontname */ + +/* + * Find the given font in the font table + * + * returns the Word font number, -1 if not found + */ +int +iFontname2Fontnumber(const char *szOurFontname, USHORT usFontStyle) +{ + int iIndex; + + for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) { + if (pFontTable[iIndex].usFontStyle == usFontStyle && + STREQ(pFontTable[iIndex].szOurFontname, szOurFontname)) { + return (int)pFontTable[iIndex].ucWordFontNumber; + } + } + return -1; +} /* end of iFontname2Fontnumber */ + +/* + * szGetDefaultFont - get the default font that matches the parameters + */ +static const char * +szGetDefaultFont(UCHAR ucFFN, int iEmphasis) +{ + UCHAR ucPrq, ucFf; + + fail(iEmphasis < 0 || iEmphasis > 3); + + ucPrq = ucFFN & 0x03; + ucFf = (ucFFN & 0x70) >> 4; + NO_DBG_DEC(ucPrq); + NO_DBG_DEC(ucFf); + if (ucPrq == PITCH_FIXED) { + /* Set to the default monospaced font */ + switch (iEmphasis) { + case 1: return FONT_MONOSPACED_BOLD; + case 2: return FONT_MONOSPACED_ITALIC; + case 3: return FONT_MONOSPACED_BOLDITALIC; + default: return FONT_MONOSPACED_PLAIN; + } + } else if (ucFf == FAMILY_ROMAN) { + /* Set to the default serif font */ + switch (iEmphasis) { + case 1: return FONT_SERIF_BOLD; + case 2: return FONT_SERIF_ITALIC; + case 3: return FONT_SERIF_BOLDITALIC; + default: return FONT_SERIF_PLAIN; + } + } else if (ucFf == FAMILY_SWISS) { + /* Set to the default sans serif font */ + switch (iEmphasis) { + case 1: return FONT_SANS_SERIF_BOLD; + case 2: return FONT_SANS_SERIF_ITALIC; + case 3: return FONT_SANS_SERIF_BOLDITALIC; + default: return FONT_SANS_SERIF_PLAIN; + } + } else { + /* Set to the default default font */ + switch (iEmphasis) { + case 1: return FONT_SERIF_BOLD; + case 2: return FONT_SERIF_ITALIC; + case 3: return FONT_SERIF_BOLDITALIC; + default: return FONT_SERIF_PLAIN; + } + } +} /* end of szGetDefaultFont */ + +/* + * See if the fontname from the Word file matches the fontname from the + * font translation file. + * If iBytesPerChar is one than aucWord is in ISO-8859-x (Word 2/6/7), + * if iBytesPerChar is two than aucWord is in Unicode (Word 8/9/10). + */ +static BOOL +bFontEqual(const UCHAR *aucWord, const char *szTable, int iBytesPerChar) +{ + const UCHAR *pucTmp; + const char *pcTmp; + + fail(aucWord == NULL || szTable == NULL); + fail(iBytesPerChar != 1 && iBytesPerChar != 2); + + for (pucTmp = aucWord, pcTmp = szTable; + *pucTmp != 0; + pucTmp += iBytesPerChar, pcTmp++) { + if (ulToUpper((ULONG)*pucTmp) != + ulToUpper((ULONG)(UCHAR)*pcTmp)) { + return FALSE; + } + } + return *pcTmp == '\0'; +} /* end of bFontEqual */ + +/* + * vFontname2Table - add fontnames to the font table + */ +static void +vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont, + int iBytesPerChar, int iEmphasis, UCHAR ucFFN, + const char *szWordFont, const char *szOurFont, + font_table_type *pFontTableRecord) +{ + BOOL bMatchFound; + + fail(aucFont == NULL || aucFont[0] == 0); + fail(aucAltFont != NULL && aucAltFont[0] == 0); + fail(iBytesPerChar != 1 && iBytesPerChar != 2); + fail(iEmphasis < 0 || iEmphasis > 3); + fail(szWordFont == NULL || szWordFont[0] == '\0'); + fail(szOurFont == NULL || szOurFont[0] == '\0'); + fail(pFontTableRecord == NULL); + + bMatchFound = bFontEqual(aucFont, szWordFont, iBytesPerChar); + + if (!bMatchFound && aucAltFont != NULL) { + bMatchFound = bFontEqual(aucAltFont, szWordFont, iBytesPerChar); + } + + if (!bMatchFound && + pFontTableRecord->szWordFontname[0] == '\0' && + szWordFont[0] == '*' && + szWordFont[1] == '\0') { + /* + * szWordFont contains a "*", so szOurFont will contain the + * "default default" font. See if we can do better than that. + */ + szOurFont = szGetDefaultFont(ucFFN, iEmphasis); + bMatchFound = TRUE; + } + + if (bMatchFound) { + switch (iBytesPerChar) { + case 1: + (void)strncpy(pFontTableRecord->szWordFontname, + (const char *)aucFont, + sizeof(pFontTableRecord->szWordFontname) - 1); + break; + case 2: + (void)unincpy(pFontTableRecord->szWordFontname, + aucFont, + sizeof(pFontTableRecord->szWordFontname) - 1); + break; + default: + DBG_FIXME(); + pFontTableRecord->szWordFontname[0] = '\0'; + break; + } + pFontTableRecord->szWordFontname[ + sizeof(pFontTableRecord->szWordFontname) - 1] = '\0'; + (void)strncpy(pFontTableRecord->szOurFontname, szOurFont, + sizeof(pFontTableRecord->szOurFontname) - 1); + pFontTableRecord->szOurFontname[ + sizeof(pFontTableRecord->szOurFontname) - 1] = '\0'; + NO_DBG_MSG(pFontTableRecord->szWordFontname); + NO_DBG_MSG(pFontTableRecord->szOurFontname); + pFontTableRecord->ucFFN = ucFFN; + pFontTableRecord->ucEmphasis = (UCHAR)iEmphasis; + } +} /* end of vFontname2Table */ + +/* + * vCreateFontTable - Create and initialize the internal font table + */ +static void +vCreateFontTable(void) +{ + font_table_type *pTmp; + int iNbr; + + if (tFontTableRecords == 0) { + pFontTable = xfree(pFontTable); + return; + } + + /* Create the font table */ + pFontTable = xcalloc(tFontTableRecords, sizeof(*pFontTable)); + + /* Initialize the font table */ + for (iNbr = 0, pTmp = pFontTable; + pTmp < pFontTable + tFontTableRecords; + iNbr++, pTmp++) { + pTmp->ucWordFontNumber = (UCHAR)(iNbr / 4); + switch (iNbr % 4) { + case 0: + pTmp->usFontStyle = FONT_REGULAR; + break; + case 1: + pTmp->usFontStyle = FONT_BOLD; + break; + case 2: + pTmp->usFontStyle = FONT_ITALIC; + break; + case 3: + pTmp->usFontStyle = FONT_BOLD|FONT_ITALIC; + break; + default: + DBG_DEC(iNbr); + break; + } + } +} /* end of vCreateFontTable */ + +/* + * vMinimizeFontTable - make the font table as small as possible + */ +static void +vMinimizeFontTable(void) +{ + font_block_type tFontNext; + const style_block_type *pStyle; + const font_block_type *pFont; + font_table_type *pTmp; + int iUnUsed; + BOOL bMustAddTableFont; + + NO_DBG_MSG("vMinimizeFontTable"); + + if (tFontTableRecords == 0) { + pFontTable = xfree(pFontTable); + return; + } + + /* See if we must add a font for our tables */ + bMustAddTableFont = TRUE; + +#if 0 + DBG_MSG("Before"); + DBG_DEC(tFontTableRecords); + for (pTmp = pFontTable; + pTmp < pFontTable + tFontTableRecords; + pTmp++) { + DBG_DEC(pTmp->ucWordFontNumber); + DBG_HEX(pTmp->usFontStyle); + DBG_MSG(pTmp->szWordFontname); + DBG_MSG(pTmp->szOurFontname); + } +#endif /* DEBUG */ + + /* See which fonts/styles we really need */ + + /* Default font/style is by definition in use */ + pFontTable[0].ucInUse = 1; + + /* Make InUse 1 for all the fonts/styles that WILL be used */ + pFont = NULL; + while((pFont = pGetNextFontInfoListItem(pFont)) != NULL) { + pTmp = pFontTable + 4 * (int)pFont->ucFontNumber; + if (bIsBold(pFont->usFontStyle)) { + pTmp++; + } + if (bIsItalic(pFont->usFontStyle)) { + pTmp += 2; + } + if (pTmp >= pFontTable + tFontTableRecords) { + continue; + } + if (STREQ(pTmp->szOurFontname, TABLE_FONT)) { + /* The table font is already present */ + bMustAddTableFont = FALSE; + } + pTmp->ucInUse = 1; + } + + /* Make InUse 1 for all the fonts/styles that MIGHT be used */ + pStyle = NULL; + while((pStyle = pGetNextStyleInfoListItem(pStyle)) != NULL) { + vFillFontFromStylesheet(pStyle->usIstdNext, &tFontNext); + vCorrectFontValues(&tFontNext); + pTmp = pFontTable + 4 * (int)tFontNext.ucFontNumber; + if (bIsBold(tFontNext.usFontStyle)) { + pTmp++; + } + if (bIsItalic(tFontNext.usFontStyle)) { + pTmp += 2; + } + if (pTmp >= pFontTable + tFontTableRecords) { + continue; + } + if (STREQ(pTmp->szOurFontname, TABLE_FONT)) { + /* The table font is already present */ + bMustAddTableFont = FALSE; + } + pTmp->ucInUse = 1; + } + + /* Remove the unused font entries from the font table */ + iUnUsed = 0; + for (pTmp = pFontTable; + pTmp < pFontTable + tFontTableRecords; + pTmp++) { + if (pTmp->ucInUse == 0) { + iUnUsed++; + continue; + } + if (iUnUsed > 0) { + fail(pTmp - iUnUsed <= pFontTable); + *(pTmp - iUnUsed) = *pTmp; + } + } + fail(iUnUsed < 0); + fail(tFontTableRecords <= (size_t)iUnUsed); + tFontTableRecords -= (size_t)iUnUsed; + + if (bMustAddTableFont) { + pTmp = pFontTable + tFontTableRecords; + fail(pTmp <= pFontTable); + pTmp->ucWordFontNumber = (pTmp - 1)->ucWordFontNumber + 1; + pTmp->usFontStyle = FONT_REGULAR; + pTmp->ucInUse = 1; + strcpy(pTmp->szWordFontname, "Extra Table Font"); + strcpy(pTmp->szOurFontname, TABLE_FONT); + tFontTableRecords++; + iUnUsed--; + } + if (iUnUsed > 0) { + /* Resize the font table */ + pFontTable = xrealloc(pFontTable, + tFontTableRecords * sizeof(*pFontTable)); + } +#if defined(DEBUG) + DBG_MSG("After"); + DBG_DEC(tFontTableRecords); + for (pTmp = pFontTable; + pTmp < pFontTable + tFontTableRecords; + pTmp++) { + DBG_DEC(pTmp->ucWordFontNumber); + DBG_HEX(pTmp->usFontStyle); + DBG_MSG(pTmp->szWordFontname); + DBG_MSG(pTmp->szOurFontname); + } +#endif /* DEBUG */ +} /* end of vMinimizeFontTable */ + +/* + * bReadFontFile - read and check a line from the font translation file + * + * returns TRUE when a correct line has been read, otherwise FALSE + */ +static BOOL +bReadFontFile(FILE *pFontTableFile, char *szWordFont, + int *piItalic, int *piBold, char *szOurFont, int *piSpecial) +{ + char *pcTmp; + int iFields; + char szLine[FONT_LINE_LENGTH]; + + fail(szWordFont == NULL || szOurFont == NULL); + fail(piItalic == NULL || piBold == NULL || piSpecial == NULL); + + while (fgets(szLine, (int)sizeof(szLine), pFontTableFile) != NULL) { + if (szLine[0] == '#' || + szLine[0] == '\n' || + szLine[0] == '\r') { + continue; + } + iFields = sscanf(szLine, "%[^,],%d,%d,%1s%[^,],%d", + szWordFont, piItalic, piBold, + &szOurFont[0], &szOurFont[1], piSpecial); + if (iFields != 6) { + pcTmp = strchr(szLine, '\r'); + if (pcTmp != NULL) { + *pcTmp = '\0'; + } + pcTmp = strchr(szLine, '\n'); + if (pcTmp != NULL) { + *pcTmp = '\0'; + } + DBG_DEC(iFields); + werr(0, "Syntax error in: '%s'", szLine); + continue; + } + if (strlen(szWordFont) >= + sizeof(pFontTable[0].szWordFontname)) { + werr(0, "Word fontname too long: '%s'", szWordFont); + continue; + } + if (strlen(szOurFont) >= + sizeof(pFontTable[0].szOurFontname)) { + werr(0, "Local fontname too long: '%s'", szOurFont); + continue; + } + /* The current line passed all the tests */ + return TRUE; + } + return FALSE; +} /* end of bReadFontFile */ + +/* + * vCreate0FontTable - create a font table from Word for DOS + */ +void +vCreate0FontTable(void) +{ + FILE *pFontTableFile; + font_table_type *pTmp; + UCHAR *aucFont; + int iBold, iItalic, iSpecial, iEmphasis, iFtc; + UCHAR ucPrq, ucFf, ucFFN; + char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; + + tFontTableRecords = 0; + pFontTable = xfree(pFontTable); + + pFontTableFile = pOpenFontTableFile(); + if (pFontTableFile == NULL) { + /* No translation table file, no translation table */ + return; + } + + /* Get the maximum number of entries in the font table */ + tFontTableRecords = 64; + tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ + tFontTableRecords++; /* One extra for the table-font */ + vCreateFontTable(); + + /* Read the font translation file */ + iItalic = 0; + iBold = 0; + iSpecial = 0; + while (bReadFontFile(pFontTableFile, szWordFont, + &iItalic, &iBold, szOurFont, &iSpecial)) { + iEmphasis = 0; + if (iBold != 0) { + iEmphasis++; + } + if (iItalic != 0) { + iEmphasis += 2; + } + for (iFtc = 0, pTmp = pFontTable + iEmphasis; + pTmp < pFontTable + tFontTableRecords; + iFtc++, pTmp += 4) { + if (iFtc >= 16 && iFtc <= 55) { + ucPrq = PITCH_VARIABLE; + ucFf = FAMILY_ROMAN; + aucFont = (UCHAR *)"Times"; + } else { + ucPrq = PITCH_FIXED; + ucFf = FAMILY_MODERN; + aucFont = (UCHAR *)"Courier"; + } + ucFFN = (ucFf << 4) | ucPrq; + vFontname2Table(aucFont, NULL, 1, iEmphasis, + ucFFN, szWordFont, szOurFont, pTmp); + } + } + (void)fclose(pFontTableFile); + vMinimizeFontTable(); +} /* end of vCreate0FontTable */ + +/* + * vCreate2FontTable - create a font table from WinWord 1/2 + */ +void +vCreate2FontTable(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +{ + FILE *pFontTableFile; + font_table_type *pTmp; + UCHAR *aucFont; + UCHAR *aucBuffer; + ULONG ulBeginFontInfo; + size_t tFontInfoLen; + int iPos, iOff, iRecLen; + int iBold, iItalic, iSpecial, iEmphasis; + UCHAR ucFFN; + char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; + + fail(pFile == NULL || aucHeader == NULL); + fail(iWordVersion != 1 && iWordVersion != 2); + + tFontTableRecords = 0; + pFontTable = xfree(pFontTable); + + pFontTableFile = pOpenFontTableFile(); + if (pFontTableFile == NULL) { + /* No translation table file, no translation table */ + return; + } + + ulBeginFontInfo = ulGetLong(0xb2, aucHeader); /* fcSttbfffn */ + DBG_HEX(ulBeginFontInfo); + tFontInfoLen = (size_t)usGetWord(0xb6, aucHeader); /* cbSttbfffn */ + DBG_DEC(tFontInfoLen); + + if (ulBeginFontInfo > (ULONG)LONG_MAX || tFontInfoLen == 0) { + /* Don't ask me why this is needed */ + DBG_HEX_C(tFontInfoLen != 0, ulBeginFontInfo); + (void)fclose(pFontTableFile); + return; + } + + aucBuffer = xmalloc(tFontInfoLen); + if (!bReadBytes(aucBuffer, tFontInfoLen, ulBeginFontInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + (void)fclose(pFontTableFile); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); + DBG_DEC(usGetWord(0, aucBuffer)); + + /* Compute the maximum number of entries in the font table */ + if (iWordVersion == 1) { + fail(tFontInfoLen < 2); + /* WinWord 1 has three implicit fonts */ + tFontTableRecords = 3; + iOff = 2; + } else { + fail(tFontInfoLen < 6); + /* WinWord 2 and up have no implicit fonts */ + tFontTableRecords = 0; + iOff = 3; + } + iPos = 2; + while (iPos + iOff < (int)tFontInfoLen) { + iRecLen = (int)ucGetByte(iPos, aucBuffer); + NO_DBG_DEC(iRecLen); + NO_DBG_MSG(aucBuffer + iPos + iOff); + iPos += iRecLen + 1; + tFontTableRecords++; + } + tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/Italic */ + tFontTableRecords++; /* One extra for the table-font */ + vCreateFontTable(); + + /* Add the tree implicit fonts (in four variations) */ + if (iWordVersion == 1) { + fail(tFontTableRecords < 13); + vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 0, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Roman", pFontTable + 0); + vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 1, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Bold", pFontTable + 1); + vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 2, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Italic", pFontTable + 2); + vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 3, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-BoldItalic", pFontTable + 3); + vFontname2Table((UCHAR *)"Symbol", NULL, 1, 0, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Roman", pFontTable + 4); + vFontname2Table((UCHAR *)"Symbol", NULL, 1, 1, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Bold", pFontTable + 5); + vFontname2Table((UCHAR *)"Symbol", NULL, 1, 2, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-Italic", pFontTable + 6); + vFontname2Table((UCHAR *)"Symbol", NULL, 1, 3, + (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), + "*", "Times-BoldItalic", pFontTable + 7); + vFontname2Table((UCHAR *)"Helv", NULL, 1, 0, + (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), + "*", "Helvetica", pFontTable + 8); + vFontname2Table((UCHAR *)"Helv", NULL, 1, 1, + (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), + "*", "Helvetica-Bold", pFontTable + 9); + vFontname2Table((UCHAR *)"Helv", NULL, 1, 2, + (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), + "*", "Helvetica-Oblique", pFontTable + 10); + vFontname2Table((UCHAR *)"Helv", NULL, 1, 3, + (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), + "*", "Helvetica-BoldOblique", pFontTable + 11); + } + + /* Read the font translation file */ + iItalic = 0; + iBold = 0; + iSpecial = 0; + while (bReadFontFile(pFontTableFile, szWordFont, + &iItalic, &iBold, szOurFont, &iSpecial)) { + iEmphasis = 0; + if (iBold != 0) { + iEmphasis++; + } + if (iItalic != 0) { + iEmphasis += 2; + } + pTmp = pFontTable + iEmphasis; + iPos = 2; + while (iPos + iOff < (int)tFontInfoLen) { + iRecLen = (int)ucGetByte(iPos, aucBuffer); + ucFFN = ucGetByte(iPos + 1, aucBuffer); + aucFont = aucBuffer + iPos + iOff; + vFontname2Table(aucFont, NULL, 1, iEmphasis, + ucFFN, szWordFont, szOurFont, pTmp); + pTmp += 4; + iPos += iRecLen + 1; + } + } + (void)fclose(pFontTableFile); + aucBuffer = xfree(aucBuffer); + vMinimizeFontTable(); +} /* end of vCreate2FontTable */ + +/* + * vCreate6FontTable - create a font table from Word 6/7 + */ +void +vCreate6FontTable(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + FILE *pFontTableFile; + font_table_type *pTmp; + UCHAR *aucFont, *aucAltFont; + UCHAR *aucBuffer; + ULONG ulBeginFontInfo; + size_t tFontInfoLen; + int iPos, iRecLen, iOffsetAltName; + int iBold, iItalic, iSpecial, iEmphasis; + UCHAR ucFFN; + char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + tFontTableRecords = 0; + pFontTable = xfree(pFontTable); + + pFontTableFile = pOpenFontTableFile(); + if (pFontTableFile == NULL) { + /* No translation table file, no translation table */ + return; + } + + ulBeginFontInfo = ulGetLong(0xd0, aucHeader); /* fcSttbfffn */ + DBG_HEX(ulBeginFontInfo); + tFontInfoLen = (size_t)ulGetLong(0xd4, aucHeader); /* lcbSttbfffn */ + DBG_DEC(tFontInfoLen); + fail(tFontInfoLen < 9); + + aucBuffer = xmalloc(tFontInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginFontInfo, tFontInfoLen)) { + aucBuffer = xfree(aucBuffer); + (void)fclose(pFontTableFile); + return; + } + DBG_DEC(usGetWord(0, aucBuffer)); + + /* Compute the maximum number of entries in the font table */ + tFontTableRecords = 0; + iPos = 2; + while (iPos + 6 < (int)tFontInfoLen) { + iRecLen = (int)ucGetByte(iPos, aucBuffer); + NO_DBG_DEC(iRecLen); + iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); + NO_DBG_MSG(aucBuffer + iPos + 6); + NO_DBG_MSG_C(iOffsetAltName > 0, + aucBuffer + iPos + 6 + iOffsetAltName); + iPos += iRecLen + 1; + tFontTableRecords++; + } + tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ + tFontTableRecords++; /* One extra for the table-font */ + vCreateFontTable(); + + /* Read the font translation file */ + iItalic = 0; + iBold = 0; + iSpecial = 0; + while (bReadFontFile(pFontTableFile, szWordFont, + &iItalic, &iBold, szOurFont, &iSpecial)) { + iEmphasis = 0; + if (iBold != 0) { + iEmphasis++; + } + if (iItalic != 0) { + iEmphasis += 2; + } + pTmp = pFontTable + iEmphasis; + iPos = 2; + while (iPos + 6 < (int)tFontInfoLen) { + iRecLen = (int)ucGetByte(iPos, aucBuffer); + ucFFN = ucGetByte(iPos + 1, aucBuffer); + aucFont = aucBuffer + iPos + 6; + iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); + if (iOffsetAltName <= 0) { + aucAltFont = NULL; + } else { + aucAltFont = aucFont + iOffsetAltName; + NO_DBG_MSG(aucFont); + NO_DBG_MSG(aucAltFont); + } + vFontname2Table(aucFont, aucAltFont, 1, iEmphasis, + ucFFN, szWordFont, szOurFont, pTmp); + pTmp += 4; + iPos += iRecLen + 1; + } + } + (void)fclose(pFontTableFile); + aucBuffer = xfree(aucBuffer); + vMinimizeFontTable(); +} /* end of vCreate6FontTable */ + +/* + * vCreate8FontTable - create a font table from Word 8/9/10 + */ +void +vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + FILE *pFontTableFile; + font_table_type *pTmp; + const ULONG *aulBlockDepot; + UCHAR *aucFont, *aucAltFont; + UCHAR *aucBuffer; + ULONG ulBeginFontInfo; + size_t tFontInfoLen, tBlockDepotLen, tBlockSize; + int iPos, iRecLen, iOffsetAltName; + int iBold, iItalic, iSpecial, iEmphasis; + UCHAR ucFFN; + char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + tFontTableRecords = 0; + pFontTable = xfree(pFontTable); + + pFontTableFile = pOpenFontTableFile(); + if (pFontTableFile == NULL) { + /* No translation table file, no translation table */ + return; + } + + ulBeginFontInfo = ulGetLong(0x112, aucHeader); /* fcSttbfffn */ + DBG_HEX(ulBeginFontInfo); + tFontInfoLen = (size_t)ulGetLong(0x116, aucHeader); /* lcbSttbfffn */ + DBG_DEC(tFontInfoLen); + fail(tFontInfoLen < 46); + + DBG_DEC(pPPS->tTable.ulSB); + DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No fontname table"); + (void)fclose(pFontTableFile); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tFontInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginFontInfo, tFontInfoLen)) { + aucBuffer = xfree(aucBuffer); + (void)fclose(pFontTableFile); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); + + /* Get the maximum number of entries in the font table */ + tFontTableRecords = (size_t)usGetWord(0, aucBuffer); + tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ + tFontTableRecords++; /* One extra for the table-font */ + vCreateFontTable(); + + /* Read the font translation file */ + iItalic = 0; + iBold = 0; + iSpecial = 0; + while (bReadFontFile(pFontTableFile, szWordFont, + &iItalic, &iBold, szOurFont, &iSpecial)) { + iEmphasis = 0; + if (iBold != 0) { + iEmphasis++; + } + if (iItalic != 0) { + iEmphasis += 2; + } + pTmp = pFontTable + iEmphasis; + iPos = 4; + while (iPos + 40 < (int)tFontInfoLen) { + iRecLen = (int)ucGetByte(iPos, aucBuffer); + ucFFN = ucGetByte(iPos + 1, aucBuffer); + aucFont = aucBuffer + iPos + 40; + iOffsetAltName = (int)unilen(aucFont); + if (iPos + 40 + iOffsetAltName + 4 >= iRecLen) { + aucAltFont = NULL; + } else { + aucAltFont = aucFont + iOffsetAltName + 2; + NO_DBG_UNICODE(aucFont); + NO_DBG_UNICODE(aucAltFont); + } + vFontname2Table(aucFont, aucAltFont, 2, iEmphasis, + ucFFN, szWordFont, szOurFont, pTmp); + pTmp += 4; + iPos += iRecLen + 1; + } + } + (void)fclose(pFontTableFile); + aucBuffer = xfree(aucBuffer); + vMinimizeFontTable(); +} /* end of vCreate8FontTable */ + +/* + * Destroy the internal font table by freeing its memory + */ +void +vDestroyFontTable(void) +{ + DBG_MSG("vDestroyFontTable"); + + tFontTableRecords = 0; + pFontTable = xfree(pFontTable); +} /* end of vDestroyFontTable */ + +/* + * pGetNextFontTableRecord + * + * returns the next record in the table or NULL if there is no next record + */ +const font_table_type * +pGetNextFontTableRecord(const font_table_type *pRecordCurr) +{ + size_t tIndexCurr; + + if (pRecordCurr == NULL) { + /* No current record, so start with the first one */ + return &pFontTable[0]; + } + + if (pRecordCurr < pFontTable || + pRecordCurr >= pFontTable + tFontTableRecords) { + /* Not a pointer in the array */ + DBG_HEX(pRecordCurr); + DBG_HEX(pFontTable); + return NULL; + } + + tIndexCurr = (size_t)(pRecordCurr - pFontTable); + if (tIndexCurr + 1 < tFontTableRecords) { + /* There is a next record, so return it */ + return &pFontTable[tIndexCurr + 1]; + } + /* There is no next record */ + return NULL; +} /* end of pGetNextFontTableRecord */ + +/* + * tGetFontTableLength + * + * returns the number of records in the internal font table + */ +size_t +tGetFontTableLength(void) +{ + return tFontTableRecords; +} /* end of tGetFontTableLength */ + +#if !defined(__riscos) +/* + * vCorrect4PDF - only include PDF default fonts + */ +static void +vCorrect4PDF(void) +{ + font_table_type *pTmp; + const char *szOurFont; + + for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { + if (STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_PLAIN) || + STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLD) || + STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_ITALIC) || + STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLDITALIC) || + STRCEQ(pTmp->szOurFontname, FONT_SERIF_PLAIN) || + STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLD) || + STRCEQ(pTmp->szOurFontname, FONT_SERIF_ITALIC) || + STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLDITALIC) || + STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_PLAIN) || + STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLD) || + STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_ITALIC) || + STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLDITALIC)) { + /* Already a default font */ + continue; + } + szOurFont = + szGetDefaultFont(pTmp->ucFFN, (int)pTmp->ucEmphasis); + (void)strncpy(pTmp->szOurFontname, szOurFont, + sizeof(pTmp->szOurFontname) - 1); + pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; + } +} /* end of vCorrect4PDF */ + +/* + * vCorrect4CyrPS - only include monospaced fonts + */ +static void +vCorrect4CyrPS(void) +{ + font_table_type *pTmp; + const char *szOurFont; + UCHAR ucFFN; + + ucFFN = (FAMILY_UNKNOWN << 4) | PITCH_FIXED; + for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { + szOurFont = szGetDefaultFont(ucFFN, (int)pTmp->ucEmphasis); + (void)strncpy(pTmp->szOurFontname, szOurFont, + sizeof(pTmp->szOurFontname) - 1); + pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; + } +} /* end of vCorrect4CyrPS */ +#endif /* __riscos */ + +/* + * vCorrectFontTable - correct the font table in special cases + */ +void +vCorrectFontTable(conversion_type eConversionType, encoding_type eEncoding) +{ +#if !defined(__riscos) + if (eConversionType == conversion_pdf) { + vCorrect4PDF(); + } + if (eConversionType == conversion_ps && + eEncoding == encoding_cyrillic) { + vCorrect4CyrPS(); + } +#endif /* __riscos */ +} /* end of vCorrectFontTable */ + +/* + * lComputeSpaceWidth - compute the width of a space character + * + * Returns the space width in millipoints + */ +long +lComputeSpaceWidth(drawfile_fontref tFontRef, USHORT usFontSize) +{ + char szSpace[] = " "; + + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + return lComputeStringWidth(szSpace, 1, tFontRef, usFontSize); +} /* end of lComputeSpaceWidth */ diff --git a/fonts_r.c b/fonts_r.c new file mode 100644 index 0000000..0898d4f --- /dev/null +++ b/fonts_r.c @@ -0,0 +1,251 @@ +/* + * fonts_r.c + * Copyright (C) 1999-2002 A.J. van Os; Released under GPL + * + * Description: + * Functions to deal with fonts (RiscOs version) + */ + +#include +#include +#include "DeskLib:Font.h" +#include "drawfile.h" +#include "antiword.h" + +static font_handle tFontCurr = (font_handle)-1; + +/* + * pOpenFontTableFile - open the Font translation file + * Copy the file to the proper place if necessary. + * + * Returns the file pointer or NULL + */ +FILE * +pOpenFontTableFile(void) +{ + FILE *pFileR, *pFileW; + char *szFontNamesFile; + size_t tSize; + BOOL bFailed; + char acBuffer[256]; + + pFileR = fopen("", "r"); + if (pFileR != NULL) { + /* The font table is already in the right directory */ + return pFileR; + } + + szFontNamesFile = getenv("AntiWord$FontNamesSave"); + if (szFontNamesFile == NULL) { + werr(0, "Warning: Name of the FontNames file not found"); + return NULL; + } + DBG_MSG(szFontNamesFile); + + pFileR = fopen(".Resources.Default", "r"); + if (pFileR == NULL) { + werr(0, "I can't find 'Resources.Default'"); + return NULL; + } + /* Here the default font translation table is known to exist */ + + if (!bMakeDirectory(szFontNamesFile)) { + werr(0, + "I can't make a directory for the FontNames file"); + return NULL; + } + /* Here the proper directory is known to exist */ + + pFileW = fopen(szFontNamesFile, "w"); + if (pFileW == NULL) { + (void)fclose(pFileR); + werr(0, "I can't create a default FontNames file"); + return NULL; + } + /* Here the proper directory is known to be writeable */ + + /* Copy the default FontNames file */ + bFailed = FALSE; + while (!feof(pFileR)) { + tSize = fread(acBuffer, 1, sizeof(acBuffer), pFileR); + if (ferror(pFileR)) { + DBG_MSG("Read error"); + bFailed = TRUE; + break; + } + if (fwrite(acBuffer, 1, tSize, pFileW) != tSize) { + DBG_MSG("Write error"); + bFailed = TRUE; + break; + } + } + (void)fclose(pFileW); + (void)fclose(pFileR); + if (bFailed) { + DBG_MSG("Copying the FontNames file failed"); + (void)remove(szFontNamesFile); + return NULL; + } + return fopen(szFontNamesFile, "r"); +} /* end of pOpenFontTableFile */ + +/* + * vCloseFont - close the current font, if any + */ +void +vCloseFont(void) +{ + os_error *e; + + NO_DBG_MSG("vCloseFont"); + + if (tFontCurr == (font_handle)-1) { + return; + } + e = Font_LoseFont(tFontCurr); + if (e != NULL) { + werr(0, "Close font error %d: %s", e->errnum, e->errmess); + } + tFontCurr = (font_handle)-1; +} /* end of vCloseFont */ + +/* + * tOpenFont - make the specified font the current font + * + * Returns the font reference number for use in a draw file + */ +drawfile_fontref +tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize) +{ + os_error *e; + const char *szOurFontname; + font_handle tFont; + int iFontnumber; + + NO_DBG_MSG("tOpenFont"); + NO_DBG_DEC(ucWordFontNumber); + NO_DBG_HEX(usFontStyle); + NO_DBG_DEC(usWordFontSize); + + /* Keep the relevant bits */ + usFontStyle &= FONT_BOLD|FONT_ITALIC; + NO_DBG_HEX(usFontStyle); + + iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle); + szOurFontname = szGetOurFontname(iFontnumber); + if (szOurFontname == NULL || szOurFontname[0] == '\0') { + tFontCurr = (font_handle)-1; + return (byte)0; + } + NO_DBG_MSG(szOurFontname); + e = Font_FindFont(&tFont, (char *)szOurFontname, + (int)usWordFontSize * 8, (int)usWordFontSize * 8, + 0, 0); + if (e != NULL) { + switch (e->errnum) { + case 523: + werr(0, "%s", e->errmess); + break; + default: + werr(0, "Open font error %d: %s", + e->errnum, e->errmess); + break; + } + tFontCurr = (font_handle)-1; + return (drawfile_fontref)0; + } + tFontCurr = tFont; + NO_DBG_DEC(tFontCurr); + return (drawfile_fontref)(iFontnumber + 1); +} /* end of tOpenFont */ + +/* + * tOpenTableFont - make the table font the current font + * + * Returns the font reference number for use in a draw file + */ +drawfile_fontref +tOpenTableFont(USHORT usWordFontSize) +{ + int iWordFontnumber; + + NO_DBG_MSG("tOpenTableFont"); + + iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR); + if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) { + DBG_DEC(iWordFontnumber); + tFontCurr = (font_handle)-1; + return (drawfile_fontref)0; + } + + return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize); +} /* end of tOpenTableFont */ + +/* + * lComputeStringWidth - compute the string width + * + * Returns the string width in millipoints + */ +long +lComputeStringWidth(const char *szString, size_t tStringLength, + drawfile_fontref tFontRef, USHORT usFontSize) +{ + font_string tStr; + os_error *e; + + fail(szString == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + if (szString[0] == '\0' || tStringLength == 0) { + /* Empty string */ + return 0; + } + if (tStringLength == 1 && szString[0] == TABLE_SEPARATOR) { + /* Font_strwidth doesn't like control characters */ + return 0; + } + if (tFontCurr == (font_handle)-1) { + /* No current font, use systemfont */ + return lChar2MilliPoints(tStringLength); + } + tStr.s = (char *)szString; + tStr.x = INT_MAX; + tStr.y = INT_MAX; + tStr.split = -1; + tStr.term = tStringLength; + e = Font_StringWidth(&tStr); + if (e == NULL) { + return (long)tStr.x; + } + DBG_DEC(e->errnum); + DBG_MSG(e->errmess); + DBG_DEC(tStringLength); + DBG_MSG(szString); + werr(0, "String width error %d: %s", e->errnum, e->errmess); + return lChar2MilliPoints(tStringLength); +} /* end of lComputeStringWidth */ + +/* + * tCountColumns - count the number of columns in a string + * + * Returns the number of columns + */ +size_t +tCountColumns(const char *szString, size_t tLength) +{ + fail(szString == NULL); + + /* One byte, one character, one column */ + return tLength; +} /* end of tCountColumns */ + +/* + * tGetCharacterLength - the length of the specified character in bytes + * + * Returns the length in bytes + */ +size_t +tGetCharacterLength(const char *szString) +{ + return 1; +} /* end of tGetCharacterLength */ diff --git a/fonts_u.c b/fonts_u.c new file mode 100644 index 0000000..a99f7d2 --- /dev/null +++ b/fonts_u.c @@ -0,0 +1,305 @@ +/* + * fonts_u.c + * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with fonts (Unix version) + */ + +#include +#include +#include +#include "antiword.h" +#include "fontinfo.h" + +/* Don't use fonts, just plain text */ +static BOOL bUsePlainText = TRUE; +/* Which character set should be used */ +static encoding_type eEncoding = encoding_neutral; + + +/* + * pOpenFontTableFile - open the Font translation file + * + * Returns the file pointer or NULL + */ +FILE * +pOpenFontTableFile(void) +{ + FILE *pFile; + const char *szHome, *szAntiword, *szGlobalFile; + char szEnvironmentFile[PATH_MAX+1]; + char szLocalFile[PATH_MAX+1]; + + szEnvironmentFile[0] = '\0'; + szLocalFile[0] = '\0'; + + /* Try the environment version of the fontnames file */ + szAntiword = szGetAntiwordDirectory(); + if (szAntiword != NULL && szAntiword[0] != '\0') { + if (strlen(szAntiword) + + sizeof(FILE_SEPARATOR FONTNAMES_FILE) >= + sizeof(szEnvironmentFile)) { + werr(0, + "The name of your ANTIWORDHOME directory is too long"); + return NULL; + } + sprintf(szEnvironmentFile, "%s%s", + szAntiword, + FILE_SEPARATOR FONTNAMES_FILE); + DBG_MSG(szEnvironmentFile); + + pFile = fopen(szEnvironmentFile, "r"); + if (pFile != NULL) { + return pFile; + } + } + + /* Try the local version of the fontnames file */ + szHome = szGetHomeDirectory(); + if (strlen(szHome) + + sizeof(FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE) >= + sizeof(szLocalFile)) { + werr(0, "The name of your HOME directory is too long"); + return NULL; + } + + sprintf(szLocalFile, "%s%s", + szHome, + FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE); + DBG_MSG(szLocalFile); + + pFile = fopen(szLocalFile, "r"); + if (pFile != NULL) { + return pFile; + } + + /* Try the global version of the fontnames file */ + szGlobalFile = GLOBAL_ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE; + DBG_MSG(szGlobalFile); + + pFile = fopen(szGlobalFile, "r"); + if (pFile != NULL) { + return pFile; + } + + if (szEnvironmentFile[0] != '\0') { + werr(0, "I can not open your fontnames file.\n" + "Neither '%s' nor\n" + "'%s' nor\n" + "'%s' can be opened for reading.", + szEnvironmentFile, szLocalFile, szGlobalFile); + } else { + werr(0, "I can not open your fontnames file.\n" + "Neither '%s' nor\n" + "'%s' can be opened for reading.", + szLocalFile, szGlobalFile); + } + return NULL; +} /* end of pOpenFontTableFile */ + +/* + * vCloseFont - close the current font, if any + */ +void +vCloseFont(void) +{ + NO_DBG_MSG("vCloseFont"); + /* For safety: to be overwritten at the next call of tOpenfont() */ + eEncoding = encoding_neutral; + bUsePlainText = TRUE; +} /* end of vCloseFont */ + +/* + * tOpenFont - make the specified font the current font + * + * Returns the font reference number + */ +drawfile_fontref +tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize) +{ + options_type tOptions; + const char *szOurFontname; + size_t tIndex; + int iFontnumber; + + NO_DBG_MSG("tOpenFont"); + NO_DBG_DEC(ucWordFontNumber); + NO_DBG_HEX(usFontStyle); + NO_DBG_DEC(usWordFontSize); + + /* Keep the relevant bits */ + usFontStyle &= FONT_BOLD|FONT_ITALIC; + NO_DBG_HEX(usFontStyle); + + vGetOptions(&tOptions); + eEncoding = tOptions.eEncoding; + bUsePlainText = tOptions.eConversionType != conversion_draw && + tOptions.eConversionType != conversion_ps && + tOptions.eConversionType != conversion_pdf; + + if (bUsePlainText) { + /* Plain text, no fonts */ + return (drawfile_fontref)0; + } + + iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle); + szOurFontname = szGetOurFontname(iFontnumber); + if (szOurFontname == NULL || szOurFontname[0] == '\0') { + DBG_DEC(iFontnumber); + return (drawfile_fontref)0; + } + NO_DBG_MSG(szOurFontname); + + for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) { + if (STREQ(szFontnames[tIndex], szOurFontname)) { + NO_DBG_DEC(tIndex); + return (drawfile_fontref)tIndex; + } + } + return (drawfile_fontref)0; +} /* end of tOpenFont */ + +/* + * tOpenTableFont - make the table font the current font + * + * Returns the font reference number + */ +drawfile_fontref +tOpenTableFont(USHORT usWordFontSize) +{ + options_type tOptions; + int iWordFontnumber; + + NO_DBG_MSG("tOpenTableFont"); + + vGetOptions(&tOptions); + eEncoding = tOptions.eEncoding; + bUsePlainText = tOptions.eConversionType != conversion_draw && + tOptions.eConversionType != conversion_ps && + tOptions.eConversionType != conversion_pdf; + + if (bUsePlainText) { + /* Plain text, no fonts */ + return (drawfile_fontref)0; + } + + iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR); + if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) { + DBG_DEC(iWordFontnumber); + return (drawfile_fontref)0; + } + + return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize); +} /* end of tOpenTableFont */ + +/* + * szGetFontname - get the fontname + */ +const char * +szGetFontname(drawfile_fontref tFontRef) +{ + fail((size_t)(UCHAR)tFontRef >= elementsof(szFontnames)); + return szFontnames[(int)(UCHAR)tFontRef]; +} /* end of szGetFontname */ + +/* + * lComputeStringWidth - compute the string width + * + * Note: the fontsize is specified in half-points! + * the stringlength is specified in bytes, not characters! + * + * Returns the string width in millipoints + */ +long +lComputeStringWidth(const char *szString, size_t tStringLength, + drawfile_fontref tFontRef, USHORT usFontSize) +{ + USHORT *ausCharWidths; + UCHAR *pucChar; + long lRelWidth; + size_t tIndex; + int iFontRef; + + fail(szString == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + if (szString[0] == '\0' || tStringLength == 0) { + /* Empty string */ + return 0; + } + + if (eEncoding == encoding_utf_8) { + fail(!bUsePlainText); + return lChar2MilliPoints( + utf8_strwidth(szString, tStringLength)); + } + + if (bUsePlainText) { + /* No current font, use "systemfont" */ + return lChar2MilliPoints(tStringLength); + } + + if (eEncoding == encoding_cyrillic) { + /* FIXME: until the character tables are available */ + return (tStringLength * 600L * (long)usFontSize + 1) / 2; + } + + DBG_DEC_C(eEncoding != encoding_latin_1 && + eEncoding != encoding_latin_2, eEncoding); + fail(eEncoding != encoding_latin_1 && + eEncoding != encoding_latin_2); + + /* Compute the relative string width */ + iFontRef = (int)(UCHAR)tFontRef; + if (eEncoding == encoding_latin_2) { + ausCharWidths = ausCharacterWidths2[iFontRef]; + } else { + ausCharWidths = ausCharacterWidths1[iFontRef]; + } + lRelWidth = 0; + for (tIndex = 0, pucChar = (UCHAR *)szString; + tIndex < tStringLength; + tIndex++, pucChar++) { + lRelWidth += (long)ausCharWidths[(int)*pucChar]; + } + + /* Compute the absolute string width */ + return (lRelWidth * (long)usFontSize + 1) / 2; +} /* end of lComputeStringWidth */ + +/* + * tCountColumns - count the number of columns in a string + * + * Note: the length is specified in bytes! + * A UTF-8 a character can be 0, 1 or 2 columns wide. + * + * Returns the number of columns + */ +size_t +tCountColumns(const char *szString, size_t tLength) +{ + fail(szString == NULL); + + if (eEncoding != encoding_utf_8) { + /* One byte, one character, one column */ + return tLength; + } + return (size_t)utf8_strwidth(szString, tLength); +} /* end of tCountColumns */ + +/* + * tGetCharacterLength - the length of the specified character in bytes + * + * Returns the length in bytes + */ +size_t +tGetCharacterLength(const char *szString) +{ + fail(szString == NULL); + + if (eEncoding != encoding_utf_8) { + return 1; + } + return (size_t)utf8_chrlength(szString); +} /* end of tGetCharacterLength */ diff --git a/hdrftrlist.c b/hdrftrlist.c new file mode 100644 index 0000000..c164188 --- /dev/null +++ b/hdrftrlist.c @@ -0,0 +1,371 @@ +/* + * hdrftrlist.c + * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy list(s) of Word Header/footer information + */ + +#include +#include "antiword.h" + + +#define HDR_EVEN_PAGES 0 +#define HDR_ODD_PAGES 1 +#define FTR_EVEN_PAGES 2 +#define FTR_ODD_PAGES 3 +#define HDR_FIRST_PAGE 4 +#define FTR_FIRST_PAGE 5 + +/* + * Private structures to hide the way the information + * is stored from the rest of the program + */ +typedef struct hdrftr_local_tag { + hdrftr_block_type tInfo; + ULONG ulCharPosStart; + ULONG ulCharPosNext; + BOOL bUseful; + BOOL bTextOriginal; +} hdrftr_local_type; +typedef struct hdrftr_mem_tag { + hdrftr_local_type atElement[6]; +} hdrftr_mem_type; + +/* Variables needed to write the Header/footer Information List */ +static hdrftr_mem_type *pHdrFtrList = NULL; +static size_t tHdrFtrLen = 0; + + +/* + * vDestroyHdrFtrInfoList - destroy the Header/footer Information List + */ +void +vDestroyHdrFtrInfoList(void) +{ + hdrftr_mem_type *pRecord; + output_type *pCurr, *pNext; + size_t tHdrFtr, tIndex; + + DBG_MSG("vDestroyHdrFtrInfoList"); + + /* Free the Header/footer Information List */ + for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) { + pRecord = pHdrFtrList + tHdrFtr; + for (tIndex = 0; + tIndex < elementsof(pRecord->atElement); + tIndex++) { + if (!pRecord->atElement[tIndex].bTextOriginal) { + continue; + } + pCurr = pRecord->atElement[tIndex].tInfo.pText; + while (pCurr != NULL) { + pCurr->szStorage = xfree(pCurr->szStorage); + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + } + } + pHdrFtrList = xfree(pHdrFtrList); + /* Reset all control variables */ + tHdrFtrLen = 0; +} /* end of vDestroyHdrFtrInfoList */ + +/* + * vCreat8HdrFtrInfoList - Create the Header/footer Information List + */ +void +vCreat8HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength) +{ + hdrftr_mem_type *pListMember; + size_t tHdrFtr, tIndex, tMainIndex; + + fail(aulCharPos == NULL); + + DBG_DEC(tLength); + if (tLength <= 1) { + return; + } + tHdrFtrLen = tLength / 12; + if (tLength % 12 != 0 && tLength % 12 != 1) { + tHdrFtrLen++; + } + DBG_DEC(tHdrFtrLen); + + pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type)); + + for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) { + pListMember = pHdrFtrList + tHdrFtr; + for (tIndex = 0, tMainIndex = tHdrFtr * 12; + tIndex < 6 && tMainIndex < tLength; + tIndex++, tMainIndex++) { + pListMember->atElement[tIndex].tInfo.pText = NULL; + pListMember->atElement[tIndex].ulCharPosStart = + aulCharPos[tMainIndex]; + if (tMainIndex + 1 < tLength) { + pListMember->atElement[tIndex].ulCharPosNext = + aulCharPos[tMainIndex + 1]; + } else { + pListMember->atElement[tIndex].ulCharPosNext = + aulCharPos[tMainIndex]; + } + } + } +} /* end of vCreat8HdrFtrInfoList */ + +/* + * vCreat6HdrFtrInfoList - Create the Header/footer Information List + */ +void +vCreat6HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength) +{ + static const size_t atIndex[] = + { SIZE_T_MAX, SIZE_T_MAX, FTR_FIRST_PAGE, HDR_FIRST_PAGE, + FTR_ODD_PAGES, FTR_EVEN_PAGES, HDR_ODD_PAGES, HDR_EVEN_PAGES, + }; + hdrftr_mem_type *pListMember; + size_t tHdrFtr, tTmp, tIndex, tMainIndex, tBit; + UCHAR ucDopSpecification, ucSepSpecification; + + fail(aulCharPos == NULL); + + DBG_DEC(tLength); + if (tLength <= 1) { + return; + } + tHdrFtrLen = tGetNumberOfSections(); + if (tHdrFtrLen == 0) { + tHdrFtrLen = 1; + } + DBG_DEC(tHdrFtrLen); + + pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type)); + + /* Get the start index in aulCharPos */ + ucDopSpecification = ucGetDopHdrFtrSpecification(); + DBG_HEX(ucDopSpecification & 0xe0); + tMainIndex = 0; + for (tBit = 7; tBit >= 5; tBit--) { + if ((ucDopSpecification & BIT(tBit)) != 0) { + tMainIndex++; + } + } + DBG_DEC(tMainIndex); + + for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) { + ucSepSpecification = ucGetSepHdrFtrSpecification(tHdrFtr); + DBG_HEX(ucSepSpecification & 0xfc); + pListMember = pHdrFtrList + tHdrFtr; + for (tTmp = 0; + tTmp < elementsof(pListMember->atElement); + tTmp++) { + pListMember->atElement[tTmp].tInfo.pText = NULL; + } + for (tBit = 7; tBit >= 2; tBit--) { + if (tMainIndex >= tLength) { + break; + } + if ((ucSepSpecification & BIT(tBit)) == 0) { + continue; + } + tIndex = atIndex[tBit]; + fail(tIndex >= 6); + pListMember->atElement[tIndex].ulCharPosStart = + aulCharPos[tMainIndex]; + if (tMainIndex + 1 < tLength) { + pListMember->atElement[tIndex].ulCharPosNext = + aulCharPos[tMainIndex + 1]; + } else { + pListMember->atElement[tIndex].ulCharPosNext = + aulCharPos[tMainIndex]; + } + tMainIndex++; + } + } +} /* end of vCreat6HdrFtrInfoList */ + +/* + * vCreat2HdrFtrInfoList - Create the Header/footer Information List + */ +void +vCreat2HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength) +{ + vCreat6HdrFtrInfoList(aulCharPos, tLength); +} /* end of vCreat2HdrFtrInfoList */ + +/* + * pGetHdrFtrInfo - get the Header/footer information + */ +const hdrftr_block_type * +pGetHdrFtrInfo(int iSectionIndex, + BOOL bWantHeader, BOOL bOddPage, BOOL bFirstInSection) +{ + hdrftr_mem_type *pCurr; + + fail(iSectionIndex < 0); + fail(pHdrFtrList == NULL && tHdrFtrLen != 0); + + if (pHdrFtrList == NULL || tHdrFtrLen == 0) { + /* No information */ + return NULL; + } + + if (iSectionIndex < 0) { + iSectionIndex = 0; + } else if (iSectionIndex >= (int)tHdrFtrLen) { + iSectionIndex = (int)(tHdrFtrLen - 1); + } + + pCurr = pHdrFtrList + iSectionIndex; + + if (bFirstInSection) { + if (bWantHeader) { + return &pCurr->atElement[HDR_FIRST_PAGE].tInfo; + } else { + return &pCurr->atElement[FTR_FIRST_PAGE].tInfo; + } + } else { + if (bWantHeader) { + if (bOddPage) { + return &pCurr->atElement[HDR_ODD_PAGES].tInfo; + } else { + return &pCurr->atElement[HDR_EVEN_PAGES].tInfo; + } + } else { + if (bOddPage) { + return &pCurr->atElement[FTR_ODD_PAGES].tInfo; + } else { + return &pCurr->atElement[FTR_EVEN_PAGES].tInfo; + } + } + } +} /* end of pGetHdrFtrInfo */ + +/* + * lComputeHdrFtrHeight - compute the height of a header or footer + * + * Returns the height in DrawUnits + */ +static long +lComputeHdrFtrHeight(const output_type *pAnchor) +{ + const output_type *pCurr; + long lTotal; + USHORT usFontSizeMax; + + lTotal = 0; + usFontSizeMax = 0; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->tNextFree == 1) { + if (pCurr->szStorage[0] == PAR_END) { + /* End of a paragraph */ + lTotal += lComputeLeading(usFontSizeMax); + lTotal += lMilliPoints2DrawUnits( + (long)pCurr->usFontSize * 200); + usFontSizeMax = 0; + continue; + } + if (pCurr->szStorage[0] == HARD_RETURN) { + /* End of a line */ + lTotal += lComputeLeading(usFontSizeMax); + usFontSizeMax = 0; + continue; + } + } + if (pCurr->usFontSize > usFontSizeMax) { + usFontSizeMax = pCurr->usFontSize; + } + } + if (usFontSizeMax != 0) { + /* Height of the last paragraph */ + lTotal += lComputeLeading(usFontSizeMax); + } + return lTotal; +} /* end of lComputeHdrFtrHeight */ + +/* + * vPrepareHdrFtrText - prepare the header/footer text + */ +void +vPrepareHdrFtrText(FILE *pFile) +{ + hdrftr_mem_type *pCurr, *pPrev; + hdrftr_local_type *pTmp; + output_type *pText; + size_t tHdrFtr, tIndex; + + fail(pFile == NULL); + fail(pHdrFtrList == NULL && tHdrFtrLen != 0); + + if (pHdrFtrList == NULL || tHdrFtrLen == 0) { + /* No information */ + return; + } + + /* Fill text, text height and useful-ness */ + for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) { + pCurr = pHdrFtrList + tHdrFtr; + for (tIndex = 0; + tIndex < elementsof(pHdrFtrList->atElement); + tIndex++) { + pTmp = &pCurr->atElement[tIndex]; + pTmp->bUseful = + pTmp->ulCharPosStart != pTmp->ulCharPosNext; + if (pTmp->bUseful) { + pText = pHdrFtrDecryptor(pFile, + pTmp->ulCharPosStart, + pTmp->ulCharPosNext); + pTmp->tInfo.pText = pText; + pTmp->tInfo.lHeight = + lComputeHdrFtrHeight(pText); + pTmp->bTextOriginal = pText != NULL; + } else { + pTmp->tInfo.pText = NULL; + pTmp->tInfo.lHeight = 0; + pTmp->bTextOriginal = FALSE; + } + } + } + + /* Replace not-useful records by using inheritance */ + if (pHdrFtrList->atElement[HDR_FIRST_PAGE].bUseful) { + pTmp = &pHdrFtrList->atElement[HDR_ODD_PAGES]; + if (!pTmp->bUseful) { + *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE]; + pTmp->bTextOriginal = FALSE; + } + pTmp = &pHdrFtrList->atElement[HDR_EVEN_PAGES]; + if (!pTmp->bUseful) { + *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE]; + pTmp->bTextOriginal = FALSE; + } + } + if (pHdrFtrList->atElement[FTR_FIRST_PAGE].bUseful) { + pTmp = &pHdrFtrList->atElement[FTR_ODD_PAGES]; + if (!pTmp->bUseful) { + *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE]; + pTmp->bTextOriginal = FALSE; + } + pTmp = &pHdrFtrList->atElement[FTR_EVEN_PAGES]; + if (!pTmp->bUseful) { + *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE]; + pTmp->bTextOriginal = FALSE; + } + } + for (tHdrFtr = 1, pCurr = &pHdrFtrList[1]; + tHdrFtr < tHdrFtrLen; + tHdrFtr++, pCurr++) { + pPrev = pCurr - 1; + for (tIndex = 0; + tIndex < elementsof(pHdrFtrList->atElement); + tIndex++) { + if (!pCurr->atElement[tIndex].bUseful && + pPrev->atElement[tIndex].bUseful) { + pCurr->atElement[tIndex] = + pPrev->atElement[tIndex]; + pCurr->atElement[tIndex].bTextOriginal = FALSE; + } + } + } +} /* end of vPrepareHdrFtrText */ diff --git a/icons.c b/icons.c new file mode 100644 index 0000000..dd88c00 --- /dev/null +++ b/icons.c @@ -0,0 +1,96 @@ +/* + * icons.c + * Copyright (C) 1998-2001 A.J. van Os; Released under GPL + * + * Description: + * Update window icons + */ + +#include +#include "DeskLib:Error.h" +#include "DeskLib:WimpSWIs.h" +#include "antiword.h" + +void +vUpdateIcon(window_handle tWindow, icon_block *pIcon) +{ + window_redrawblock tRedraw; + BOOL bMore; + + tRedraw.window = tWindow; + tRedraw.rect = pIcon->workarearect; + Error_CheckFatal(Wimp_UpdateWindow(&tRedraw, &bMore)); + while (bMore) { + Error_CheckFatal(Wimp_PlotIcon(pIcon)); + Error_CheckFatal(Wimp_GetRectangle(&tRedraw, &bMore)); + } +} /* end of vUpdateIcon */ + +void +vUpdateRadioButton(window_handle tWindow, icon_handle tIconNumber, + BOOL bSelected) +{ + icon_block tIcon; + + Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon)); + DBG_DEC(tIconNumber); + DBG_HEX(tIcon.flags.data.selected); + if (bSelected == (tIcon.flags.data.selected == 1)) { + /* No update needed */ + return; + } + Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber, + bSelected ? 0x00200000 : 0, 0x00200000)); + vUpdateIcon(tWindow, &tIcon); +} /* end of vUpdateRadioButton */ + +/* + * vUpdateWriteable - update a writeable icon with a string + */ +void +vUpdateWriteable(window_handle tWindow, icon_handle tIconNumber, + const char *szString) +{ + icon_block tIcon; + caret_block tCaret; + int iLen; + + fail(szString == NULL); + + NO_DBG_DEC(tIconNumber); + NO_DBG_MSG(szString); + + Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon)); + NO_DBG_HEX(tIcon.flags); + if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) { + werr(1, "Icon %d must be indirected text", (int)tIconNumber); + return; + } + strncpy(tIcon.data.indirecttext.buffer, + szString, + tIcon.data.indirecttext.bufflen - 1); + /* Ensure the caret is behind the last character of the text */ + Error_CheckFatal(Wimp_GetCaretPosition(&tCaret)); + if (tCaret.window == tWindow && tCaret.icon == tIconNumber) { + iLen = strlen(tIcon.data.indirecttext.buffer); + if (tCaret.index != iLen) { + tCaret.index = iLen; + Error_CheckFatal(Wimp_SetCaretPosition(&tCaret)); + } + } + Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber, 0, 0)); + vUpdateIcon(tWindow, &tIcon); +} /* end of vUpdateWriteable */ + +/* + * vUpdateWriteableNumber - update a writeable icon with a number + */ +void +vUpdateWriteableNumber(window_handle tWindow, icon_handle tIconNumber, + int iNumber) +{ + char szTmp[1+3*sizeof(int)+1]; + + (void)sprintf(szTmp, "%d", iNumber); + vUpdateWriteable(tWindow, tIconNumber, szTmp); +} /* end of vUpdateWriteableNumber */ diff --git a/imgexam.c b/imgexam.c new file mode 100644 index 0000000..2b8384a --- /dev/null +++ b/imgexam.c @@ -0,0 +1,1044 @@ +/* + * imgexam.c + * Copyright (C) 2000-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to examine image headers + * + *================================================================ + * Part of this software is based on: + * jpeg2ps - convert JPEG compressed images to PostScript Level 2 + * Copyright (C) 1994-99 Thomas Merz (tm@muc.de) + *================================================================ + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include +#include +#include "antiword.h" + +/* BMP compression types */ +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 + +/* PNG colortype bits */ +#define PNG_CB_PALETTE 0x01 +#define PNG_CB_COLOR 0x02 +#define PNG_CB_ALPHA 0x04 + +/* Instance signature */ +#define MSOBI_WMF 0x0216 +#define MSOBI_EMF 0x03d4 +#define MSOBI_PICT 0x0542 +#define MSOBI_PNG 0x06e0 +#define MSOBI_JPEG 0x046a +#define MSOBI_DIB 0x07a8 + +/* The following enum is stolen from the IJG JPEG library */ +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, /* baseline DCT */ + M_SOF1 = 0xc1, /* extended sequential DCT */ + M_SOF2 = 0xc2, /* progressive DCT */ + M_SOF3 = 0xc3, /* lossless (sequential) */ + + M_SOF5 = 0xc5, /* differential sequential DCT */ + M_SOF6 = 0xc6, /* differential progressive DCT */ + M_SOF7 = 0xc7, /* differential lossless */ + + M_JPG = 0xc8, /* JPEG extensions */ + M_SOF9 = 0xc9, /* extended sequential DCT */ + M_SOF10 = 0xca, /* progressive DCT */ + M_SOF11 = 0xcb, /* lossless (sequential) */ + + M_SOF13 = 0xcd, /* differential sequential DCT */ + M_SOF14 = 0xce, /* differential progressive DCT */ + M_SOF15 = 0xcf, /* differential lossless */ + + M_DHT = 0xc4, /* define Huffman tables */ + + M_DAC = 0xcc, /* define arithmetic conditioning table */ + + M_RST0 = 0xd0, /* restart */ + M_RST1 = 0xd1, /* restart */ + M_RST2 = 0xd2, /* restart */ + M_RST3 = 0xd3, /* restart */ + M_RST4 = 0xd4, /* restart */ + M_RST5 = 0xd5, /* restart */ + M_RST6 = 0xd6, /* restart */ + M_RST7 = 0xd7, /* restart */ + + M_SOI = 0xd8, /* start of image */ + M_EOI = 0xd9, /* end of image */ + M_SOS = 0xda, /* start of scan */ + M_DQT = 0xdb, /* define quantization tables */ + M_DNL = 0xdc, /* define number of lines */ + M_DRI = 0xdd, /* define restart interval */ + M_DHP = 0xde, /* define hierarchical progression */ + M_EXP = 0xdf, /* expand reference image(s) */ + + M_APP0 = 0xe0, /* application marker, used for JFIF */ + M_APP1 = 0xe1, /* application marker */ + M_APP2 = 0xe2, /* application marker */ + M_APP3 = 0xe3, /* application marker */ + M_APP4 = 0xe4, /* application marker */ + M_APP5 = 0xe5, /* application marker */ + M_APP6 = 0xe6, /* application marker */ + M_APP7 = 0xe7, /* application marker */ + M_APP8 = 0xe8, /* application marker */ + M_APP9 = 0xe9, /* application marker */ + M_APP10 = 0xea, /* application marker */ + M_APP11 = 0xeb, /* application marker */ + M_APP12 = 0xec, /* application marker */ + M_APP13 = 0xed, /* application marker */ + M_APP14 = 0xee, /* application marker, used by Adobe */ + M_APP15 = 0xef, /* application marker */ + + M_JPG0 = 0xf0, /* reserved for JPEG extensions */ + M_JPG13 = 0xfd, /* reserved for JPEG extensions */ + M_COM = 0xfe, /* comment */ + + M_TEM = 0x01 /* temporary use */ +} JPEG_MARKER; + + +/* + * bFillPaletteDIB - fill the palette part of the imagesdata + * + * returns TRUE if the images must be a color image, otherwise FALSE; + */ +static BOOL +bFillPaletteDIB(FILE *pFile, imagedata_type *pImg, BOOL bNewFormat) +{ + int iIndex; + BOOL bIsColorPalette; + + fail(pFile == NULL); + fail(pImg == NULL); + + if (pImg->uiBitsPerComponent > 8) { + /* No palette, image uses more than 256 colors */ + return TRUE; + } + + if (pImg->iColorsUsed <= 0) { + /* Not specified, so compute the number of colors used */ + pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent; + } + + fail(pImg->iColorsUsed > 256); + if (pImg->iColorsUsed > 256) { + pImg->iColorsUsed = 256; + } + + bIsColorPalette = FALSE; + for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) { + /* From BGR order to RGB order */ + pImg->aucPalette[iIndex][2] = (UCHAR)iNextByte(pFile); + pImg->aucPalette[iIndex][1] = (UCHAR)iNextByte(pFile); + pImg->aucPalette[iIndex][0] = (UCHAR)iNextByte(pFile); + if (bNewFormat) { + (void)iNextByte(pFile); + } + NO_DBG_PRINT_BLOCK(pImg->aucPalette[iIndex], 3); + if (pImg->aucPalette[iIndex][0] != + pImg->aucPalette[iIndex][1] || + pImg->aucPalette[iIndex][1] != + pImg->aucPalette[iIndex][2]) { + bIsColorPalette = TRUE; + } + } + + return bIsColorPalette; +} /* end of bFillPaletteDIB */ + +/* + * bExamineDIB - Examine a DIB header + * + * return TRUE if successful, otherwise FALSE + */ +static BOOL +bExamineDIB(FILE *pFile, imagedata_type *pImg) +{ + size_t tHeaderSize; + int iPlanes, iCompression; + + tHeaderSize = (size_t)ulNextLong(pFile); + switch (tHeaderSize) { + case 12: + pImg->iWidth = (int)usNextWord(pFile); + pImg->iHeight = (int)usNextWord(pFile); + iPlanes = (int)usNextWord(pFile); + pImg->uiBitsPerComponent = (UINT)usNextWord(pFile); + iCompression = BI_RGB; + pImg->iColorsUsed = 0; + break; + case 40: + case 64: + pImg->iWidth = (int)ulNextLong(pFile); + pImg->iHeight = (int)ulNextLong(pFile); + iPlanes = (int)usNextWord(pFile); + pImg->uiBitsPerComponent = (UINT)usNextWord(pFile); + iCompression = (int)ulNextLong(pFile); + (void)tSkipBytes(pFile, 12); + pImg->iColorsUsed = (int)ulNextLong(pFile); + (void)tSkipBytes(pFile, tHeaderSize - 36); + break; + default: + DBG_DEC(tHeaderSize); + return FALSE; + } + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + DBG_DEC(pImg->uiBitsPerComponent); + DBG_DEC(iCompression); + DBG_DEC(pImg->iColorsUsed); + + /* Do some sanity checks with the parameters */ + if (iPlanes != 1) { + DBG_DEC(iPlanes); + return FALSE; + } + if (pImg->iWidth <= 0 || pImg->iHeight <= 0) { + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + return FALSE; + } + if (pImg->uiBitsPerComponent != 1 && pImg->uiBitsPerComponent != 4 && + pImg->uiBitsPerComponent != 8 && pImg->uiBitsPerComponent != 24) { + DBG_DEC(pImg->uiBitsPerComponent); + return FALSE; + } + if (iCompression != BI_RGB && + (pImg->uiBitsPerComponent == 1 || pImg->uiBitsPerComponent == 24)) { + return FALSE; + } + if (iCompression == BI_RLE8 && pImg->uiBitsPerComponent == 4) { + return FALSE; + } + if (iCompression == BI_RLE4 && pImg->uiBitsPerComponent == 8) { + return FALSE; + } + + switch (iCompression) { + case BI_RGB: + pImg->eCompression = compression_none; + break; + case BI_RLE4: + pImg->eCompression = compression_rle4; + break; + case BI_RLE8: + pImg->eCompression = compression_rle8; + break; + default: + DBG_DEC(iCompression); + return FALSE; + } + + pImg->bColorImage = bFillPaletteDIB(pFile, pImg, tHeaderSize > 12); + + if (pImg->uiBitsPerComponent <= 8) { + pImg->iComponents = 1; + } else { + pImg->iComponents = (int)(pImg->uiBitsPerComponent / 8); + } + + return TRUE; +} /* end of bExamineDIB */ + +/* + * iNextMarker - read the next JPEG marker + */ +static int +iNextMarker(FILE *pFile) +{ + int iMarker; + + do { + do { + iMarker = iNextByte(pFile); + } while (iMarker != 0xff && iMarker != EOF); + if (iMarker == EOF) { + return EOF; + } + do { + iMarker = iNextByte(pFile); + } while (iMarker == 0xff); + } while (iMarker == 0x00); /* repeat if ff/00 */ + + return iMarker; +} /* end of iNextMarker */ + +/* + * bExamineJPEG - Examine a JPEG header + * + * return TRUE if successful, otherwise FALSE + */ +static BOOL +bExamineJPEG(FILE *pFile, imagedata_type *pImg) +{ + size_t tLength; + int iMarker, iIndex; + char appstring[10]; + BOOL bSOFDone; + + tLength = 0; + bSOFDone = FALSE; + + /* process JPEG markers */ + while (!bSOFDone && (iMarker = iNextMarker(pFile)) != (int)M_EOI) { + switch (iMarker) { + case EOF: + DBG_MSG("Error: unexpected end of JPEG file"); + return FALSE; + /* The following are not officially supported in PostScript level 2 */ + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + DBG_HEX(iMarker); + return FALSE; + case M_SOF0: + case M_SOF1: + tLength = (size_t)usNextWordBE(pFile); + pImg->uiBitsPerComponent = (UINT)iNextByte(pFile); + pImg->iHeight = (int)usNextWordBE(pFile); + pImg->iWidth = (int)usNextWordBE(pFile); + pImg->iComponents = iNextByte(pFile); + bSOFDone = TRUE; + break; + case M_APP14: + /* + * Check for Adobe application marker. It is known (per Adobe's + * TN5116) to contain the string "Adobe" at the start of the + * APP14 marker. + */ + tLength = (size_t)usNextWordBE(pFile); + if (tLength < 12) { + (void)tSkipBytes(pFile, tLength - 2); + } else { + for (iIndex = 0; iIndex < 5; iIndex++) { + appstring[iIndex] = + (char)iNextByte(pFile); + } + appstring[5] = '\0'; + if (STREQ(appstring, "Adobe")) { + pImg->bAdobe = TRUE; + } + (void)tSkipBytes(pFile, tLength - 7); + } + break; + case M_SOI: /* ignore markers without parameters */ + case M_EOI: + case M_TEM: + case M_RST0: + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + break; + default: /* skip variable length markers */ + tLength = (size_t)usNextWordBE(pFile); + (void)tSkipBytes(pFile, tLength - 2); + break; + } + } + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + DBG_DEC(pImg->uiBitsPerComponent); + DBG_DEC(pImg->iComponents); + + /* Do some sanity checks with the parameters */ + if (pImg->iHeight <= 0 || + pImg->iWidth <= 0 || + pImg->iComponents <= 0) { + DBG_DEC(pImg->iHeight); + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iComponents); + return FALSE; + } + + /* Some broken JPEG files have this but they print anyway... */ + if (pImg->iComponents * 3 + 8 != (int)tLength) { + DBG_MSG("Warning: SOF marker has incorrect length - ignored"); + } + + if (pImg->uiBitsPerComponent != 8) { + DBG_DEC(pImg->uiBitsPerComponent); + DBG_MSG("Not supported in PostScript level 2"); + return FALSE; + } + + if (pImg->iComponents != 1 && + pImg->iComponents != 3 && + pImg->iComponents != 4) { + DBG_DEC(pImg->iComponents); + return FALSE; + } + + pImg->bColorImage = pImg->iComponents >= 3; + pImg->iColorsUsed = 0; + pImg->eCompression = compression_jpeg; + + return TRUE; +} /* end of bExamineJPEG */ + +/* + * bFillPalettePNG - fill the palette part of the imagesdata + * + * returns TRUE if sucessful, otherwise FALSE; + */ +static BOOL +bFillPalettePNG(FILE *pFile, imagedata_type *pImg, size_t tLength) +{ + int iIndex, iEntries; + + fail(pFile == NULL); + fail(pImg == NULL); + + if (pImg->uiBitsPerComponent > 8) { + /* No palette, image uses more than 256 colors */ + return TRUE; + } + + if (!pImg->bColorImage) { + /* Only color images can have a palette */ + return FALSE; + } + + if (tLength % 3 != 0) { + /* Each palette entry takes three bytes */ + DBG_DEC(tLength); + return FALSE; + } + + iEntries = (int)(tLength / 3); + DBG_DEC(iEntries); + pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent; + DBG_DEC(pImg->iColorsUsed); + + if (iEntries > 256) { + DBG_DEC(iEntries); + return FALSE; + } + + for (iIndex = 0; iIndex < iEntries; iIndex++) { + pImg->aucPalette[iIndex][0] = (UCHAR)iNextByte(pFile); + pImg->aucPalette[iIndex][1] = (UCHAR)iNextByte(pFile); + pImg->aucPalette[iIndex][2] = (UCHAR)iNextByte(pFile); + NO_DBG_PRINT_BLOCK(pImg->aucPalette[iIndex], 3); + } + for (;iIndex < pImg->iColorsUsed; iIndex++) { + pImg->aucPalette[iIndex][0] = 0; + pImg->aucPalette[iIndex][1] = 0; + pImg->aucPalette[iIndex][2] = 0; + } + + return TRUE; +} /* end of bFillPalettePNG */ + +/* + * bExaminePNG - Examine a PNG header + * + * return TRUE if successful, otherwise FALSE + */ +static BOOL +bExaminePNG(FILE *pFile, imagedata_type *pImg) +{ + size_t tLength; + ULONG ulLong1, ulLong2, ulName; + int iIndex, iTmp; + int iCompressionMethod, iFilterMethod, iInterlaceMethod; + int iColor, iIncrement; + BOOL bHasPalette, bHasAlpha; + UCHAR aucBuf[4]; + + /* Check signature */ + ulLong1 = ulNextLongBE(pFile); + ulLong2 = ulNextLongBE(pFile); + if (ulLong1 != 0x89504e47UL || ulLong2 != 0x0d0a1a0aUL) { + DBG_HEX(ulLong1); + DBG_HEX(ulLong2); + return FALSE; + } + + ulName = 0x00; + bHasPalette = FALSE; + + /* Examine chunks */ + while (ulName != PNG_CN_IEND) { + tLength = (size_t)ulNextLongBE(pFile); + ulName = 0x00; + for (iIndex = 0; iIndex < (int)elementsof(aucBuf); iIndex++) { + aucBuf[iIndex] = (UCHAR)iNextByte(pFile); + if (!isalpha(aucBuf[iIndex])) { + DBG_HEX(aucBuf[iIndex]); + return FALSE; + } + ulName <<= 8; + ulName |= aucBuf[iIndex]; + } + + switch (ulName) { + case PNG_CN_IHDR: + /* Header chunck */ + if (tLength < 13) { + DBG_DEC(tLength); + return FALSE; + } + pImg->iWidth = (int)ulNextLongBE(pFile); + pImg->iHeight = (int)ulNextLongBE(pFile); + pImg->uiBitsPerComponent = (UINT)iNextByte(pFile); + iTmp = iNextByte(pFile); + NO_DBG_HEX(iTmp); + pImg->bColorImage = (iTmp & PNG_CB_COLOR) != 0; + bHasPalette = (iTmp & PNG_CB_PALETTE) != 0; + bHasAlpha = (iTmp & PNG_CB_ALPHA) != 0; + if (bHasPalette && pImg->uiBitsPerComponent > 8) { + /* This should not happen */ + return FALSE; + } + pImg->iComponents = + (bHasPalette || !pImg->bColorImage) ? 1 : 3; + if (bHasAlpha) { + pImg->iComponents++; + } + iCompressionMethod = iNextByte(pFile); + if (iCompressionMethod != 0) { + DBG_DEC(iCompressionMethod); + return FALSE; + } + iFilterMethod = iNextByte(pFile); + if (iFilterMethod != 0) { + DBG_DEC(iFilterMethod); + return FALSE; + } + iInterlaceMethod = iNextByte(pFile); + if (iInterlaceMethod != 0) { + DBG_DEC(iInterlaceMethod); + return FALSE; + } + pImg->iColorsUsed = 0; + (void)tSkipBytes(pFile, tLength - 13 + 4); + break; + case PNG_CN_PLTE: + if (!bHasPalette) { + return FALSE; + } + if (!bFillPalettePNG(pFile, pImg, tLength)) { + return FALSE; + } + (void)tSkipBytes(pFile, 4); + break; + default: + (void)tSkipBytes(pFile, tLength + 4); + break; + } + } + + DBG_DEC(pImg->iWidth); + DBG_DEC(pImg->iHeight); + DBG_DEC(pImg->uiBitsPerComponent); + DBG_DEC(pImg->iColorsUsed); + DBG_DEC(pImg->iComponents); + + /* Do some sanity checks with the parameters */ + if (pImg->iWidth <= 0 || pImg->iHeight <= 0) { + return FALSE; + } + + if (pImg->uiBitsPerComponent != 1 && pImg->uiBitsPerComponent != 2 && + pImg->uiBitsPerComponent != 4 && pImg->uiBitsPerComponent != 8 && + pImg->uiBitsPerComponent != 16) { + DBG_DEC(pImg->uiBitsPerComponent); + return FALSE; + } + + if (pImg->iComponents != 1 && pImg->iComponents != 3) { + /* Not supported */ + DBG_DEC(pImg->iComponents); + return FALSE; + } + + if (pImg->uiBitsPerComponent > 8) { + /* Not supported */ + DBG_DEC(pImg->uiBitsPerComponent); + return FALSE; + } + + if (pImg->iColorsUsed == 0 && + pImg->iComponents == 1 && + pImg->uiBitsPerComponent <= 4) { + /* + * No palette is supplied, but PostScript needs one in these + * cases, so we add a default palette here + */ + pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent; + iIncrement = 0xff / (pImg->iColorsUsed - 1); + for (iIndex = 0, iColor = 0x00; + iIndex < pImg->iColorsUsed; + iIndex++, iColor += iIncrement) { + pImg->aucPalette[iIndex][0] = (UCHAR)iColor; + pImg->aucPalette[iIndex][1] = (UCHAR)iColor; + pImg->aucPalette[iIndex][2] = (UCHAR)iColor; + } + /* Just to be sure */ + pImg->bColorImage = FALSE; + } + + pImg->eCompression = compression_zlib; + + return TRUE; +} /* end of bExaminePNG */ + +/* + * bExamineWMF - Examine a WMF header + * + * return TRUE if successful, otherwise FALSE + */ +static BOOL +bExamineWMF(FILE *pFile, imagedata_type *pImg) +{ + ULONG ulFileSize, ulMaxRecord, ulMagic; + USHORT usType, usHeaderSize, usVersion, usNoObjects; + + usType = usNextWord(pFile); + usHeaderSize = usNextWord(pFile); + ulMagic = ((ULONG)usHeaderSize << 16) | (ULONG)usType; + usVersion = usNextWord(pFile); + ulFileSize = ulNextLong(pFile); + usNoObjects = usNextWord(pFile); + ulMaxRecord = ulNextLong(pFile); + + DBG_HEX(ulMagic); + DBG_DEC(usType); + DBG_DEC(usHeaderSize); + DBG_HEX(usVersion); + DBG_DEC(ulFileSize); + DBG_DEC(usNoObjects); + DBG_DEC(ulMaxRecord); + + return FALSE; +} /* end of bExamineWMF */ + +#if !defined(__riscos) +/* + * vImage2Papersize - make sure the image fits on the paper + * + * This function should not be needed if Word would do a proper job + */ +static void +vImage2Papersize(imagedata_type *pImg) +{ + static int iNetPageHeight = -1; + static int iNetPageWidth = -1; + options_type tOptions; + double dVerFactor, dHorFactor, dFactor; + + DBG_MSG("vImage2Papersize"); + + fail(pImg == NULL); + + if (iNetPageHeight < 0 || iNetPageWidth < 0) { + /* Get the page dimensions from the options */ + vGetOptions(&tOptions); + /* Add 999 to err on the save side */ + iNetPageHeight = tOptions.iPageHeight - + (lDrawUnits2MilliPoints( + PS_TOP_MARGIN + PS_BOTTOM_MARGIN) + + 999) / 1000; + iNetPageWidth = tOptions.iPageWidth - + (lDrawUnits2MilliPoints( + PS_LEFT_MARGIN + PS_RIGHT_MARGIN) + + 999) / 1000; + DBG_DEC(iNetPageHeight); + DBG_DEC(iNetPageWidth); + } + + if (pImg->iVerSizeScaled < iNetPageHeight && + pImg->iHorSizeScaled < iNetPageWidth) { + /* The image fits on the paper */ + return; + } + + dVerFactor = (double)iNetPageHeight / (double)pImg->iVerSizeScaled; + dHorFactor = (double)iNetPageWidth / (double)pImg->iHorSizeScaled; + dFactor = min(dVerFactor, dHorFactor); + DBG_FLT(dFactor); + /* Round down, just to be on the save side */ + pImg->iVerSizeScaled = (int)(pImg->iVerSizeScaled * dFactor); + pImg->iHorSizeScaled = (int)(pImg->iHorSizeScaled * dFactor); +} /* end of vImage2Papersize */ +#endif /* !__riscos */ + +/* + * tFind6Image - skip until the image is found + * + * Find the image in Word 6/7 files + * + * returns the new position when a image is found, otherwise -1 + */ +static size_t +tFind6Image(FILE *pFile, size_t tPosition, size_t tLength, + imagetype_enum *peImageType) +{ + ULONG ulMarker; + size_t tRecordLength, tToSkip; + USHORT usMarker; + + fail(pFile == NULL); + fail(peImageType == NULL); + + *peImageType = imagetype_is_unknown; + if (tPosition + 18 >= tLength) { + return (size_t)-1; + } + + ulMarker = ulNextLong(pFile); + if (ulMarker != 0x00090001) { + DBG_HEX(ulMarker); + return (size_t)-1; + } + usMarker = usNextWord(pFile); + if (usMarker != 0x0300) { + DBG_HEX(usMarker); + return (size_t)-1; + } + (void)tSkipBytes(pFile, 10); + usMarker = usNextWord(pFile); + if (usMarker != 0x0000) { + DBG_HEX(usMarker); + return (size_t)-1; + } + tPosition += 18; + + while (tPosition + 6 <= tLength) { + tRecordLength = (size_t)ulNextLong(pFile); + usMarker = usNextWord(pFile); + tPosition += 6; + NO_DBG_DEC(tRecordLength); + NO_DBG_HEX(usMarker); + switch (usMarker) { + case 0x0000: + DBG_HEX(ulGetDataOffset(pFile)); + return (size_t)-1; + case 0x0b41: + DBG_MSG("DIB"); + *peImageType = imagetype_is_dib; + tPosition += tSkipBytes(pFile, 20); + return tPosition; + case 0x0f43: + DBG_MSG("DIB"); + *peImageType = imagetype_is_dib; + tPosition += tSkipBytes(pFile, 22); + return tPosition; + default: + if (tRecordLength < 3) { + break; + } + if (tRecordLength > SIZE_T_MAX / 2) { + /* + * No need to compute the number of bytes + * to skip + */ + DBG_DEC(tRecordLength); + DBG_HEX(tRecordLength); + DBG_FIXME(); + return (size_t)-1; + } + tToSkip = tRecordLength * 2 - 6; + if (tToSkip > tLength - tPosition) { + /* You can't skip this number of bytes */ + DBG_DEC(tToSkip); + DBG_DEC(tLength - tPosition); + return (size_t)-1; + } + tPosition += tSkipBytes(pFile, tToSkip); + break; + } + } + + return (size_t)-1; +} /* end of tFind6Image */ + +/* + * tFind8Image - skip until the image is found + * + * Find the image in Word 8/9/10 files + * + * returns the new position when a image is found, otherwise -1 + */ +static size_t +tFind8Image(FILE *pFile, size_t tPosition, size_t tLength, + imagetype_enum *peImageType) +{ + size_t tRecordLength, tNameLen; + USHORT usRecordVersion, usRecordType, usRecordInstance; + USHORT usTmp; + + fail(pFile == NULL); + fail(peImageType == NULL); + + *peImageType = imagetype_is_unknown; + while (tPosition + 8 <= tLength) { + usTmp = usNextWord(pFile); + usRecordVersion = usTmp & 0x000f; + usRecordInstance = usTmp >> 4; + usRecordType = usNextWord(pFile); + tRecordLength = (size_t)ulNextLong(pFile); + tPosition += 8; + NO_DBG_HEX(usRecordVersion); + NO_DBG_HEX(usRecordInstance); + NO_DBG_HEX(usRecordType); + NO_DBG_DEC(tRecordLength); + switch (usRecordType) { + case 0xf000: case 0xf001: case 0xf002: case 0xf003: + case 0xf004: case 0xf005: + break; + case 0xf007: + tPosition += tSkipBytes(pFile, 33); + tNameLen = (size_t)iNextByte(pFile); + tPosition++; + DBG_DEC_C(tNameLen != 0, tNameLen); + tPosition += tSkipBytes(pFile, 2 + tNameLen * 2); + break; + case 0xf008: + tPosition += tSkipBytes(pFile, 8); + break; + case 0xf009: + tPosition += tSkipBytes(pFile, 16); + break; + case 0xf006: case 0xf00a: case 0xf00b: case 0xf00d: + case 0xf00e: case 0xf00f: case 0xf010: case 0xf011: + case 0xf122: + tPosition += tSkipBytes(pFile, tRecordLength); + break; + case 0xf01a: + DBG_MSG("EMF"); + *peImageType = imagetype_is_emf; + tPosition += tSkipBytes(pFile, 50); + if ((usRecordInstance ^ MSOBI_EMF) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf01b: + DBG_MSG("WMF"); + *peImageType = imagetype_is_wmf; + tPosition += tSkipBytes(pFile, 50); + if ((usRecordInstance ^ MSOBI_WMF) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf01c: + DBG_MSG("PICT"); + *peImageType = imagetype_is_pict; + tPosition += tSkipBytes(pFile, 50); + if ((usRecordInstance ^ MSOBI_PICT) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf01d: + DBG_MSG("JPEG"); + *peImageType = imagetype_is_jpeg; + tPosition += tSkipBytes(pFile, 17); + if ((usRecordInstance ^ MSOBI_JPEG) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf01e: + DBG_MSG("PNG"); + *peImageType = imagetype_is_png; + tPosition += tSkipBytes(pFile, 17); + if ((usRecordInstance ^ MSOBI_PNG) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf01f: + DBG_MSG("DIB"); + /* DIB is a BMP minus its 14 byte header */ + *peImageType = imagetype_is_dib; + tPosition += tSkipBytes(pFile, 17); + if ((usRecordInstance ^ MSOBI_DIB) == 1) { + tPosition += tSkipBytes(pFile, 16); + } + return tPosition; + case 0xf00c: + default: + DBG_HEX(usRecordType); + DBG_DEC_C(tRecordLength % 4 != 0, tRecordLength); + DBG_FIXME(); + return (size_t)-1; + } + } + + return (size_t)-1; +} /* end of tFind8Image */ + +/* + * eExamineImage - Examine the image + * + * Returns an indication of the amount of information found + */ +image_info_enum +eExamineImage(FILE *pFile, ULONG ulFileOffsetImage, imagedata_type *pImg) +{ + long lTmp; + size_t tWordHeaderLen, tLength, tPos; + int iType, iHorSize, iVerSize; + USHORT usHorScalingFactor, usVerScalingFactor; + + if (ulFileOffsetImage == FC_INVALID) { + return image_no_information; + } + DBG_HEX(ulFileOffsetImage); + + if (!bSetDataOffset(pFile, ulFileOffsetImage)) { + return image_no_information; + } + + tLength = (size_t)ulNextLong(pFile); + DBG_DEC(tLength); + if (tLength < 46) { + /* Smaller than the smallest known header */ + DBG_FIXME(); + return image_no_information; + } + tWordHeaderLen = (size_t)usNextWord(pFile); + DBG_DEC(tWordHeaderLen); + fail(tWordHeaderLen != 46 && + tWordHeaderLen != 58 && + tWordHeaderLen != 68); + + if (tLength < tWordHeaderLen) { + /* Smaller than the current header */ + return image_no_information; + } + iType = (int)usNextWord(pFile); + DBG_DEC(iType); + (void)tSkipBytes(pFile, 28 - 8); + + lTmp = lTwips2MilliPoints(usNextWord(pFile)); + iHorSize = (int)(lTmp / 1000); + if (lTmp % 1000 != 0) { + iHorSize++; + } + DBG_DEC(iHorSize); + lTmp = lTwips2MilliPoints(usNextWord(pFile)); + iVerSize = (int)(lTmp / 1000); + if (lTmp % 1000 != 0) { + iVerSize++; + } + DBG_DEC(iVerSize); + + usHorScalingFactor = usNextWord(pFile); + DBG_DEC(usHorScalingFactor); + usVerScalingFactor = usNextWord(pFile); + DBG_DEC(usVerScalingFactor); + + /* Sanity checks */ + lTmp = (long)iHorSize * (long)usHorScalingFactor; + if (lTmp < 2835) { + /* This image would be less than 1 millimeter wide */ + DBG_DEC(lTmp); + return image_no_information; + } + lTmp = (long)iVerSize * (long)usVerScalingFactor; + if (lTmp < 2835) { + /* This image would be less than 1 millimeter high */ + DBG_DEC(lTmp); + return image_no_information; + } + + /* Skip the rest of the header */ + (void)tSkipBytes(pFile, tWordHeaderLen - 36); + tPos = tWordHeaderLen; + + (void)memset(pImg, 0, sizeof(*pImg)); + + switch (iType) { + case 7: + case 8: + tPos = tFind6Image(pFile, tPos, tLength, &pImg->eImageType); + if (tPos == (size_t)-1) { + /* No image found */ + return image_no_information; + } + DBG_HEX(tPos); + break; + case 94: /* Word 6/7, no image just a pathname */ + pImg->eImageType = imagetype_is_external; + DBG_HEX(ulFileOffsetImage + tPos); + break; + case 100: + tPos = tFind8Image(pFile, tPos, tLength, &pImg->eImageType); + if (tPos == (size_t)-1) { + /* No image found */ + return image_no_information; + } + DBG_HEX(tPos); + break; + case 102: /* Word 8/9/10, no image just a pathname or URL */ + pImg->eImageType = imagetype_is_external; + DBG_HEX(ulFileOffsetImage + tPos); + break; + default: + DBG_DEC(iType); + DBG_HEX(ulFileOffsetImage + tPos); + DBG_FIXME(); + return image_no_information; + } + + /* Minimal information is now available */ + pImg->tLength = tLength; + pImg->tPosition = tPos; + pImg->iHorSizeScaled = + (int)(((long)iHorSize * (long)usHorScalingFactor + 500) / 1000); + pImg->iVerSizeScaled = + (int)(((long)iVerSize * (long)usVerScalingFactor + 500) / 1000); +#if !defined(__riscos) + vImage2Papersize(pImg); +#endif /* !__riscos */ + + /* Image type specific examinations */ + switch (pImg->eImageType) { + case imagetype_is_dib: + if (bExamineDIB(pFile, pImg)) { + return image_full_information; + } + return image_minimal_information; + case imagetype_is_jpeg: + if (bExamineJPEG(pFile, pImg)) { + return image_full_information; + } + return image_minimal_information; + case imagetype_is_png: + if (bExaminePNG(pFile, pImg)) { + return image_full_information; + } + return image_minimal_information; + case imagetype_is_wmf: + if (bExamineWMF(pFile, pImg)) { + return image_full_information; + } + return image_minimal_information; + case imagetype_is_emf: + case imagetype_is_pict: + case imagetype_is_external: + return image_minimal_information; + case imagetype_is_unknown: + default: + return image_no_information; + } +} /* end of eExamineImage */ diff --git a/imgtrans.c b/imgtrans.c new file mode 100644 index 0000000..1b284c4 --- /dev/null +++ b/imgtrans.c @@ -0,0 +1,71 @@ +/* + * imgtrans.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Generic functions to translate Word images + */ + +#include +#include "antiword.h" + + +/* + * bTranslateImage - translate the image + * + * This function reads the type of the given image and and gets it translated. + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslateImage(diagram_type *pDiag, FILE *pFile, BOOL bMinimalInformation, + ULONG ulFileOffsetImage, const imagedata_type *pImg) +{ + options_type tOptions; + + DBG_MSG("bTranslateImage"); + + fail(pDiag == NULL); + fail(pFile == NULL); + fail(ulFileOffsetImage == FC_INVALID); + fail(pImg == NULL); + fail(pImg->iHorSizeScaled <= 0); + fail(pImg->iVerSizeScaled <= 0); + + vGetOptions(&tOptions); + fail(tOptions.eImageLevel == level_no_images); + + if (bMinimalInformation) { + return bAddDummyImage(pDiag, pImg); + } + + switch (pImg->eImageType) { + case imagetype_is_dib: + return bTranslateDIB(pDiag, pFile, + ulFileOffsetImage + pImg->tPosition, + pImg); + case imagetype_is_jpeg: + return bTranslateJPEG(pDiag, pFile, + ulFileOffsetImage + pImg->tPosition, + pImg->tLength - pImg->tPosition, + pImg); + case imagetype_is_png: + if (tOptions.eImageLevel == level_ps_2) { + return bAddDummyImage(pDiag, pImg); + } + return bTranslatePNG(pDiag, pFile, + ulFileOffsetImage + pImg->tPosition, + pImg->tLength - pImg->tPosition, + pImg); + case imagetype_is_emf: + case imagetype_is_wmf: + case imagetype_is_pict: + case imagetype_is_external: + /* FIXME */ + return bAddDummyImage(pDiag, pImg); + case imagetype_is_unknown: + default: + DBG_DEC(pImg->eImageType); + return bAddDummyImage(pDiag, pImg); + } +} /* end of bTranslateImage */ diff --git a/jpeg2eps.c b/jpeg2eps.c new file mode 100644 index 0000000..ee438ce --- /dev/null +++ b/jpeg2eps.c @@ -0,0 +1,74 @@ +/* + * jpeg2eps.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate jpeg pictures into eps + * + */ + +#include +#include "antiword.h" + +#if defined(DEBUG) +static int iPicCounter = 0; +#endif /* DEBUG */ + + +#if defined(DEBUG) +/* + * vCopy2File + */ +static void +vCopy2File(FILE *pFile, ULONG ulFileOffset, size_t tPictureLen) +{ + FILE *pOutFile; + size_t tIndex; + int iTmp; + char szFilename[30]; + + if (!bSetDataOffset(pFile, ulFileOffset)) { + return; + } + + sprintf(szFilename, "/tmp/pic/pic%04d.jpg", ++iPicCounter); + pOutFile = fopen(szFilename, "wb"); + if (pOutFile == NULL) { + return; + } + for (tIndex = 0; tIndex < tPictureLen; tIndex++) { + iTmp = iNextByte(pFile); + if (putc(iTmp, pOutFile) == EOF) { + break; + } + } + (void)fclose(pOutFile); +} /* end of vCopy2File */ +#endif /* DEBUG */ + +/* + * bTranslateJPEG - translate a JPEG picture + * + * This function translates a picture from jpeg to eps + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslateJPEG(diagram_type *pDiag, FILE *pFile, + ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg) +{ +#if defined(DEBUG) + vCopy2File(pFile, ulFileOffset, tPictureLen); +#endif /* DEBUG */ + + /* Seek to start position of JPEG data */ + if (!bSetDataOffset(pFile, ulFileOffset)) { + return FALSE; + } + + vImagePrologue(pDiag, pImg); + vASCII85EncodeFile(pFile, pDiag->pOutFile, tPictureLen); + vImageEpilogue(pDiag); + + return TRUE; +} /* end of bTranslateJPEG */ diff --git a/jpeg2sprt.c b/jpeg2sprt.c new file mode 100644 index 0000000..28bd6cd --- /dev/null +++ b/jpeg2sprt.c @@ -0,0 +1,97 @@ +/* + * jpeg2sprt.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate jpeg pictures into sprites + */ + +#include +#include "antiword.h" + +#if 0 /* defined(DEBUG) */ +static int iPicCounter = 0; +#endif /* DEBUG */ + + +#if 0 /* defined(DEBUG) */ +static void +vCopy2File(UCHAR *pucJpeg, size_t tJpegSize) +{ + FILE *pOutFile; + size_t tIndex; + char szFilename[30]; + + sprintf(szFilename, ".jpeg%04d", ++iPicCounter); + pOutFile = fopen(szFilename, "wb"); + if (pOutFile == NULL) { + return; + } + DBG_MSG(szFilename); + for (tIndex = 0; tIndex < tJpegSize; tIndex++) { + if (putc(pucJpeg[tIndex], pOutFile) == EOF) { + break; + } + } + (void)fclose(pOutFile); + vSetFiletype(szFilename, FILETYPE_JPEG); +} /* end of vCopy2File */ +#endif /* DEBUG */ + +/* + * bSave2Draw - save the JPEG picture to the Draw file + * + * This function puts a JPEG picture in a Draw file + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bSave2Draw(diagram_type *pDiag, FILE *pFile, + size_t tJpegSize, const imagedata_type *pImg) +{ + UCHAR *pucJpeg, *pucTmp; + size_t tLen; + int iByte; + + pucJpeg = xmalloc(tJpegSize); + for (pucTmp = pucJpeg, tLen = 0; tLen < tJpegSize; pucTmp++, tLen++) { + iByte = iNextByte(pFile); + if (iByte == EOF) { + return FALSE; + } + *pucTmp = (UCHAR)iByte; + } + +#if 0 /* defined(DEBUG) */ + vCopy2File(pucJpeg, tJpegSize); +#endif /* DEBUG */ + + /* Add the JPEG to the Draw file */ + vImage2Diagram(pDiag, pImg, pucJpeg, tJpegSize); + + xfree(pucJpeg); + return TRUE; +} /* end of bSave2Draw */ + +/* + * bTranslateJPEG - translate a JPEG picture + * + * This function translates a picture from jpeg to sprite + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslateJPEG(diagram_type *pDiag, FILE *pFile, + ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg) +{ + /* Seek to start position of JPEG data */ + if (!bSetDataOffset(pFile, ulFileOffset)) { + return FALSE; + } + + if (iGetRiscOsVersion() >= 360) { + return bSave2Draw(pDiag, pFile, tPictureLen, pImg); + } + /* JPEG is not supported until RISC OS 3.6 */ + return bAddDummyImage(pDiag, pImg); +} /* end of bTranslateJPEG */ diff --git a/listlist.c b/listlist.c new file mode 100644 index 0000000..eb86589 --- /dev/null +++ b/listlist.c @@ -0,0 +1,330 @@ +/* + * listlist.c + * Copyright (C) 2002,2003 A.J. van Os; Released under GPL + * + * Description: + * Build, read and destroy a list of Word list information + * + * Note: + * This list only exists when the Word document is saved by Word 8 or later + */ + +#include "antiword.h" + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct list_desc_tag { + list_block_type tInfo; + ULONG ulListID; + USHORT usIstd; + UCHAR ucListLevel; + struct list_desc_tag *pNext; +} list_desc_type; + +typedef struct list_value_tag { + USHORT usValue; + USHORT usListIndex; + UCHAR ucListLevel; + struct list_value_tag *pNext; +} list_value_type; + +/* Variables needed to describe the LFO list (pllfo) */ +static ULONG *aulLfoList = NULL; +static USHORT usLfoLen = 0; +/* Variables needed to write the List Information List */ +static list_desc_type *pAnchor = NULL; +static list_desc_type *pBlockLast = NULL; +/* Variable needed for numbering new lists */ +static list_value_type *pValues = NULL; +/* Variables needed for numbering old lists */ +static int iOldListSeqNumber = 0; +static USHORT usOldListValue = 0; + + +/* + * vDestroyListInfoList - destroy the List Information List + */ +void +vDestroyListInfoList(void) +{ + list_desc_type *pCurr, *pNext; + list_value_type *pValueCurr, *pValueNext; + + DBG_MSG("vDestroyListInfoList"); + + /* Free the LFO list */ + usLfoLen = 0; + aulLfoList = xfree(aulLfoList); + + /* Free the List Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pBlockLast = NULL; + + /* Free the values list */ + pValueCurr = pValues; + while (pValueCurr != NULL) { + pValueNext = pValueCurr->pNext; + pValueCurr = xfree(pValueCurr); + pValueCurr = pValueNext; + } + pValues = NULL; + /* Reset the values for the old lists */ + iOldListSeqNumber = 0; + usOldListValue = 0; +} /* end of vDestroyListInfoList */ + +/* + * vBuildLfoList - build the LFO list (pllfo) + */ +void +vBuildLfoList(const UCHAR *aucBuffer, size_t tBufLen) +{ + size_t tRecords; + int iIndex; + + fail(aucBuffer == NULL); + + if (tBufLen < 4) { + return; + } + tRecords = (size_t)ulGetLong(0, aucBuffer); + NO_DBG_DEC(tRecords); + if (4 + 16 * tRecords > tBufLen || tRecords >= 0x7fff) { + /* Just a sanity check */ + DBG_DEC(tRecords); + DBG_DEC(4 + 16 * tRecords); + DBG_DEC(tBufLen); + return; + } + aulLfoList = xcalloc(tRecords, sizeof(ULONG)); + for (iIndex = 0; iIndex < (int)tRecords; iIndex++) { + aulLfoList[iIndex] = ulGetLong(4 + 16 * iIndex, aucBuffer); + NO_DBG_HEX(aulLfoList[iIndex]); + } + usLfoLen = (USHORT)tRecords; +} /* end of vBuildLfoList */ + +/* + * vAdd2ListInfoList - add an element to the List Information list + */ +void +vAdd2ListInfoList(ULONG ulListID, USHORT usIstd, UCHAR ucListLevel, + const list_block_type *pListBlock) +{ + list_desc_type *pListMember; + + fail(pListBlock == NULL); + + NO_DBG_HEX(ulListID); + NO_DBG_DEC(usIstd); + NO_DBG_DEC(ucListLevel); + NO_DBG_DEC(pListBlock->ulStartAt); + NO_DBG_DEC(pListBlock->bNoRestart); + NO_DBG_DEC(pListBlock->sLeftIndent); + NO_DBG_HEX(pListBlock->ucNFC); + NO_DBG_HEX(pListBlock->usListChar); + + /* Create list member */ + pListMember = xmalloc(sizeof(list_desc_type)); + /* Fill the list member */ + pListMember->tInfo = *pListBlock; + pListMember->ulListID = ulListID; + pListMember->usIstd = usIstd; + pListMember->ucListLevel = ucListLevel; + pListMember->pNext = NULL; + /* Correct the values where needed */ + if (pListMember->tInfo.ulStartAt > 0xffff) { + DBG_DEC(pListMember->tInfo.ulStartAt); + pListMember->tInfo.ulStartAt = 1; + } + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + } else { + fail(pBlockLast == NULL); + pBlockLast->pNext = pListMember; + } + pBlockLast = pListMember; +} /* end of vAdd2ListInfoList */ + +/* + * Get a matching record from the List Information List + * + * Returns NULL if no matching records is found + */ +const list_block_type * +pGetListInfo(USHORT usListIndex, UCHAR ucListLevel) +{ + list_desc_type *pCurr; + list_block_type *pNearMatch; + ULONG ulListID; + + if (usListIndex == 0) { + return NULL; + } + if (usListIndex - 1 >= usLfoLen || ucListLevel > 8) { + DBG_DEC(usListIndex); + DBG_DEC(ucListLevel); + return NULL; + } + fail(aulLfoList == NULL); + ulListID = aulLfoList[usListIndex - 1]; + NO_DBG_HEX(ulListID); + + pNearMatch = NULL; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->ulListID != ulListID) { + /* No match */ + continue; + } + if (pCurr->ucListLevel == ucListLevel) { + /* Exact match */ + return &pCurr->tInfo; + } + if (pCurr->ucListLevel == 0) { + /* Near match */ + pNearMatch = &pCurr->tInfo; + } + } + /* No exact match, use a near match if any */ + return pNearMatch; +} /* end of pGetListInfo */ + +/* + * Get a matching record from the List Information List + * + * Returns NULL if no matching records is found + */ +const list_block_type * +pGetListInfoByIstd(USHORT usIstd) +{ + list_desc_type *pCurr; + + if (usIstd == ISTD_INVALID || usIstd == STI_NIL || usIstd == STI_USER) { + return NULL; + } + + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->usIstd == usIstd) { + return &pCurr->tInfo; + } + } + return NULL; +} /* end of pGetListInfoByIstd */ + +/* + * vRestartListValues - reset the less significant list levels + */ +static void +vRestartListValues(USHORT usListIndex, UCHAR ucListLevel) +{ + list_value_type *pPrev, *pCurr, *pNext; + int iCounter; + + iCounter = 0; + pPrev = NULL; + pCurr = pValues; + + while (pCurr != NULL) { + if (pCurr->usListIndex != usListIndex || + pCurr->ucListLevel <= ucListLevel) { + pPrev = pCurr; + pCurr = pCurr->pNext; + continue; + } + /* Reset the level by deleting the record */ + pNext = pCurr->pNext; + if (pPrev == NULL) { + pValues = pNext; + } else { + pPrev->pNext = pNext; + } + DBG_DEC(pCurr->usListIndex); + DBG_DEC(pCurr->ucListLevel); + pCurr = xfree(pCurr); + pCurr = pNext; + iCounter++; + } + DBG_DEC_C(iCounter > 0, iCounter); +} /* end of vRestartListValues */ + +/* + * usGetListValue - Get the current value of the given list + * + * Returns the value of the given list + */ +USHORT +usGetListValue(int iListSeqNumber, int iWordVersion, + const style_block_type *pStyle) +{ + list_value_type *pCurr; + USHORT usValue; + + fail(iListSeqNumber < 0); + fail(iListSeqNumber < iOldListSeqNumber); + fail(iWordVersion < 0); + fail(pStyle == NULL); + + if (iListSeqNumber <= 0) { + return 0; + } + + if (iWordVersion < 8) { + /* Old style list */ + if (iListSeqNumber == iOldListSeqNumber || + (iListSeqNumber == iOldListSeqNumber + 1 && + eGetNumType(pStyle->ucNumLevel) == level_type_sequence)) { + if (!pStyle->bNumPause) { + usOldListValue++; + } + } else { + usOldListValue = pStyle->usStartAt; + } + iOldListSeqNumber = iListSeqNumber; + return usOldListValue; + } + + /* New style list */ + if (pStyle->usListIndex == 0 || + pStyle->usListIndex - 1 >= usLfoLen || + pStyle->ucListLevel > 8) { + /* Out of range; no need to search */ + return 0; + } + + for (pCurr = pValues; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->usListIndex == pStyle->usListIndex && + pCurr->ucListLevel == pStyle->ucListLevel) { + /* Record found; increment and return the value */ + pCurr->usValue++; + usValue = pCurr->usValue; + if (!pStyle->bNoRestart) { + vRestartListValues(pStyle->usListIndex, + pStyle->ucListLevel); + } + return usValue; + } + } + + /* Record not found; create it and add it to the front of the list */ + pCurr = xmalloc(sizeof(list_value_type)); + pCurr->usValue = pStyle->usStartAt; + pCurr->usListIndex = pStyle->usListIndex; + pCurr->ucListLevel = pStyle->ucListLevel; + pCurr->pNext = pValues; + pValues = pCurr; + usValue = pCurr->usValue; + if (!pStyle->bNoRestart) { + vRestartListValues(pStyle->usListIndex, pStyle->ucListLevel); + } + return usValue; +} /* end of usGetListValue */ diff --git a/main_ros.c b/main_ros.c new file mode 100644 index 0000000..8f4f316 --- /dev/null +++ b/main_ros.c @@ -0,0 +1,520 @@ +/* + * main_ros.c + * + * Released under GPL + * + * Copyright (C) 1998-2005 A.J. van Os + * + * 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. + * + * Description: + * The main program of !Antiword (RISC OS version) + */ + +#include +#include +#include +#include "DeskLib:Dialog2.h" +#include "DeskLib:Error.h" +#include "DeskLib:Event.h" +#include "DeskLib:EventMsg.h" +#include "DeskLib:Handler.h" +#include "DeskLib:Menu.h" +#include "DeskLib:Resource.h" +#include "DeskLib:Screen.h" +#include "DeskLib:Template.h" +#include "DeskLib:Window.h" +#if defined(__GNUC__) +#include "flexlib:flex.h" +#endif /* __GNUC__ */ +#include "version.h" +#include "antiword.h" + + +/* The name of this program */ +static char *szTask = "!Antiword"; + +/* The window handle of the choices window */ +static window_handle tChoicesWindow = 0; + +/* Dummy diagram with the iconbar menu pointer */ +static diagram_type tDummyDiagram; + +/* Program information Box */ +static dialog2_block *pInfoBox = NULL; + +/* Info box fields */ +#define PURPOSE_INFO_FIELD 2 +#define AUTHOR_INFO_FIELD 3 +#define VERSION_INFO_FIELD 4 +#define STATUS_INFO_FIELD 5 + +/* Iconbar menu fields */ +#define ICONBAR_INFO_FIELD 0 +#define ICONBAR_CHOICES_FIELD 1 +#define ICONBAR_QUIT_FIELD 2 + + +/* + * bBarInfo - Show iconbar information + */ +static BOOL +bBarInfo(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + + TRACE_MSG("bBarInfo"); + + fail(pEvent == NULL); + fail(pEvent->type != event_SEND); + fail(pEvent->data.message.header.action != message_MENUWARN); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + if (menu_currentopen != pDiag->pSaveMenu || + pEvent->data.message.data.menuwarn.selection[0] != ICONBAR_INFO_FIELD) { + return FALSE; + } + + Dialog2_OpenDialogMenuLeaf(pEvent, pInfoBox); + return TRUE; +} /* end of bBarInfo */ + +/* + * vBarInfoSetText - Set the iconbar infobox text + */ +static void +vBarInfoSetText(dialog2_block *pBox) +{ + TRACE_MSG("vBarInfoSetText"); + + fail(pBox == NULL); + fail(pBox != pInfoBox); + + Icon_SetText(pBox->window, PURPOSE_INFO_FIELD, PURPOSESTRING); + Icon_SetText(pBox->window, AUTHOR_INFO_FIELD, AUTHORSTRING); + Icon_SetText(pBox->window, VERSION_INFO_FIELD, VERSIONSTRING); + Icon_SetText(pBox->window, STATUS_INFO_FIELD, STATUSSTRING); +} /* end of vBarInfoSetText */ + +/* + * bMouseButtonClick - respond to mouse button click + */ +static BOOL +bMouseButtonClick(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + menu_ptr pMenu; + int iPosY; + + TRACE_MSG("bMouseButtonClick"); + + fail(pEvent == NULL); + fail(pEvent->type != event_CLICK); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + if (pEvent->data.mouse.button.data.menu) { + pMenu = pDiag->pSaveMenu; + iPosY = (pMenu == tDummyDiagram.pSaveMenu) ? + -1 : pEvent->data.mouse.pos.y; + Menu_Show(pMenu, pEvent->data.mouse.pos.x, iPosY); + return TRUE; + } + if (pEvent->data.mouse.window == pDiag->tMainWindow && + pEvent->data.mouse.icon == -1) { + vMainButtonClick(&pEvent->data.mouse); + return TRUE; + } + if (pEvent->data.mouse.window == pDiag->tScaleWindow && + pEvent->data.mouse.icon >= 0) { + vScaleButtonClick(&pEvent->data.mouse, pDiag); + return TRUE; + } + return FALSE; +} /* end of bMouseButtonClick */ + +/* + * bAutoRedrawWindow - the redraw is handled by the WIMP + */ +static BOOL +bAutoRedrawWindow(event_pollblock *pEvent, void *pvReference) +{ + return TRUE; +} /* end of bAutoRedrawWindow */ + +static BOOL +bSaveSelect(event_pollblock *pEvent, void *pvReference) +{ + TRACE_MSG("bSaveSelect"); + + fail(pEvent == NULL); + fail(pEvent->type != event_MENU); + fail(pvReference == NULL); + + DBG_DEC(pEvent->data.selection[0]); + + switch (pEvent->data.selection[0]) { + case SAVEMENU_SCALEVIEW: + return bScaleOpenAction(pEvent, pvReference); + case SAVEMENU_SAVEDRAW: + return bSaveDrawfile(pEvent, pvReference); + case SAVEMENU_SAVETEXT: + return bSaveTextfile(pEvent, pvReference); + default: + DBG_DEC(pEvent->data.selection[0]); + return FALSE; + } +} /* end of bSaveSelect */ + +/* + * Create the window for the text from the given file + */ +static diagram_type * +pCreateTextWindow(const char *szFilename) +{ + diagram_type *pDiag; + + TRACE_MSG("pCreateTextWindow"); + + fail(szFilename == NULL || szFilename[0] == '\0'); + + /* Create the diagram */ + pDiag = pCreateDiagram(szTask+1, szFilename); + if (pDiag == NULL) { + werr(0, "Sorry, no new diagram object"); + return NULL; + } + + /* Prepare a save menu for this diagram */ + pDiag->pSaveMenu = Menu_New(szTask+1, + ">Scale view," + ">Save (Drawfile) F3," + ">Save (Text only) \213F3"); + if (pDiag->pSaveMenu == NULL) { + werr(1, "Sorry, no Savemenu object"); + } + Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SCALEVIEW, + TRUE, bScaleOpenAction, pDiag); + Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVEDRAW, + TRUE, bSaveDrawfile, pDiag); + Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVETEXT, + TRUE, bSaveTextfile, pDiag); + + /* Claim events for the main window */ + Event_Claim(event_REDRAW, pDiag->tMainWindow, icon_ANY, + bRedrawMainWindow, pDiag); + Event_Claim(event_CLOSE, pDiag->tMainWindow, icon_ANY, + bDestroyDiagram, pDiag); + Event_Claim(event_CLICK, pDiag->tMainWindow, icon_ANY, + bMouseButtonClick, pDiag); + Event_Claim(event_KEY, pDiag->tMainWindow, icon_ANY, + bMainKeyPressed, pDiag); + + /* Claim events for the scale window */ + Event_Claim(event_REDRAW, pDiag->tScaleWindow, icon_ANY, + bAutoRedrawWindow, NULL); + Event_Claim(event_CLICK, pDiag->tScaleWindow, icon_ANY, + bMouseButtonClick, pDiag); + Event_Claim(event_KEY, pDiag->tScaleWindow, icon_ANY, + bScaleKeyPressed, pDiag); + + /* Set the window title */ + vSetTitle(pDiag); + return pDiag; +} /* end of pCreateTextWindow */ + +/* + * vProcessFile - process one file + */ +static void +vProcessFile(const char *szFilename, int iFiletype) +{ + options_type tOptions; + FILE *pFile; + diagram_type *pDiag; + long lFilesize; + int iWordVersion; + + TRACE_MSG("vProcessFile"); + + fail(szFilename == NULL || szFilename[0] == '\0'); + + DBG_MSG(szFilename); + + pFile = fopen(szFilename, "rb"); + if (pFile == NULL) { + werr(0, "I can't open '%s' for reading", szFilename); + return; + } + + lFilesize = lGetFilesize(szFilename); + if (lFilesize < 0) { + (void)fclose(pFile); + werr(0, "I can't get the size of '%s'", szFilename); + return; + } + + iWordVersion = iGuessVersionNumber(pFile, lFilesize); + if (iWordVersion < 0 || iWordVersion == 3) { + if (bIsRtfFile(pFile)) { + werr(0, "%s is not a Word Document." + " It is probably a Rich Text Format file", + szFilename); + } if (bIsWordPerfectFile(pFile)) { + werr(0, "%s is not a Word Document." + " It is probably a Word Perfect file", + szFilename); + } else { + werr(0, "%s is not a Word Document.", szFilename); + } + (void)fclose(pFile); + return; + } + /* Reset any reading done during file-testing */ + rewind(pFile); + + if (iFiletype != FILETYPE_MSWORD) { + vGetOptions(&tOptions); + if (tOptions.bAutofiletypeAllowed) { + vSetFiletype(szFilename, FILETYPE_MSWORD); + } + } + + pDiag = pCreateTextWindow(szFilename); + if (pDiag == NULL) { + (void)fclose(pFile); + return; + } + + (void)bWordDecryptor(pFile, lFilesize, pDiag); + Error_CheckFatal(Drawfile_VerifyDiagram(&pDiag->tInfo)); + vShowDiagram(pDiag); + TRACE_MSG("After vShowDiagram"); + + TRACE_MSG("before debug print"); + DBG_HEX(pFile); + TRACE_MSG("before fclose"); + (void)fclose(pFile); + TRACE_MSG("after fclose"); +} /* end of vProcessFile */ + +/* + * vSendAck - send an acknowledge + */ +static void +vSendAck(event_pollblock *pEvent) +{ + message_block tMessage; + + TRACE_MSG("vSendAck"); + + fail(pEvent == NULL); + fail(pEvent->type != event_SEND && pEvent->type != event_SENDWANTACK); + fail(pEvent->data.message.header.action != message_DATALOAD && + pEvent->data.message.header.action != message_DATAOPEN); + + tMessage.header.action = message_DATALOADACK; + tMessage.header.size = sizeof(tMessage); + tMessage.header.yourref = pEvent->data.message.header.myref; + Error_CheckFatal(Wimp_SendMessage(event_SEND, &tMessage, + pEvent->data.message.header.sender, 0)); +} /* end of vSendAck */ + +static BOOL +bEventMsgHandler(event_pollblock *pEvent, void *pvReference) +{ + TRACE_MSG("bEventMsgHandler"); + + fail(pEvent == NULL); + + switch (pEvent->type) { + case event_SEND: + case event_SENDWANTACK: + switch (pEvent->data.message.header.action) { + case message_CLOSEDOWN: + exit(EXIT_SUCCESS); + break; + case message_DATALOAD: + case message_DATAOPEN: + vProcessFile( + pEvent->data.message.data.dataload.filename, + pEvent->data.message.data.dataload.filetype); + vSendAck(pEvent); + break; + default: + DBG_DEC(pEvent->data.message.header.action); + break; + } + return TRUE; + default: + DBG_DEC(pEvent->type); + return FALSE; + } +} /* end of bEventMsgHandler */ + +/* + * bMenuSelect - select from the iconbar menu + */ +static BOOL +bMenuSelect(event_pollblock *pEvent, void *pvReference) +{ + TRACE_MSG("bMenuSelect"); + + fail(pEvent == NULL); + fail(pEvent->type != event_MENU); + + DBG_DEC(pEvent->data.selection[0]); + + switch (pEvent->data.selection[0]) { + case ICONBAR_INFO_FIELD: + return bBarInfo(pEvent, pvReference); + case ICONBAR_CHOICES_FIELD: + vChoicesOpenAction(tChoicesWindow); + Window_BringToFront(tChoicesWindow); + break; + case ICONBAR_QUIT_FIELD: + TRACE_MSG("before exit"); + exit(EXIT_SUCCESS); + break; + default: + DBG_DEC(pEvent->data.selection[0]); + break; + } + return TRUE; +} /* end of bMenuSelect */ + +/* + * bMenuClick - respond to an menu click + */ +static BOOL +bMenuClick(event_pollblock *pEvent, void *pvReference) +{ + TRACE_MSG("bMenuClick"); + + fail(pEvent == NULL); + fail(pEvent->type != event_MENU); + + if (menu_currentopen == tDummyDiagram.pSaveMenu) { + return bMenuSelect(pEvent, pvReference); + } else if (pvReference == NULL) { + return FALSE; + } + return bSaveSelect(pEvent, pvReference); +} /* end of bMenuClick */ + +static void +vTemplates(void) +{ + TRACE_MSG("vTemplates"); + + Template_Initialise(); + Template_LoadFile("Templates"); + + tChoicesWindow = Window_Create("Choices", template_TITLEMIN); + if (tChoicesWindow == 0) { + werr(1, "I can't find the 'Choices' template"); + } + + /* Claim events for the choices window */ + Event_Claim(event_REDRAW, tChoicesWindow, icon_ANY, + bAutoRedrawWindow, NULL); + Event_Claim(event_CLICK, tChoicesWindow, icon_ANY, + bChoicesMouseClick, NULL); + Event_Claim(event_KEY, tChoicesWindow, icon_ANY, + bChoicesKeyPressed, NULL); +} /* end of vTemplates */ + +static void +vInitialise(void) +{ + int aiMessages[] = {0}; + icon_handle tBarIcon; + + + TRACE_MSG("vInitialise"); + + Resource_Initialise(szTask+1); + Event_Initialise3(szTask+1, 310, aiMessages); + EventMsg_Initialise(); + Screen_CacheModeInfo(); +#if defined(__GNUC__) + flex_init(szTask+1, 0, 0); + flex_set_budge(1); +#endif /* __GNUC__ */ + vTemplates(); + + /* Prepare iconbar menu */ + tDummyDiagram.tInfo.data = NULL; + tDummyDiagram.tInfo.length = 0; + tDummyDiagram.pSaveMenu = Menu_New(szTask+1, ">Info,Choices...,Quit"); + if (tDummyDiagram.pSaveMenu == NULL) { + werr(1, "Sorry, no Barmenu object"); + } + pInfoBox = Dialog2_CreateDialogBlock("ProgInfo", -1, -1, + vBarInfoSetText, NULL, NULL); + + if (pInfoBox == NULL) { + werr(1, "Sorry, no Infobox object"); + } + Menu_Warn(tDummyDiagram.pSaveMenu, ICONBAR_INFO_FIELD, + TRUE, bBarInfo, &tDummyDiagram); + + /* Create an icon on the icon bar */ + tBarIcon = Icon_BarIcon(szTask, iconbar_RIGHT); + Event_Claim(event_CLICK, window_ICONBAR, tBarIcon, + bMouseButtonClick, &tDummyDiagram); + + /* Generic claims */ + Event_Claim(event_OPEN, window_ANY, icon_ANY, + Handler_OpenWindow, NULL); + Event_Claim(event_CLOSE, window_ANY, icon_ANY, + Handler_CloseWindow, NULL); + Event_Claim(event_MENU, window_ANY, icon_ANY, + bMenuClick, NULL); + EventMsg_Claim(message_DATALOAD, window_ICONBAR, + bEventMsgHandler, NULL); + EventMsg_Claim(message_MODECHANGE, window_ANY, + Handler_ModeChange, NULL); +} /* end of vInitialise */ + +int +main(int argc, char **argv) +{ + int iFirst, iFiletype; + + TRACE_MSG("main"); + + vInitialise(); + iFirst = iReadOptions(argc, argv); + if (iFirst != 1) { + return EXIT_FAILURE; + } + + if (argc > 1) { + iFiletype = iGetFiletype(argv[1]); + if (iFiletype < 0) { + return EXIT_FAILURE; + } + vProcessFile(argv[1], iFiletype); + TRACE_MSG("main after vProcessFile"); + } + + for (;;) { + Event_Poll(); + } +} /* end of main */ diff --git a/main_u.c b/main_u.c new file mode 100644 index 0000000..4eaaea3 --- /dev/null +++ b/main_u.c @@ -0,0 +1,321 @@ +/* + * main_u.c + * + * Released under GPL + * + * Copyright (C) 1998-2004 A.J. van Os + * + * 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. + * + * Description: + * The main program of 'antiword' (Unix version) + */ + +#include +#include +#if defined(__dos) +#include +#include +#endif /* __dos */ +#if defined(__CYGWIN__) || defined(__CYGMING__) +# ifdef X_LOCALE +# include +# else +# include +# endif +#else +#include +#endif /* __CYGWIN__ || __CYGMING__ */ +#if defined(N_PLAT_NLM) +#if !defined(_VA_LIST) +#include "NW-only/nw_os.h" +#endif /* !_VA_LIST */ +#include "getopt.h" +#endif /* N_PLAT_NLM */ +#include "version.h" +#include "antiword.h" + +/* The name of this program */ +static const char *szTask = NULL; + + +static void +vUsage(void) +{ + fprintf(stderr, "\tName: %s\n", szTask); + fprintf(stderr, "\tPurpose: "PURPOSESTRING"\n"); + fprintf(stderr, "\tAuthor: "AUTHORSTRING"\n"); + fprintf(stderr, "\tVersion: "VERSIONSTRING); +#if defined(__dos) + fprintf(stderr, VERSIONSTRING2); +#endif /* __dos */ + fprintf(stderr, "\n"); + fprintf(stderr, "\tStatus: "STATUSSTRING"\n"); + fprintf(stderr, + "\tUsage: %s [switches] wordfile1 [wordfile2 ...]\n", szTask); + fprintf(stderr, + "\tSwitches: [-f|-t|-a papersize|-p papersize|-x dtd]" + "[-m mapping][-w #][-i #][-Ls]\n"); + fprintf(stderr, "\t\t-f formatted text output\n"); + fprintf(stderr, "\t\t-t text output (default)\n"); + fprintf(stderr, "\t\t-a Adobe PDF output\n"); + fprintf(stderr, "\t\t-p PostScript output\n"); + fprintf(stderr, "\t\t paper size like: a4, letter or legal\n"); + fprintf(stderr, "\t\t-x XML output\n"); + fprintf(stderr, "\t\t like: db (DocBook)\n"); + fprintf(stderr, "\t\t-m character mapping file\n"); + fprintf(stderr, "\t\t-w in characters of text output\n"); + fprintf(stderr, "\t\t-i image level (PostScript only)\n"); + fprintf(stderr, "\t\t-L use landscape mode (PostScript only)\n"); + fprintf(stderr, "\t\t-r Show removed text\n"); + fprintf(stderr, "\t\t-s Show hidden (by Word) text\n"); +} /* end of vUsage */ + +/* + * pStdin2TmpFile - save stdin in a temporary file + * + * returns: the pointer to the temporary file or NULL + */ +static FILE * +pStdin2TmpFile(long *lFilesize) +{ + FILE *pTmpFile; + size_t tSize; + BOOL bFailure; + UCHAR aucBytes[BUFSIZ]; + + DBG_MSG("pStdin2TmpFile"); + + fail(lFilesize == NULL); + + /* Open the temporary file */ + pTmpFile = tmpfile(); + if (pTmpFile == NULL) { + return NULL; + } + +#if defined(__dos) + /* Stdin must be read as a binary stream */ + setmode(fileno(stdin), O_BINARY); +#endif /* __dos */ + + /* Copy stdin to the temporary file */ + *lFilesize = 0; + bFailure = TRUE; + for (;;) { + tSize = fread(aucBytes, 1, sizeof(aucBytes), stdin); + if (tSize == 0) { + bFailure = feof(stdin) == 0; + break; + } + if (fwrite(aucBytes, 1, tSize, pTmpFile) != tSize) { + bFailure = TRUE; + break; + } + *lFilesize += (long)tSize; + } + +#if defined(__dos) + /* Switch stdin back to a text stream */ + setmode(fileno(stdin), O_TEXT); +#endif /* __dos */ + + /* Deal with the result of the copy action */ + if (bFailure) { + *lFilesize = 0; + (void)fclose(pTmpFile); + return NULL; + } + rewind(pTmpFile); + return pTmpFile; +} /* end of pStdin2TmpFile */ + +/* + * bProcessFile - process a single file + * + * returns: TRUE when the given file is a supported Word file, otherwise FALSE + */ +static BOOL +bProcessFile(const char *szFilename) +{ + FILE *pFile; + diagram_type *pDiag; + long lFilesize; + int iWordVersion; + BOOL bResult; + + fail(szFilename == NULL || szFilename[0] == '\0'); + + DBG_MSG(szFilename); + + if (szFilename[0] == '-' && szFilename[1] == '\0') { + pFile = pStdin2TmpFile(&lFilesize); + if (pFile == NULL) { + werr(0, "I can't save the standard input to a file"); + return FALSE; + } + } else { + pFile = fopen(szFilename, "rb"); + if (pFile == NULL) { + werr(0, "I can't open '%s' for reading", szFilename); + return FALSE; + } + + lFilesize = lGetFilesize(szFilename); + if (lFilesize < 0) { + (void)fclose(pFile); + werr(0, "I can't get the size of '%s'", szFilename); + return FALSE; + } + } + + iWordVersion = iGuessVersionNumber(pFile, lFilesize); + if (iWordVersion < 0 || iWordVersion == 3) { + if (bIsRtfFile(pFile)) { + werr(0, "%s is not a Word Document." + " It is probably a Rich Text Format file", + szFilename); + } if (bIsWordPerfectFile(pFile)) { + werr(0, "%s is not a Word Document." + " It is probably a Word Perfect file", + szFilename); + } else { +#if defined(__dos) + werr(0, "%s is not a Word Document or the filename" + " is not in the 8+3 format.", szFilename); +#else + werr(0, "%s is not a Word Document.", szFilename); +#endif /* __dos */ + } + (void)fclose(pFile); + return FALSE; + } + /* Reset any reading done during file testing */ + rewind(pFile); + + pDiag = pCreateDiagram(szTask, szFilename); + if (pDiag == NULL) { + (void)fclose(pFile); + return FALSE; + } + + bResult = bWordDecryptor(pFile, lFilesize, pDiag); + vDestroyDiagram(pDiag); + + (void)fclose(pFile); + return bResult; +} /* end of bProcessFile */ + +int +main(int argc, char **argv) +{ + options_type tOptions; + const char *szWordfile; + int iFirst, iIndex, iGoodCount; + BOOL bUsage, bMultiple, bUseTXT, bUseXML; + + if (argc <= 0) { + return EXIT_FAILURE; + } + + szTask = szBasename(argv[0]); + + if (argc <= 1) { + iFirst = 1; + bUsage = TRUE; + } else { + iFirst = iReadOptions(argc, argv); + bUsage = iFirst <= 0; + } + if (bUsage) { + vUsage(); + return iFirst < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } + +#if defined(N_PLAT_NLM) && !defined(_VA_LIST) + nwinit(); +#endif /* N_PLAT_NLM && !_VA_LIST */ + + vGetOptions(&tOptions); + +#if !defined(__dos) + if (is_locale_utf8()) { +#if defined(__STDC_ISO_10646__) + /* + * If the user wants UTF-8 and the envirionment variables + * support UTF-8, than set the locale accordingly + */ + if (tOptions.eEncoding == encoding_utf_8) { + if (setlocale(LC_CTYPE, "") == NULL) { + werr(1, "Can't set the UTF-8 locale! " + "Check LANG, LC_CTYPE, LC_ALL."); + } + DBG_MSG("The UTF-8 locale has been set"); + } else { + (void)setlocale(LC_CTYPE, "C"); + } +#endif /* __STDC_ISO_10646__ */ + } else { + if (setlocale(LC_CTYPE, "") == NULL) { + werr(0, "Can't set the locale! Will use defaults"); + (void)setlocale(LC_CTYPE, "C"); + } + DBG_MSG("The locale has been set"); + } +#endif /* !__dos */ + + bMultiple = argc - iFirst > 1; + bUseTXT = tOptions.eConversionType == conversion_text || + tOptions.eConversionType == conversion_fmt_text; + bUseXML = tOptions.eConversionType == conversion_xml; + iGoodCount = 0; + +#if defined(__dos) + if (tOptions.eConversionType == conversion_pdf) { + /* PDF must be written as a binary stream */ + setmode(fileno(stdout), O_BINARY); + } +#endif /* __dos */ + + if (bUseXML) { + fprintf(stdout, + "\n" + "\n", + bMultiple ? "set" : "book"); + if (bMultiple) { + fprintf(stdout, "\n"); + } + } + + for (iIndex = iFirst; iIndex < argc; iIndex++) { + if (bMultiple && bUseTXT) { + szWordfile = szBasename(argv[iIndex]); + fprintf(stdout, "::::::::::::::\n"); + fprintf(stdout, "%s\n", szWordfile); + fprintf(stdout, "::::::::::::::\n"); + } + if (bProcessFile(argv[iIndex])) { + iGoodCount++; + } + } + + if (bMultiple && bUseXML) { + fprintf(stdout, "\n"); + } + + DBG_DEC(iGoodCount); + return iGoodCount <= 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} /* end of main */ diff --git a/misc.c b/misc.c new file mode 100644 index 0000000..609a2f0 --- /dev/null +++ b/misc.c @@ -0,0 +1,894 @@ +/* + * misc.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Miscellaneous functions + */ + +#include +#include +#include +#include +#include +#if defined(__riscos) +#include "DeskLib:SWI.h" +#else +#include +#include +#include +#endif /* __riscos */ +#if !defined(S_ISREG) +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif /* !S_ISREG */ +#include "antiword.h" +#if defined(__vms) +#include +#endif + +#if !defined(__riscos) +/* + * szGetHomeDirectory - get the name of the home directory + */ +const char * +szGetHomeDirectory(void) +{ + const char *szHome; + +#if defined(__vms) + szHome = decc$translate_vms(getenv("HOME")); +#elif defined(__Plan9__) + szHome = getenv("home"); +#else + szHome = getenv("HOME"); +#endif /* __vms */ + + if (szHome == NULL || szHome[0] == '\0') { +#if defined(N_PLAT_NLM) + szHome = "SYS:"; +#elif defined(__dos) + szHome = "C:"; +#else + werr(0, "I can't find the name of your HOME directory"); + szHome = ""; +#endif /* __dos */ + } + return szHome; +} /* end of szGetHomeDirectory */ + +/* + * szGetAntiwordDirectory - get the name of the Antiword directory + */ +const char * +szGetAntiwordDirectory(void) +{ +#if defined(__vms) + return decc$translate_vms(getenv("ANTIWORDHOME")); +#else + return getenv("ANTIWORDHOME"); +#endif /* __vms */ +} /* end of szGetAntiwordDirectory */ +#endif /* !__riscos */ + +/* + * Get the size of the specified file. + * Returns -1 if the file does not exist or is not a proper file. + */ +long +lGetFilesize(const char *szFilename) +{ +#if defined(__riscos) + os_error *e; + int iType, iSize; + + e = SWI(2, 5, SWI_OS_File | XOS_Bit, + 17, szFilename, + &iType, NULL, NULL, NULL, &iSize); + if (e != NULL) { + werr(0, "Get Filesize error %d: %s", + e->errnum, e->errmess); + return -1; + } + if (iType != 1) { + /* It's not a proper file or the file does not exist */ + return -1; + } + return (long)iSize; +#else + struct stat tBuffer; + + errno = 0; + if (stat(szFilename, &tBuffer) != 0) { + werr(0, "Get Filesize error %d", errno); + return -1; + } + if (!S_ISREG(tBuffer.st_mode)) { + /* It's not a regular file */ + return -1; + } + return (long)tBuffer.st_size; +#endif /* __riscos */ +} /* end of lGetFilesize */ + +#if defined(DEBUG) +void +vPrintBlock(const char *szFile, int iLine, + const UCHAR *aucBlock, size_t tLength) +{ + int i, j; + + fail(szFile == NULL || iLine < 0 || aucBlock == NULL); + + fprintf(stderr, "%s[%3d]:\n", szFile, iLine); + for (i = 0; i < 32; i++) { + if (16 * i >= (int)tLength) { + return; + } + fprintf(stderr, "%03x: ", (unsigned int)(16 * i)); + for (j = 0; j < 16; j++) { + if (16 * i + j < (int)tLength) { + fprintf(stderr, "%02x ", + (unsigned int)aucBlock[16 * i + j]); + } + } + fprintf(stderr, "\n"); + } +} /* end of vPrintBlock */ + +void +vPrintUnicode(const char *szFile, int iLine, const UCHAR *aucUni, size_t tLen) +{ + char *szASCII; + + fail(tLen % 2 != 0); + + tLen /= 2; /* Length in bytes to length in characters */ + szASCII = xmalloc(tLen + 1); + (void)unincpy(szASCII, aucUni, tLen); + szASCII[tLen] = '\0'; + (void)fprintf(stderr, "%s[%3d]: %.*s\n", + szFile, iLine, (int)tLen, szASCII); + szASCII = xfree(szASCII); +} /* end of vPrintUnicode */ + +BOOL +bCheckDoubleLinkedList(output_type *pAnchor) +{ + output_type *pCurr, *pLast; + int iInList; + + pLast = pAnchor; + iInList = 0; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + pLast = pCurr; + iInList++; + } + NO_DBG_DEC(iInList); + for (pCurr = pLast; pCurr != NULL; pCurr = pCurr->pPrev) { + pLast = pCurr; + iInList--; + } + DBG_DEC_C(iInList != 0, iInList); + return pAnchor == pLast && iInList == 0; +} /* end of bCheckDoubleLinkedList */ +#endif /* DEBUG */ + +/* + * bReadBytes + * This function reads the specified number of bytes from the specified file, + * starting from the specified offset. + * Returns TRUE when successfull, otherwise FALSE + */ +BOOL +bReadBytes(UCHAR *aucBytes, size_t tMemb, ULONG ulOffset, FILE *pFile) +{ + fail(aucBytes == NULL || pFile == NULL || ulOffset > (ULONG)LONG_MAX); + + if (ulOffset > (ULONG)LONG_MAX) { + return FALSE; + } + if (fseek(pFile, (long)ulOffset, SEEK_SET) != 0) { + return FALSE; + } + if (fread(aucBytes, sizeof(UCHAR), tMemb, pFile) != tMemb) { + return FALSE; + } + return TRUE; +} /* end of bReadBytes */ + +/* + * bReadBuffer + * This function fills the specified buffer with the specified number of bytes, + * starting at the specified offset within the Big/Small Block Depot. + * + * Returns TRUE when successful, otherwise FALSE + */ +BOOL +bReadBuffer(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBlockDepot, size_t tBlockDepotLen, size_t tBlockSize, + UCHAR *aucBuffer, ULONG ulOffset, size_t tToRead) +{ + ULONG ulBegin, ulIndex; + size_t tLen; + + fail(pFile == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBlockDepot == NULL); + fail(tBlockSize != BIG_BLOCK_SIZE && tBlockSize != SMALL_BLOCK_SIZE); + fail(aucBuffer == NULL); + fail(tToRead == 0); + + for (ulIndex = ulStartBlock; + ulIndex != END_OF_CHAIN && tToRead != 0; + ulIndex = aulBlockDepot[ulIndex]) { + if (ulIndex >= (ULONG)tBlockDepotLen) { + DBG_DEC(ulIndex); + DBG_DEC(tBlockDepotLen); + if (tBlockSize >= BIG_BLOCK_SIZE) { + werr(1, "The Big Block Depot is damaged"); + } else { + werr(1, "The Small Block Depot is damaged"); + } + } + if (ulOffset >= (ULONG)tBlockSize) { + ulOffset -= tBlockSize; + continue; + } + ulBegin = ulDepotOffset(ulIndex, tBlockSize) + ulOffset; + tLen = min(tBlockSize - (size_t)ulOffset, tToRead); + ulOffset = 0; + if (!bReadBytes(aucBuffer, tLen, ulBegin, pFile)) { + werr(0, "Read big block 0x%lx not possible", ulBegin); + return FALSE; + } + aucBuffer += tLen; + tToRead -= tLen; + } + DBG_DEC_C(tToRead != 0, tToRead); + return tToRead == 0; +} /* end of bReadBuffer */ + +/* + * Convert a Word colornumber into a true color for use in a drawfile + * + * Returns the true color + */ +ULONG +ulColor2Color(UCHAR ucFontColor) +{ + static const ULONG aulColorTable[] = { + /* 0 */ 0x00000000UL, /* Automatic */ + /* 1 */ 0x00000000UL, /* Black */ + /* 2 */ 0xff000000UL, /* Blue */ + /* 3 */ 0xffff0000UL, /* Turquoise */ + /* 4 */ 0x00ff0000UL, /* Bright Green */ + /* 5 */ 0xff00ff00UL, /* Pink */ + /* 6 */ 0x0000ff00UL, /* Red */ + /* 7 */ 0x00ffff00UL, /* Yellow */ + /* 8 */ 0xffffff00UL, /* White */ + /* 9 */ 0x80000000UL, /* Dark Blue */ + /* 10 */ 0x80800000UL, /* Teal */ + /* 11 */ 0x00800000UL, /* Green */ + /* 12 */ 0x80008000UL, /* Violet */ + /* 13 */ 0x00008000UL, /* Dark Red */ + /* 14 */ 0x00808000UL, /* Dark Yellow */ + /* 15 */ 0x80808000UL, /* Gray 50% */ + /* 16 */ 0xc0c0c000UL, /* Gray 25% */ + }; + if ((size_t)ucFontColor >= elementsof(aulColorTable)) { + return aulColorTable[0]; + } + return aulColorTable[(int)ucFontColor]; +} /* end of ulColor2Color */ + +/* + * iFindSplit - find a place to split the string + * + * returns the index of the split character or -1 if no split found. + */ +static int +iFindSplit(const char *szString, size_t tStringLen) +{ + size_t tSplit; + + if (tStringLen == 0) { + return -1; + } + tSplit = tStringLen - 1; + while (tSplit >= 1) { + if (szString[tSplit] == ' ' || + (szString[tSplit] == '-' && szString[tSplit - 1] != ' ')) { + return (int)tSplit; + } + tSplit--; + } + return -1; +} /* end of iFindSplit */ + +/* + * pSplitList - split the specified list in a printable part and a leftover part + * + * returns the pointer to the leftover part + */ +output_type * +pSplitList(output_type *pAnchor) +{ + output_type *pCurr, *pLeftOver; + int iIndex; + + fail(pAnchor == NULL); + + for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext) + ; /* EMPTY */ + iIndex = -1; + for (; pCurr != NULL; pCurr = pCurr->pPrev) { + iIndex = iFindSplit(pCurr->szStorage, pCurr->tNextFree); + if (iIndex >= 0) { + break; + } + } + + if (pCurr == NULL || iIndex < 0) { + /* No split, no leftover */ + return NULL; + } + /* Split over the iIndex-th character */ + NO_DBG_MSG("pLeftOver"); + pLeftOver = xmalloc(sizeof(*pLeftOver)); + fail(pCurr->tNextFree < (size_t)iIndex); + pLeftOver->tStorageSize = pCurr->tNextFree - (size_t)iIndex; + pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); + pLeftOver->tNextFree = pCurr->tNextFree - (size_t)iIndex - 1; + (void)strncpy(pLeftOver->szStorage, + pCurr->szStorage + iIndex + 1, pLeftOver->tNextFree); + pLeftOver->szStorage[pLeftOver->tNextFree] = '\0'; + NO_DBG_MSG(pLeftOver->szStorage); + pLeftOver->ucFontColor = pCurr->ucFontColor; + pLeftOver->usFontStyle = pCurr->usFontStyle; + pLeftOver->tFontRef = pCurr->tFontRef; + pLeftOver->usFontSize = pCurr->usFontSize; + pLeftOver->lStringWidth = lComputeStringWidth( + pLeftOver->szStorage, + pLeftOver->tNextFree, + pLeftOver->tFontRef, + pLeftOver->usFontSize); + pLeftOver->pPrev = NULL; + pLeftOver->pNext = pCurr->pNext; + if (pLeftOver->pNext != NULL) { + pLeftOver->pNext->pPrev = pLeftOver; + } + fail(!bCheckDoubleLinkedList(pLeftOver)); + + NO_DBG_MSG("pAnchor"); + NO_DBG_HEX(pCurr->szStorage[iIndex]); + while (iIndex >= 0 && isspace((int)(UCHAR)pCurr->szStorage[iIndex])) { + iIndex--; + } + pCurr->tNextFree = (size_t)iIndex + 1; + pCurr->szStorage[pCurr->tNextFree] = '\0'; + NO_DBG_MSG(pCurr->szStorage); + pCurr->lStringWidth = lComputeStringWidth( + pCurr->szStorage, + pCurr->tNextFree, + pCurr->tFontRef, + pCurr->usFontSize); + pCurr->pNext = NULL; + fail(!bCheckDoubleLinkedList(pAnchor)); + + return pLeftOver; +} /* end of pSplitList */ + +/* + * tNumber2Roman - convert a number to Roman Numerals + * + * returns the number of characters written + */ +size_t +tNumber2Roman(UINT uiNumber, BOOL bUpperCase, char *szOutput) +{ + char *outp, *p, *q; + UINT uiNextVal, uiValue; + + fail(szOutput == NULL); + + uiNumber %= 4000; /* Very high numbers can't be represented */ + if (uiNumber == 0) { + szOutput[0] = '\0'; + return 0; + } + + outp = szOutput; + p = bUpperCase ? "M\2D\5C\2L\5X\2V\5I" : "m\2d\5c\2l\5x\2v\5i"; + uiValue = 1000; + for (;;) { + while (uiNumber >= uiValue) { + *outp++ = *p; + uiNumber -= uiValue; + } + if (uiNumber == 0) { + *outp = '\0'; + fail(outp < szOutput); + return (size_t)(outp - szOutput); + } + q = p + 1; + uiNextVal = uiValue / (UINT)(UCHAR)*q; + if ((int)*q == 2) { /* magic */ + uiNextVal /= (UINT)(UCHAR)*(q += 2); + } + if (uiNumber + uiNextVal >= uiValue) { + *outp++ = *++q; + uiNumber += uiNextVal; + } else { + p++; + uiValue /= (UINT)(UCHAR)(*p++); + } + } +} /* end of tNumber2Roman */ + +/* + * iNumber2Alpha - convert a number to alphabetic "numbers" + * + * returns the number of characters written + */ +size_t +tNumber2Alpha(UINT uiNumber, BOOL bUpperCase, char *szOutput) +{ + char *outp; + UINT uiTmp; + + fail(szOutput == NULL); + + if (uiNumber == 0) { + szOutput[0] = '\0'; + return 0; + } + + outp = szOutput; + uiTmp = (UINT)(bUpperCase ? 'A': 'a'); + if (uiNumber <= 26) { + uiNumber -= 1; + *outp++ = (char)(uiTmp + uiNumber); + } else if (uiNumber <= 26U + 26U*26U) { + uiNumber -= 26 + 1; + *outp++ = (char)(uiTmp + uiNumber / 26); + *outp++ = (char)(uiTmp + uiNumber % 26); + } else if (uiNumber <= 26U + 26U*26U + 26U*26U*26U) { + uiNumber -= 26 + 26*26 + 1; + *outp++ = (char)(uiTmp + uiNumber / (26*26)); + *outp++ = (char)(uiTmp + uiNumber / 26 % 26); + *outp++ = (char)(uiTmp + uiNumber % 26); + } + *outp = '\0'; + fail(outp < szOutput); + return (size_t)(outp - szOutput); +} /* end of tNumber2Alpha */ + +/* + * unincpy - copy a counted Unicode string to an single-byte string + */ +char * +unincpy(char *s1, const UCHAR *s2, size_t n) +{ + char *pcDest; + ULONG ulChar; + size_t tLen; + USHORT usUni; + + for (pcDest = s1, tLen = 0; tLen < n; pcDest++, tLen++) { + usUni = usGetWord(tLen * 2, s2); + if (usUni == 0) { + break; + } + ulChar = ulTranslateCharacters(usUni, 0, 8, + conversion_unknown, encoding_neutral, FALSE); + if (ulChar == IGNORE_CHARACTER) { + ulChar = (ULONG)'?'; + } + *pcDest = (char)ulChar; + } + for (; tLen < n; tLen++) { + *pcDest++ = '\0'; + } + return s1; +} /* end of unincpy */ + +/* + * unilen - calculate the length of a Unicode string + * + * returns the length in bytes + */ +size_t +unilen(const UCHAR *s) +{ + size_t tLen; + USHORT usUni; + + tLen = 0; + for (;;) { + usUni = usGetWord(tLen, s); + if (usUni == 0) { + return tLen; + } + tLen += 2; + } +} /* end of unilen */ + +/* + * szBaseName - get the basename of the specified filename + */ +const char * +szBasename(const char *szFilename) +{ + const char *szTmp; + + fail(szFilename == NULL); + + if (szFilename == NULL || szFilename[0] == '\0') { + return "null"; + } + + szTmp = strrchr(szFilename, FILE_SEPARATOR[0]); + if (szTmp == NULL) { + return szFilename; + } + return ++szTmp; +} /* end of szBasename */ + +/* + * lComputeLeading - compute the leading + * + * NOTE: the fontsize is specified in half points + * + * Returns the leading in drawunits + */ +long +lComputeLeading(USHORT usFontSize) +{ + long lLeading; + + lLeading = (long)usFontSize * 500L; + if (usFontSize < 18) { /* Small text: 112% */ + lLeading *= 112; + } else if (usFontSize < 28) { /* Normal text: 124% */ + lLeading *= 124; + } else if (usFontSize < 48) { /* Small headlines: 104% */ + lLeading *= 104; + } else { /* Large headlines: 100% */ + lLeading *= 100; + } + lLeading = lMilliPoints2DrawUnits(lLeading); + lLeading += 50; + lLeading /= 100; + return lLeading; +} /* end of lComputeLeading */ + +/* + * Convert a UCS character to an UTF-8 string + * + * Returns the string length of the result + */ +size_t +tUcs2Utf8(ULONG ulChar, char *szResult, size_t tMaxResultLen) +{ + if (szResult == NULL || tMaxResultLen == 0) { + return 0; + } + + if (ulChar < 0x80 && tMaxResultLen >= 2) { + szResult[0] = (char)ulChar; + szResult[1] = '\0'; + return 1; + } + if (ulChar < 0x800 && tMaxResultLen >= 3) { + szResult[0] = (char)(0xc0 | ulChar >> 6); + szResult[1] = (char)(0x80 | (ulChar & 0x3f)); + szResult[2] = '\0'; + return 2; + } + if (ulChar < 0x10000 && tMaxResultLen >= 4) { + szResult[0] = (char)(0xe0 | ulChar >> 12); + szResult[1] = (char)(0x80 | (ulChar >> 6 & 0x3f)); + szResult[2] = (char)(0x80 | (ulChar & 0x3f)); + szResult[3] = '\0'; + return 3; + } + if (ulChar < 0x200000 && tMaxResultLen >= 5) { + szResult[0] = (char)(0xf0 | ulChar >> 18); + szResult[1] = (char)(0x80 | (ulChar >> 12 & 0x3f)); + szResult[2] = (char)(0x80 | (ulChar >> 6 & 0x3f)); + szResult[3] = (char)(0x80 | (ulChar & 0x3f)); + szResult[4] = '\0'; + return 4; + } + szResult[0] = '\0'; + return 0; +} /* end of tUcs2Utf8 */ + +/* + * vGetBulletValue - get the bullet value for the conversing type and encoding + */ +void +vGetBulletValue(conversion_type eConversionType, encoding_type eEncoding, + char *szResult, size_t tMaxResultLen) +{ + fail(szResult == NULL); + fail(tMaxResultLen < 2); + + if (eEncoding == encoding_utf_8) { + (void)tUcs2Utf8(UNICODE_BULLET, szResult, tMaxResultLen); + } else { + szResult[0] = (char)ucGetBulletCharacter(eConversionType, + eEncoding); + szResult[1] = '\0'; + } +} /* end of vGetBulletValue */ + +/* + * bAllZero - are all bytes zero? + */ +BOOL +bAllZero(const UCHAR *aucBytes, size_t tLength) +{ + size_t tIndex; + + if (aucBytes == NULL || tLength == 0) { + return TRUE; + } + + for (tIndex = 0; tIndex < tLength; tIndex++) { + if (aucBytes[tIndex] != 0) { + return FALSE; + } + } + return TRUE; +} /* end of bAllZero */ + +#if !defined(__riscos) +/* + * GetCodesetFromLocale - get the codeset from the current locale + * + * Original version: Copyright (C) 1999 Bruno Haible + * Syntax: + * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]] + * + * Returns TRUE when sucessful, otherwise FALSE + */ +static BOOL +bGetCodesetFromLocale(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) +{ +#if !defined(__dos) + const char *szLocale; + const char *pcTmp; + size_t tIndex; + char szModifier[6]; +#endif /* __dos */ + + if (pbEuro != NULL) { + *pbEuro = FALSE; /* Until proven otherwise */ + } + if (szCodeset == NULL || tMaxCodesetLength == 0) { + return FALSE; + } + +#if defined(__dos) + if (tMaxCodesetLength < 2 + sizeof(int) * 3 + 1) { + DBG_DEC(tMaxCodesetLength); + DBG_DEC(2 + sizeof(int) * 3 + 1); + return FALSE; + } + /* Get the active codepage from DOS */ + sprintf(szCodeset, "cp%d", iGetCodepage()); + DBG_MSG(szCodeset); +#else + /* Get the locale from the environment */ + szLocale = getenv("LC_ALL"); + if (szLocale == NULL || szLocale[0] == '\0') { + szLocale = getenv("LC_CTYPE"); + if (szLocale == NULL || szLocale[0] == '\0') { + szLocale = getenv("LANG"); + } + } + if (szLocale == NULL || szLocale[0] == '\0') { + /* No locale, so no codeset name and no modifier */ + return FALSE; + } + DBG_MSG(szLocale); + pcTmp = strchr(szLocale, '.'); + if (pcTmp == NULL) { + /* No codeset name */ + szCodeset[0] = '\0'; + } else { + /* Copy the codeset name */ + pcTmp++; + for (tIndex = 0; tIndex < tMaxCodesetLength; tIndex++) { + if (*pcTmp == '@' || *pcTmp == '+' || + *pcTmp == ',' || *pcTmp == '_' || + *pcTmp == '\0') { + szCodeset[tIndex] = '\0'; + break; + } + szCodeset[tIndex] = *pcTmp; + pcTmp++; + } + szCodeset[tMaxCodesetLength - 1] = '\0'; + } + if (pbEuro == NULL) { + /* No need to get the modifier */ + return TRUE; + } + pcTmp = strchr(szLocale, '@'); + if (pcTmp != NULL) { + /* Copy the modifier */ + pcTmp++; + for (tIndex = 0; tIndex < sizeof(szModifier); tIndex++) { + if (*pcTmp == '+' || *pcTmp == ',' || + *pcTmp == '_' || *pcTmp == '\0') { + szModifier[tIndex] = '\0'; + break; + } + szModifier[tIndex] = *pcTmp; + pcTmp++; + } + szModifier[sizeof(szModifier) - 1] = '\0'; + *pbEuro = STRCEQ(szModifier, "Euro"); + } +#endif /* __dos */ + return TRUE; +} /* end of bGetCodesetFromLocale */ + +/* + * GetNormalizedCodeset - get the normalized codeset from the current locale + * + * Returns TRUE when sucessful, otherwise FALSE + */ +BOOL +bGetNormalizedCodeset(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) +{ + BOOL bOnlyDigits; + const char *pcSrc; + char *pcDest; + char *szTmp, *szCodesetNorm; + + if (pbEuro != NULL) { + *pbEuro = FALSE; /* Until proven otherwise */ + } + if (szCodeset == NULL || tMaxCodesetLength < 4) { + return FALSE; + } + + /* Get the codeset name */ + szTmp = xmalloc(tMaxCodesetLength - 3); + if (!bGetCodesetFromLocale(szTmp, tMaxCodesetLength - 3, pbEuro)) { + szTmp = xfree(szTmp); + return FALSE; + } + /* Normalize the codeset name */ + szCodesetNorm = xmalloc(tMaxCodesetLength - 3); + bOnlyDigits = TRUE; + pcDest = szCodesetNorm; + for (pcSrc = szTmp; *pcSrc != '\0'; pcSrc++) { + if (isalnum(*pcSrc)) { + *pcDest = tolower(*pcSrc); + if (!isdigit(*pcDest)) { + bOnlyDigits = FALSE; + } + pcDest++; + } + } + *pcDest = '\0'; + DBG_MSG(szCodesetNorm); + /* Add "iso" when szCodesetNorm contains all digits */ + if (bOnlyDigits && szCodesetNorm[0] != '\0') { + fail(strlen(szCodesetNorm) + 3 >= tMaxCodesetLength); + sprintf(szCodeset, "iso%s", szCodesetNorm); + } else { + fail(strlen(szCodesetNorm) >= tMaxCodesetLength); + strncpy(szCodeset, szCodesetNorm, pcDest - szCodesetNorm + 1); + szCodeset[tMaxCodesetLength - 1] = '\0'; + } + DBG_MSG(szCodeset); + /* Clean up and leave */ + szCodesetNorm = xfree(szCodesetNorm); + szTmp = xfree(szTmp); + return TRUE; +} /* end of bGetNormalizedCodeset */ + +/* + * szGetDefaultMappingFile - get the default mapping file + * + * Returns the basename of the default mapping file + */ +const char * +szGetDefaultMappingFile(void) +{ + static const struct { + const char *szCodeset; + const char *szMappingFile; + } atMappingFile[] = { + { "iso88591", MAPPING_FILE_8859_1 }, + { "iso88592", MAPPING_FILE_8859_2 }, + { "iso88593", "8859-3.txt" }, + { "iso88594", "8859-4.txt" }, + { "iso88595", "8859-5.txt" }, + { "iso88596", MAPPING_FILE_8859_5 }, + { "iso88597", "8859-7.txt" }, + { "iso88598", "8859-8.txt" }, + { "iso88599", "8859-9.txt" }, + { "iso885910", "8859-10.txt" }, + { "iso885913", "8859-13.txt" }, + { "iso885914", "8859-14.txt" }, + { "iso885915", MAPPING_FILE_8859_15 }, + { "iso885916", "8859-16.txt" }, + { "koi8r", MAPPING_FILE_KOI8_R }, + { "koi8u", MAPPING_FILE_KOI8_U }, + { "utf8", MAPPING_FILE_UTF_8 }, + { "cp437", MAPPING_FILE_CP437 }, + { "cp850", "cp850.txt" }, + { "cp852", MAPPING_FILE_CP852 }, + { "cp862", "cp862.txt" }, + { "cp864", "cp864.txt" }, + { "cp866", MAPPING_FILE_CP866 }, + { "cp1250", MAPPING_FILE_CP1250 }, + { "cp1251", MAPPING_FILE_CP1251 }, + { "cp1252", "cp1252.txt" }, + }; + size_t tIndex; + BOOL bEuro; + char szCodeset[20]; + + szCodeset[0] = '\0'; + bEuro = FALSE; + /* Get the normalized codeset name */ + if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), &bEuro)) { + return MAPPING_FILE_8859_1; + } + if (szCodeset[0] == '\0') { + if (bEuro) { + /* Default mapping file (with Euro sign) */ + return MAPPING_FILE_8859_15; + } else { + /* Default mapping file (without Euro sign) */ + return MAPPING_FILE_8859_1; + } + } + /* Find the name in the table */ + for (tIndex = 0; tIndex < elementsof(atMappingFile); tIndex++) { + if (STREQ(atMappingFile[tIndex].szCodeset, szCodeset)) { + return atMappingFile[tIndex].szMappingFile; + } + } + /* Default default mapping file */ +#if defined(__dos) + return MAPPING_FILE_CP437; +#else + return MAPPING_FILE_8859_1; +#endif /* __dos */ +} /* end of szGetDefaultMappingFile */ +#endif /* !__riscos */ + +/* + * tConvertDTTM - convert Windows Date and Time format + * + * returns Unix time_t or -1 + */ +time_t +tConvertDTTM(ULONG ulDTTM) +{ + struct tm tTime; + time_t tResult; + + if (ulDTTM == 0) { + return (time_t)-1; + } + memset(&tTime, 0, sizeof(tTime)); + tTime.tm_min = (int)(ulDTTM & 0x0000003f); + tTime.tm_hour = (int)((ulDTTM & 0x000007c0) >> 6); + tTime.tm_mday = (int)((ulDTTM & 0x0000f800) >> 11); + tTime.tm_mon = (int)((ulDTTM & 0x000f0000) >> 16); + tTime.tm_year = (int)((ulDTTM & 0x1ff00000) >> 20); + tTime.tm_isdst = -1; + tTime.tm_mon--; /* From 01-12 to 00-11 */ + tResult = mktime(&tTime); + NO_DBG_MSG(ctime(&tResult)); + return tResult; +} /* end of tConvertDTTM */ diff --git a/mkfile b/mkfile new file mode 100644 index 0000000..d609c25 --- /dev/null +++ b/mkfile @@ -0,0 +1,30 @@ + fontinfo.h diff --git a/notes.c b/notes.c new file mode 100644 index 0000000..ffc7526 --- /dev/null +++ b/notes.c @@ -0,0 +1,876 @@ +/* + * notes.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to tell the difference between footnotes and endnotes + */ + +#include "antiword.h" + +/* + * Private structures to hide the way the information + * is stored from the rest of the program + */ +typedef struct footnote_local_tag { + footnote_block_type tInfo; + ULONG ulCharPosStart; + ULONG ulCharPosNext; + BOOL bUseful; +} footnote_local_type; + +/* Variables needed to write the Footnote and Endnote information */ +static ULONG *aulFootnoteList = NULL; +static size_t tFootnoteListLength = 0; +static ULONG *aulEndnoteList = NULL; +static size_t tEndnoteListLength = 0; +/* Variables needed to write the Footnote Text */ +static footnote_local_type *pFootnoteText = NULL; +static size_t tFootnoteTextLength = 0; + + +/* + * Destroy the lists with footnote and endnote information + */ +void +vDestroyNotesInfoLists(void) +{ + footnote_local_type *pRecord; + size_t tFootnote; + + TRACE_MSG("vDestroyNotesInfoLists"); + + /* Free the lists and reset all control variables */ + aulEndnoteList = xfree(aulEndnoteList); + aulFootnoteList = xfree(aulFootnoteList); + tEndnoteListLength = 0; + tFootnoteListLength = 0; + for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) { + pRecord = pFootnoteText + tFootnote; + pRecord->tInfo.szText = xfree(pRecord->tInfo.szText); + } + pFootnoteText = xfree(pFootnoteText); + tFootnoteTextLength = 0; +} /* end of vDestroyNotesInfoLists */ + +/* + * Build the list with footnote information for Word for DOS files + */ +static void +vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader) +{ + footnote_local_type *pCurr; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo; + ULONG ulCharPos, ulBeginNextBlock; + size_t tFootnotes, tFootnoteInfoLen; + size_t tIndex; + UCHAR aucTmp[2]; + + TRACE_MSG("vGet0FootnotesInfoAndText"); + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginOfText = 128; + NO_DBG_HEX(ulBeginOfText); + ulBeginFootnoteInfo = 128 * (ULONG)usGetWord(0x14, aucHeader); + DBG_HEX(ulBeginFootnoteInfo); + ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader); + DBG_HEX(ulBeginNextBlock); + + if (ulBeginFootnoteInfo == ulBeginNextBlock) { + DBG_MSG("No Footnotes in this document"); + return; + } + + /* Read the the number of footnotes + 1 */ + if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) { + return; + } + tFootnotes = (size_t)usGetWord(0, aucTmp); + if (tFootnotes < 2) { + DBG_MSG("No Footnotes in this document (2)"); + } + DBG_DEC(tFootnotes); + tFootnoteInfoLen = 8 * tFootnotes; + + aucBuffer = xmalloc(tFootnoteInfoLen); + if (!bReadBytes(aucBuffer, + tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen); + + /* Get footnote information */ + fail(tFootnoteListLength != 0); + tFootnoteListLength = tFootnotes - 1; + fail(tFootnoteListLength == 0); + + fail(aulFootnoteList != NULL); + aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 8, aucBuffer); + DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + DBG_HEX(ulFileOffset); + aulFootnoteList[tIndex] = ulFileOffset; + } + + /* Get footnote text */ + fail(tFootnoteTextLength != 0); + tFootnoteTextLength = tFootnotes - 1; + fail(tFootnoteTextLength == 0); + + fail(pFootnoteText != NULL); + pFootnoteText = xcalloc(tFootnoteTextLength, + sizeof(footnote_local_type)); + + for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { + pCurr = pFootnoteText + tIndex; + pCurr->tInfo.szText = NULL; + ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer); + DBG_HEX(ulOffset); + ulCharPos = ulBeginOfText + ulOffset; + DBG_HEX(ulCharPos); + DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosStart = ulCharPos; + ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer); + DBG_HEX(ulOffset); + ulCharPos = ulBeginOfText + ulOffset; + DBG_HEX(ulCharPos); + DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosNext = ulCharPos; + pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet0FootnotesInfoAndText */ + +/* + * Build the lists note information for Word for DOS files + */ +static void +vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader) +{ + TRACE_MSG("vGet0NotesInfo"); + + vGet0FootnotesInfoAndText(pFile, aucHeader); + /* There are no endnotes in a Word for DOS file */ +} /* end of vGet0NotesInfo */ + +/* + * Build the list with footnote information for WinWord 1/2 files + */ +static void +vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo; + size_t tFootnoteInfoLen; + size_t tIndex; + + TRACE_MSG("vGet2FootnotesInfo"); + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */ + NO_DBG_HEX(ulBeginFootnoteInfo); + tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */ + NO_DBG_DEC(tFootnoteInfoLen); + + if (tFootnoteInfoLen < 10) { + DBG_MSG("No Footnotes in this document"); + return; + } + + aucBuffer = xmalloc(tFootnoteInfoLen); + if (!bReadBytes(aucBuffer, + tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen); + + fail(tFootnoteListLength != 0); + tFootnoteListLength = (tFootnoteInfoLen - 4) / 6; + fail(tFootnoteListLength == 0); + + fail(aulFootnoteList != NULL); + aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + NO_DBG_HEX(ulFileOffset); + aulFootnoteList[tIndex] = ulFileOffset; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet2FootnotesInfo */ + +/* + * Build the list with footnote text information for WinWord 1/2 files + */ +static void +vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader) +{ + footnote_local_type *pCurr; + UCHAR *aucBuffer; + ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText; + size_t tFootnoteTextLen; + size_t tIndex; + + TRACE_MSG("vGet2FootnotesText"); + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */ + ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */ + NO_DBG_HEX(ulBeginOfFootnotes); + + ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */ + NO_DBG_HEX(ulBeginFootnoteText); + tFootnoteTextLen = + (size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */ + NO_DBG_DEC(tFootnoteTextLen); + + if (tFootnoteTextLen < 12) { + DBG_MSG("No Footnote text in this document"); + return; + } + + aucBuffer = xmalloc(tFootnoteTextLen); + if (!bReadBytes(aucBuffer, + tFootnoteTextLen, ulBeginFootnoteText, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen); + + fail(tFootnoteTextLength != 0); + tFootnoteTextLength = tFootnoteTextLen / 4 - 2; + fail(tFootnoteTextLength == 0); + + fail(pFootnoteText != NULL); + pFootnoteText = xcalloc(tFootnoteTextLength, + sizeof(footnote_local_type)); + + for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { + pCurr = pFootnoteText + tIndex; + pCurr->tInfo.szText = NULL; + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosStart = ulCharPos; + ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosNext = ulCharPos; + pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet2FootnotesText */ + +/* + * Build the lists note information for WinWord 1/2 files + */ +static void +vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader) +{ + TRACE_MSG("vGet2NotesInfo"); + + vGet2FootnotesInfo(pFile, aucHeader); + vGet2FootnotesText(pFile, aucHeader); + /* There are no endnotes in a WinWord 1/2 file */ +} /* end of vGet2NotesInfo */ + +/* + * Build the list with footnote information for Word 6/7 files + */ +static void +vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo; + size_t tFootnoteInfoLen; + size_t tIndex; + + TRACE_MSG("vGet6FootnotesInfo"); + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */ + NO_DBG_HEX(ulBeginFootnoteInfo); + tFootnoteInfoLen = + (size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */ + NO_DBG_DEC(tFootnoteInfoLen); + + if (tFootnoteInfoLen < 10) { + DBG_MSG("No Footnotes in this document"); + return; + } + + aucBuffer = xmalloc(tFootnoteInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen); + + fail(tFootnoteListLength != 0); + tFootnoteListLength = (tFootnoteInfoLen - 4) / 6; + fail(tFootnoteListLength == 0); + + fail(aulFootnoteList != NULL); + aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + NO_DBG_HEX(ulFileOffset); + aulFootnoteList[tIndex] = ulFileOffset; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet6FootnotesInfo */ + +/* + * Build the list with footnote text information for Word 6/7 files + */ +static void +vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + footnote_local_type *pCurr; + UCHAR *aucBuffer; + ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText; + size_t tFootnoteTextLen; + size_t tIndex; + + TRACE_MSG("vGet6FootnotesText"); + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */ + ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */ + NO_DBG_HEX(ulBeginOfFootnotes); + + ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */ + NO_DBG_HEX(ulBeginFootnoteText); + tFootnoteTextLen = + (size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */ + NO_DBG_DEC(tFootnoteTextLen); + + if (tFootnoteTextLen < 12) { + DBG_MSG("No Footnote text in this document"); + return; + } + + aucBuffer = xmalloc(tFootnoteTextLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen); + + fail(tFootnoteTextLength != 0); + tFootnoteTextLength = tFootnoteTextLen / 4 - 2; + fail(tFootnoteTextLength == 0); + + fail(pFootnoteText != NULL); + pFootnoteText = xcalloc(tFootnoteTextLength, + sizeof(footnote_local_type)); + + for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { + pCurr = pFootnoteText + tIndex; + pCurr->tInfo.szText = NULL; + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosStart = ulCharPos; + ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosNext = ulCharPos; + pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet6FootnotesText */ + +/* + * Build the list with endnote information for Word 6/7 files + */ +static void +vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo; + size_t tEndnoteInfoLen; + size_t tIndex; + + TRACE_MSG("vGet6EndnotesInfo"); + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */ + NO_DBG_HEX(ulBeginEndnoteInfo); + tEndnoteInfoLen = + (size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */ + NO_DBG_DEC(tEndnoteInfoLen); + + if (tEndnoteInfoLen < 10) { + DBG_MSG("No Endnotes in this document"); + return; + } + + aucBuffer = xmalloc(tEndnoteInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen); + + fail(tEndnoteListLength != 0); + tEndnoteListLength = (tEndnoteInfoLen - 4) / 6; + fail(tEndnoteListLength == 0); + + fail(aulEndnoteList != NULL); + aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + NO_DBG_HEX(ulFileOffset); + aulEndnoteList[tIndex] = ulFileOffset; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet6EndnotesInfo */ + +/* + * Build the lists note information for Word 6/7 files + */ +static void +vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + TRACE_MSG("vGet6NotesInfo"); + + vGet6FootnotesInfo(pFile, ulStartBlock, + aulBBD, tBBDLen, aucHeader); + vGet6FootnotesText(pFile, ulStartBlock, + aulBBD, tBBDLen, aucHeader); + vGet6EndnotesInfo(pFile, ulStartBlock, + aulBBD, tBBDLen, aucHeader); +} /* end of vGet6NotesInfo */ + +/* + * Build the list with footnote information for Word 8/9/10 files + */ +static void +vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo; + size_t tFootnoteInfoLen, tBlockDepotLen, tBlockSize; + size_t tIndex; + + TRACE_MSG("vGet8FootnotesInfo"); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */ + NO_DBG_HEX(ulBeginFootnoteInfo); + tFootnoteInfoLen = + (size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */ + NO_DBG_DEC(tFootnoteInfoLen); + + if (tFootnoteInfoLen < 10) { + DBG_MSG("No Footnotes in this document"); + return; + } + + NO_DBG_DEC(pPPS->tTable.ulSB); + NO_DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No footnotes information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tFootnoteInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen); + + fail(tFootnoteListLength != 0); + tFootnoteListLength = (tFootnoteInfoLen - 4) / 6; + fail(tFootnoteListLength == 0); + + fail(aulFootnoteList != NULL); + aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + NO_DBG_HEX(ulFileOffset); + aulFootnoteList[tIndex] = ulFileOffset; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet8FootnotesInfo */ + +/* + * Build the list with footnote text information for Word 8/9/10 files + */ +static void +vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + footnote_local_type *pCurr; + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText; + size_t tFootnoteTextLen, tBlockDepotLen, tBlockSize; + size_t tIndex; + + TRACE_MSG("vGet8FootnotesText"); + + ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */ + ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */ + NO_DBG_HEX(ulBeginOfFootnotes); + + ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */ + NO_DBG_HEX(ulBeginFootnoteText); + tFootnoteTextLen = + (size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */ + NO_DBG_DEC(tFootnoteTextLen); + + if (tFootnoteTextLen < 12) { + DBG_MSG("No Footnote text in this document"); + return; + } + + NO_DBG_DEC(pPPS->tTable.ulSB); + NO_DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No footnote text information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tFootnoteTextLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen); + + fail(tFootnoteTextLength != 0); + tFootnoteTextLength = tFootnoteTextLen / 4 - 2; + fail(tFootnoteTextLength == 0); + + fail(pFootnoteText != NULL); + pFootnoteText = xcalloc(tFootnoteTextLength, + sizeof(footnote_local_type)); + + for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { + pCurr = pFootnoteText + tIndex; + pCurr->tInfo.szText = NULL; + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosStart = ulCharPos; + ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulCharPos = ulBeginOfFootnotes + ulOffset; + NO_DBG_HEX(ulCharPos); + NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); + pCurr->ulCharPosNext = ulCharPos; + pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet8FootnotesText */ + +/* + * Build the list with endnote information for Word 8/9/10 files + */ +static void +vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo; + size_t tEndnoteInfoLen, tBlockDepotLen, tBlockSize; + size_t tIndex; + + TRACE_MSG("vGet8EndnotesInfo"); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */ + NO_DBG_HEX(ulBeginEndnoteInfo); + tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */ + NO_DBG_DEC(tEndnoteInfoLen); + + if (tEndnoteInfoLen < 10) { + DBG_MSG("No endnotes in this document"); + return; + } + + NO_DBG_DEC(pPPS->tTable.ulSB); + NO_DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No endnotes information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tEndnoteInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen); + + fail(tEndnoteListLength != 0); + tEndnoteListLength = (tEndnoteInfoLen - 4) / 6; + fail(tEndnoteListLength == 0); + + fail(aulEndnoteList != NULL); + aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG)); + + for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) { + ulOffset = ulGetLong(tIndex * 4, aucBuffer); + NO_DBG_HEX(ulOffset); + ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); + NO_DBG_HEX(ulFileOffset); + aulEndnoteList[tIndex] = ulFileOffset; + } + aucBuffer = xfree(aucBuffer); +} /* end of vGet8EndnotesInfo */ + +/* + * Build the lists with footnote and endnote information for Word 8/9/10 files + */ +static void +vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + TRACE_MSG("vGet8NotesInfo"); + + vGet8FootnotesInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8FootnotesText(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8EndnotesInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); +} /* end of vGet8NotesInfo */ + +/* + * Build the lists with footnote and endnote information + */ +void +vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader, int iWordVersion) +{ + TRACE_MSG("vGetNotesInfo"); + + fail(pFile == NULL); + fail(pPPS == NULL && iWordVersion >= 6); + fail(aulBBD == NULL && tBBDLen != 0); + fail(aulSBD == NULL && tSBDLen != 0); + fail(aucHeader == NULL); + + switch (iWordVersion) { + case 0: + vGet0NotesInfo(pFile, aucHeader); + break; + case 1: + case 2: + vGet2NotesInfo(pFile, aucHeader); + break; + case 4: + case 5: + break; + case 6: + case 7: + vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + break; + case 8: + vGet8NotesInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + break; + default: + werr(0, "Sorry, no notes information"); + break; + } +} /* end of vGetNotesInfo */ + +/* + * vPrepareFootnoteText - prepare the footnote text + */ +void +vPrepareFootnoteText(FILE *pFile) +{ + footnote_local_type *pCurr; + size_t tFootnote; + + fail(pFile == NULL); + fail(pFootnoteText == NULL && tFootnoteTextLength != 0); + + if (pFootnoteText == NULL || tFootnoteTextLength == 0) { + /* No information */ + return; + } + + /* Fill text and useful-ness */ + for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) { + pCurr = pFootnoteText + tFootnote; + pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; + if (pCurr->bUseful) { + pCurr->tInfo.szText = szFootnoteDecryptor(pFile, + pCurr->ulCharPosStart, + pCurr->ulCharPosNext); + } else { + pCurr->tInfo.szText = NULL; + } + } +} /* end of vPrepareFootnoteText */ + +/* + * szGetFootnootText - get the text of the spefified footnote + */ +const char * +szGetFootnootText(UINT uiFootnoteIndex) +{ + if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) { + return NULL; + } + return pFootnoteText[uiFootnoteIndex].tInfo.szText; +} /* end of szGetFootnootText */ + +/* + * Get the notetype of the note at the given fileoffset + */ +notetype_enum +eGetNotetype(ULONG ulFileOffset) +{ + size_t tIndex; + + TRACE_MSG("eGetNotetype"); + + fail(aulFootnoteList == NULL && tFootnoteListLength != 0); + fail(aulEndnoteList == NULL && tEndnoteListLength != 0); + + /* Go for the easy answers first */ + if (tFootnoteListLength == 0 && tEndnoteListLength == 0) { + return notetype_is_unknown; + } + if (tEndnoteListLength == 0) { + return notetype_is_footnote; + } + if (tFootnoteListLength == 0) { + return notetype_is_endnote; + } + /* No easy answer, so we search */ + for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { + if (aulFootnoteList[tIndex] == ulFileOffset) { + return notetype_is_footnote; + } + } + for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) { + if (aulEndnoteList[tIndex] == ulFileOffset) { + return notetype_is_endnote; + } + } + /* Not found */ + return notetype_is_unknown; +} /* end of eGetNotetype */ diff --git a/options.c b/options.c new file mode 100644 index 0000000..8379fef --- /dev/null +++ b/options.c @@ -0,0 +1,950 @@ +/* + * options.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Read and write the options + */ + +#include +#include +#include +#if defined(__riscos) +#include "DeskLib:Error.h" +#include "DeskLib:Wimp.h" +#else +#include +#if defined(__dos) || defined(N_PLAT_NLM) +extern int getopt(int, char **, const char *); +#else +#include +#endif /* __dos */ +#endif /* __riscos */ +#include "antiword.h" + +#if defined(__riscos) +#define PARAGRAPH_BREAK "set paragraph_break=%d" +#define AUTOFILETYPE "set autofiletype_allowed=%d" +#define USE_OUTLINEFONTS "set use_outlinefonts=%d" +#define SHOW_IMAGES "set show_images=%d" +#define HIDE_HIDDEN_TEXT "set hide_hidden_text=%d" +#define SCALE_FACTOR_START "set scale_factor_start=%d" +#else +#define LEAFNAME_SIZE (32+1) +#endif /* __riscos */ + +/* Current values for options */ +static options_type tOptionsCurr; +#if defined(__riscos) +/* Temporary values for options */ +static options_type tOptionsTemp; +#else +typedef struct papersize_tag { + char szName[16]; /* Papersize name */ + USHORT usWidth; /* In points */ + USHORT usHeight; /* In points */ +} papersize_type; + +static const papersize_type atPaperSizes[] = { + { "10x14", 720, 1008 }, + { "a3", 842, 1191 }, + { "a4", 595, 842 }, + { "a5", 420, 595 }, + { "b4", 729, 1032 }, + { "b5", 516, 729 }, + { "executive", 540, 720 }, + { "folio", 612, 936 }, + { "legal", 612, 1008 }, + { "letter", 612, 792 }, + { "note", 540, 720 }, + { "quarto", 610, 780 }, + { "statement", 396, 612 }, + { "tabloid", 792, 1224 }, + { "", 0, 0 }, +}; +#endif /* __riscos */ +/* Default values for options */ +static const options_type tOptionsDefault = { + DEFAULT_SCREEN_WIDTH, +#if defined(__riscos) + conversion_draw, +#else + conversion_text, +#endif /* __riscos */ + TRUE, + TRUE, + FALSE, + encoding_latin_1, + INT_MAX, + INT_MAX, + level_default, +#if defined(__riscos) + TRUE, + DEFAULT_SCALE_FACTOR, +#endif /* __riscos */ +}; + + +#if !defined(__riscos) +/* + * bCorrectPapersize - see if the papersize is correct + * + * TRUE if the papersize is correct, otherwise FALSE + */ +static BOOL +bCorrectPapersize(const char *szName, conversion_type eConversionType) +{ + const papersize_type *pPaperSize; + + for (pPaperSize = atPaperSizes; + pPaperSize->szName[0] != '\0'; + pPaperSize++) { + if (!STRCEQ(pPaperSize->szName, szName)) { + continue; + } + DBG_DEC(pPaperSize->usWidth); + DBG_DEC(pPaperSize->usHeight); + tOptionsCurr.eConversionType = eConversionType; + tOptionsCurr.iPageHeight = (int)pPaperSize->usHeight; + tOptionsCurr.iPageWidth = (int)pPaperSize->usWidth; + return TRUE; + } + return FALSE; +} /* end of bCorrectPapersize */ + +/* + * szCreateSuffix - create a suffix for the file + * + * Returns the suffix + */ +static const char * +szCreateSuffix(const char *szLeafname) +{ + const char *pcDot; + + pcDot = strrchr(szLeafname, '.'); + if (pcDot != NULL && STRCEQ(pcDot, ".txt")) { + /* There is already a .txt suffix, no need for another one */ + return ""; + } + return ".txt"; +} /* end of szCreateSuffix */ + +/* + * eMappingFile2Encoding - convert the mapping file to an encoding + */ +static encoding_type +eMappingFile2Encoding(const char *szLeafname) +{ + char szMappingFile[LEAFNAME_SIZE+4]; + + fail(szLeafname == NULL); + + if (strlen(szLeafname) + 4 >= sizeof(szMappingFile)) { + DBG_MSG(szLeafname); + return encoding_latin_1; + } + + sprintf(szMappingFile, "%s%s", szLeafname, szCreateSuffix(szLeafname)); + + DBG_MSG(szMappingFile); + + if (STRCEQ(szMappingFile, MAPPING_FILE_UTF_8)) { + return encoding_utf_8; + } + if (STRCEQ(szMappingFile, MAPPING_FILE_CP852) || + STRCEQ(szMappingFile, MAPPING_FILE_CP1250) || + STRCEQ(szMappingFile, MAPPING_FILE_8859_2)) { + return encoding_latin_2; + } + if (STRCEQ(szMappingFile, MAPPING_FILE_KOI8_R) || + STRCEQ(szMappingFile, MAPPING_FILE_KOI8_U) || + STRCEQ(szMappingFile, MAPPING_FILE_CP866) || + STRCEQ(szMappingFile, MAPPING_FILE_CP1251) || + STRCEQ(szMappingFile, MAPPING_FILE_8859_5)) { + return encoding_cyrillic; + } + return encoding_latin_1; +} /* end of eMappingFile2Encoding */ +#endif /* !__riscos */ + +/* + * pOpenCharacterMappingFile - open the mapping file + * + * Returns the file pointer or NULL + */ +static FILE * +pOpenCharacterMappingFile(const char *szLeafname) +{ +#if !defined(__riscos) + FILE *pFile; + const char *szHome, *szAntiword, *szSuffix; + size_t tFilenameLen; + char szMappingFile[PATH_MAX+1]; +#endif /* !__riscos */ + + if (szLeafname == NULL || szLeafname[0] == '\0') { + return NULL; + } + + DBG_MSG(szLeafname); + +#if defined(__riscos) + return fopen(szLeafname, "r"); +#else + /* Set the suffix */ + szSuffix = szCreateSuffix(szLeafname); + + /* Set length */ + tFilenameLen = strlen(szLeafname) + strlen(szSuffix); + + /* Try the environment version of the mapping file */ + szAntiword = szGetAntiwordDirectory(); + if (szAntiword != NULL && szAntiword[0] != '\0') { + if (strlen(szAntiword) + tFilenameLen < + sizeof(szMappingFile) - + sizeof(FILE_SEPARATOR)) { + sprintf(szMappingFile, + "%s" FILE_SEPARATOR "%s%s", + szAntiword, szLeafname, szSuffix); + DBG_MSG(szMappingFile); + pFile = fopen(szMappingFile, "r"); + if (pFile != NULL) { + return pFile; + } + } else { + werr(0, "Environment mappingfilename ignored"); + } + } + + /* Try the local version of the mapping file */ + szHome = szGetHomeDirectory(); + if (strlen(szHome) + tFilenameLen < + sizeof(szMappingFile) - + sizeof(ANTIWORD_DIR) - + 2 * sizeof(FILE_SEPARATOR)) { + sprintf(szMappingFile, + "%s" FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR "%s%s", + szHome, szLeafname, szSuffix); + DBG_MSG(szMappingFile); + pFile = fopen(szMappingFile, "r"); + if (pFile != NULL) { + return pFile; + } + } else { + werr(0, "Local mappingfilename too long, ignored"); + } + + /* Try the global version of the mapping file */ + if (tFilenameLen < + sizeof(szMappingFile) - + sizeof(GLOBAL_ANTIWORD_DIR) - + sizeof(FILE_SEPARATOR)) { + sprintf(szMappingFile, + GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s", + szLeafname, szSuffix); + DBG_MSG(szMappingFile); + pFile = fopen(szMappingFile, "r"); + if (pFile != NULL) { + return pFile; + } + } else { + werr(0, "Global mappingfilename too long, ignored"); + } + werr(0, "I can't open your mapping file (%s%s)\n" + "It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '" + GLOBAL_ANTIWORD_DIR "'.", szLeafname, szSuffix, szHome); + return NULL; +#endif /* __riscos */ +} /* end of pOpenCharacterMappingFile */ + +/* + * vCloseCharacterMappingFile - close the mapping file + */ +static void +vCloseCharacterMappingFile(FILE *pFile) +{ + (void)fclose(pFile); +} /* end of pCloseCharacterMappingFile */ + + +/* + * iReadOptions - read options + * + * returns: -1: error + * 0: help + * >0: index first file argument + */ +int +iReadOptions(int argc, char **argv) +{ +#if defined(__riscos) + FILE *pFile; + const char *szAlphabet; + int iAlphabet; + char szLine[81]; +#else + extern char *optarg; + extern int optind; + char *pcChar, *szTmp; + int iChar; + char szLeafname[LEAFNAME_SIZE]; +#endif /* __riscos */ + FILE *pCharacterMappingFile; + int iTmp; + BOOL bSuccess; + + DBG_MSG("iReadOptions"); + +/* Defaults */ + tOptionsCurr = tOptionsDefault; + +#if defined(__riscos) +/* Choices file */ + pFile = fopen("", "r"); + DBG_MSG_C(pFile == NULL, "Choices file not found"); + DBG_HEX_C(pFile != NULL, pFile); + if (pFile != NULL) { + while (fgets(szLine, (int)sizeof(szLine), pFile) != NULL) { + DBG_MSG(szLine); + if (szLine[0] == '#' || + szLine[0] == '\r' || + szLine[0] == '\n') { + continue; + } + if (sscanf(szLine, PARAGRAPH_BREAK, &iTmp) == 1 && + (iTmp == 0 || + (iTmp >= MIN_SCREEN_WIDTH && + iTmp <= MAX_SCREEN_WIDTH))) { + tOptionsCurr.iParagraphBreak = iTmp; + DBG_DEC(tOptionsCurr.iParagraphBreak); + } else if (sscanf(szLine, AUTOFILETYPE, &iTmp) + == 1) { + tOptionsCurr.bAutofiletypeAllowed = + iTmp != 0; + DBG_DEC(tOptionsCurr.bAutofiletypeAllowed); + } else if (sscanf(szLine, USE_OUTLINEFONTS, &iTmp) + == 1) { + tOptionsCurr.eConversionType = + iTmp == 0 ? + conversion_text : conversion_draw; + DBG_DEC(tOptionsCurr.eConversionType); + } else if (sscanf(szLine, SHOW_IMAGES, &iTmp) + == 1) { + tOptionsCurr.eImageLevel = iTmp != 0 ? + level_default : level_no_images; + } else if (sscanf(szLine, HIDE_HIDDEN_TEXT, &iTmp) + == 1) { + tOptionsCurr.bHideHiddenText = iTmp != 0; + DBG_DEC(tOptionsCurr.bHideHiddenText); + } else if (sscanf(szLine, SCALE_FACTOR_START, &iTmp) + == 1) { + if (iTmp >= MIN_SCALE_FACTOR && + iTmp <= MAX_SCALE_FACTOR) { + tOptionsCurr.iScaleFactor = iTmp; + DBG_DEC(tOptionsCurr.iScaleFactor); + } + } + } + (void)fclose(pFile); + } + iAlphabet = iReadCurrentAlphabetNumber(); + switch (iAlphabet) { + case 101: /* ISO-8859-1 aka Latin1 */ + szAlphabet = ""; + break; + case 112: /* ISO-8859-15 aka Latin9 */ + szAlphabet = ""; + break; + default: + werr(0, "Alphabet '%d' is not supported", iAlphabet); + return -1; + } + pCharacterMappingFile = pOpenCharacterMappingFile(szAlphabet); + if (pCharacterMappingFile != NULL) { + bSuccess = bReadCharacterMappingTable(pCharacterMappingFile); + vCloseCharacterMappingFile(pCharacterMappingFile); + } else { + bSuccess = FALSE; + } + return bSuccess ? 1 : -1; +#else +/* Environment */ + szTmp = getenv("COLUMNS"); + if (szTmp != NULL) { + DBG_MSG(szTmp); + iTmp = (int)strtol(szTmp, &pcChar, 10); + if (*pcChar == '\0') { + iTmp -= 4; /* This is for the edge */ + if (iTmp < MIN_SCREEN_WIDTH) { + iTmp = MIN_SCREEN_WIDTH; + } else if (iTmp > MAX_SCREEN_WIDTH) { + iTmp = MAX_SCREEN_WIDTH; + } + tOptionsCurr.iParagraphBreak = iTmp; + DBG_DEC(tOptionsCurr.iParagraphBreak); + } + } + strncpy(szLeafname, szGetDefaultMappingFile(), sizeof(szLeafname) - 1); + szLeafname[sizeof(szLeafname) - 1] = '\0'; +/* Command line */ + while ((iChar = getopt(argc, argv, "La:fhi:m:p:rstw:x:")) != -1) { + switch (iChar) { + case 'L': + tOptionsCurr.bUseLandscape = TRUE; + break; + case 'a': + if (!bCorrectPapersize(optarg, conversion_pdf)) { + werr(0, "-a without a valid papersize"); + return -1; + } + break; + case 'f': + tOptionsCurr.eConversionType = conversion_fmt_text; + break; + case 'h': + return 0; + case 'i': + iTmp = (int)strtol(optarg, &pcChar, 10); + if (*pcChar != '\0') { + break; + } + switch (iTmp) { + case 0: + tOptionsCurr.eImageLevel = level_gs_special; + break; + case 1: + tOptionsCurr.eImageLevel = level_no_images; + break; + case 2: + tOptionsCurr.eImageLevel = level_ps_2; + break; + case 3: + tOptionsCurr.eImageLevel = level_ps_3; + break; + default: + tOptionsCurr.eImageLevel = level_default; + break; + } + DBG_DEC(tOptionsCurr.eImageLevel); + break; + case 'm': + if (tOptionsCurr.eConversionType == conversion_xml) { + werr(0, "XML doesn't need a mapping file"); + break; + } + strncpy(szLeafname, optarg, sizeof(szLeafname) - 1); + szLeafname[sizeof(szLeafname) - 1] = '\0'; + DBG_MSG(szLeafname); + break; + case 'p': + if (!bCorrectPapersize(optarg, conversion_ps)) { + werr(0, "-p without a valid papersize"); + return -1; + } + break; + case 'r': + tOptionsCurr.bRemoveRemovedText = FALSE; + break; + case 's': + tOptionsCurr.bHideHiddenText = FALSE; + break; + case 't': + tOptionsCurr.eConversionType = conversion_text; + break; + case 'w': + iTmp = (int)strtol(optarg, &pcChar, 10); + if (*pcChar == '\0') { + if (iTmp != 0 && iTmp < MIN_SCREEN_WIDTH) { + iTmp = MIN_SCREEN_WIDTH; + } else if (iTmp > MAX_SCREEN_WIDTH) { + iTmp = MAX_SCREEN_WIDTH; + } + tOptionsCurr.iParagraphBreak = iTmp; + DBG_DEC(tOptionsCurr.iParagraphBreak); + } + break; + case 'x': + if (STREQ(optarg, "db")) { + tOptionsCurr.iParagraphBreak = 0; + tOptionsCurr.eConversionType = conversion_xml; + strcpy(szLeafname, MAPPING_FILE_UTF_8); + } else { + werr(0, "-x %s is not supported", optarg); + return -1; + } + break; + default: + return -1; + } + } + + tOptionsCurr.eEncoding = eMappingFile2Encoding(szLeafname); + DBG_DEC(tOptionsCurr.eEncoding); + + if (tOptionsCurr.eConversionType == conversion_ps && + tOptionsCurr.eEncoding == encoding_utf_8) { + werr(0, + "The combination PostScript and UTF-8 is not supported"); + return -1; + } + + if (tOptionsCurr.eConversionType == conversion_pdf && + tOptionsCurr.eEncoding == encoding_utf_8) { + werr(0, + "The combination PDF and UTF-8 is not supported"); + return -1; + } + + if (tOptionsCurr.eConversionType == conversion_pdf && + tOptionsCurr.eEncoding == encoding_cyrillic) { + werr(0, + "The combination PDF and Cyrillic is not supported"); + return -1; + } + + if (tOptionsCurr.eConversionType == conversion_ps || + tOptionsCurr.eConversionType == conversion_pdf) { + /* PostScript or PDF mode */ + if (tOptionsCurr.bUseLandscape) { + /* Swap the page height and width */ + iTmp = tOptionsCurr.iPageHeight; + tOptionsCurr.iPageHeight = tOptionsCurr.iPageWidth; + tOptionsCurr.iPageWidth = iTmp; + } + /* The paragraph break depends on the width of the paper */ + tOptionsCurr.iParagraphBreak = iMilliPoints2Char( + (long)tOptionsCurr.iPageWidth * 1000 - + lDrawUnits2MilliPoints( + PS_LEFT_MARGIN + PS_RIGHT_MARGIN)); + DBG_DEC(tOptionsCurr.iParagraphBreak); + } + + pCharacterMappingFile = pOpenCharacterMappingFile(szLeafname); + if (pCharacterMappingFile != NULL) { + bSuccess = bReadCharacterMappingTable(pCharacterMappingFile); + vCloseCharacterMappingFile(pCharacterMappingFile); + } else { + bSuccess = FALSE; + } + return bSuccess ? optind : -1; +#endif /* __riscos */ +} /* end of iReadOptions */ + +/* + * vGetOptions - get a copy of the current option values + */ +void +vGetOptions(options_type *pOptions) +{ + fail(pOptions == NULL); + + *pOptions = tOptionsCurr; +} /* end of vGetOptions */ + +#if defined(__riscos) +/* + * vWriteOptions - write the current options to the Options file + */ +static void +vWriteOptions(void) +{ + FILE *pFile; + char *szOptionsFile; + + TRACE_MSG("vWriteOptions"); + + szOptionsFile = getenv("AntiWord$ChoicesSave"); + if (szOptionsFile == NULL) { + werr(0, "Warning: Name of the Choices file not found"); + return; + } + if (!bMakeDirectory(szOptionsFile)) { + werr(0, + "Warning: I can't make a directory for the Choices file"); + return; + } + pFile = fopen(szOptionsFile, "w"); + if (pFile == NULL) { + werr(0, "Warning: I can't write the Choices file"); + return; + } + (void)fprintf(pFile, PARAGRAPH_BREAK"\n", + tOptionsCurr.iParagraphBreak); + (void)fprintf(pFile, AUTOFILETYPE"\n", + tOptionsCurr.bAutofiletypeAllowed); + (void)fprintf(pFile, USE_OUTLINEFONTS"\n", + tOptionsCurr.eConversionType == conversion_text ? 0 : 1); + (void)fprintf(pFile, SHOW_IMAGES"\n", + tOptionsCurr.eImageLevel == level_no_images ? 0 : 1); + (void)fprintf(pFile, HIDE_HIDDEN_TEXT"\n", + tOptionsCurr.bHideHiddenText); + (void)fprintf(pFile, SCALE_FACTOR_START"\n", + tOptionsCurr.iScaleFactor); + (void)fclose(pFile); +} /* end of vWriteOptions */ + +/* + * vChoicesOpenAction - action to be taken when the Choices window opens + */ +void +vChoicesOpenAction(window_handle tWindow) +{ + TRACE_MSG("vChoicesOpenAction"); + + tOptionsTemp = tOptionsCurr; + if (tOptionsTemp.iParagraphBreak == 0) { + vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, FALSE); + vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, TRUE); + vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE, + DEFAULT_SCREEN_WIDTH); + } else { + vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE); + vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE); + vUpdateWriteableNumber(tWindow, + CHOICES_BREAK_WRITEABLE, + tOptionsTemp.iParagraphBreak); + } + vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON, + tOptionsTemp.bAutofiletypeAllowed); + vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON, + tOptionsTemp.bHideHiddenText); + if (tOptionsTemp.eConversionType == conversion_draw) { + vUpdateRadioButton(tWindow, + CHOICES_WITH_IMAGES_BUTTON, + tOptionsTemp.eImageLevel != level_no_images); + vUpdateRadioButton(tWindow, + CHOICES_NO_IMAGES_BUTTON, + tOptionsTemp.eImageLevel == level_no_images); + vUpdateRadioButton(tWindow, + CHOICES_TEXTONLY_BUTTON, FALSE); + } else { + vUpdateRadioButton(tWindow, + CHOICES_WITH_IMAGES_BUTTON, FALSE); + vUpdateRadioButton(tWindow, + CHOICES_NO_IMAGES_BUTTON, FALSE); + vUpdateRadioButton(tWindow, + CHOICES_TEXTONLY_BUTTON, TRUE); + } + vUpdateWriteableNumber(tWindow, + CHOICES_SCALE_WRITEABLE, tOptionsTemp.iScaleFactor); + TRACE_MSG("end of vChoicesOpenAction"); +} /* end of vChoicesOpenAction */ + +/* + * vDefaultButtonAction - action when the default button is clicked + */ +static void +vDefaultButtonAction(window_handle tWindow) +{ + TRACE_MSG("vDefaultButtonAction"); + + tOptionsTemp = tOptionsDefault; + vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE); + vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE); + vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE, + tOptionsTemp.iParagraphBreak); + vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON, + tOptionsTemp.bAutofiletypeAllowed); + vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON, + tOptionsTemp.bHideHiddenText); + vUpdateRadioButton(tWindow, CHOICES_WITH_IMAGES_BUTTON, + tOptionsTemp.eConversionType == conversion_draw && + tOptionsTemp.eImageLevel != level_no_images); + vUpdateRadioButton(tWindow, CHOICES_NO_IMAGES_BUTTON, + tOptionsTemp.eConversionType == conversion_draw && + tOptionsTemp.eImageLevel == level_no_images); + vUpdateRadioButton(tWindow, CHOICES_TEXTONLY_BUTTON, + tOptionsTemp.eConversionType == conversion_text); + vUpdateWriteableNumber(tWindow, CHOICES_SCALE_WRITEABLE, + tOptionsTemp.iScaleFactor); +} /* end of vDefaultButtonAction */ + +/* + * vApplyButtonAction - action to be taken when the OK button is clicked + */ +static void +vApplyButtonAction(void) +{ + TRACE_MSG("vApplyButtonAction"); + + tOptionsCurr = tOptionsTemp; +} /* end of vApplyButtonAction */ + +/* + * vSaveButtonAction - action to be taken when the save button is clicked + */ +static void +vSaveButtonAction(void) +{ + TRACE_MSG("vSaveButtonAction"); + + vApplyButtonAction(); + vWriteOptions(); +} /* end of vSaveButtonAction */ + +/* + * vSetParagraphBreak - set the paragraph break to the given number + */ +static void +vSetParagraphBreak(window_handle tWindow, int iNumber) +{ + tOptionsTemp.iParagraphBreak = iNumber; + if (tOptionsTemp.iParagraphBreak == 0) { + return; + } + vUpdateWriteableNumber(tWindow, + CHOICES_BREAK_WRITEABLE, + tOptionsTemp.iParagraphBreak); +} /* end of vSetParagraphBreak */ + +/* + * vChangeParagraphBreak - change the paragraph break with the given number + */ +static void +vChangeParagraphBreak(window_handle tWindow, int iNumber) +{ + int iTmp; + + iTmp = tOptionsTemp.iParagraphBreak + iNumber; + if (iTmp < MIN_SCREEN_WIDTH || iTmp > MAX_SCREEN_WIDTH) { + /* Ignore */ + return; + } + tOptionsTemp.iParagraphBreak = iTmp; + vUpdateWriteableNumber(tWindow, + CHOICES_BREAK_WRITEABLE, + tOptionsTemp.iParagraphBreak); +} /* end of vChangeParagraphBreak */ + +/* + * vChangeAutofiletype - invert the permission to autofiletype + */ +static void +vChangeAutofiletype(window_handle tWindow) +{ + tOptionsTemp.bAutofiletypeAllowed = + !tOptionsTemp.bAutofiletypeAllowed; + vUpdateRadioButton(tWindow, + CHOICES_AUTOFILETYPE_BUTTON, + tOptionsTemp.bAutofiletypeAllowed); +} /* end of vChangeAutofiletype */ + +/* + * vChangeHiddenText - invert the hide/show hidden text + */ +static void +vChangeHiddenText(window_handle tWindow) +{ + tOptionsTemp.bHideHiddenText = !tOptionsTemp.bHideHiddenText; + vUpdateRadioButton(tWindow, + CHOICES_HIDDEN_TEXT_BUTTON, + tOptionsTemp.bHideHiddenText); +} /* end of vChangeHiddenText */ + +/* + * vUseFontsImages - use outline fonts, show images + */ +static void +vUseFontsImages(BOOL bUseOutlineFonts, BOOL bShowImages) +{ + tOptionsTemp.eConversionType = + bUseOutlineFonts ? conversion_draw : conversion_text; + tOptionsTemp.eImageLevel = + bUseOutlineFonts && bShowImages ? + level_default : level_no_images; +} /* end of vUseFontsImages */ + +/* + * vSetScaleFactor - set the scale factor to the given number + */ +static void +vSetScaleFactor(window_handle tWindow, int iNumber) +{ + tOptionsTemp.iScaleFactor = iNumber; + vUpdateWriteableNumber(tWindow, + CHOICES_SCALE_WRITEABLE, + tOptionsTemp.iScaleFactor); +} /* end of vSetScaleFactor */ + +/* + * vChangeScaleFactor - change the scale factor with the given number + */ +static void +vChangeScaleFactor(window_handle tWindow, int iNumber) +{ + int iTmp; + + iTmp = tOptionsTemp.iScaleFactor + iNumber; + if (iTmp < MIN_SCALE_FACTOR || iTmp > MAX_SCALE_FACTOR) { + /* Ignore */ + return; + } + tOptionsTemp.iScaleFactor = iTmp; + vUpdateWriteableNumber(tWindow, + CHOICES_SCALE_WRITEABLE, + tOptionsTemp.iScaleFactor); +} /* end of vChangeScaleFactor */ + +/* + * bChoicesMouseClick - handle a mouse click in the Choices window + */ +BOOL +bChoicesMouseClick(event_pollblock *pEvent, void *pvReference) +{ + icon_handle tAction; + mouse_block *pMouse; + BOOL bCloseWindow; + + TRACE_MSG("bChoicesMouseClick"); + + fail(pEvent == NULL); + fail(pEvent->type != event_CLICK); + + pMouse = &pEvent->data.mouse; + if (!pMouse->button.data.select && !pMouse->button.data.adjust) { + /* Not handled here */ + DBG_HEX(pMouse->button.value); + return FALSE; + } + + /* Which action should be taken */ + tAction = pMouse->icon; + if (pMouse->button.data.adjust) { + /* The adjust button reverses the direction */ + switch (pMouse->icon) { + case CHOICES_BREAK_UP_BUTTON: + tAction = CHOICES_BREAK_DOWN_BUTTON; + break; + case CHOICES_BREAK_DOWN_BUTTON: + tAction = CHOICES_BREAK_UP_BUTTON; + break; + case CHOICES_SCALE_UP_BUTTON: + tAction = CHOICES_SCALE_DOWN_BUTTON; + break; + case CHOICES_SCALE_DOWN_BUTTON: + tAction = CHOICES_SCALE_UP_BUTTON; + break; + default: + break; + } + } + + /* Actions */ + bCloseWindow = FALSE; + switch (tAction) { + case CHOICES_DEFAULT_BUTTON: + vDefaultButtonAction(pMouse->window); + break; + case CHOICES_SAVE_BUTTON: + vSaveButtonAction(); + break; + case CHOICES_CANCEL_BUTTON: + bCloseWindow = TRUE; + break; + case CHOICES_APPLY_BUTTON: + vApplyButtonAction(); + bCloseWindow = TRUE; + break; + case CHOICES_BREAK_BUTTON: + vSetParagraphBreak(pMouse->window, DEFAULT_SCREEN_WIDTH); + break; + case CHOICES_BREAK_UP_BUTTON: + vChangeParagraphBreak(pMouse->window, 1); + break; + case CHOICES_BREAK_DOWN_BUTTON: + vChangeParagraphBreak(pMouse->window, -1); + break; + case CHOICES_NO_BREAK_BUTTON: + vSetParagraphBreak(pMouse->window, 0); + break; + case CHOICES_AUTOFILETYPE_BUTTON: + vChangeAutofiletype(pMouse->window); + break; + case CHOICES_HIDDEN_TEXT_BUTTON: + vChangeHiddenText(pMouse->window); + break; + case CHOICES_WITH_IMAGES_BUTTON: + vUseFontsImages(TRUE, TRUE); + break; + case CHOICES_NO_IMAGES_BUTTON: + vUseFontsImages(TRUE, FALSE); + break; + case CHOICES_TEXTONLY_BUTTON: + vUseFontsImages(FALSE, FALSE); + break; + case CHOICES_SCALE_UP_BUTTON: + vChangeScaleFactor(pMouse->window, 5); + break; + case CHOICES_SCALE_DOWN_BUTTON: + vChangeScaleFactor(pMouse->window, -5); + break; + default: + DBG_DEC(pMouse->icon); + break; + } + if (bCloseWindow) { + Error_CheckFatal(Wimp_CloseWindow(pMouse->window)); + } + return TRUE; +} /* end of bChoicesMouseClick */ + +/* + * bChoicesKeyPressed - handle a key in the Choices window + */ +BOOL +bChoicesKeyPressed(event_pollblock *pEvent, void *pvReference) +{ + icon_block tIcon; + caret_block *pCaret; + char *pcChar; + int iNumber; + + DBG_MSG("bChoicesKeyPressed"); + + fail(pEvent == NULL); + fail(pEvent->type != event_KEY); + + if (pEvent->data.key.code != '\r') { + Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code)); + return TRUE; + } + + pCaret = &pEvent->data.key.caret; + + Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon)); + if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) { + werr(1, "Icon %d must be indirected text", (int)pCaret->icon); + } + iNumber = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10); + + switch(pCaret->icon) { + case CHOICES_BREAK_WRITEABLE: + if (*pcChar != '\0' && *pcChar != '\r') { + DBG_DEC(*pcChar); + iNumber = DEFAULT_SCREEN_WIDTH; + } else if (iNumber < MIN_SCREEN_WIDTH) { + iNumber = MIN_SCREEN_WIDTH; + } else if (iNumber > MAX_SCREEN_WIDTH) { + iNumber = MAX_SCREEN_WIDTH; + } + vSetParagraphBreak(pCaret->window, iNumber); + break; + case CHOICES_SCALE_WRITEABLE: + if (*pcChar != '\0' && *pcChar != '\r') { + DBG_DEC(*pcChar); + iNumber = DEFAULT_SCALE_FACTOR; + } else if (iNumber < MIN_SCALE_FACTOR) { + iNumber = MIN_SCALE_FACTOR; + } else if (iNumber > MAX_SCALE_FACTOR) { + iNumber = MAX_SCALE_FACTOR; + } + vSetScaleFactor(pCaret->window, iNumber); + break; + default: + DBG_DEC(pCaret->icon); + break; + } + return TRUE; +} /* end of bChoicesKeyPressed */ +#endif /* __riscos */ diff --git a/out2window.c b/out2window.c new file mode 100644 index 0000000..9bdacc3 --- /dev/null +++ b/out2window.c @@ -0,0 +1,768 @@ +/* + * out2window.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GPL + * + * Description: + * Output to a text window + */ + +#include +#include +#include +#include "antiword.h" + +/* Used for numbering the chapters */ +static unsigned int auiHdrCounter[9]; + + +/* + * vString2Diagram - put a string into a diagram + */ +static void +vString2Diagram(diagram_type *pDiag, output_type *pAnchor) +{ + output_type *pOutput; + long lWidth; + USHORT usMaxFontSize; + + TRACE_MSG("vString2Diagram"); + + fail(pDiag == NULL); + fail(pAnchor == NULL); + + /* Compute the maximum fontsize in this string */ + usMaxFontSize = MIN_FONT_SIZE; + for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) { + if (pOutput->usFontSize > usMaxFontSize) { + usMaxFontSize = pOutput->usFontSize; + } + } + + /* Goto the next line */ + vMove2NextLine(pDiag, pAnchor->tFontRef, usMaxFontSize); + + /* Output all substrings */ + for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) { + lWidth = lMilliPoints2DrawUnits(pOutput->lStringWidth); + vSubstring2Diagram(pDiag, pOutput->szStorage, + pOutput->tNextFree, lWidth, pOutput->ucFontColor, + pOutput->usFontStyle, pOutput->tFontRef, + pOutput->usFontSize, usMaxFontSize); + } + + /* Goto the start of the line */ + pDiag->lXleft = 0; + TRACE_MSG("leaving vString2Diagram"); +} /* end of vString2Diagram */ + +/* + * vSetLeftIndentation - set the left indentation of the specified diagram + */ +void +vSetLeftIndentation(diagram_type *pDiag, long lLeftIndentation) +{ + long lX; + + TRACE_MSG("vSetLeftIndentation"); + + fail(pDiag == NULL); + fail(lLeftIndentation < 0); + + lX = lMilliPoints2DrawUnits(lLeftIndentation); + if (lX > 0) { + pDiag->lXleft = lX; + } else { + pDiag->lXleft = 0; + } +} /* end of vSetLeftIndentation */ + +/* + * lComputeNetWidth - compute the net string width + */ +static long +lComputeNetWidth(output_type *pAnchor) +{ + output_type *pTmp; + long lNetWidth; + + TRACE_MSG("lComputeNetWidth"); + + fail(pAnchor == NULL); + + /* Step 1: Count all but the last sub-string */ + lNetWidth = 0; + for (pTmp = pAnchor; pTmp->pNext != NULL; pTmp = pTmp->pNext) { + fail(pTmp->lStringWidth < 0); + lNetWidth += pTmp->lStringWidth; + } + fail(pTmp == NULL); + fail(pTmp->pNext != NULL); + + /* Step 2: remove the white-space from the end of the string */ + while (pTmp->tNextFree != 0 && + isspace((int)(UCHAR)pTmp->szStorage[pTmp->tNextFree - 1])) { + pTmp->szStorage[pTmp->tNextFree - 1] = '\0'; + pTmp->tNextFree--; + NO_DBG_DEC(pTmp->lStringWidth); + pTmp->lStringWidth = lComputeStringWidth( + pTmp->szStorage, + pTmp->tNextFree, + pTmp->tFontRef, + pTmp->usFontSize); + NO_DBG_DEC(pTmp->lStringWidth); + } + + /* Step 3: Count the last sub-string */ + lNetWidth += pTmp->lStringWidth; + return lNetWidth; +} /* end of lComputeNetWidth */ + +/* + * iComputeHoles - compute number of holes + * (A hole is a number of whitespace characters followed by a + * non-whitespace character) + */ +static int +iComputeHoles(output_type *pAnchor) +{ + output_type *pTmp; + size_t tIndex; + int iCounter; + BOOL bWasSpace, bIsSpace; + + TRACE_MSG("iComputeHoles"); + + fail(pAnchor == NULL); + + iCounter = 0; + bIsSpace = FALSE; + /* Count the holes */ + for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) { + fail(pTmp->tNextFree != strlen(pTmp->szStorage)); + for (tIndex = 0; tIndex <= pTmp->tNextFree; tIndex++) { + bWasSpace = bIsSpace; + bIsSpace = isspace((int)(UCHAR)pTmp->szStorage[tIndex]); + if (bWasSpace && !bIsSpace) { + iCounter++; + } + } + } + return iCounter; +} /* end of iComputeHoles */ + +/* + * vAlign2Window - Align a string and insert it into the text + */ +void +vAlign2Window(diagram_type *pDiag, output_type *pAnchor, + long lScreenWidth, UCHAR ucAlignment) +{ + long lNetWidth, lLeftIndentation; + + TRACE_MSG("vAlign2Window"); + + fail(pDiag == NULL || pAnchor == NULL); + fail(lScreenWidth < lChar2MilliPoints(MIN_SCREEN_WIDTH)); + + lNetWidth = lComputeNetWidth(pAnchor); + + if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) || + lNetWidth <= 0) { + /* + * Screenwidth is "infinite", so no alignment is possible + * Don't bother to align an empty line + */ + vString2Diagram(pDiag, pAnchor); + TRACE_MSG("leaving vAlign2Window #1"); + return; + } + + switch (ucAlignment) { + case ALIGNMENT_CENTER: + lLeftIndentation = (lScreenWidth - lNetWidth) / 2; + DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation); + if (lLeftIndentation > 0) { + vSetLeftIndentation(pDiag, lLeftIndentation); + } + break; + case ALIGNMENT_RIGHT: + lLeftIndentation = lScreenWidth - lNetWidth; + DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation); + if (lLeftIndentation > 0) { + vSetLeftIndentation(pDiag, lLeftIndentation); + } + break; + case ALIGNMENT_JUSTIFY: + case ALIGNMENT_LEFT: + default: + break; + } + vString2Diagram(pDiag, pAnchor); + TRACE_MSG("leaving vAlign2Window #2"); +} /* end of vAlign2Window */ + +/* + * vJustify2Window - Justify a string and insert it into the text + */ +void +vJustify2Window(diagram_type *pDiag, output_type *pAnchor, + long lScreenWidth, long lRightIndentation, UCHAR ucAlignment) +{ + output_type *pTmp; + char *pcNew, *pcOld, *szStorage; + long lNetWidth, lSpaceWidth, lToAdd; + int iFillerLen, iHoles; + + TRACE_MSG("vJustify2Window"); + + fail(pDiag == NULL || pAnchor == NULL); + fail(lScreenWidth < MIN_SCREEN_WIDTH); + fail(lRightIndentation > 0); + + if (ucAlignment != ALIGNMENT_JUSTIFY) { + vAlign2Window(pDiag, pAnchor, lScreenWidth, ucAlignment); + return; + } + + lNetWidth = lComputeNetWidth(pAnchor); + + if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) || + lNetWidth <= 0) { + /* + * Screenwidth is "infinite", so justify is not possible + * Don't bother to justify an empty line + */ + vString2Diagram(pDiag, pAnchor); + TRACE_MSG("leaving vJustify2Window #1"); + return; + } + + /* Justify */ + fail(ucAlignment != ALIGNMENT_JUSTIFY); + lSpaceWidth = lComputeStringWidth(" ", 1, + pAnchor->tFontRef, pAnchor->usFontSize); + lToAdd = lScreenWidth - + lNetWidth - + lDrawUnits2MilliPoints(pDiag->lXleft) + + lRightIndentation; +#if defined(DEBUG) + if (lToAdd / lSpaceWidth < -1) { + DBG_DEC(lSpaceWidth); + DBG_DEC(lToAdd); + DBG_DEC(lScreenWidth); + DBG_DEC(lNetWidth); + DBG_DEC(lDrawUnits2MilliPoints(pDiag->lXleft)); + DBG_DEC(pDiag->lXleft); + DBG_DEC(lRightIndentation); + } +#endif /* DEBUG */ + lToAdd /= lSpaceWidth; + DBG_DEC_C(lToAdd < 0, lToAdd); + if (lToAdd <= 0) { + vString2Diagram(pDiag, pAnchor); + TRACE_MSG("leaving vJustify2Window #2"); + return; + } + + /* Justify by adding spaces */ + iHoles = iComputeHoles(pAnchor); + for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) { + fail(pTmp->tNextFree != strlen(pTmp->szStorage)); + fail(lToAdd < 0); + szStorage = xmalloc(pTmp->tNextFree + (size_t)lToAdd + 1); + pcNew = szStorage; + for (pcOld = pTmp->szStorage; *pcOld != '\0'; pcOld++) { + *pcNew++ = *pcOld; + if (*pcOld == ' ' && + *(pcOld + 1) != ' ' && + iHoles > 0) { + iFillerLen = (int)(lToAdd / iHoles); + lToAdd -= iFillerLen; + iHoles--; + for (; iFillerLen > 0; iFillerLen--) { + *pcNew++ = ' '; + } + } + } + *pcNew = '\0'; + pTmp->szStorage = xfree(pTmp->szStorage); + pTmp->szStorage = szStorage; + pTmp->tStorageSize = pTmp->tNextFree + (size_t)lToAdd + 1; + pTmp->lStringWidth += + (pcNew - szStorage - (long)pTmp->tNextFree) * + lSpaceWidth; + fail(pcNew < szStorage); + pTmp->tNextFree = (size_t)(pcNew - szStorage); + fail(pTmp->tNextFree != strlen(pTmp->szStorage)); + } + DBG_DEC_C(lToAdd != 0, lToAdd); + vString2Diagram(pDiag, pAnchor); + TRACE_MSG("leaving vJustify2Window #3"); +} /* end of vJustify2Window */ + +/* + * vResetStyles - reset the style information variables + */ +void +vResetStyles(void) +{ + TRACE_MSG("vResetStyles"); + + (void)memset(auiHdrCounter, 0, sizeof(auiHdrCounter)); +} /* end of vResetStyles */ + +/* + * tStyle2Window - Add the style characters to the line + * + * Returns the length of the resulting string + */ +size_t +tStyle2Window(char *szLine, size_t tLineSize, const style_block_type *pStyle, + const section_block_type *pSection) +{ + char *pcTxt; + size_t tIndex, tStyleIndex; + BOOL bNeedPrevLvl; + level_type_enum eNumType; + UCHAR ucNFC; + + TRACE_MSG("tStyle2Window"); + + fail(szLine == NULL || pStyle == NULL || pSection == NULL); + + if (pStyle->usIstd == 0 || pStyle->usIstd > 9) { + szLine[0] = '\0'; + return 0; + } + + /* Set the numbers */ + tStyleIndex = (size_t)pStyle->usIstd - 1; + for (tIndex = 0; tIndex < 9; tIndex++) { + if (tIndex == tStyleIndex) { + auiHdrCounter[tIndex]++; + } else if (tIndex > tStyleIndex) { + auiHdrCounter[tIndex] = 0; + } else if (auiHdrCounter[tIndex] == 0) { + auiHdrCounter[tIndex] = 1; + } + } + + eNumType = eGetNumType(pStyle->ucNumLevel); + if (eNumType != level_type_outline) { + szLine[0] = '\0'; + return 0; + } + + /* Print the numbers */ + pcTxt = szLine; + bNeedPrevLvl = (pSection->usNeedPrevLvl & BIT(tStyleIndex)) != 0; + for (tIndex = 0; tIndex <= tStyleIndex; tIndex++) { + if (tIndex == tStyleIndex || + (bNeedPrevLvl && tIndex < tStyleIndex)) { + if (pcTxt - szLine >= tLineSize - 25) { + /* Prevent a possible buffer overflow */ + DBG_DEC(pcTxt - szLine); + DBG_DEC(tLineSize - 25); + DBG_FIXME(); + szLine[0] = '\0'; + return 0; + } + ucNFC = pSection->aucNFC[tIndex]; + switch(ucNFC) { + case LIST_ARABIC_NUM: + case LIST_NUMBER_TXT: + case LIST_ORDINAL_TXT: + pcTxt += sprintf(pcTxt, "%u", + auiHdrCounter[tIndex]); + break; + case LIST_UPPER_ROMAN: + case LIST_LOWER_ROMAN: + pcTxt += tNumber2Roman( + auiHdrCounter[tIndex], + ucNFC == LIST_UPPER_ROMAN, + pcTxt); + break; + case LIST_UPPER_ALPHA: + case LIST_LOWER_ALPHA: + pcTxt += tNumber2Alpha( + auiHdrCounter[tIndex], + ucNFC == LIST_UPPER_ALPHA, + pcTxt); + break; + case LIST_OUTLINE_NUM: + pcTxt += sprintf(pcTxt, "%02u", + auiHdrCounter[tIndex]); + break; + default: + DBG_DEC(ucNFC); + DBG_FIXME(); + pcTxt += sprintf(pcTxt, "%u", + auiHdrCounter[tIndex]); + break; + } + if (tIndex < tStyleIndex) { + *pcTxt++ = '.'; + } else if (tIndex == tStyleIndex) { + *pcTxt++ = ' '; + } + } + } + *pcTxt = '\0'; + NO_DBG_MSG_C((int)pStyle->usIstd >= 1 && + (int)pStyle->usIstd <= 9 && + eNumType != level_type_none && + eNumType != level_type_outline, szLine); + NO_DBG_MSG_C(szLine[0] != '\0', szLine); + fail(pcTxt < szLine); + return (size_t)(pcTxt - szLine); +} /* end of tStyle2Window */ + +/* + * vRemoveRowEnd - remove the end of table row indicator + * + * Remove the double TABLE_SEPARATOR characters from the end of the string. + * Special: remove the TABLE_SEPARATOR, 0x0a sequence + */ +static void +vRemoveRowEnd(char *szRowTxt) +{ + int iLastIndex; + + TRACE_MSG("vRemoveRowEnd"); + + fail(szRowTxt == NULL || szRowTxt[0] == '\0'); + + iLastIndex = (int)strlen(szRowTxt) - 1; + + if (szRowTxt[iLastIndex] == TABLE_SEPARATOR || + szRowTxt[iLastIndex] == (char)0x0a) { + szRowTxt[iLastIndex] = '\0'; + iLastIndex--; + } else { + DBG_HEX(szRowTxt[iLastIndex]); + } + + if (iLastIndex >= 0 && szRowTxt[iLastIndex] == (char)0x0a) { + szRowTxt[iLastIndex] = '\0'; + iLastIndex--; + } + + if (iLastIndex >= 0 && szRowTxt[iLastIndex] == TABLE_SEPARATOR) { + szRowTxt[iLastIndex] = '\0'; + return; + } + + DBG_DEC(iLastIndex); + DBG_HEX(szRowTxt[iLastIndex]); + DBG_MSG(szRowTxt); +} /* end of vRemoveRowEnd */ + +/* + * tComputeStringLengthMax - max string length in relation to max column width + * + * Return the maximum string length + */ +static size_t +tComputeStringLengthMax(const char *szString, size_t tColumnWidthMax) +{ + const char *pcTmp; + size_t tLengthMax, tLenPrev, tLen, tWidth; + + TRACE_MSG("tComputeStringLengthMax"); + + fail(szString == NULL); + fail(tColumnWidthMax == 0); + + pcTmp = strchr(szString, '\n'); + if (pcTmp != NULL) { + tLengthMax = (size_t)(pcTmp - szString + 1); + } else { + tLengthMax = strlen(szString); + } + if (tLengthMax == 0) { + return 0; + } + + tLen = 0; + tWidth = 0; + for (;;) { + tLenPrev = tLen; + tLen += tGetCharacterLength(szString + tLen); + DBG_DEC_C(tLen > tLengthMax, tLen); + DBG_DEC_C(tLen > tLengthMax, tLengthMax); + fail(tLen > tLengthMax); + tWidth = tCountColumns(szString, tLen); + if (tWidth > tColumnWidthMax) { + return tLenPrev; + } + if (tLen >= tLengthMax) { + return tLengthMax; + } + } +} /* end of tComputeStringLengthMax */ + +/* + * tGetBreakingPoint - get the number of bytes that fit the column + * + * Returns the number of bytes that fit the column + */ +static size_t +tGetBreakingPoint(const char *szString, + size_t tLen, size_t tWidth, size_t tColumnWidthMax) +{ + int iIndex; + + TRACE_MSG("tGetBreakingPoint"); + + fail(szString == NULL); + fail(tLen > strlen(szString)); + fail(tWidth > tColumnWidthMax); + + if (tWidth < tColumnWidthMax || + (tWidth == tColumnWidthMax && + (szString[tLen] == ' ' || + szString[tLen] == '\n' || + szString[tLen] == '\0'))) { + /* The string already fits, do nothing */ + return tLen; + } + /* Search for a breaking point */ + for (iIndex = (int)tLen - 1; iIndex >= 0; iIndex--) { + if (szString[iIndex] == ' ') { + return (size_t)iIndex; + } + } + /* No breaking point found, just fill the column */ + return tLen; +} /* end of tGetBreakingPoint */ + +/* + * tComputeColumnWidthMax - compute the maximum column width + */ +static size_t +tComputeColumnWidthMax(short sWidth, long lCharWidth, double dFactor) +{ + size_t tColumnWidthMax; + + TRACE_MSG("tComputeColumnWidthMax"); + + fail(sWidth < 0); + fail(lCharWidth <= 0); + fail(dFactor <= 0.0); + + tColumnWidthMax = (size_t)( + (lTwips2MilliPoints(sWidth) * dFactor + lCharWidth / 2.0) / + lCharWidth); + if (tColumnWidthMax == 0) { + /* Minimum column width */ + return 1; + } + if (tColumnWidthMax > 1) { + /* Make room for the TABLE_SEPARATOR_CHAR */ + tColumnWidthMax--; + } + NO_DBG_DEC(tColumnWidthMax); + return tColumnWidthMax; +} /* end of tComputeColumnWidthMax */ + +/* + * vTableRow2Window - put a table row into a diagram + */ +void +vTableRow2Window(diagram_type *pDiag, output_type *pOutput, + const row_block_type *pRowInfo, + conversion_type eConversionType, int iParagraphBreak) +{ + output_type tRow; + char *aszColTxt[TABLE_COLUMN_MAX]; + char *szLine, *pcTxt; + double dMagnify; + long lCharWidthLarge, lCharWidthSmall; + size_t tColumnWidthTotal, atColumnWidthMax[TABLE_COLUMN_MAX]; + size_t tSize, tColumnWidthMax, tWidth, tLen; + int iIndex, iNbrOfColumns, iTmp; + BOOL bNotReady; + + TRACE_MSG("vTableRow2Window"); + + fail(pDiag == NULL || pOutput == NULL || pRowInfo == NULL); + fail(pOutput->szStorage == NULL); + fail(pOutput->pNext != NULL); + fail(iParagraphBreak < 0); + + /* Character sizes */ + lCharWidthLarge = lComputeStringWidth("W", 1, + pOutput->tFontRef, pOutput->usFontSize); + NO_DBG_DEC(lCharWidthLarge); + lCharWidthSmall = lComputeStringWidth("i", 1, + pOutput->tFontRef, pOutput->usFontSize); + NO_DBG_DEC(lCharWidthSmall); + /* For the time being: use a fixed width font */ + fail(lCharWidthLarge != lCharWidthSmall); + + vRemoveRowEnd(pOutput->szStorage); + + /* Split the row text into a set of column texts */ + aszColTxt[0] = pOutput->szStorage; + for (iNbrOfColumns = 1; + iNbrOfColumns < TABLE_COLUMN_MAX; + iNbrOfColumns++) { + aszColTxt[iNbrOfColumns] = + strchr(aszColTxt[iNbrOfColumns - 1], + TABLE_SEPARATOR); + if (aszColTxt[iNbrOfColumns] == NULL) { + break; + } + *aszColTxt[iNbrOfColumns] = '\0'; + aszColTxt[iNbrOfColumns]++; + NO_DBG_DEC(iNbrOfColumns); + NO_DBG_MSG(aszColTxt[iNbrOfColumns]); + } + + /* Work around a bug in Word */ + while (iNbrOfColumns > (int)pRowInfo->ucNumberOfColumns && + pRowInfo->asColumnWidth[iNbrOfColumns] == 0) { + iNbrOfColumns--; + } + + DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns, + iNbrOfColumns); + DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns, + pRowInfo->ucNumberOfColumns); + if (iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns) { + werr(0, "Skipping an unmatched table row"); + return; + } + +#if defined(__FULL_TEXT_SEARCH) + /* No table formatting: use for full-text search (untested) */ + for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { + fprintf(pDiag->pOutFile, "%s\n" , aszColTxt[iIndex]); + } +#else + if (bAddTableRow(pDiag, aszColTxt, iNbrOfColumns, + pRowInfo->asColumnWidth, pRowInfo->ucBorderInfo)) { + /* All work has been done */ + return; + } + + /* Fill the table with maximum column widths */ + if (eConversionType == conversion_text || + eConversionType == conversion_fmt_text) { + if (iParagraphBreak == 0 || + iParagraphBreak >= MAX_SCREEN_WIDTH) { + dMagnify = (double)MAX_SCREEN_WIDTH; + } else if (iParagraphBreak <= MIN_SCREEN_WIDTH) { + dMagnify = (double)MIN_SCREEN_WIDTH; + } else { + dMagnify = (double)iParagraphBreak; + } + dMagnify /= (double)DEFAULT_SCREEN_WIDTH; + DBG_FLT_C(dMagnify < 0.99 || dMagnify > 1.01, dMagnify); + } else { + dMagnify = 1.0; + } + tColumnWidthTotal = 0; + for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { + atColumnWidthMax[iIndex] = tComputeColumnWidthMax( + pRowInfo->asColumnWidth[iIndex], + lCharWidthLarge, + dMagnify); + tColumnWidthTotal += atColumnWidthMax[iIndex]; + } + + /* + * Get enough space for the row. + * Worst case: three bytes per UTF-8 character + */ + tSize = 3 * (1 + tColumnWidthTotal + (size_t)iNbrOfColumns + 3); + szLine = xmalloc(tSize); + + do { + /* Print one line of a table row */ + bNotReady = FALSE; + pcTxt = szLine; + *pcTxt++ = TABLE_SEPARATOR_CHAR; + for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { + tColumnWidthMax = atColumnWidthMax[iIndex]; + if (aszColTxt[iIndex] == NULL) { + /* Add an empty column */ + for (iTmp = 0; + iTmp < (int)tColumnWidthMax; + iTmp++) { + *pcTxt++ = (char)FILLER_CHAR; + } + *pcTxt++ = TABLE_SEPARATOR_CHAR; + *pcTxt = '\0'; + continue; + } + /* Compute the length and width of the column text */ + tLen = tComputeStringLengthMax( + aszColTxt[iIndex], tColumnWidthMax); + NO_DBG_DEC(tLen); + while (tLen != 0 && + (aszColTxt[iIndex][tLen - 1] == '\n' || + aszColTxt[iIndex][tLen - 1] == ' ')) { + aszColTxt[iIndex][tLen - 1] = ' '; + tLen--; + } + tWidth = tCountColumns(aszColTxt[iIndex], tLen); + fail(tWidth > tColumnWidthMax); + tLen = tGetBreakingPoint(aszColTxt[iIndex], + tLen, tWidth, tColumnWidthMax); + tWidth = tCountColumns(aszColTxt[iIndex], tLen); + if (tLen == 0 && *aszColTxt[iIndex] == '\0') { + /* No text at all */ + aszColTxt[iIndex] = NULL; + } else { + /* Add the text */ + pcTxt += sprintf(pcTxt, + "%.*s", (int)tLen, aszColTxt[iIndex]); + if (tLen == 0 && *aszColTxt[iIndex] != ' ') { + tLen = tGetCharacterLength( + aszColTxt[iIndex]); + DBG_CHR(*aszColTxt[iIndex]); + DBG_FIXME(); + fail(tLen == 0); + } + aszColTxt[iIndex] += tLen; + while (*aszColTxt[iIndex] == ' ') { + aszColTxt[iIndex]++; + } + if (*aszColTxt[iIndex] == '\0') { + /* This row is now complete */ + aszColTxt[iIndex] = NULL; + } else { + /* This row needs more lines */ + bNotReady = TRUE; + } + } + /* Fill up the rest */ + for (iTmp = 0; + iTmp < (int)tColumnWidthMax - (int)tWidth; + iTmp++) { + *pcTxt++ = (char)FILLER_CHAR; + } + /* End of column */ + *pcTxt++ = TABLE_SEPARATOR_CHAR; + *pcTxt = '\0'; + } + /* Output the table row line */ + *pcTxt = '\0'; + tRow = *pOutput; + tRow.szStorage = szLine; + fail(pcTxt < szLine); + tRow.tNextFree = (size_t)(pcTxt - szLine); + tRow.lStringWidth = lComputeStringWidth( + tRow.szStorage, + tRow.tNextFree, + tRow.tFontRef, + tRow.usFontSize); + vString2Diagram(pDiag, &tRow); + TRACE_MSG("after vString2Diagram in vTableRow2Window"); + } while (bNotReady); + /* Clean up before you leave */ + szLine = xfree(szLine); + TRACE_MSG("leaving vTableRow2Window"); +#endif /* __FULL_TEXT_SEARCH */ +} /* end of vTableRow2Window */ diff --git a/output.c b/output.c new file mode 100644 index 0000000..b2757ab --- /dev/null +++ b/output.c @@ -0,0 +1,538 @@ +/* + * output.c + * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Generic output generating functions + */ + +#include "antiword.h" + +static conversion_type eConversionType = conversion_unknown; +static encoding_type eEncoding = encoding_neutral; + + +/* + * vPrologue1 - get options and call a specific initialization + */ +static void +vPrologue1(diagram_type *pDiag, const char *szTask, const char *szFilename) +{ + options_type tOptions; + + fail(pDiag == NULL); + fail(szTask == NULL || szTask[0] == '\0'); + + vGetOptions(&tOptions); + eConversionType = tOptions.eConversionType; + eEncoding = tOptions.eEncoding; + + switch (eConversionType) { + case conversion_text: + vPrologueTXT(pDiag, &tOptions); + break; + case conversion_fmt_text: + vPrologueFMT(pDiag, &tOptions); + break; + case conversion_ps: + vProloguePS(pDiag, szTask, szFilename, &tOptions); + break; + case conversion_xml: + vPrologueXML(pDiag, &tOptions); + break; + case conversion_pdf: + vProloguePDF(pDiag, szTask, &tOptions); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vPrologue1 */ + +/* + * vEpilogue - clean up after everything is done + */ +static void +vEpilogue(diagram_type *pDiag) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + vEpilogueTXT(pDiag->pOutFile); + break; + case conversion_ps: + vEpiloguePS(pDiag); + break; + case conversion_xml: + vEpilogueXML(pDiag); + break; + case conversion_pdf: + vEpiloguePDF(pDiag); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vEpilogue */ + +/* + * vImagePrologue - perform image initialization + */ +void +vImagePrologue(diagram_type *pDiag, const imagedata_type *pImg) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + vImageProloguePS(pDiag, pImg); + break; + case conversion_xml: + break; + case conversion_pdf: + vImageProloguePDF(pDiag, pImg); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vImagePrologue */ + +/* + * vImageEpilogue - clean up an image + */ +void +vImageEpilogue(diagram_type *pDiag) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + vImageEpiloguePS(pDiag); + break; + case conversion_xml: + break; + case conversion_pdf: + vImageEpiloguePDF(pDiag); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vImageEpilogue */ + +/* + * bAddDummyImage - add a dummy image + * + * return TRUE when successful, otherwise FALSE + */ +BOOL +bAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + return FALSE; + case conversion_ps: + return bAddDummyImagePS(pDiag, pImg); + case conversion_xml: + return FALSE; + case conversion_pdf: + return bAddDummyImagePDF(pDiag, pImg); + default: + DBG_DEC(eConversionType); + return FALSE; + } +} /* end of bAddDummyImage */ + +/* + * pCreateDiagram - create and initialize a diagram + * + * remark: does not return if the diagram can't be created + */ +diagram_type * +pCreateDiagram(const char *szTask, const char *szFilename) +{ + diagram_type *pDiag; + + fail(szTask == NULL || szTask[0] == '\0'); + DBG_MSG("pCreateDiagram"); + + /* Get the necessary memory */ + pDiag = xmalloc(sizeof(diagram_type)); + /* Initialization */ + pDiag->pOutFile = stdout; + vPrologue1(pDiag, szTask, szFilename); + /* Return success */ + return pDiag; +} /* end of pCreateDiagram */ + +/* + * vDestroyDiagram - remove a diagram by freeing the memory it uses + */ +void +vDestroyDiagram(diagram_type *pDiag) +{ + DBG_MSG("vDestroyDiagram"); + + fail(pDiag == NULL); + + if (pDiag == NULL) { + return; + } + vEpilogue(pDiag); + pDiag = xfree(pDiag); +} /* end of vDestroyDiagram */ + +/* + * vPrologue2 - call a specific initialization + */ +void +vPrologue2(diagram_type *pDiag, int iWordVersion) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + vAddFontsPS(pDiag); + break; + case conversion_xml: + vCreateBookIntro(pDiag, iWordVersion); + break; + case conversion_pdf: + vCreateInfoDictionary(pDiag, iWordVersion); + vAddFontsPDF(pDiag); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vPrologue2 */ + +/* + * vMove2NextLine - move to the next line + */ +void +vMove2NextLine(diagram_type *pDiag, drawfile_fontref tFontRef, + USHORT usFontSize) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + vMove2NextLineTXT(pDiag); + break; + case conversion_ps: + vMove2NextLinePS(pDiag, usFontSize); + break; + case conversion_xml: + vMove2NextLineXML(pDiag); + break; + case conversion_pdf: + vMove2NextLinePDF(pDiag, usFontSize); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vMove2NextLine */ + +/* + * vSubstring2Diagram - put a sub string into a diagram + */ +void +vSubstring2Diagram(diagram_type *pDiag, + char *szString, size_t tStringLength, long lStringWidth, + UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, + USHORT usFontSize, USHORT usMaxFontSize) +{ + switch (eConversionType) { + case conversion_text: + vSubstringTXT(pDiag, szString, tStringLength, lStringWidth); + break; + case conversion_fmt_text: + vSubstringFMT(pDiag, szString, tStringLength, lStringWidth, + usFontstyle); + break; + case conversion_ps: + vSubstringPS(pDiag, szString, tStringLength, lStringWidth, + ucFontColor, usFontstyle, tFontRef, + usFontSize, usMaxFontSize); + break; + case conversion_xml: + vSubstringXML(pDiag, szString, tStringLength, lStringWidth, + usFontstyle); + break; + case conversion_pdf: + vSubstringPDF(pDiag, szString, tStringLength, lStringWidth, + ucFontColor, usFontstyle, tFontRef, + usFontSize, usMaxFontSize); + break; + default: + DBG_DEC(eConversionType); + break; + } + pDiag->lXleft += lStringWidth; +} /* end of vSubstring2Diagram */ + +/* + * Create a start of paragraph (phase 1) + * Before indentation, list numbering, bullets etc. + */ +void +vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation) +{ + fail(pDiag == NULL); + + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + vStartOfParagraphTXT(pDiag, lBeforeIndentation); + break; + case conversion_ps: + vStartOfParagraphPS(pDiag, lBeforeIndentation); + break; + case conversion_xml: + break; + case conversion_pdf: + vStartOfParagraphPDF(pDiag, lBeforeIndentation); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vStartOfParagraph1 */ + +/* + * Create a start of paragraph (phase 2) + * After indentation, list numbering, bullets etc. + */ +void +vStartOfParagraph2(diagram_type *pDiag) +{ + fail(pDiag == NULL); + + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vStartOfParagraphXML(pDiag, 1); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vStartOfParagraph2 */ + +/* + * Create an end of paragraph + */ +void +vEndOfParagraph(diagram_type *pDiag, + drawfile_fontref tFontRef, USHORT usFontSize, long lAfterIndentation) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(lAfterIndentation < 0); + + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + vEndOfParagraphTXT(pDiag, lAfterIndentation); + break; + case conversion_ps: + vEndOfParagraphPS(pDiag, usFontSize, lAfterIndentation); + break; + case conversion_xml: + vEndOfParagraphXML(pDiag, 1); + break; + case conversion_pdf: + vEndOfParagraphPDF(pDiag, usFontSize, lAfterIndentation); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vEndOfParagraph */ + +/* + * Create an end of page + */ +void +vEndOfPage(diagram_type *pDiag, long lAfterIndentation, BOOL bNewSection) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + vEndOfPageTXT(pDiag, lAfterIndentation); + break; + case conversion_ps: + vEndOfPagePS(pDiag, bNewSection); + break; + case conversion_xml: + vEndOfPageXML(pDiag); + break; + case conversion_pdf: + vEndOfPagePDF(pDiag, bNewSection); + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vEndOfPage */ + +/* + * vSetHeaders - set the headers + */ +void +vSetHeaders(diagram_type *pDiag, USHORT usIstd) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vSetHeadersXML(pDiag, usIstd); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vSetHeaders */ + +/* + * Create a start of list + */ +void +vStartOfList(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vStartOfListXML(pDiag, ucNFC, bIsEndOfTable); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vStartOfList */ + +/* + * Create an end of list + */ +void +vEndOfList(diagram_type *pDiag) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vEndOfListXML(pDiag); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vEndOfList */ + +/* + * Create a start of a list item + */ +void +vStartOfListItem(diagram_type *pDiag, BOOL bNoMarks) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vStartOfListItemXML(pDiag, bNoMarks); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vStartOfListItem */ + +/* + * Create an end of a table + */ +void +vEndOfTable(diagram_type *pDiag) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vEndOfTableXML(pDiag); + break; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } +} /* end of vEndOfTable */ + +/* + * Add a table row + * + * Returns TRUE when conversion type is XML + */ +BOOL +bAddTableRow(diagram_type *pDiag, char **aszColTxt, + int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo) +{ + switch (eConversionType) { + case conversion_text: + case conversion_fmt_text: + break; + case conversion_ps: + break; + case conversion_xml: + vAddTableRowXML(pDiag, aszColTxt, + iNbrOfColumns, asColumnWidth, + ucBorderInfo); + return TRUE; + case conversion_pdf: + break; + default: + DBG_DEC(eConversionType); + break; + } + return FALSE; +} /* end of bAddTableRow */ diff --git a/pdf.c b/pdf.c new file mode 100644 index 0000000..85b7101 --- /dev/null +++ b/pdf.c @@ -0,0 +1,1148 @@ +/* + * pdf.c + * Copyright (C) 2003-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with the Adobe Portable Document Format (pdf) + * + */ + +#include +#include +#include "version.h" +#include "antiword.h" + + +/* Constants for the file positions */ +#define INITIAL_LOCATION_SIZE 20 +#define INITIAL_PAGEOBJECT_SIZE 5 +#if defined(DEBUG) +#define EXTENSION_ARRAY_SIZE 10 +#else +#define EXTENSION_ARRAY_SIZE 30 +#endif /* DEBUG */ + +/* The character set */ +static encoding_type eEncoding = encoding_neutral; +/* Current creator for a PDF header */ +static const char *szProducer = NULL; +/* The height and width of a PDF page (in DrawUnits) */ +static long lPageHeight = LONG_MAX; +static long lPageWidth = LONG_MAX; +/* The height of the footer on the current page (in DrawUnits) */ +static long lFooterHeight = 0; +/* Inside a footer (to prevent an infinite loop when the footer is too big) */ +static BOOL bInFtrSpace = FALSE; +/* Current font information */ +static drawfile_fontref tFontRefCurr = (drawfile_fontref)-1; +static USHORT usFontSizeCurr = 0; +static int iFontColorCurr = -1; +/* Current vertical position information */ +static long lYtopCurr = -1; +/* Image counter */ +static int iImageCount = 0; +/* Section index */ +static int iSectionIndex = 0; +/* Are we on the first page of the section? */ +static BOOL bFirstInSection = TRUE; +/* File positions */ +static long lFilePosition = 0; +static long *alLocation = NULL; +static size_t tLocations = 0; +static int iMaxLocationNumber = 0; +/* File position at the start of a page */ +static long lStreamStart = -1; +/* Page objects */ +static int *aiPageObject = NULL; +static int iPageCount = 0; +static size_t tMaxPageObjects = 0; +/* Current object number */ +/* 1 = root; 2 = info; 3 = pages; 4 = encoding; 5-16 = fonts; 17 = resources */ +static int iObjectNumberCurr = 17; + +static void vMoveTo(diagram_type *, long); + +static const struct { + const char *szPDFname; + const char *szPSname; +} atFontname[] = { + { "Courier", FONT_MONOSPACED_PLAIN }, + { "Courier-Bold", FONT_MONOSPACED_BOLD }, + { "Courier-Oblique", FONT_MONOSPACED_ITALIC }, + { "Courier-BoldOblique", FONT_MONOSPACED_BOLDITALIC }, + { "Helvetica", FONT_SANS_SERIF_PLAIN }, + { "Helvetica-Bold", FONT_SANS_SERIF_BOLD }, + { "Helvetica-Oblique", FONT_SANS_SERIF_ITALIC }, + { "Helvetica-BoldOblique", FONT_SANS_SERIF_BOLDITALIC }, + { "Times-Roman", FONT_SERIF_PLAIN }, + { "Times-Bold", FONT_SERIF_BOLD }, + { "Times-Italic", FONT_SERIF_ITALIC }, + { "Times-BoldItalic", FONT_SERIF_BOLDITALIC }, +}; + +static const char *iso_8859_1[] = { +"128 /Euro", +"140 /ellipsis /trademark /perthousand /bullet", +" /quoteleft /quoteright /guilsinglleft /guilsinglright", +" /quotedblleft /quotedblright /quotedblbase /endash /emdash", +" /minus /OE /oe /dagger /daggerdbl /fi /fl", +"160 /space /exclamdown /cent /sterling /currency", +" /yen /brokenbar /section /dieresis /copyright", +" /ordfeminine /guillemotleft /logicalnot /hyphen /registered", +" /macron /degree /plusminus /twosuperior /threesuperior", +" /acute /mu /paragraph /periodcentered /cedilla", +" /onesuperior /ordmasculine /guillemotright /onequarter", +" /onehalf /threequarters /questiondown /Agrave /Aacute", +" /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla", +" /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute", +" /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute", +" /Ocircumflex /Otilde /Odieresis /multiply /Oslash", +" /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn", +" /germandbls /agrave /aacute /acircumflex /atilde", +" /adieresis /aring /ae /ccedilla /egrave /eacute", +" /ecircumflex /edieresis /igrave /iacute /icircumflex", +" /idieresis /eth /ntilde /ograve /oacute /ocircumflex", +" /otilde /odieresis /divide /oslash /ugrave /uacute", +" /ucircumflex /udieresis /yacute /thorn /ydieresis", +}; + +static const char *iso_8859_2[] = { +"160 /space /Aogonek /breve /Lslash /currency /Lcaron", +" /Sacute /section /dieresis /Scaron /Scommaaccent", +" /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent /degree", +" /aogonek /ogonek /lslash /acute /lcaron /sacute", +" /caron /cedilla /scaron /scommaaccent /tcaron", +" /zacute /hungarumlaut /zcaron /zdotaccent /Racute", +" /Aacute /Acircumflex /Abreve /Adieresis /Lacute", +" /Cacute /Ccedilla /Ccaron /Eacute /Eogonek", +" /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron", +" /.notdef /Nacute /Ncaron /Oacute /Ocircumflex", +" /Ohungarumlaut /Odieresis /multiply /Rcaron /Uring", +" /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcommaaccent", +" /germandbls /racute /aacute /acircumflex /abreve", +" /adieresis /lacute /cacute /ccedilla /ccaron /eacute", +" /eogonek /edieresis /ecaron /iacute /icircumflex", +" /dcaron /.notdef /nacute /ncaron /oacute /ocircumflex", +" /ohungarumlaut /odieresis /divide /rcaron /uring", +" /uacute /uhungarumlaut /udieresis /yacute /tcommaaccent", +" /dotaccent", +}; + + +/* + * tGetFontIndex - get the font index + */ +static size_t +tGetFontIndex(drawfile_fontref tFontRef) +{ + const char *szFontname; + size_t tIndex; + + /* Get the font name */ + szFontname = szGetFontname(tFontRef); + fail(szFontname == NULL); + if (szFontname == NULL) { + return 0; + } + + /* Find the name in the table */ + for (tIndex = 0; tIndex < elementsof(atFontname); tIndex++) { + if (STRCEQ(atFontname[tIndex].szPSname, szFontname)) { + return tIndex; + } + } + /* Not found */ + DBG_DEC(tFontRef); + DBG_MSG(szFontname); + return 0; +} /* end of tGetFontIndex */ + +/* + * vSetLocation - store the location of objects + */ +static void +vSetLocation(int iLocationNumber) +{ + fail(iLocationNumber <= 0); + + if ((size_t)iLocationNumber >= tLocations) { + /* Extend and set to zero */ + tLocations += EXTENSION_ARRAY_SIZE; + alLocation = xrealloc(alLocation, tLocations * sizeof(long)); + memset(alLocation + tLocations - EXTENSION_ARRAY_SIZE, + 0, + EXTENSION_ARRAY_SIZE * sizeof(long)); + DBG_DEC(tLocations); + } + if (iLocationNumber > iMaxLocationNumber) { + iMaxLocationNumber = iLocationNumber; + } + + DBG_DEC_C((size_t)iLocationNumber >= tLocations, iLocationNumber); + DBG_DEC_C((size_t)iLocationNumber >= tLocations, tLocations); + fail((size_t)iLocationNumber >= tLocations); + + alLocation[iLocationNumber] = lFilePosition; +} /* end of vSetLocation */ + +/* + * vFillNextPageObject - fil the next page object with the current object number + */ +static void +vFillNextPageObject(void) +{ + iPageCount++; + if ((size_t)iPageCount >= tMaxPageObjects) { + /* Extend the array */ + tMaxPageObjects += EXTENSION_ARRAY_SIZE; + aiPageObject = xrealloc(aiPageObject, + tMaxPageObjects * sizeof(int)); + DBG_DEC(tMaxPageObjects); + } + aiPageObject[iPageCount] = iObjectNumberCurr; +} /* end of vFillNextPageObject */ + +/* + * vFPprintf - printf and update the fileposition + * + * called with arguments like fprintf(3) + */ +static void +vFPprintf(FILE *pOutFile, const char *szFormat, ...) +{ + va_list tArg; + + va_start(tArg, szFormat); + lFilePosition += vfprintf(pOutFile, szFormat, tArg); + va_end(tArg); +} /* end of vFPprintf */ + +/* + * vCreateInfoDictionary - create the document information dictionary + */ +void +vCreateInfoDictionary(diagram_type *pDiag, int iWordVersion) +{ + FILE *pOutFile; + const char *szTitle, *szAuthor, *szSubject, *szCreator; + const char *szCreationDate, *szModDate; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(iWordVersion < 0); + fail(szProducer == NULL || szProducer[0] == '\0'); + + szTitle = szGetTitle(); + szAuthor = szGetAuthor(); + szSubject = szGetSubject(); + szCreationDate = szGetCreationDate(); + szModDate = szGetModDate(); + + switch (iWordVersion) { + case 0: szCreator = "Word for DOS"; break; + case 1: szCreator = "WinWord 1.x"; break; + case 2: szCreator = "WinWord 2.0"; break; + case 4: szCreator = "MacWord 4"; break; + case 5: szCreator = "MacWord 5"; break; + case 6: szCreator = "Word 6"; break; + case 7: szCreator = "Word 7/95"; break; + case 8: szCreator = "Word 97 or later"; break; + default: szCreator = NULL; break; + } + + pOutFile = pDiag->pOutFile; + + vSetLocation(2); + vFPprintf(pOutFile, "2 0 obj\n"); + vFPprintf(pOutFile, "<<\n"); + if (szTitle != NULL && szTitle[0] != '\0') { + vFPprintf(pOutFile, "/Title (%s)\n", szTitle); + } + if (szAuthor != NULL && szAuthor[0] != '\0') { + vFPprintf(pOutFile, "/Author (%s)\n", szAuthor); + } + if (szSubject != NULL && szSubject[0] != '\0') { + vFPprintf(pOutFile, "/Subject (%s)\n", szSubject); + } + if (szCreator != NULL && szCreator[0] != '\0') { + vFPprintf(pOutFile, "/Creator (%s)\n", szCreator); + } + vFPprintf(pOutFile, "/Producer (%s %s)\n", szProducer, VERSIONSTRING); + if (szCreationDate != NULL && szCreationDate[0] != '\0') { + vFPprintf(pOutFile, "/CreationDate (%s)\n", szCreationDate); + } + if (szModDate != NULL && szModDate[0] != '\0') { + vFPprintf(pOutFile, "/ModDate (%s)\n", szModDate); + } + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); +} /* end of vCreateInfoDictionary */ + +/* + * vAddHdrFtr - add a header or footer + */ +static void +vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo) +{ + output_type *pStart, *pPrev, *pNext; + + fail(pDiag == NULL); + fail(pHdrFtrInfo == NULL); + + vStartOfParagraphPDF(pDiag, 0); + pStart = pHdrFtrInfo->pText; + while (pStart != NULL) { + pNext = pStart; + while (pNext != NULL && + (pNext->tNextFree != 1 || + (pNext->szStorage[0] != PAR_END && + pNext->szStorage[0] != HARD_RETURN))) { + pNext = pNext->pNext; + } + if (pNext == NULL) { + if (bOutputContainsText(pStart)) { + vAlign2Window(pDiag, pStart, + lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), + ALIGNMENT_LEFT); + } else { + vMove2NextLinePDF(pDiag, pStart->usFontSize); + } + break; + } + fail(pNext->tNextFree != 1); + fail(pNext->szStorage[0] != PAR_END && + pNext->szStorage[0] != HARD_RETURN); + + if (pStart != pNext) { + /* There is something to print */ + pPrev = pNext->pPrev; + fail(pPrev->pNext != pNext); + /* Cut the chain */ + pPrev->pNext = NULL; + if (bOutputContainsText(pStart)) { + /* Print it */ + vAlign2Window(pDiag, pStart, + lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), + ALIGNMENT_LEFT); + } else { + /* Just an empty line */ + vMove2NextLinePDF(pDiag, pStart->usFontSize); + } + /* Repair the chain */ + pPrev->pNext = pNext; + } + if (pNext->szStorage[0] == PAR_END) { + vEndOfParagraphPDF(pDiag, pNext->usFontSize, + (long)pNext->usFontSize * 200); + } + pStart = pNext->pNext; + } +} /* end of vAddHdrFtr */ + +/* + * vAddHeader - add a page header + */ +static void +vAddHeader(diagram_type *pDiag) +{ + const hdrftr_block_type *pHdrInfo; + const hdrftr_block_type *pFtrInfo; + + fail(pDiag == NULL); + + NO_DBG_MSG("vAddHeader"); + + pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE, + odd(iPageCount), bFirstInSection); + pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, + odd(iPageCount), bFirstInSection); + /* Set the height of the footer of this page */ + lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight; + fail(lFooterHeight < 0); + + if (pHdrInfo == NULL || + pHdrInfo->pText == NULL || + pHdrInfo->lHeight <= 0) { + fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0); + fail(pHdrInfo != NULL && + pHdrInfo->pText != NULL && + pHdrInfo->lHeight == 0); + return; + } + + vAddHdrFtr(pDiag, pHdrInfo); + + DBG_DEC_C(pHdrInfo->lHeight != + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, + pHdrInfo->lHeight); + DBG_DEC_C(pHdrInfo->lHeight != + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop); +} /* end of vAddHeader */ + +/* + * vAddFooter - add a page footer + */ +static void +vAddFooter(diagram_type *pDiag) +{ + const hdrftr_block_type *pFtrInfo; + + fail(pDiag == NULL); + + NO_DBG_MSG("vAddFooter"); + + pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, + odd(iPageCount), bFirstInSection); + bFirstInSection = FALSE; + if (pFtrInfo == NULL || + pFtrInfo->pText == NULL || + pFtrInfo->lHeight <= 0) { + fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0); + fail(pFtrInfo != NULL && + pFtrInfo->pText != NULL && + pFtrInfo->lHeight == 0); + return; + } + + bInFtrSpace = TRUE; + + DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight); + DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight); + DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + pDiag->lYtop); + DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + lFooterHeight + PS_BOTTOM_MARGIN); + + if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) { + /* Move down to the start of the footer */ + pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; + vMoveTo(pDiag, 0); + } else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) { + DBG_FIXME(); + /* + * Move up to the start of the footer, to prevent moving + * of the bottom edge of the paper + */ + pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; + vMoveTo(pDiag, 0); + } + + DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop)); + + vAddHdrFtr(pDiag, pFtrInfo); + bInFtrSpace = FALSE; +} /* end of vAddFooter */ + +/* + * vEndPageObject - end the current page object + */ +static void +vEndPageObject(FILE *pOutFile) +{ + long lStreamEnd; + + if (lStreamStart < 0) { + /* There is no current page object */ + return; + } + + vFPprintf(pOutFile, "ET\n"); + lStreamEnd = lFilePosition; + vFPprintf(pOutFile, "endstream\n"); + vFPprintf(pOutFile, "endobj\n"); + + iObjectNumberCurr++; + vSetLocation(iObjectNumberCurr); + vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); + vFPprintf(pOutFile, "%lu\n", lStreamEnd - lStreamStart); + vFPprintf(pOutFile, "endobj\n"); +} /* end of vEndPageObject */ + +/* + * vMove2NextPage - move to the start of the next page + */ +static void +vMove2NextPage(diagram_type *pDiag, BOOL bNewSection) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + + vAddFooter(pDiag); + /* End the old page object */ + vEndPageObject(pOutFile); + if (bNewSection) { + iSectionIndex++; + bFirstInSection = TRUE; + } + + /* Start the new page object */ + iObjectNumberCurr++; + vSetLocation(iObjectNumberCurr); + vFillNextPageObject(); + vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Type /Page\n"); + vFPprintf(pOutFile, "/Parent 3 0 R\n"); + vFPprintf(pOutFile, "/Resources 17 0 R\n"); + vFPprintf(pOutFile, "/Contents %d 0 R\n", iObjectNumberCurr + 1); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); + + /* Start the new text object */ + iObjectNumberCurr++; + vSetLocation(iObjectNumberCurr); + vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Length %d 0 R\n", iObjectNumberCurr + 1); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "stream\n"); + lStreamStart = lFilePosition; + vFPprintf(pOutFile, "BT\n"); + + /* Set variables to their start of page values */ + pDiag->lYtop = lPageHeight - PS_TOP_MARGIN; + tFontRefCurr = (drawfile_fontref)-1; + usFontSizeCurr = 0; + iFontColorCurr = -1; + lYtopCurr = -1; + vAddHeader(pDiag); +} /* end of vMove2NextPage */ + +/* + * vMoveTo - move to the specified X,Y coordinates + * + * Move the current position of the specified diagram to its X,Y coordinates, + * start on a new page if needed + */ +static void +vMoveTo(diagram_type *pDiag, long lLastVerticalMovement) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) { + vMove2NextPage(pDiag, FALSE); + /* Repeat the last vertical movement on the new page */ + pDiag->lYtop -= lLastVerticalMovement; + } + + fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace); + DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop); + fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3); + + if (pDiag->lYtop != lYtopCurr) { + vFPprintf(pDiag->pOutFile, "1 0 0 1 %.2f %.2f Tm\n", + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop)); + lYtopCurr = pDiag->lYtop; + } +} /* end of vMoveTo */ + +/* + * vProloguePDF - set options and perform the PDF initialization + */ +void +vProloguePDF(diagram_type *pDiag, + const char *szTask, const options_type *pOptions) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pOptions == NULL); + + pOutFile = pDiag->pOutFile; + + eEncoding = pOptions->eEncoding; + + /* Create an empty location array */ + tLocations = INITIAL_LOCATION_SIZE; + alLocation = xcalloc(tLocations, sizeof(long)); + + /* Create an empty pageobject array */ + tMaxPageObjects = INITIAL_PAGEOBJECT_SIZE; + aiPageObject = xcalloc(tMaxPageObjects, sizeof(int)); + + if (pOptions->iPageHeight == INT_MAX) { + lPageHeight = LONG_MAX; + } else { + lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight); + } + DBG_DEC(lPageHeight); + if (pOptions->iPageWidth == INT_MAX) { + lPageWidth = LONG_MAX; + } else { + lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth); + } + DBG_DEC(lPageWidth); + lFooterHeight = 0; + bInFtrSpace = FALSE; + + tFontRefCurr = (drawfile_fontref)-1; + usFontSizeCurr = 0; + iFontColorCurr = -1; + lYtopCurr = -1; + iPageCount = 0; + iImageCount = 0; + iSectionIndex = 0; + bFirstInSection = TRUE; + lFilePosition = 0; + iMaxLocationNumber = 0; + lStreamStart = -1; + iObjectNumberCurr = 17; + pDiag->lXleft = 0; + pDiag->lYtop = 0; + + szProducer = szTask; + + vFPprintf(pOutFile, "%%PDF-1.3\n"); + vFPprintf(pOutFile, "%%%c%c%c%c\n", 0xe2, 0xe3, 0xcf, 0xd3); + + /* Root catalog */ + vSetLocation(1); + vFPprintf(pOutFile, "1 0 obj\n"); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Type /Catalog\n"); + vFPprintf(pOutFile, "/Pages 3 0 R\n"); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); +} /* end of vProloguePDF */ + +/* + * vEpiloguePDF - clean up after everything is done + */ +void +vEpiloguePDF(diagram_type *pDiag) +{ + FILE *pOutFile; + long lXref; + int iIndex; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + + vAddFooter(pDiag); + /* End the old page object */ + vEndPageObject(pOutFile); + + vSetLocation(3); + vFPprintf(pOutFile, "3 0 obj\n"); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Type /Pages\n"); + vFPprintf(pOutFile, "/Count %d\n", iPageCount); + vFPprintf(pOutFile, "/MediaBox [ 0 0 %.0f %.0f ]\n", + dDrawUnits2Points(lPageWidth), + dDrawUnits2Points(lPageHeight)); + vFPprintf(pOutFile, "/Kids [ "); + for (iIndex = 1; iIndex <= iPageCount; iIndex++) { + vFPprintf(pOutFile, "\t%d 0 R\n", aiPageObject[iIndex]); + } + vFPprintf(pOutFile, "]\n"); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); + + lXref = lFilePosition; + + vFPprintf(pOutFile, "xref\n"); + vFPprintf(pOutFile, "0 %d\n", iMaxLocationNumber + 1); + vFPprintf(pOutFile, "0000000000 65535 f \n"); + for (iIndex = 1; iIndex <= iMaxLocationNumber; iIndex++) { + vFPprintf(pOutFile, "%.10ld 00000 n \n", alLocation[iIndex]); + } + + vFPprintf(pOutFile, "trailer\n"); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Size %d\n", iMaxLocationNumber + 1); + vFPprintf(pOutFile, "/Root 1 0 R\n"); + vFPprintf(pOutFile, "/Info 2 0 R\n"); + vFPprintf(pOutFile, ">>\n"); + + vFPprintf(pOutFile, "startxref\n"); + vFPprintf(pOutFile, "%ld\n", lXref); + vFPprintf(pOutFile, "%%%%EOF\n"); + + szProducer = NULL; + aiPageObject = xfree(aiPageObject); + alLocation = xfree(alLocation); +} /* end of vEpiloguePDF */ + +/* + * vPrintPalette - print a pdf color space (palette) + */ +static void +vPrintPalette(FILE *pOutFile, const imagedata_type *pImg) +{ + int iIndex; + + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 2); + fail(pImg->iColorsUsed > 256); + + vFPprintf(pOutFile, "\t/ColorSpace [ /Indexed\n"); + vFPprintf(pOutFile, "\t/Device%s %d\n", + pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1); + vFPprintf(pOutFile, "<"); + for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) { + vFPprintf(pOutFile, "%02x", + (unsigned int)pImg->aucPalette[iIndex][0]); + if (pImg->bColorImage) { + vFPprintf(pOutFile, "%02x%02x", + (unsigned int)pImg->aucPalette[iIndex][1], + (unsigned int)pImg->aucPalette[iIndex][2]); + } + if (iIndex % 8 == 7) { + vFPprintf(pOutFile, "\n"); + } else { + vFPprintf(pOutFile, " "); + } + } + vFPprintf(pOutFile, "> ]\n"); +} /* end of vPrintPalette */ + +/* + * vImageProloguePDF - perform the image initialization + */ +void +vImageProloguePDF(diagram_type *pDiag, const imagedata_type *pImg) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pImg == NULL); + + if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { + return; + } + + iImageCount++; + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); + vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); + + pOutFile = pDiag->pOutFile; + + vFPprintf(pOutFile, "ET\n"); + vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount); + if (pImg->eImageType == imagetype_is_dib) { + /* Scanning from left to right and bottom to top */ + vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", + pImg->iHorSizeScaled, -pImg->iVerSizeScaled, + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop) + pImg->iVerSizeScaled); + } else { + /* Scanning from left to right and top to bottom */ + vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", + pImg->iHorSizeScaled, pImg->iVerSizeScaled, + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop)); + } + vFPprintf(pOutFile, "BI\n"); + vFPprintf(pOutFile, "\t/Width %d\n", pImg->iWidth); + vFPprintf(pOutFile, "\t/Height %d\n", pImg->iHeight); + switch (pImg->eImageType) { + case imagetype_is_jpeg: + switch (pImg->iComponents) { + case 1: + vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n"); + break; + case 3: + vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); + break; + case 4: + vFPprintf(pOutFile, "\t/ColorSpace /DeviceCMYK\n"); + if (pImg->bAdobe) { + /* + * Adobe-conforming CMYK file + * applying workaround for color inversion + */ + vFPprintf(pOutFile, + "\t/Decode [1 0 1 0 1 0 1 0]\n"); + } + break; + default: + DBG_DEC(pImg->iComponents); + break; + } + vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); + vFPprintf(pOutFile, + "\t/Filter [ /ASCII85Decode /DCTDecode ]\n"); + break; + case imagetype_is_png: + if (pImg->iComponents == 3 || pImg->iComponents == 4) { + vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); + vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); + } else if (pImg->iColorsUsed > 0) { + vPrintPalette(pOutFile, pImg); + fail(pImg->uiBitsPerComponent > 8); + vFPprintf(pOutFile, "\t/BitsPerComponent %u\n", + pImg->uiBitsPerComponent); + } else { + vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n"); + vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); + } + vFPprintf(pOutFile, + "\t/Filter [ /ASCII85Decode /FlateDecode ]\n"); + vFPprintf(pOutFile, "\t/DecodeParms [ null <<\n"); + vFPprintf(pOutFile, "\t\t/Predictor 10\n"); + vFPprintf(pOutFile, "\t\t/Colors %d\n", pImg->iComponents); + vFPprintf(pOutFile, "\t\t/BitsPerComponent %u\n", + pImg->uiBitsPerComponent); + vFPprintf(pOutFile, "\t\t/Columns %d\n", pImg->iWidth); + vFPprintf(pOutFile, "\t\t>> ]\n"); + break; + case imagetype_is_dib: + if (pImg->uiBitsPerComponent <= 8) { + vPrintPalette(pOutFile, pImg); + } else { + vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); + } + vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); + vFPprintf(pOutFile, "\t/Filter /ASCII85Decode\n"); + break; + default: + vFPprintf(pOutFile, "\t/ColorSpace /Device%s\n", + pImg->bColorImage ? "RGB" : "Gray"); + vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); + vFPprintf(pOutFile, "\t/Filter /ASCIIHexDecode\n"); + break; + } + vFPprintf(pOutFile, "ID\n"); +} /* end of vImageProloguePDF */ + +/* + * vImageEpiloguePDF - clean up after the image + */ +void +vImageEpiloguePDF(diagram_type *pDiag) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + + /* Correction for the image bytes */ + lFilePosition = ftell(pOutFile); + + vFPprintf(pOutFile, "EI\n"); + vFPprintf(pOutFile, "Q\n"); + vFPprintf(pOutFile, "BT\n"); + + pDiag->lXleft = 0; +} /* end of vImageEpiloguePDF */ + +/* + * bAddDummyImagePDF - add a dummy image + * + * return TRUE when successful, otherwise FALSE + */ +BOOL +bAddDummyImagePDF(diagram_type *pDiag, const imagedata_type *pImg) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pImg == NULL); + + if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { + return FALSE; + } + + iImageCount++; + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); + vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); + + pOutFile = pDiag->pOutFile; + + vFPprintf(pOutFile, "ET\n"); + vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount); + vFPprintf(pOutFile, "\t1.0 w\n"); + vFPprintf(pOutFile, "\t0.3 G\n"); + vFPprintf(pOutFile, "\t%.2f %.2f %d %d re\n", + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop), + pImg->iHorSizeScaled, + pImg->iVerSizeScaled); + vFPprintf(pOutFile, "\tS\n"); + vFPprintf(pOutFile, "Q\n"); + vFPprintf(pOutFile, "BT\n"); + + pDiag->lXleft = 0; + + return TRUE; +} /* end of bAddDummyImagePDF */ + +/* + * vAddFontsPDF - add the font information + */ +void +vAddFontsPDF(diagram_type *pDiag) +{ + FILE *pOutFile; + size_t tIndex; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + + /* The font encoding */ + vSetLocation(4); + vFPprintf(pOutFile, "4 0 obj\n"); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Type /Encoding\n"); + vFPprintf(pOutFile, "/BaseEncoding /StandardEncoding\n"); + vFPprintf(pOutFile, "/Differences [\n"); + switch (eEncoding) { + case encoding_latin_1: + for (tIndex = 0; + tIndex < elementsof(iso_8859_1); + tIndex++) { + vFPprintf(pOutFile, "%s\n", iso_8859_1[tIndex]); + } + break; + case encoding_latin_2: + for (tIndex = 0; + tIndex < elementsof(iso_8859_2); + tIndex++) { + vFPprintf(pOutFile, "%s\n", iso_8859_2[tIndex]); + } + break; + case encoding_cyrillic: + werr(1, + "The combination PDF and Cyrillic is not supported"); + break; + case encoding_utf_8: + werr(1, + "The combination PDF and UTF-8 is not supported"); + break; + default: + DBG_DEC(eEncoding); + break; + } + vFPprintf(pOutFile, "]\n"); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); + + /* Twelve of the standard type 1 fonts */ + for (tIndex = 0; tIndex < 12; tIndex++) { + vSetLocation(5 + tIndex); + vFPprintf(pOutFile, "%u 0 obj\n", 5 + tIndex); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/Type /Font\n"); + vFPprintf(pOutFile, "/Subtype /Type1\n"); + vFPprintf(pOutFile, "/Name /F%u\n", 1 + tIndex); + vFPprintf(pOutFile, "/BaseFont /%s\n", + atFontname[tIndex].szPDFname); + vFPprintf(pOutFile, "/Encoding 4 0 R\n"); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); + } + + /* The Resources */ + vSetLocation(17); + vFPprintf(pOutFile, "17 0 obj\n"); + vFPprintf(pOutFile, "<<\n"); + vFPprintf(pOutFile, "/ProcSet [ /PDF /Text ]\n"); + vFPprintf(pOutFile, "/Font <<\n"); + for (tIndex = 0; tIndex < 12; tIndex++) { + vFPprintf(pOutFile, "\t/F%u %u 0 R\n", 1 + tIndex, 5 + tIndex); + } + vFPprintf(pOutFile, "\t>>\n"); + vFPprintf(pOutFile, ">>\n"); + vFPprintf(pOutFile, "endobj\n"); + vAddHeader(pDiag); +} /* end of vAddFontsPDF */ + +/* + * vPrintPDF - print a PDF string + */ +static void +vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength, + USHORT usFontstyle) +{ + const UCHAR *aucBytes; + double dMove; + size_t tCount; + + fail(szString == NULL); + + if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { + return; + } + DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr); + + dMove = 0.0; + + /* Up for superscript */ + if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) { + dMove = (double)((usFontSizeCurr + 1) / 2) * 0.375; + vFPprintf(pFile, "%.2f Ts\n", dMove); + } + + /* Down for subscript */ + if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) { + dMove = (double)usFontSizeCurr * 0.125; + vFPprintf(pFile, "%.2f Ts\n", -dMove); + } + + /* Generate and print the PDF output */ + aucBytes = (UCHAR *)szString; + vFPprintf(pFile, "("); + for (tCount = 0; tCount < tStringLength ; tCount++) { + switch (aucBytes[tCount]) { + case '(': + case ')': + case '\\': + vFPprintf(pFile, "\\%c", szString[tCount]); + break; + default: + if (aucBytes[tCount] < 0x20 || + aucBytes[tCount] == 0x7f || + (aucBytes[tCount] >= 0x81 && + aucBytes[tCount] < 0x8c)) { + DBG_HEX(aucBytes[tCount]); + vFPprintf(pFile, " "); + } else if (aucBytes[tCount] >= 0x80) { + vFPprintf(pFile, "\\%03o", + (UINT)aucBytes[tCount]); + } else { + vFPprintf(pFile, "%c", szString[tCount]); + } + break; + } + } + vFPprintf(pFile, ") Tj\n"); + + /* Undo the superscript/subscript move */ + if (dMove != 0.0) { + vFPprintf(pFile, "0 Ts\n"); + } +} /* end of vPrintPDF */ + +/* + * vSetColor - move to the specified color + */ +static void +vSetColor(FILE *pFile, UCHAR ucFontColor) +{ + ULONG ulTmp, ulRed, ulGreen, ulBlue; + + ulTmp = ulColor2Color(ucFontColor); + ulRed = (ulTmp & 0x0000ff00) >> 8; + ulGreen = (ulTmp & 0x00ff0000) >> 16; + ulBlue = (ulTmp & 0xff000000) >> 24; + vFPprintf(pFile, "%.3f %.3f %.3f rg\n", + ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0); +} /* end of vSetColor */ + +/* + * vMove2NextLinePDF - move to the next line + */ +void +vMove2NextLinePDF(diagram_type *pDiag, USHORT usFontSize) +{ + fail(pDiag == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + pDiag->lYtop -= lComputeLeading(usFontSize); +} /* end of vMove2NextLinePDF */ + +/* + * vSubstringPDF - print a sub string + */ +void +vSubstringPDF(diagram_type *pDiag, + char *szString, size_t tStringLength, long lStringWidth, + UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, + USHORT usFontSize, USHORT usMaxFontSize) +{ + size_t tFontIndex; + + fail(pDiag == NULL || szString == NULL); + fail(pDiag->pOutFile == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE); + fail(usFontSize > usMaxFontSize); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + vMoveTo(pDiag, lComputeLeading(usMaxFontSize)); + if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) { + tFontIndex = tGetFontIndex(tFontRef); + vFPprintf(pDiag->pOutFile, "/F%u %.1f Tf\n", + 1 + tFontIndex, (double)usFontSize / 2.0); + tFontRefCurr = tFontRef; + usFontSizeCurr = usFontSize; + } + if ((int)ucFontColor != iFontColorCurr) { + vSetColor(pDiag->pOutFile, ucFontColor); + iFontColorCurr = (int)ucFontColor; + } + vPrintPDF(pDiag->pOutFile, szString, tStringLength, usFontstyle); + pDiag->lXleft += lStringWidth; +} /* end of vSubstringPDF */ + +/* + * Create an start of paragraph by moving the y-top mark + */ +void +vStartOfParagraphPDF(diagram_type *pDiag, long lBeforeIndentation) +{ + fail(pDiag == NULL); + fail(lBeforeIndentation < 0); + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation); +} /* end of vStartOfParagraphPDF */ + +/* + * Create an end of paragraph by moving the y-top mark + */ +void +vEndOfParagraphPDF(diagram_type *pDiag, + USHORT usFontSize, long lAfterIndentation) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(lAfterIndentation < 0); + + if (pDiag->lXleft > 0) { + /* To the start of the line */ + vMove2NextLinePDF(pDiag, usFontSize); + } + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation); +} /* end of vEndOfParagraphPDF */ + +/* + * Create an end of page + */ +void +vEndOfPagePDF(diagram_type *pDiag, BOOL bNewSection) +{ + vMove2NextPage(pDiag, bNewSection); +} /* end of vEndOfPagePDF */ diff --git a/pictlist.c b/pictlist.c new file mode 100644 index 0000000..dd9e4bf --- /dev/null +++ b/pictlist.c @@ -0,0 +1,109 @@ +/* + * pictlist.c + * Copyright (C) 2000-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy a list of Word picture information + */ + +#include +#include "antiword.h" + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct picture_mem_tag { + picture_block_type tInfo; + struct picture_mem_tag *pNext; +} picture_mem_type; + +/* Variables needed to write the Picture Information List */ +static picture_mem_type *pAnchor = NULL; +static picture_mem_type *pPictureLast = NULL; + + +/* + * vDestroyPictInfoList - destroy the Picture Information List + */ +void +vDestroyPictInfoList(void) +{ + picture_mem_type *pCurr, *pNext; + + DBG_MSG("vDestroyPictInfoList"); + + /* Free the Picture Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pPictureLast = NULL; +} /* end of vDestroyPictInfoList */ + +/* + * vAdd2PictInfoList - Add an element to the Picture Information List + */ +void +vAdd2PictInfoList(const picture_block_type *pPictureBlock) +{ + picture_mem_type *pListMember; + + fail(pPictureBlock == NULL); + + NO_DBG_MSG("bAdd2PictInfoList"); + + if (pPictureBlock->ulFileOffset == FC_INVALID) { + /* + * This offset is really past the end of the file, + * so don't waste any memory by storing it. + */ + return; + } + if (pPictureBlock->ulFileOffsetPicture == FC_INVALID) { + /* + * The place where this picture is supposed to be stored + * doesn't exist. + */ + return; + } + + NO_DBG_HEX(pPictureBlock->ulFileOffset); + NO_DBG_HEX(pPictureBlock->ulFileOffsetPicture); + NO_DBG_HEX(pPictureBlock->ulPictureOffset); + + /* Create list member */ + pListMember = xmalloc(sizeof(picture_mem_type)); + /* Fill the list member */ + pListMember->tInfo = *pPictureBlock; + pListMember->pNext = NULL; + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + } else { + fail(pPictureLast == NULL); + pPictureLast->pNext = pListMember; + } + pPictureLast = pListMember; +} /* end of vAdd2PictInfoList */ + +/* + * Get the info with the given file offset from the Picture Information List + */ +ULONG +ulGetPictInfoListItem(ULONG ulFileOffset) +{ + picture_mem_type *pCurr; + + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->tInfo.ulFileOffset == ulFileOffset) { + return pCurr->tInfo.ulFileOffsetPicture; + } + } + return FC_INVALID; +} /* end of ulGetPictInfoListItem */ diff --git a/png2eps.c b/png2eps.c new file mode 100644 index 0000000..25d1755 --- /dev/null +++ b/png2eps.c @@ -0,0 +1,191 @@ +/* + * png2eps.c + * Copyright (C) 2000-2002 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate png images into eps + * + */ + +#include +#include +#include "antiword.h" + +#if defined(DEBUG) +static int iPicCounter = 0; +#endif /* DEBUG */ + + +/* + * tSkipToData - skip until a IDAT chunk is found + * + * returns the length of the pixeldata or -1 in case of error + */ +static size_t +tSkipToData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) +{ + ULONG ulName, ulTmp; + size_t tDataLength, tToSkip; + int iCounter; + + fail(pFile == NULL); + fail(ptSkipped == NULL); + + /* Examine chunks */ + while (*ptSkipped + 8 < tMaxBytes) { + tDataLength = (size_t)ulNextLongBE(pFile); + DBG_DEC(tDataLength); + *ptSkipped += 4; + + ulName = 0x00; + for (iCounter = 0; iCounter < 4; iCounter++) { + ulTmp = (ULONG)iNextByte(pFile); + if (!isalpha((int)ulTmp)) { + DBG_HEX(ulTmp); + return (size_t)-1; + } + ulName <<= 8; + ulName |= ulTmp; + } + DBG_HEX(ulName); + *ptSkipped += 4; + + if (ulName == PNG_CN_IEND) { + break; + } + if (ulName == PNG_CN_IDAT) { + return tDataLength; + } + + tToSkip = tDataLength + 4; + if (tToSkip >= tMaxBytes - *ptSkipped) { + DBG_DEC(tToSkip); + DBG_DEC(tMaxBytes - *ptSkipped); + return (size_t)-1; + } + (void)tSkipBytes(pFile, tToSkip); + *ptSkipped += tToSkip; + } + + return (size_t)-1; +} /* end of iSkipToData */ + +/* + * iFindFirstPixelData - find the first pixeldata if a PNG image + * + * returns the length of the pixeldata or -1 in case of error + */ +static size_t +tFindFirstPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) +{ + fail(pFile == NULL); + fail(tMaxBytes == 0); + fail(ptSkipped == NULL); + + if (tMaxBytes < 8) { + DBG_DEC(tMaxBytes); + return (size_t)-1; + } + + /* Skip over the PNG signature */ + (void)tSkipBytes(pFile, 8); + *ptSkipped = 8; + + return tSkipToData(pFile, tMaxBytes, ptSkipped); +} /* end of iFindFirstPixelData */ + +/* + * tFindNextPixelData - find the next pixeldata if a PNG image + * + * returns the length of the pixeldata or -1 in case of error + */ +static size_t +tFindNextPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) +{ + fail(pFile == NULL); + fail(tMaxBytes == 0); + fail(ptSkipped == NULL); + + if (tMaxBytes < 4) { + DBG_DEC(tMaxBytes); + return (size_t)-1; + } + + /* Skip over the crc */ + (void)tSkipBytes(pFile, 4); + *ptSkipped = 4; + + return tSkipToData(pFile, tMaxBytes, ptSkipped); +} /* end of tFindNextPixelData */ + +#if defined(DEBUG) +/* + * vCopy2File + */ +static void +vCopy2File(FILE *pFile, ULONG ulFileOffset, size_t tPictureLen) +{ + FILE *pOutFile; + size_t tIndex; + int iTmp; + char szFilename[30]; + + if (!bSetDataOffset(pFile, ulFileOffset)) { + return; + } + + sprintf(szFilename, "/tmp/pic/pic%04d.png", ++iPicCounter); + pOutFile = fopen(szFilename, "wb"); + if (pOutFile == NULL) { + return; + } + for (tIndex = 0; tIndex < tPictureLen; tIndex++) { + iTmp = iNextByte(pFile); + if (putc(iTmp, pOutFile) == EOF) { + break; + } + } + (void)fclose(pOutFile); +} /* end of vCopy2File */ +#endif /* DEBUG */ + +/* + * bTranslatePNG - translate a PNG image + * + * This function translates an image from png to eps + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslatePNG(diagram_type *pDiag, FILE *pFile, + ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg) +{ + size_t tMaxBytes, tDataLength, tSkipped; + +#if defined(DEBUG) + vCopy2File(pFile, ulFileOffset, tPictureLen); +#endif /* DEBUG */ + + /* Seek to start position of PNG data */ + if (!bSetDataOffset(pFile, ulFileOffset)) { + return FALSE; + } + + tMaxBytes = tPictureLen; + tDataLength = tFindFirstPixelData(pFile, tMaxBytes, &tSkipped); + if (tDataLength == (size_t)-1) { + return FALSE; + } + + vImagePrologue(pDiag, pImg); + do { + tMaxBytes -= tSkipped; + vASCII85EncodeArray(pFile, pDiag->pOutFile, tDataLength); + tMaxBytes -= tDataLength; + tDataLength = tFindNextPixelData(pFile, tMaxBytes, &tSkipped); + } while (tDataLength != (size_t)-1); + vASCII85EncodeByte(pDiag->pOutFile, EOF); + vImageEpilogue(pDiag); + + return TRUE; +} /* end of bTranslatePNG */ diff --git a/png2sprt.c b/png2sprt.c new file mode 100644 index 0000000..d40ceb6 --- /dev/null +++ b/png2sprt.c @@ -0,0 +1,26 @@ +/* + * png2sprt.c + * Copyright (C) 2000 A.J. van Os; Released under GPL + * + * Description: + * Functions to translate png pictures into sprites + */ + +#include +#include "antiword.h" + + +/* + * bTranslatePNG - translate a PNG picture + * + * This function translates a picture from png to sprite + * + * return TRUE when sucessful, otherwise FALSE + */ +BOOL +bTranslatePNG(diagram_type *pDiag, FILE *pFile, + ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg) +{ + /* PNG is not supported yet */ + return bAddDummyImage(pDiag, pImg); +} /* end of bTranslatePNG */ diff --git a/postscript.c b/postscript.c new file mode 100644 index 0000000..fd20e53 --- /dev/null +++ b/postscript.c @@ -0,0 +1,1171 @@ +/* + * postscript.c + * Copyright (C) 1999-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with the PostScript format + * + *================================================================ + * The function vImagePrologue is based on: + * jpeg2ps - convert JPEG compressed images to PostScript Level 2 + * Copyright (C) 1994-99 Thomas Merz (tm@muc.de) + *================================================================ + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include +#include +#include +#include "version.h" +#include "antiword.h" + +/* The character set */ +static encoding_type eEncoding = encoding_neutral; +/* The image level */ +static image_level_enum eImageLevel = level_default; +/* The output must use landscape orientation */ +static BOOL bUseLandscape = FALSE; +/* The height and width of a PostScript page (in DrawUnits) */ +static long lPageHeight = LONG_MAX; +static long lPageWidth = LONG_MAX; +/* The height of the footer on the current page (in DrawUnits) */ +static long lFooterHeight = 0; +/* Inside a footer (to prevent an infinite loop when the footer is too big) */ +static BOOL bInFtrSpace = FALSE; +/* Current time for a PS header */ +static const char *szCreationDate = NULL; +/* Current creator for a PS header */ +static const char *szCreator = NULL; +/* Current font information */ +static drawfile_fontref tFontRefCurr = (drawfile_fontref)-1; +static USHORT usFontSizeCurr = 0; +static int iFontColorCurr = -1; +/* Current vertical position information */ +static long lYtopCurr = -1; +/* PostScript page counter */ +static int iPageCount = 0; +/* Image counter */ +static int iImageCount = 0; +/* Section index */ +static int iSectionIndex = 0; +/* Are we on the first page of the section? */ +static BOOL bFirstInSection = TRUE; + +static void vMoveTo(diagram_type *, long); + +static const char *iso_8859_1_data[] = { +"/newcodes % ISO-8859-1 character encodings", +"[", +"140/ellipsis 141/trademark 142/perthousand 143/bullet", +"144/quoteleft 145/quoteright 146/guilsinglleft 147/guilsinglright", +"148/quotedblleft 149/quotedblright 150/quotedblbase 151/endash 152/emdash", +"153/minus 154/OE 155/oe 156/dagger 157/daggerdbl 158/fi 159/fl", +"160/space 161/exclamdown 162/cent 163/sterling 164/currency", +"165/yen 166/brokenbar 167/section 168/dieresis 169/copyright", +"170/ordfeminine 171/guillemotleft 172/logicalnot 173/hyphen 174/registered", +"175/macron 176/degree 177/plusminus 178/twosuperior 179/threesuperior", +"180/acute 181/mu 182/paragraph 183/periodcentered 184/cedilla", +"185/onesuperior 186/ordmasculine 187/guillemotright 188/onequarter", +"189/onehalf 190/threequarters 191/questiondown 192/Agrave 193/Aacute", +"194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198/AE 199/Ccedilla", +"200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204/Igrave 205/Iacute", +"206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve 211/Oacute", +"212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash", +"217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn", +"223/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde", +"228/adieresis 229/aring 230/ae 231/ccedilla 232/egrave 233/eacute", +"234/ecircumflex 235/edieresis 236/igrave 237/iacute 238/icircumflex", +"239/idieresis 240/eth 241/ntilde 242/ograve 243/oacute 244/ocircumflex", +"245/otilde 246/odieresis 247/divide 248/oslash 249/ugrave 250/uacute", +"251/ucircumflex 252/udieresis 253/yacute 254/thorn 255/ydieresis", +"] bind def", +"", +"/reencdict 12 dict def", +"", +}; + +static const char *iso_8859_2_data[] = { +"/newcodes % ISO-8859-2 character encodings", +"[", +"160/space 161/Aogonek 162/breve 163/Lslash 164/currency 165/Lcaron", +"166/Sacute 167/section 168/dieresis 169/Scaron 170/Scommaaccent", +"171/Tcaron 172/Zacute 173/hyphen 174/Zcaron 175/Zdotaccent 176/degree", +"177/aogonek 178/ogonek 179/lslash 180/acute 181/lcaron 182/sacute", +"183/caron 184/cedilla 185/scaron 186/scommaaccent 187/tcaron", +"188/zacute 189/hungarumlaut 190/zcaron 191/zdotaccent 192/Racute", +"193/Aacute 194/Acircumflex 195/Abreve 196/Adieresis 197/Lacute", +"198/Cacute 199/Ccedilla 200/Ccaron 201/Eacute 202/Eogonek", +"203/Edieresis 204/Ecaron 205/Iacute 206/Icircumflex 207/Dcaron", +"208/Dcroat 209/Nacute 210/Ncaron 211/Oacute 212/Ocircumflex", +"213/Ohungarumlaut 214/Odieresis 215/multiply 216/Rcaron 217/Uring", +"218/Uacute 219/Uhungarumlaut 220/Udieresis 221/Yacute 222/Tcommaaccent", +"223/germandbls 224/racute 225/aacute 226/acircumflex 227/abreve", +"228/adieresis 229/lacute 230/cacute 231/ccedilla 232/ccaron 233/eacute", +"234/eogonek 235/edieresis 236/ecaron 237/iacute 238/icircumflex", +"239/dcaron 240/dcroat 241/nacute 242/ncaron 243/oacute 244/ocircumflex", +"245/ohungarumlaut 246/odieresis 247/divide 248/rcaron 249/uring", +"250/uacute 251/uhungarumlaut 252/udieresis 253/yacute 254/tcommaaccent", +"255/dotaccent", +"] bind def", +"", +"/reencdict 12 dict def", +"", +}; + +static const char *iso_8859_5_data[] = { +"/newcodes % ISO-8859-5 character encodings", +"[", +"160/space 161/afii10023 162/afii10051 163/afii10052 164/afii10053", +"165/afii10054 166/afii10055 167/afii10056 168/afii10057 169/afii10058", +"170/afii10059 171/afii10060 172/afii10061 173/hyphen 174/afii10062", +"175/afii10145 176/afii10017 177/afii10018 178/afii10019 179/afii10020", +"180/afii10021 181/afii10022 182/afii10024 183/afii10025 184/afii10026", +"185/afii10027 186/afii10028 187/afii10029 188/afii10030 189/afii10031", +"190/afii10032 191/afii10033 192/afii10034 193/afii10035 194/afii10036", +"195/afii10037 196/afii10038 197/afii10039 198/afii10040 199/afii10041", +"200/afii10042 201/afii10043 202/afii10044 203/afii10045 204/afii10046", +"205/afii10047 206/afii10048 207/afii10049 208/afii10065 209/afii10066", +"210/afii10067 211/afii10068 212/afii10069 213/afii10070 214/afii10072", +"215/afii10073 216/afii10074 217/afii10075 218/afii10076 219/afii10077", +"220/afii10078 221/afii10079 222/afii10080 223/afii10081 224/afii10082", +"225/afii10083 226/afii10084 227/afii10085 228/afii10086 229/afii10087", +"230/afii10088 231/afii10089 232/afii10090 233/afii10091 234/afii10092", +"235/afii10093 236/afii10094 237/afii10095 238/afii10096 239/afii10097", +"240/afii61352 241/afii10071 242/afii10099 243/afii10100 244/afii10101", +"245/afii10102 246/afii10103 247/afii10104 248/afii10105 249/afii10106", +"250/afii10107 251/afii10108 252/afii10109 253/section 254/afii10110", +"255/afii10193", +"] bind def", +"", +"/reencdict 12 dict def", +"", +}; + +static const char *iso_8859_x_func[] = { +"% change fonts using ISO-8859-x characters", +"/ChgFnt % size psname natname => font", +"{", +" dup FontDirectory exch known % is re-encoded name known?", +" { exch pop } % yes, get rid of long name", +" { dup 3 1 roll ReEncode } ifelse % no, re-encode it", +" findfont exch scalefont setfont", +"} bind def", +"", +"/ReEncode", +"{", +"reencdict begin", +" /newname exch def", +" /basename exch def", +" /basedict basename findfont def", +" /newfont basedict maxlength dict def", +" basedict", +" { exch dup /FID ne", +" { dup /Encoding eq", +" { exch dup length array copy newfont 3 1 roll put }", +" { exch newfont 3 1 roll put } ifelse", +" }", +" { pop pop } ifelse", +" } forall", +" newfont /FontName newname put", +" newcodes aload pop newcodes length 2 idiv", +" { newfont /Encoding get 3 1 roll put } repeat", +" newname newfont definefont pop", +"end", +"} bind def", +"", +}; + +static const char *misc_func[] = { +"% draw a line and show the string", +"/LineShow % string linewidth movement", +"{", +" gsave", +" 0 exch rmoveto", +" setlinewidth", +" dup", +" stringwidth pop", +" 0 rlineto stroke", +" grestore", +" show", +"} bind def", +"", +"% begin an EPS file (level 2 and up)", +"/BeginEPSF", +"{", +" /b4_Inc_state save def", +" /dict_count countdictstack def", +" /op_count count 1 sub def", +" userdict begin", +" /showpage { } def", +" 0 setgray 0 setlinecap", +" 1 setlinewidth 0 setlinejoin", +" 10 setmiterlimit [ ] 0 setdash newpath", +" false setstrokeadjust false setoverprint", +"} bind def", +"", +"% end an EPS file", +"/EndEPSF {", +" count op_count sub { pop } repeat", +" countdictstack dict_count sub { end } repeat", +" b4_Inc_state restore", +"} bind def", +"", +}; + + +/* + * vAddPageSetup - add the page setup + */ +static void +vAddPageSetup(FILE *pOutFile) +{ + if (bUseLandscape) { + fprintf(pOutFile, "%%%%BeginPageSetup\n"); + fprintf(pOutFile, "90 rotate\n"); + fprintf(pOutFile, "0.00 %.2f translate\n", + -dDrawUnits2Points(lPageHeight)); + fprintf(pOutFile, "%%%%EndPageSetup\n"); + } +} /* end of vAddPageSetup */ + +/* + * vAddHdrFtr - add a header or footer + */ +static void +vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo) +{ + output_type *pStart, *pPrev, *pNext; + + fail(pDiag == NULL); + fail(pHdrFtrInfo == NULL); + + vStartOfParagraphPS(pDiag, 0); + pStart = pHdrFtrInfo->pText; + while (pStart != NULL) { + pNext = pStart; + while (pNext != NULL && + (pNext->tNextFree != 1 || + (pNext->szStorage[0] != PAR_END && + pNext->szStorage[0] != HARD_RETURN))) { + pNext = pNext->pNext; + } + if (pNext == NULL) { + if (bOutputContainsText(pStart)) { + vAlign2Window(pDiag, pStart, + lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), + ALIGNMENT_LEFT); + } else { + vMove2NextLinePS(pDiag, pStart->usFontSize); + } + break; + } + fail(pNext->tNextFree != 1); + fail(pNext->szStorage[0] != PAR_END && + pNext->szStorage[0] != HARD_RETURN); + + if (pStart != pNext) { + /* There is something to print */ + pPrev = pNext->pPrev; + fail(pPrev->pNext != pNext); + /* Cut the chain */ + pPrev->pNext = NULL; + if (bOutputContainsText(pStart)) { + /* Print it */ + vAlign2Window(pDiag, pStart, + lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), + ALIGNMENT_LEFT); + } else { + /* Just an empty line */ + vMove2NextLinePS(pDiag, pStart->usFontSize); + } + /* Repair the chain */ + pPrev->pNext = pNext; + } + if (pNext->szStorage[0] == PAR_END) { + vEndOfParagraphPS(pDiag, pNext->usFontSize, + (long)pNext->usFontSize * 200); + } + pStart = pNext->pNext; + } +} /* end of vAddHdrFtr */ + +/* + * vAddHeader - add a page header + */ +static void +vAddHeader(diagram_type *pDiag) +{ + const hdrftr_block_type *pHdrInfo; + const hdrftr_block_type *pFtrInfo; + + fail(pDiag == NULL); + + NO_DBG_MSG("vAddHeader"); + + pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE, + odd(iPageCount), bFirstInSection); + pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, + odd(iPageCount), bFirstInSection); + /* Set the height of the footer of this page */ + lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight; + fail(lFooterHeight < 0); + + if (pHdrInfo == NULL || + pHdrInfo->pText == NULL || + pHdrInfo->lHeight <= 0) { + fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0); + fail(pHdrInfo != NULL && + pHdrInfo->pText != NULL && + pHdrInfo->lHeight == 0); + return; + } + + vAddHdrFtr(pDiag, pHdrInfo); + + DBG_DEC_C(pHdrInfo->lHeight != + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, + pHdrInfo->lHeight); + DBG_DEC_C(pHdrInfo->lHeight != + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop); + +#if 0 /* defined(DEBUG) */ + fprintf(pDiag->pOutFile, + "(HEADER: FileOffset 0x%04lx-0x%04lx; Height %ld-%ld) show\n", + ulCharPos2FileOffset(pHdrInfo->ulCharPosStart), + ulCharPos2FileOffset(pHdrInfo->ulCharPosNext), + pHdrInfo->lHeight, + lPageHeight - PS_TOP_MARGIN - pDiag->lYtop); +#endif +} /* end of vAddHeader */ + +/* + * vAddFooter - add a page footer + */ +static void +vAddFooter(diagram_type *pDiag) +{ + const hdrftr_block_type *pFtrInfo; + + fail(pDiag == NULL); + + NO_DBG_MSG("vAddFooter"); + pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, + odd(iPageCount), bFirstInSection); + bFirstInSection = FALSE; + if (pFtrInfo == NULL || + pFtrInfo->pText == NULL || + pFtrInfo->lHeight <= 0) { + fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0); + fail(pFtrInfo != NULL && + pFtrInfo->pText != NULL && + pFtrInfo->lHeight == 0); + return; + } + + bInFtrSpace = TRUE; + + DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight); + DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight); + DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + pDiag->lYtop); + DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + lFooterHeight + PS_BOTTOM_MARGIN); + + if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) { + /* Move down to the start of the footer */ + pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; + vMoveTo(pDiag, 0); + } else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) { + DBG_FIXME(); + /* + * Move up to the start of the footer, to prevent moving + * of the bottom edge of the paper + */ + pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; + vMoveTo(pDiag, 0); + } + + DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, + dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop)); + +#if 0 /* defined(DEBUG) */ + fprintf(pDiag->pOutFile, + "(FOOTER: FileOffset 0x%04lx-0x%04lx; Bottom %ld-%ld) show\n", + ulCharPos2FileOffset(pFtrInfo->ulCharPosStart), + ulCharPos2FileOffset(pFtrInfo->ulCharPosNext), + pDiag->lYtop, + pFtrInfo->lHeight + PS_BOTTOM_MARGIN); +#endif + vAddHdrFtr(pDiag, pFtrInfo); + bInFtrSpace = FALSE; +} /* end of vAddFooter */ + +/* + * vMove2NextPage - move to the start of the next page + */ +static void +vMove2NextPage(diagram_type *pDiag, BOOL bNewSection) +{ + fail(pDiag == NULL); + + vAddFooter(pDiag); + fprintf(pDiag->pOutFile, "showpage\n"); + iPageCount++; + fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount); + if (bNewSection) { + iSectionIndex++; + bFirstInSection = TRUE; + } + vAddPageSetup(pDiag->pOutFile); + pDiag->lYtop = lPageHeight - PS_TOP_MARGIN; + lYtopCurr = -1; + vAddHeader(pDiag); +} /* end of vMove2NextPage */ + +/* + * vMoveTo - move to the specified X,Y coordinates + * + * Move the current position of the specified diagram to its X,Y coordinates, + * start on a new page if needed + */ +static void +vMoveTo(diagram_type *pDiag, long lLastVerticalMovement) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) { + vMove2NextPage(pDiag, FALSE); + /* Repeat the last vertical movement on the new page */ + pDiag->lYtop -= lLastVerticalMovement; + } + + fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace); + DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop); + fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3); + + if (pDiag->lYtop != lYtopCurr) { + fprintf(pDiag->pOutFile, "%.2f %.2f moveto\n", + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop)); + lYtopCurr = pDiag->lYtop; + } +} /* end of vMoveTo */ + +/* + * vProloguePS - set options and perform the PostScript initialization + */ +void +vProloguePS(diagram_type *pDiag, + const char *szTask, const char *szFilename, + const options_type *pOptions) +{ + FILE *pOutFile; + const char *szTmp; + time_t tTime; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(szTask == NULL || szTask[0] == '\0'); + fail(pOptions == NULL); + + pOutFile = pDiag->pOutFile; + + bUseLandscape = pOptions->bUseLandscape; + eEncoding = pOptions->eEncoding; + eImageLevel = pOptions->eImageLevel; + + if (pOptions->iPageHeight == INT_MAX) { + lPageHeight = LONG_MAX; + } else { + lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight); + } + DBG_DEC(lPageHeight); + if (pOptions->iPageWidth == INT_MAX) { + lPageWidth = LONG_MAX; + } else { + lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth); + } + DBG_DEC(lPageWidth); + lFooterHeight = 0; + bInFtrSpace = FALSE; + + tFontRefCurr = (drawfile_fontref)-1; + usFontSizeCurr = 0; + iFontColorCurr = -1; + lYtopCurr = -1; + iPageCount = 0; + iImageCount = 0; + iSectionIndex = 0; + bFirstInSection = TRUE; + pDiag->lXleft = 0; + pDiag->lYtop = lPageHeight - PS_TOP_MARGIN; + + szCreator = szTask; + + fprintf(pOutFile, "%%!PS-Adobe-2.0\n"); + fprintf(pOutFile, "%%%%Title: %s\n", szBasename(szFilename)); + fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING); + szTmp = getenv("LOGNAME"); + if (szTmp == NULL || szTmp[0] == '\0') { + szTmp = getenv("USER"); + if (szTmp == NULL || szTmp[0] == '\0') { + szTmp = "unknown"; + } + } + fprintf(pOutFile, "%%%%For: %.50s\n", szTmp); + errno = 0; + tTime = time(NULL); + if (tTime == (time_t)-1 && errno != 0) { + szCreationDate = NULL; + } else { + szCreationDate = ctime(&tTime); + } + if (szCreationDate == NULL || szCreationDate[0] == '\0') { + szCreationDate = "unknown\n"; + } + fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate); + if (bUseLandscape) { + fprintf(pOutFile, "%%%%Orientation: Landscape\n"); + fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n", + dDrawUnits2Points(lPageHeight), + dDrawUnits2Points(lPageWidth)); + } else { + fprintf(pOutFile, "%%%%Orientation: Portrait\n"); + fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n", + dDrawUnits2Points(lPageWidth), + dDrawUnits2Points(lPageHeight)); + } +} /* end of vProloguePS */ + +/* + * vEpiloguePS - clean up after everything is done + */ +void +vEpiloguePS(diagram_type *pDiag) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + if (pDiag->lYtop < lPageHeight - PS_TOP_MARGIN) { + vAddFooter(pDiag); + fprintf(pDiag->pOutFile, "showpage\n"); + } + fprintf(pDiag->pOutFile, "%%%%Trailer\n"); + fprintf(pDiag->pOutFile, "%%%%Pages: %d\n", iPageCount); + fprintf(pDiag->pOutFile, "%%%%EOF\n"); + szCreationDate = NULL; + szCreator = NULL; +} /* end of vEpiloguePS */ + +/* + * vPrintPalette - print a postscript palette + */ +static void +vPrintPalette(FILE *pOutFile, const imagedata_type *pImg) +{ + int iIndex; + + fail(pOutFile == NULL); + fail(pImg == NULL); + fail(pImg->iColorsUsed < 2); + fail(pImg->iColorsUsed > 256); + + fprintf(pOutFile, "[ /Indexed\n"); + fprintf(pOutFile, "\t/Device%s %d\n", + pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1); + fprintf(pOutFile, "<"); + for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) { + fprintf(pOutFile, "%02x", + (unsigned int)pImg->aucPalette[iIndex][0]); + if (pImg->bColorImage) { + fprintf(pOutFile, "%02x%02x", + (unsigned int)pImg->aucPalette[iIndex][1], + (unsigned int)pImg->aucPalette[iIndex][2]); + } + if (iIndex % 8 == 7) { + fprintf(pOutFile, "\n"); + } else { + fprintf(pOutFile, " "); + } + } + fprintf(pOutFile, ">\n"); + fprintf(pOutFile, "] setcolorspace\n"); +} /* end of vPrintPalette */ + +/* + * vImageProloguePS - perform the Encapsulated PostScript initialization + */ +void +vImageProloguePS(diagram_type *pDiag, const imagedata_type *pImg) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pImg == NULL); + + if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { + return; + } + + fail(szCreationDate == NULL); + fail(szCreator == NULL); + fail(eImageLevel == level_no_images); + + iImageCount++; + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); + vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); + + pOutFile = pDiag->pOutFile; + + fprintf(pOutFile, "BeginEPSF\n"); + fprintf(pOutFile, "%%%%BeginDocument: image%03d.eps\n", iImageCount); + fprintf(pOutFile, "%%!PS-Adobe-2.0 EPSF-2.0\n"); + fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING); + fprintf(pOutFile, "%%%%Title: Image %03d\n", iImageCount); + fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate); + fprintf(pOutFile, "%%%%BoundingBox: 0 0 %d %d\n", + pImg->iHorSizeScaled, pImg->iVerSizeScaled); + fprintf(pOutFile, "%%%%DocumentData: Clean7Bit\n"); + fprintf(pOutFile, "%%%%LanguageLevel: 2\n"); + fprintf(pOutFile, "%%%%EndComments\n"); + fprintf(pOutFile, "%%%%BeginProlog\n"); + fprintf(pOutFile, "%%%%EndProlog\n"); + fprintf(pOutFile, "%%%%Page: 1 1\n"); + + fprintf(pOutFile, "save\n"); + + switch (pImg->eImageType) { + case imagetype_is_jpeg: + fprintf(pOutFile, "/Data1 currentfile "); + fprintf(pOutFile, "/ASCII85Decode filter def\n"); + fprintf(pOutFile, "/Data Data1 << "); + fprintf(pOutFile, ">> /DCTDecode filter def\n"); + switch (pImg->iComponents) { + case 1: + fprintf(pOutFile, "/DeviceGray setcolorspace\n"); + break; + case 3: + fprintf(pOutFile, "/DeviceRGB setcolorspace\n"); + break; + case 4: + fprintf(pOutFile, "/DeviceCMYK setcolorspace\n"); + break; + default: + DBG_DEC(pImg->iComponents); + break; + } + break; + case imagetype_is_png: + if (eImageLevel == level_gs_special) { + fprintf(pOutFile, + "/Data2 currentfile /ASCII85Decode filter def\n"); + fprintf(pOutFile, + "/Data1 Data2 << >> /FlateDecode filter def\n"); + fprintf(pOutFile, "/Data Data1 <<\n"); + fprintf(pOutFile, "\t/Colors %d\n", pImg->iComponents); + fprintf(pOutFile, "\t/BitsPerComponent %u\n", + pImg->uiBitsPerComponent); + fprintf(pOutFile, "\t/Columns %d\n", pImg->iWidth); + fprintf(pOutFile, + ">> /PNGPredictorDecode filter def\n"); + } else { + fprintf(pOutFile, + "/Data1 currentfile /ASCII85Decode filter def\n"); + fprintf(pOutFile, + "/Data Data1 << >> /FlateDecode filter def\n"); + } + if (pImg->iComponents == 3 || pImg->iComponents == 4) { + fprintf(pOutFile, "/DeviceRGB setcolorspace\n"); + } else if (pImg->iColorsUsed > 0) { + vPrintPalette(pOutFile, pImg); + } else { + fprintf(pOutFile, "/DeviceGray setcolorspace\n"); + } + break; + case imagetype_is_dib: + fprintf(pOutFile, "/Data currentfile "); + fprintf(pOutFile, "/ASCII85Decode filter def\n"); + if (pImg->uiBitsPerComponent <= 8) { + vPrintPalette(pOutFile, pImg); + } else { + fprintf(pOutFile, "/DeviceRGB setcolorspace\n"); + } + break; + default: + fprintf(pOutFile, "/Data currentfile "); + fprintf(pOutFile, "/ASCIIHexDecode filter def\n"); + fprintf(pOutFile, "/Device%s setcolorspace\n", + pImg->bColorImage ? "RGB" : "Gray"); + break; + } + + /* Translate to lower left corner of image */ + fprintf(pOutFile, "%.2f %.2f translate\n", + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop)); + + fprintf(pOutFile, "%d %d scale\n", + pImg->iHorSizeScaled, pImg->iVerSizeScaled); + + fprintf(pOutFile, "{ <<\n"); + fprintf(pOutFile, "\t/ImageType 1\n"); + fprintf(pOutFile, "\t/Width %d\n", pImg->iWidth); + fprintf(pOutFile, "\t/Height %d\n", pImg->iHeight); + if (pImg->eImageType == imagetype_is_dib) { + /* Scanning from left to right and bottom to top */ + fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 0 ]\n", + pImg->iWidth, pImg->iHeight); + } else { + /* Scanning from left to right and top to bottom */ + fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 %d ]\n", + pImg->iWidth, -pImg->iHeight, pImg->iHeight); + } + fprintf(pOutFile, "\t/DataSource Data\n"); + + switch (pImg->eImageType) { + case imagetype_is_jpeg: + fprintf(pOutFile, "\t/BitsPerComponent 8\n"); + switch (pImg->iComponents) { + case 1: + fprintf(pOutFile, "\t/Decode [0 1]\n"); + break; + case 3: + fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n"); + break; + case 4: + if (pImg->bAdobe) { + /* + * Adobe-conforming CMYK file + * applying workaround for color inversion + */ + fprintf(pOutFile, + "\t/Decode [1 0 1 0 1 0 1 0]\n"); + } else { + fprintf(pOutFile, + "\t/Decode [0 1 0 1 0 1 0 1]\n"); + } + break; + default: + DBG_DEC(pImg->iComponents); + break; + } + break; + case imagetype_is_png: + if (pImg->iComponents == 3) { + fprintf(pOutFile, "\t/BitsPerComponent 8\n"); + fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n"); + } else if (pImg->iColorsUsed > 0) { + fail(pImg->uiBitsPerComponent > 8); + fprintf(pOutFile, "\t/BitsPerComponent %u\n", + pImg->uiBitsPerComponent); + fprintf(pOutFile, "\t/Decode [0 %d]\n", + (1 << pImg->uiBitsPerComponent) - 1); + } else { + fprintf(pOutFile, "\t/BitsPerComponent 8\n"); + fprintf(pOutFile, "\t/Decode [0 1]\n"); + } + break; + case imagetype_is_dib: + fprintf(pOutFile, "\t/BitsPerComponent 8\n"); + if (pImg->uiBitsPerComponent <= 8) { + fprintf(pOutFile, "\t/Decode [0 255]\n"); + } else { + fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n"); + } + break; + default: + fprintf(pOutFile, "\t/BitsPerComponent 8\n"); + if (pImg->bColorImage) { + fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n"); + } else { + fprintf(pOutFile, "\t/Decode [0 1]\n"); + } + break; + } + + fprintf(pOutFile, " >> image\n"); + fprintf(pOutFile, " Data closefile\n"); + fprintf(pOutFile, " showpage\n"); + fprintf(pOutFile, " restore\n"); + fprintf(pOutFile, "} exec\n"); +} /* end of vImageProloguePS */ + +/* + * vImageEpiloguePS - clean up after Encapsulated PostScript + */ +void +vImageEpiloguePS(diagram_type *pDiag) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + + fprintf(pOutFile, "%%%%EOF\n"); + fprintf(pOutFile, "%%%%EndDocument\n"); + fprintf(pOutFile, "EndEPSF\n"); + + pDiag->lXleft = 0; +} /* end of vImageEpiloguePS */ + +/* + * bAddDummyImagePS - add a dummy image + * + * return TRUE when successful, otherwise FALSE + */ +BOOL +bAddDummyImagePS(diagram_type *pDiag, const imagedata_type *pImg) +{ + FILE *pOutFile; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pImg == NULL); + + if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { + return FALSE; + } + + iImageCount++; + + DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); + + pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); + vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); + + pOutFile = pDiag->pOutFile; + + fprintf(pOutFile, "gsave %% Image %03d\n", iImageCount); + fprintf(pOutFile, "\tnewpath\n"); + fprintf(pOutFile, "\t%.2f %.2f moveto\n", + dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), + dDrawUnits2Points(pDiag->lYtop)); + fprintf(pOutFile, "\t1.0 setlinewidth\n"); + fprintf(pOutFile, "\t0.3 setgray\n"); + fprintf(pOutFile, "\t0 %d rlineto\n", pImg->iVerSizeScaled); + fprintf(pOutFile, "\t%d 0 rlineto\n", pImg->iHorSizeScaled); + fprintf(pOutFile, "\t0 %d rlineto\n", -pImg->iVerSizeScaled); + fprintf(pOutFile, "\tclosepath\n"); + fprintf(pOutFile, "\tstroke\n"); + fprintf(pOutFile, "grestore\n"); + + pDiag->lXleft = 0; + + return TRUE; +} /* end of bAddDummyImagePS */ + +/* + * vAddFontsPS - add the list of fonts and complete the prologue + */ +void +vAddFontsPS(diagram_type *pDiag) +{ + FILE *pOutFile; + const font_table_type *pTmp, *pTmp2; + size_t tIndex; + int iLineLen, iOurFontnameLen; + BOOL bFound; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pOutFile = pDiag->pOutFile; + iLineLen = fprintf(pOutFile, "%%%%DocumentFonts:"); + + if (tGetFontTableLength() == 0) { + iLineLen += fprintf(pOutFile, " Courier"); + } else { + pTmp = NULL; + while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) { + /* Print the document fonts */ + bFound = FALSE; + pTmp2 = NULL; + while ((pTmp2 = pGetNextFontTableRecord(pTmp2)) + != NULL && pTmp2 < pTmp) { + bFound = STREQ(pTmp2->szOurFontname, + pTmp->szOurFontname); + if (bFound) { + break; + } + } + iOurFontnameLen = (int)strlen(pTmp->szOurFontname); + if (bFound || iOurFontnameLen <= 0) { + continue; + } + if (iLineLen + iOurFontnameLen > 76) { + fprintf(pOutFile, "\n%%%%+"); + iLineLen = 3; + } + iLineLen += fprintf(pOutFile, + " %s", pTmp->szOurFontname); + } + } + fprintf(pOutFile, "\n"); + fprintf(pOutFile, "%%%%Pages: (atend)\n"); + fprintf(pOutFile, "%%%%EndComments\n"); + fprintf(pOutFile, "%%%%BeginProlog\n"); + + switch (eEncoding) { + case encoding_latin_1: + for (tIndex = 0; + tIndex < elementsof(iso_8859_1_data); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_1_data[tIndex]); + } + fprintf(pOutFile, "\n"); + for (tIndex = 0; + tIndex < elementsof(iso_8859_x_func); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]); + } + break; + case encoding_latin_2: + for (tIndex = 0; + tIndex < elementsof(iso_8859_2_data); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_2_data[tIndex]); + } + fprintf(pOutFile, "\n"); + for (tIndex = 0; + tIndex < elementsof(iso_8859_x_func); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]); + } + break; + case encoding_cyrillic: + for (tIndex = 0; + tIndex < elementsof(iso_8859_5_data); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_5_data[tIndex]); + } + fprintf(pOutFile, "\n"); + for (tIndex = 0; + tIndex < elementsof(iso_8859_x_func); + tIndex++) { + fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]); + } + break; + case encoding_utf_8: + werr(1, + "The combination PostScript and UTF-8 is not supported"); + break; + default: + DBG_DEC(eEncoding); + break; + } + + /* The rest of the functions */ + for (tIndex = 0; tIndex < elementsof(misc_func); tIndex++) { + fprintf(pOutFile, "%s\n", misc_func[tIndex]); + } + fprintf(pOutFile, "%%%%EndProlog\n"); + iPageCount = 1; + fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount); + vAddPageSetup(pDiag->pOutFile); + vAddHeader(pDiag); +} /* end of vAddFontsPS */ + +/* + * vPrintPS - print a PostScript string + */ +static void +vPrintPS(FILE *pFile, const char *szString, size_t tStringLength, + USHORT usFontstyle) +{ + double dSuperscriptMove, dSubscriptMove; + const UCHAR *ucBytes; + size_t tCount; + + fail(szString == NULL); + + if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { + return; + } + DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr); + + dSuperscriptMove = 0.0; + dSubscriptMove = 0.0; + + /* Up for superscript */ + if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) { + dSuperscriptMove = (double)((usFontSizeCurr + 1) / 2) * 0.375; + fprintf(pFile, "0 %.2f rmoveto\n", dSuperscriptMove); + } + + /* Down for subscript */ + if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) { + dSubscriptMove = (double)usFontSizeCurr * 0.125; + fprintf(pFile, "0 %.2f rmoveto\n", -dSubscriptMove); + } + + /* Generate and print the PostScript output */ + ucBytes = (UCHAR *)szString; + (void)putc('(', pFile); + for (tCount = 0; tCount < tStringLength ; tCount++) { + switch (ucBytes[tCount]) { + case '(': + case ')': + case '\\': + (void)putc('\\', pFile); + (void)putc(szString[tCount], pFile); + break; + default: + if (ucBytes[tCount] < 0x20 || + (ucBytes[tCount] >= 0x7f && + ucBytes[tCount] < 0x8c)) { + DBG_HEX(ucBytes[tCount]); + (void)putc(' ', pFile); + } else if (ucBytes[tCount] >= 0x80) { + fprintf(pFile, "\\%03o", (UINT)ucBytes[tCount]); + } else { + (void)putc(szString[tCount], pFile); + } + break; + } + } + fprintf(pFile, ") "); + if ((bIsStrike(usFontstyle) || bIsMarkDel(usFontstyle)) && + usFontSizeCurr != 0) { + fprintf(pFile, "%.2f %.2f LineShow\n", + (double)usFontSizeCurr * 0.02, + (double)usFontSizeCurr * 0.12); + } else if (bIsUnderline(usFontstyle) && usFontSizeCurr != 0) { + fprintf(pFile, "%.2f %.2f LineShow\n", + (double)usFontSizeCurr * 0.02, + (double)usFontSizeCurr * -0.06); + } else { + fprintf(pFile, "show\n"); + } + + /* Undo the superscript move */ + if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) { + fprintf(pFile, "0 %.2f rmoveto\n", -dSuperscriptMove); + } + + /* Undo the subscript move */ + if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) { + fprintf(pFile, "0 %.2f rmoveto\n", dSubscriptMove); + } +} /* end of vPrintPS */ + +/* + * vSetColor - move to the specified color + */ +static void +vSetColor(FILE *pFile, UCHAR ucFontColor) +{ + ULONG ulTmp, ulRed, ulGreen, ulBlue; + + ulTmp = ulColor2Color(ucFontColor); + ulRed = (ulTmp & 0x0000ff00) >> 8; + ulGreen = (ulTmp & 0x00ff0000) >> 16; + ulBlue = (ulTmp & 0xff000000) >> 24; + fprintf(pFile, "%.3f %.3f %.3f setrgbcolor\n", + ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0); +} /* end of vSetColor */ + +/* + * vMove2NextLinePS - move to the next line + */ +void +vMove2NextLinePS(diagram_type *pDiag, USHORT usFontSize) +{ + fail(pDiag == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + + pDiag->lYtop -= lComputeLeading(usFontSize); +} /* end of vMove2NextLinePS */ + +/* + * vSubstringPS - print a sub string + */ +void +vSubstringPS(diagram_type *pDiag, + char *szString, size_t tStringLength, long lStringWidth, + UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, + USHORT usFontSize, USHORT usMaxFontSize) +{ + const char *szOurFontname; + + fail(pDiag == NULL || szString == NULL); + fail(pDiag->pOutFile == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE); + fail(usFontSize > usMaxFontSize); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) { + szOurFontname = szGetFontname(tFontRef); + fail(szOurFontname == NULL); + fprintf(pDiag->pOutFile, + "%.1f /%s /%s-ISO-8859-x ChgFnt\n", + (double)usFontSize / 2.0, + szOurFontname, szOurFontname); + tFontRefCurr = tFontRef; + usFontSizeCurr = usFontSize; + } + if ((int)ucFontColor != iFontColorCurr) { + vSetColor(pDiag->pOutFile, ucFontColor); + iFontColorCurr = (int)ucFontColor; + } + vMoveTo(pDiag, lComputeLeading(usMaxFontSize)); + vPrintPS(pDiag->pOutFile, szString, tStringLength, usFontstyle); + pDiag->lXleft += lStringWidth; +} /* end of vSubstringPS */ + +/* + * Create an start of paragraph by moving the y-top mark + */ +void +vStartOfParagraphPS(diagram_type *pDiag, long lBeforeIndentation) +{ + fail(pDiag == NULL); + fail(lBeforeIndentation < 0); + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation); +} /* end of vStartOfParagraphPS */ + +/* + * Create an end of paragraph by moving the y-top mark + */ +void +vEndOfParagraphPS(diagram_type *pDiag, + USHORT usFontSize, long lAfterIndentation) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); + fail(lAfterIndentation < 0); + + if (pDiag->lXleft > 0) { + /* To the start of the line */ + vMove2NextLinePS(pDiag, usFontSize); + } + + pDiag->lXleft = 0; + pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation); +} /* end of vEndOfParagraphPS */ + +/* + * Create an end of page + */ +void +vEndOfPagePS(diagram_type *pDiag, BOOL bNewSection) +{ + vMove2NextPage(pDiag, bNewSection); +} /* end of vEndOfPagePS */ diff --git a/prop0.c b/prop0.c new file mode 100644 index 0000000..bac2fbd --- /dev/null +++ b/prop0.c @@ -0,0 +1,489 @@ +/* + * prop0.c + * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Read the property information from a Word for DOS file + */ + +#include +#include +#include "antiword.h" + + +/* + * tConvertDosDate - convert DOS date format + * + * returns Unix time_t or -1 + */ +static time_t +tConvertDosDate(const char *szDosDate) +{ + struct tm tTime; + const char *pcTmp; + time_t tResult; + + memset(&tTime, 0, sizeof(tTime)); + pcTmp = szDosDate; + /* Get the month */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_mon = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_mon *= 10; + tTime.tm_mon += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Get the first separater */ + if (isalnum(*pcTmp)) { + return (time_t)-1; + } + pcTmp++; + /* Get the day */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_mday = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_mday *= 10; + tTime.tm_mday += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Get the second separater */ + if (isalnum(*pcTmp)) { + return (time_t)-1; + } + pcTmp++; + /* Get the year */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_year = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_year *= 10; + tTime.tm_year += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Check the values */ + if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) { + return (time_t)-1; + } + /* Correct the values */ + tTime.tm_mon--; /* From 01-12 to 00-11 */ + if (tTime.tm_year < 80) { + tTime.tm_year += 100; /* 00 means 2000 is 100 */ + } + tTime.tm_isdst = -1; + tResult = mktime(&tTime); + NO_DBG_MSG(ctime(&tResult)); + return tResult; +} /* end of tConvertDosDate */ + +/* + * Build the lists with Document Property Information for Word for DOS files + */ +void +vGet0DopInfo(FILE *pFile, const UCHAR *aucHeader) +{ + document_block_type tDocument; + UCHAR *aucBuffer; + ULONG ulBeginSumdInfo, ulBeginNextBlock; + size_t tLen; + USHORT usOffset; + + tDocument.ucHdrFtrSpecification = 0; + tDocument.usDefaultTabWidth = usGetWord(0x70, aucHeader); /* dxaTab */ + tDocument.tCreateDate = (time_t)-1; + tDocument.tRevisedDate = (time_t)-1; + + ulBeginSumdInfo = 128 * (ULONG)usGetWord(0x1c, aucHeader); + DBG_HEX(ulBeginSumdInfo); + ulBeginNextBlock = 128 * (ULONG)usGetWord(0x6a, aucHeader); + DBG_HEX(ulBeginNextBlock); + + if (ulBeginSumdInfo < ulBeginNextBlock && ulBeginNextBlock != 0) { + /* There is a summary information block */ + tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo); + aucBuffer = xmalloc(tLen); + /* Read the summary information block */ + if (bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) { + usOffset = usGetWord(12, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_STRN(aucBuffer + usOffset, 8); + tDocument.tRevisedDate = + tConvertDosDate((char *)aucBuffer + usOffset); + } + usOffset = usGetWord(14, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_STRN(aucBuffer + usOffset, 8); + tDocument.tCreateDate = + tConvertDosDate((char *)aucBuffer + usOffset); + } + } + aucBuffer = xfree(aucBuffer); + } + vCreateDocumentInfoList(&tDocument); +} /* end of vGet0DopInfo */ + +/* + * Fill the section information block with information + * from a Word for DOS file. + */ +static void +vGet0SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, + section_block_type *pSection) +{ + USHORT usCcol; + UCHAR ucTmp; + + fail(aucGrpprl == NULL || pSection == NULL); + + if (tBytes < 2) { + return; + } + /* bkc */ + ucTmp = ucGetByte(1, aucGrpprl); + DBG_HEX(ucTmp); + ucTmp &= 0x07; + DBG_HEX(ucTmp); + pSection->bNewPage = ucTmp != 0 && ucTmp != 1; + if (tBytes < 18) { + return; + } + /* ccolM1 */ + usCcol = (USHORT)ucGetByte(17, aucGrpprl); + DBG_DEC(usCcol); +} /* end of vGet0SectionInfo */ + +/* + * Build the lists with Section Property Information for Word for DOS files + */ +void +vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader) +{ + section_block_type tSection; + UCHAR *aucBuffer; + ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; + ULONG ulCharPos, ulSectPage, ulBeginNextBlock; + size_t tSectInfoLen, tIndex, tSections, tBytes; + UCHAR aucTmp[2], aucFpage[35]; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginOfText = 128; + NO_DBG_HEX(ulBeginOfText); + ulBeginSectInfo = 128 * (ULONG)usGetWord(0x18, aucHeader); + DBG_HEX(ulBeginSectInfo); + ulBeginNextBlock = 128 * (ULONG)usGetWord(0x1a, aucHeader); + DBG_HEX(ulBeginNextBlock); + if (ulBeginSectInfo == ulBeginNextBlock) { + /* There is no section information block */ + return; + } + + /* Get the the number of sections */ + if (!bReadBytes(aucTmp, 2, ulBeginSectInfo, pFile)) { + return; + } + tSections = (size_t)usGetWord(0, aucTmp); + NO_DBG_DEC(tSections); + + /* Read the Section Descriptors */ + tSectInfoLen = 10 * tSections; + NO_DBG_DEC(tSectInfoLen); + aucBuffer = xmalloc(tSectInfoLen); + if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo + 4, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); + + /* Read the Section Properties */ + for (tIndex = 0; tIndex < tSections; tIndex++) { + ulTextOffset = ulGetLong(10 * tIndex, aucBuffer); + NO_DBG_HEX(ulTextOffset); + ulCharPos = ulBeginOfText + ulTextOffset; + NO_DBG_HEX(ulTextOffset); + ulSectPage = ulGetLong(10 * tIndex + 6, aucBuffer); + NO_DBG_HEX(ulSectPage); + if (ulSectPage == FC_INVALID || /* Must use defaults */ + ulSectPage < 128 || /* Should not happen */ + ulSectPage >= ulBeginSectInfo) { /* Should not happen */ + DBG_HEX_C(ulSectPage != FC_INVALID, ulSectPage); + vDefault2SectionInfoList(ulCharPos); + continue; + } + /* Get the number of bytes to read */ + if (!bReadBytes(aucTmp, 1, ulSectPage, pFile)) { + continue; + } + tBytes = 1 + (size_t)ucGetByte(0, aucTmp); + NO_DBG_DEC(tBytes); + if (tBytes > sizeof(aucFpage)) { + DBG_DEC(tBytes); + tBytes = sizeof(aucFpage); + } + /* Read the bytes */ + if (!bReadBytes(aucFpage, tBytes, ulSectPage, pFile)) { + continue; + } + NO_DBG_PRINT_BLOCK(aucFpage, tBytes); + /* Process the bytes */ + vGetDefaultSection(&tSection); + vGet0SectionInfo(aucFpage + 1, tBytes - 1, &tSection); + vAdd2SectionInfoList(&tSection, ulCharPos); + } + /* Clean up before you leave */ + aucBuffer = xfree(aucBuffer); +} /* end of vGet0SepInfo */ + +/* + * Fill the style information block with information + * from a Word for DOS file. + */ +static void +vGet0StyleInfo(int iFodo, const UCHAR *aucGrpprl, style_block_type *pStyle) +{ + int iBytes; + UCHAR ucTmp; + + fail(iFodo <= 0 || aucGrpprl == NULL || pStyle == NULL); + + pStyle->usIstdNext = ISTD_NORMAL; + + iBytes = (int)ucGetByte(iFodo, aucGrpprl); + if (iBytes < 1) { + return; + } + /* stc if styled */ + ucTmp = ucGetByte(iFodo + 1, aucGrpprl); + if ((ucTmp & BIT(0)) != 0) { + ucTmp >>= 1; + if (ucTmp >= 88 && ucTmp <= 94) { + /* Header levels 1 through 7 */ + pStyle->usIstd = ucTmp - 87; + pStyle->ucNumLevel = 1; + } + } + if (iBytes < 2) { + return; + } + /* jc */ + ucTmp = ucGetByte(iFodo + 2, aucGrpprl); + pStyle->ucAlignment = ucTmp & 0x02; + if (iBytes < 3) { + return; + } + /* stc */ + ucTmp = ucGetByte(iFodo + 3, aucGrpprl); + ucTmp &= 0x7f; + if (ucTmp >= 88 && ucTmp <= 94) { + /* Header levels 1 through 7 */ + pStyle->usIstd = ucTmp - 87; + pStyle->ucNumLevel = 1; + } + if (iBytes < 6) { + return; + } + /* dxaRight */ + pStyle->sRightIndent = (short)usGetWord(iFodo + 5, aucGrpprl); + NO_DBG_DEC(pStyle->sRightIndent); + if (iBytes < 8) { + return; + } + /* dxaLeft */ + pStyle->sLeftIndent = (short)usGetWord(iFodo + 7, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent); + if (iBytes < 10) { + return; + } + /* dxaLeft1 */ + pStyle->sLeftIndent1 = (short)usGetWord(iFodo + 9, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent1); + if (iBytes < 14) { + return; + } + /* dyaBefore */ + pStyle->usBeforeIndent = usGetWord(iFodo + 13, aucGrpprl); + NO_DBG_DEC(pStyle->usBeforeIndent); + if (iBytes < 16) { + return; + } + /* dyaAfter */ + pStyle->usAfterIndent = usGetWord(iFodo + 15, aucGrpprl); + NO_DBG_DEC(pStyle->usAfterIndent); +} /* end of vGet0StyleInfo */ + +/* + * Build the lists with Paragraph Information for Word for DOS files + */ +void +vGet0PapInfo(FILE *pFile, const UCHAR *aucHeader) +{ + style_block_type tStyle; + ULONG ulBeginParfInfo, ulCharPos, ulCharPosNext; + int iIndex, iRun, iFodo; + UCHAR aucFpage[128]; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginParfInfo = 128 * (ULONG)usGetWord(0x12, aucHeader); + NO_DBG_HEX(ulBeginParfInfo); + + do { + if (!bReadBytes(aucFpage, 128, ulBeginParfInfo, pFile)) { + return; + } + NO_DBG_PRINT_BLOCK(aucFpage, 128); + ulCharPosNext = ulGetLong(0, aucFpage); + iRun = (int)ucGetByte(0x7f, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex = 0; iIndex < iRun; iIndex++) { + iFodo = (int)usGetWord(6 * iIndex + 8, aucFpage); + if (iFodo <= 0 || iFodo > 0x79) { + DBG_DEC_C(iFodo != (int)0xffff, iFodo); + continue; + } + vFillStyleFromStylesheet(0, &tStyle); + vGet0StyleInfo(iFodo, aucFpage + 4, &tStyle); + ulCharPos = ulCharPosNext; + ulCharPosNext = ulGetLong(6 * iIndex + 4, aucFpage); + tStyle.ulFileOffset = ulCharPos; + vAdd2StyleInfoList(&tStyle); + } + ulBeginParfInfo += 128; + } while (ulCharPosNext == ulBeginParfInfo); +} /* end of vGet0PapInfo */ + +/* + * Fill the font information block with information + * from a Word for DOS file. + */ +static void +vGet0FontInfo(int iFodo, const UCHAR *aucGrpprl, font_block_type *pFont) +{ + int iBytes; + UCHAR ucTmp; + + fail(iFodo <= 0 || aucGrpprl == NULL || pFont == NULL); + + iBytes = (int)ucGetByte(iFodo, aucGrpprl); + if (iBytes < 2) { + return; + } + /* fBold, fItalic, cFtc */ + ucTmp = ucGetByte(iFodo + 2, aucGrpprl); + if ((ucTmp & BIT(0)) != 0) { + pFont->usFontStyle |= FONT_BOLD; + } + if ((ucTmp & BIT(1)) != 0) { + pFont->usFontStyle |= FONT_ITALIC; + } + pFont->ucFontNumber = ucTmp >> 2; + NO_DBG_DEC(pFont->ucFontNumber); + if (iBytes < 3) { + return; + } + /* cHps */ + pFont->usFontSize = (USHORT)ucGetByte(iFodo + 3, aucGrpprl); + NO_DBG_DEC(pFont->usFontSize); + if (iBytes < 4) { + return; + } + /* cKul, fStrike, fCaps, fSmallCaps, fVanish */ + ucTmp = ucGetByte(iFodo + 4, aucGrpprl); + if ((ucTmp & BIT(0)) != 0 || (ucTmp & BIT(2)) != 0) { + pFont->usFontStyle |= FONT_UNDERLINE; + } + if ((ucTmp & BIT(1)) != 0) { + pFont->usFontStyle |= FONT_STRIKE; + } + if ((ucTmp & BIT(4)) != 0) { + pFont->usFontStyle |= FONT_CAPITALS; + } + if ((ucTmp & BIT(5)) != 0) { + pFont->usFontStyle |= FONT_SMALL_CAPITALS; + } + if ((ucTmp & BIT(7)) != 0) { + pFont->usFontStyle |= FONT_HIDDEN; + } + DBG_HEX(pFont->usFontStyle); + if (iBytes < 6) { + return; + } + /* cIss */ + ucTmp = ucGetByte(iFodo + 6, aucGrpprl); + if (ucTmp != 0) { + if (ucTmp < 128) { + pFont->usFontStyle |= FONT_SUPERSCRIPT; + DBG_MSG("Superscript"); + } else { + pFont->usFontStyle |= FONT_SUBSCRIPT; + DBG_MSG("Subscript"); + } + } + if (iBytes < 7) { + return; + } + /* cIco */ + ucTmp = ucGetByte(iFodo + 7, aucGrpprl); + switch (ucTmp & 0x07) { + case 0: pFont->ucFontColor = FONT_COLOR_BLACK; break; + case 1: pFont->ucFontColor = FONT_COLOR_RED; break; + case 2: pFont->ucFontColor = FONT_COLOR_GREEN; break; + case 3: pFont->ucFontColor = FONT_COLOR_BLUE; break; + case 4: pFont->ucFontColor = FONT_COLOR_CYAN; break; + case 5: pFont->ucFontColor = FONT_COLOR_MAGENTA; break; + case 6: pFont->ucFontColor = FONT_COLOR_YELLOW; break; + case 7: pFont->ucFontColor = FONT_COLOR_WHITE; break; + default:pFont->ucFontColor = FONT_COLOR_BLACK; break; + } + NO_DBG_DEC(pFont->ucFontColor); +} /* end of vGet0FontInfo */ + +/* + * Build the lists with Character Information for Word for DOS files + */ +void +vGet0ChrInfo(FILE *pFile, const UCHAR *aucHeader) +{ + font_block_type tFont; + ULONG ulBeginCharInfo, ulCharPos, ulCharPosNext; + int iIndex, iRun, iFodo; + UCHAR aucFpage[128]; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginCharInfo = ulGetLong(0x0e, aucHeader); + NO_DBG_HEX(ulBeginCharInfo); + ulBeginCharInfo = ROUND128(ulBeginCharInfo); + NO_DBG_HEX(ulBeginCharInfo); + + do { + if (!bReadBytes(aucFpage, 128, ulBeginCharInfo, pFile)) { + return; + } + NO_DBG_PRINT_BLOCK(aucFpage, 128); + ulCharPosNext = ulGetLong(0, aucFpage); + iRun = (int)ucGetByte(0x7f, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex = 0; iIndex < iRun; iIndex++) { + iFodo = (int)usGetWord(6 * iIndex + 8, aucFpage); + if (iFodo <= 0 || iFodo > 0x79) { + DBG_DEC_C(iFodo != (int)0xffff, iFodo); + continue; + } + vFillFontFromStylesheet(0, &tFont); + vGet0FontInfo(iFodo, aucFpage + 4, &tFont); + ulCharPos = ulCharPosNext; + ulCharPosNext = ulGetLong(6 * iIndex + 4, aucFpage); + tFont.ulFileOffset = ulCharPos; + vAdd2FontInfoList(&tFont); + } + ulBeginCharInfo += 128; + } while (ulCharPosNext == ulBeginCharInfo); +} /* end of vGet0ChrInfo */ diff --git a/prop2.c b/prop2.c new file mode 100644 index 0000000..eda108a --- /dev/null +++ b/prop2.c @@ -0,0 +1,1067 @@ +/* + * prop2.c + * Copyright (C) 2002-2005 A.J. van Os; Released under GPL + * + * Description: + * Read the property information from a WinWord 1 or 2 file + */ + +#include +#include "antiword.h" + + +#define MAX_FILESIZE 0x2000000UL /* 32 Mb */ + +/* + * iGet2InfoLength - the length of the information for WinWord 1/2 files + */ +static int +iGet2InfoLength(int iByteNbr, const UCHAR *aucGrpprl) +{ + int iTmp, iDel, iAdd; + + switch (ucGetByte(iByteNbr, aucGrpprl)) { + case 3: case 15: case 78: case 152: case 154: case 155: + return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl); + case 16: case 17: case 18: case 19: case 21: case 22: case 26: + case 27: case 28: case 30: case 31: case 32: case 33: case 34: + case 35: case 36: case 38: case 39: case 40: case 41: case 42: + case 43: case 45: case 46: case 47: case 48: case 49: case 68: + case 71: case 72: case 82: case 83: case 96: case 97: case 98: + case 99: case 115: case 116: case 119: case 120: case 123: case 124: + case 129: case 130: case 131: case 132: case 135: case 136: case 139: + case 140: case 141: case 142: case 143: case 144: case 145: case 146: + case 147: case 148: case 153: case 159: case 161: case 162: + return 1 + 2; + case 23: + iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl); + if (iTmp == 255) { + iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl); + iAdd = (int)ucGetByte( + iByteNbr + 3 + iDel * 4, aucGrpprl); + iTmp = 2 + iDel * 4 + iAdd * 3; + } + return 2 + iTmp; + case 70: + return 1 + 3; + case 95: + return 1 + 13; + case 157: case 163: + return 1 + 5; + case 158: case 160: case 164: + return 1 + 4; + default: + return 1 + 1; + } +} /* end of iGet2InfoLength */ + +/* + * Build the lists with Document Property Information for WinWord 1/2 files + */ +void +vGet2DopInfo(FILE *pFile, const UCHAR *aucHeader) +{ + document_block_type tDocument; + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo, ulTmp; + size_t tDocpInfoLen; + USHORT usTmp; + + ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 28) { + DBG_MSG("No Document information"); + return; + } + + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + + usTmp = usGetWord(0x00, aucBuffer); + tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ + tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ + ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ + tDocument.tCreateDate = tConvertDTTM(ulTmp); + ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ + tDocument.tRevisedDate = tConvertDTTM(ulTmp); + vCreateDocumentInfoList(&tDocument); + + aucBuffer = xfree(aucBuffer); +} /* end of vGet2DopInfo */ + +/* + * Fill the section information block with information + * from a WinWord 1/2 file. + */ +static void +vGet2SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, + section_block_type *pSection) +{ + int iFodoOff, iInfoLen; + USHORT usCcol; + UCHAR ucTmp; + + fail(aucGrpprl == NULL || pSection == NULL); + + iFodoOff = 0; + while (tBytes >= (size_t)iFodoOff + 1) { + switch (ucGetByte(iFodoOff, aucGrpprl)) { + case 117: /* bkc */ + ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl); + DBG_DEC(ucTmp); + pSection->bNewPage = ucTmp != 0 && ucTmp != 1; + break; + case 119: /* ccolM1 */ + usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl); + DBG_DEC(usCcol); + break; + case 128: /* grpfIhdt */ + pSection->ucHdrFtrSpecification = + ucGetByte(iFodoOff + 1, aucGrpprl); + break; + default: + break; + } + iInfoLen = iGet2InfoLength(iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + iFodoOff += iInfoLen; + } +} /* end of vGet2SectionInfo */ + +/* + * Build the lists with Section Property Information for WinWord 1/2 files + */ +void +vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader) +{ + section_block_type tSection; + ULONG *aulSectPage, *aulCharPos; + UCHAR *aucBuffer, *aucFpage; + ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; + size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; + UCHAR aucTmp[1]; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginSectInfo = ulGetLong(0x7c, aucHeader); /* fcPlcfsed */ + DBG_HEX(ulBeginSectInfo); + tSectInfoLen = (size_t)usGetWord(0x80, aucHeader); /* cbPlcfsed */ + DBG_DEC(tSectInfoLen); + if (tSectInfoLen < 4) { + DBG_DEC(tSectInfoLen); + return; + } + + aucBuffer = xmalloc(tSectInfoLen); + if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); + + /* Read the Section Descriptors */ + tLen = (tSectInfoLen - 4) / 10; + /* Save the section offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; + tIndex < tLen; + tIndex++, tOffset += 4) { + ulTextOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulTextOffset); + aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; + NO_DBG_HEX(aulCharPos[tIndex]); + } + /* Save the Sepx offsets */ + aulSectPage = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = (tLen + 1) * 4; + tIndex < tLen; + tIndex++, tOffset += 6) { + aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); + NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ + } + aucBuffer = xfree(aucBuffer); + + /* Read the Section Properties */ + for (tIndex = 0; tIndex < tLen; tIndex++) { + if (aulSectPage[tIndex] == FC_INVALID) { + vDefault2SectionInfoList(aulCharPos[tIndex]); + continue; + } + /* Get the number of bytes to read */ + if (!bReadBytes(aucTmp, 1, aulSectPage[tIndex], pFile)) { + continue; + } + tBytes = 1 + (size_t)ucGetByte(0, aucTmp); + NO_DBG_DEC(tBytes); + /* Read the bytes */ + aucFpage = xmalloc(tBytes); + if (!bReadBytes(aucFpage, tBytes, aulSectPage[tIndex], pFile)) { + aucFpage = xfree(aucFpage); + continue; + } + NO_DBG_PRINT_BLOCK(aucFpage, tBytes); + /* Process the bytes */ + vGetDefaultSection(&tSection); + vGet2SectionInfo(aucFpage + 1, tBytes - 1, &tSection); + vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); + aucFpage = xfree(aucFpage); + } + aulCharPos = xfree(aulCharPos); + aulSectPage = xfree(aulSectPage); +} /* end of vGet2SepInfo */ + +/* + * Build the list with Header/Footer Information for WinWord 1/2 files + */ +void +vGet2HdrFtrInfo(FILE *pFile, const UCHAR *aucHeader) +{ + ULONG *aulCharPos; + UCHAR *aucBuffer; + ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; + size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginHdrFtrInfo = ulGetLong(0x9a, aucHeader); /* fcPlcfhdd */ + NO_DBG_HEX(ulBeginHdrFtrInfo); + tHdrFtrInfoLen = (size_t)usGetWord(0x9e, aucHeader); /* cbPlcfhdd */ + NO_DBG_DEC(tHdrFtrInfoLen); + if (tHdrFtrInfoLen < 8) { + DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); + return; + } + + aucBuffer = xmalloc(tHdrFtrInfoLen); + if (!bReadBytes(aucBuffer, tHdrFtrInfoLen, ulBeginHdrFtrInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); + + tLen = tHdrFtrInfoLen / 4 - 1; + /* Save the header/footer offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; + tIndex < tLen; + tIndex++, tOffset += 4) { + ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulHdrFtrOffset); + aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); + NO_DBG_HEX(aulCharPos[tIndex]); + } + vCreat2HdrFtrInfoList(aulCharPos, tLen); + aulCharPos = xfree(aulCharPos); + aucBuffer = xfree(aucBuffer); +} /* end of vGet2HdrFtrInfo */ + +/* + * Translate the rowinfo to a member of the row_info enumeration + */ +row_info_enum +eGet2RowInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) +{ + int iFodoOff, iInfoLen; + int iIndex, iSize, iCol; + int iPosCurr, iPosPrev; + USHORT usTmp; + BOOL bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound154; + + fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL); + + iFodoOff = 0; + bFound24_0 = FALSE; + bFound24_1 = FALSE; + bFound25_0 = FALSE; + bFound25_1 = FALSE; + bFound154 = FALSE; + while (iBytes >= iFodoOff + 1) { + iInfoLen = 0; + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 24: /* fIntable */ + if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { + bFound24_1 = TRUE; + } else { + bFound24_0 = TRUE; + } + break; + case 25: /* fTtp */ + if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { + bFound25_1 = TRUE; + } else { + bFound25_0 = TRUE; + } + break; + case 30: /* brcTop10 */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x01ff; + NO_DBG_DEC(usTmp >> 6); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_TOP; + } + break; + case 31: /* brcLeft10 */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x01ff; + NO_DBG_DEC(usTmp >> 6); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_LEFT; + } + break; + case 32: /* brcBottom10 */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x01ff; + NO_DBG_DEC(usTmp >> 6); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; + } + break; + case 33: /* brcRight10 */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x01ff; + NO_DBG_DEC(usTmp >> 6); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; + } + break; + case 38: /* brcTop */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_TOP; + } + break; + case 39: /* brcLeft */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_LEFT; + } + break; + case 40: /* brcBottom */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; + } + break; + case 41: /* brcRight */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; + } + break; + case 152: /* cDefTable10 */ + case 154: /* cDefTable */ + iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + if (iSize < 6 || iBytes < iFodoOff + 7) { + DBG_DEC(iSize); + DBG_DEC(iBytes); + DBG_DEC(iFodoOff); + iInfoLen = 1; + break; + } + iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); + if (iCol < 1 || + iBytes < iFodoOff + 3 + (iCol + 1) * 2) { + DBG_DEC(iCol); + DBG_DEC(iBytes); + DBG_DEC(iFodoOff); + DBG_DEC(ucGetByte(iFodo + iFodoOff, aucGrpprl)); + iInfoLen = 1; + break; + } + if (iCol >= (int)elementsof(pRow->asColumnWidth)) { + DBG_DEC(iCol); + werr(1, "The number of columns is corrupt"); + } + pRow->ucNumberOfColumns = (UCHAR)iCol; + iPosPrev = (int)(short)usGetWord( + iFodo + iFodoOff + 4, + aucGrpprl); + for (iIndex = 0; iIndex < iCol; iIndex++) { + iPosCurr = (int)(short)usGetWord( + iFodo + iFodoOff + 6 + iIndex * 2, + aucGrpprl); + pRow->asColumnWidth[iIndex] = + (short)(iPosCurr - iPosPrev); + iPosPrev = iPosCurr; + } + bFound154 = TRUE; + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet2InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } + if (bFound24_1 && bFound25_1 && bFound154) { + return found_end_of_row; + } + if (bFound24_0 && bFound25_0 && !bFound154) { + return found_not_end_of_row; + } + if (bFound24_1) { + return found_a_cell; + } + if (bFound24_0) { + return found_not_a_cell; + } + return found_nothing; +} /* end of eGet2RowInfo */ + +/* + * Fill the style information block with information + * from a WinWord 1/2 file. + */ +void +vGet2StyleInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) +{ + int iFodoOff, iInfoLen; + int iTmp, iDel, iAdd; + short sTmp; + UCHAR ucTmp; + + fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); + + NO_DBG_DEC(pStyle->usIstd); + + iFodoOff = 0; + while (iBytes >= iFodoOff + 1) { + iInfoLen = 0; + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 2: /* istd */ + sTmp = (short)ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(sTmp); + break; + case 5: /* jc */ + pStyle->ucAlignment = ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + break; + case 12: /* nfcSeqNumb */ + pStyle->ucNFC = ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + break; + case 13: /* nLvlAnm */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + pStyle->ucNumLevel = ucTmp; + pStyle->bNumPause = + eGetNumType(ucTmp) == level_type_pause; + break; + case 15: /* ChgTabsPapx */ + case 23: /* ChgTabs */ + iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (iTmp < 2) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iTmp); + iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (iTmp < 2 + 2 * iDel) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iDel); + iAdd = (int)ucGetByte( + iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl); + if (iTmp < 2 + 2 * iDel + 2 * iAdd) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iAdd); + break; + case 16: /* dxaRight */ + pStyle->sRightIndent = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sRightIndent); + break; + case 17: /* dxaLeft */ + pStyle->sLeftIndent = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent); + break; + case 18: /* Nest dxaLeft */ + sTmp = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + pStyle->sLeftIndent += sTmp; + if (pStyle->sLeftIndent < 0) { + pStyle->sLeftIndent = 0; + } + NO_DBG_DEC(sTmp); + NO_DBG_DEC(pStyle->sLeftIndent); + break; + case 19: /* dxaLeft1 */ + pStyle->sLeftIndent1 = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent1); + break; + case 21: /* dyaBefore */ + pStyle->usBeforeIndent = usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->usBeforeIndent); + break; + case 22: /* dyaAfter */ + pStyle->usAfterIndent = usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->usAfterIndent); + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet2InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } +} /* end of vGet2StyleInfo */ + +/* + * Build the lists with Paragraph Information for WinWord 1/2 files + */ +void +vGet2PapInfo(FILE *pFile, const UCHAR *aucHeader) +{ + row_block_type tRow; + style_block_type tStyle; + USHORT *ausParfPage; + UCHAR *aucBuffer; + ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; + ULONG ulBeginParfInfo; + size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen; + int iIndex, iIndex2, iRun, iFodo, iLen; + row_info_enum eRowInfo; + USHORT usParfFirstPage, usCount, usIstd; + UCHAR ucStc; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginParfInfo = ulGetLong(0xa6, aucHeader); /* fcPlcfbtePapx */ + NO_DBG_HEX(ulBeginParfInfo); + tParfInfoLen = (size_t)usGetWord(0xaa, aucHeader); /* cbPlcfbtePapx */ + NO_DBG_DEC(tParfInfoLen); + if (tParfInfoLen < 4) { + DBG_DEC(tParfInfoLen); + return; + } + + aucBuffer = xmalloc(tParfInfoLen); + if (!bReadBytes(aucBuffer, tParfInfoLen, ulBeginParfInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); + + tLen = (tParfInfoLen - 4) / 6; + ausParfPage = xcalloc(tLen, sizeof(USHORT)); + for (iIndex = 0, tOffset = (tLen + 1) * 4; + iIndex < (int)tLen; + iIndex++, tOffset += 2) { + ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(ausParfPage[iIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + tParfPageNum = (size_t)usGetWord(0x144, aucHeader); /* cpnBtePap */ + DBG_DEC(tParfPageNum); + if (tLen < tParfPageNum) { + /* Replace ParfPage by a longer version */ + tLenOld = tLen; + usParfFirstPage = usGetWord(0x140, aucHeader); /* pnPapFirst */ + DBG_DEC(usParfFirstPage); + tLen += tParfPageNum - 1; + tSize = tLen * sizeof(USHORT); + ausParfPage = xrealloc(ausParfPage, tSize); + /* Add new values */ + usCount = usParfFirstPage + 1; + for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) { + ausParfPage[iIndex] = usCount; + NO_DBG_DEC(ausParfPage[iIndex]); + usCount++; + } + } + + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + for (iIndex = 0; iIndex < (int)tLen; iIndex++) { + if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE, + (ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE, + pFile)) { + break; + } + NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); + iRun = (int)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { + if ((iRun + 1) * 4 + iIndex2 * 1 >= BIG_BLOCK_SIZE) { + break; + } + NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); + iFodo = 2 * (int)ucGetByte( + (iRun + 1) * 4 + iIndex2 * 1, aucFpage); + if (iFodo <= 0) { + continue; + } + + iLen = 2 * (int)ucGetByte(iFodo, aucFpage); + + ucStc = ucGetByte(iFodo + 1, aucFpage); + usIstd = usStc2istd(ucStc); + + vFillStyleFromStylesheet(usIstd, &tStyle); + vGet2StyleInfo(iFodo, aucFpage + 8, iLen - 8, &tStyle); + ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPos); + tStyle.ulFileOffset = ulCharPos; + vAdd2StyleInfoList(&tStyle); + + eRowInfo = eGet2RowInfo(iFodo, + aucFpage + 8, iLen - 8, &tRow); + + switch(eRowInfo) { + case found_a_cell: + if (ulCharPosFirst != CP_INVALID) { + break; + } + ulCharPosFirst = ulGetLong( + iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosFirst); + tRow.ulCharPosStart = ulCharPosFirst; + tRow.ulFileOffsetStart = ulCharPosFirst; + break; + case found_end_of_row: + ulCharPosLast = ulGetLong( + iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosLast); + tRow.ulCharPosEnd = ulCharPosLast; + /* Add 1 for compatiblity with Word 6 and up */ + tRow.ulFileOffsetEnd = ulCharPosLast + 1; + vAdd2RowInfoList(&tRow); + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + break; + case found_nothing: + break; + default: + DBG_DEC(eRowInfo); + break; + } + } + } + ausParfPage = xfree(ausParfPage); +} /* end of vGet2PapInfo */ + +/* + * Fill the font information block with information + * from a WinWord 1 file. + */ +void +vGet1FontInfo(int iFodo, + const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont) +{ + BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange; + USHORT usTmp; + UCHAR ucTmp; + UCHAR aucChpx[12]; + + fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); + + if (tBytes > sizeof(aucChpx)) { + NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); + return; + } + + /* Build the CHPX structure */ + (void)memset(aucChpx, 0, sizeof(aucChpx)); + (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); + + usTmp = usGetWord(0, aucChpx); + if ((usTmp & BIT(0)) != 0) { + pFont->usFontStyle ^= FONT_BOLD; + } + if ((usTmp & BIT(1)) != 0) { + pFont->usFontStyle ^= FONT_ITALIC; + } + if ((usTmp & BIT(2)) != 0) { + pFont->usFontStyle ^= FONT_STRIKE; + } + if ((usTmp & BIT(5)) != 0) { + pFont->usFontStyle ^= FONT_SMALL_CAPITALS; + } + if ((usTmp & BIT(6)) != 0) { + pFont->usFontStyle ^= FONT_CAPITALS; + } + if ((usTmp & BIT(7)) != 0) { + pFont->usFontStyle ^= FONT_HIDDEN; + } + + ucTmp = ucGetByte(5, aucChpx); + if (ucTmp != 0) { + if (ucTmp < 128) { + pFont->usFontStyle |= FONT_SUPERSCRIPT; + DBG_MSG("Superscript"); + } else { + pFont->usFontStyle |= FONT_SUBSCRIPT; + DBG_MSG("Subscript"); + } + } + + bIcoChange = (usTmp & BIT(10)) != 0; + bFtcChange = (usTmp & BIT(11)) != 0; + bHpsChange = (usTmp & BIT(12)) != 0; + bKulChange = (usTmp & BIT(13)) != 0; + + if (bFtcChange) { + usTmp = usGetWord(2, aucChpx); + if (usTmp <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usTmp; + } else { + pFont->ucFontNumber = 0; + } + } + + if (bHpsChange) { + pFont->usFontSize = (USHORT)ucGetByte(4, aucChpx); + } + + if (bIcoChange || bKulChange) { + usTmp = usGetWord(6, aucChpx); + if (bIcoChange) { + pFont->ucFontColor = (UCHAR)((usTmp & 0x0f00) >> 8); + if (pFont->ucFontColor <= 7) { + /* Add 1 for compatibility with Word 2 and up */ + pFont->ucFontColor++; + } else { + DBG_DEC(pFont->ucFontColor); + pFont->ucFontColor = 0; + } + } + if (bKulChange) { + usTmp = (usTmp & 0x7000) >> 12; + DBG_DEC_C(usTmp > 4, usTmp); + if (usTmp == 0) { + pFont->usFontStyle &= ~FONT_UNDERLINE; + } else { + pFont->usFontStyle |= FONT_UNDERLINE; + } + } + } +} /* end of vGet1FontInfo */ + +/* + * Fill the font information block with information + * from a WinWord 1/2 file. + */ +void +vGet2FontInfo(int iFodo, + const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont) +{ + BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange; + USHORT usTmp; + UCHAR ucTmp; + UCHAR aucChpx[18]; + + fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); + + if (tBytes > sizeof(aucChpx)) { + NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); + return; + } + + /* Build the CHPX structure */ + (void)memset(aucChpx, 0, sizeof(aucChpx)); + (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); + + usTmp = usGetWord(0, aucChpx); + if ((usTmp & BIT(0)) != 0) { + pFont->usFontStyle ^= FONT_BOLD; + } + if ((usTmp & BIT(1)) != 0) { + pFont->usFontStyle ^= FONT_ITALIC; + } + if (usTmp & BIT(3)) { + pFont->usFontStyle ^= FONT_MARKDEL; + } + if ((usTmp & BIT(5)) != 0) { + pFont->usFontStyle ^= FONT_SMALL_CAPITALS; + } + if ((usTmp & BIT(6)) != 0) { + pFont->usFontStyle ^= FONT_CAPITALS; + } + if ((usTmp & BIT(7)) != 0) { + pFont->usFontStyle ^= FONT_HIDDEN; + } + if (usTmp & BIT(10)) { + pFont->usFontStyle ^= FONT_STRIKE; + } + + ucTmp = ucGetByte(10, aucChpx); + DBG_MSG_C(ucTmp != 0 && ucTmp < 128, "Superscript"); + DBG_MSG_C(ucTmp >= 128, "Subscript"); + + usTmp = usGetWord(2, aucChpx); + if (usTmp == 0) { + /* No changes, nothing to do */ + return; + } + + bIcoChange = (usTmp & BIT(0)) != 0; + bFtcChange = (usTmp & BIT(1)) != 0; + bHpsChange = (usTmp & BIT(2)) != 0; + bKulChange = (usTmp & BIT(3)) != 0; + + if (bFtcChange) { + usTmp = usGetWord(4, aucChpx); + if (usTmp <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usTmp; + } else { + pFont->ucFontNumber = 0; + } + } + + if (bHpsChange) { + pFont->usFontSize = usGetWord(6, aucChpx); + } + + if (bIcoChange || bKulChange) { + ucTmp = ucGetByte(9, aucChpx); + if (bIcoChange) { + pFont->ucFontColor = ucTmp & 0x1f; + if (pFont->ucFontColor > 16) { + DBG_DEC(pFont->ucFontColor); + pFont->ucFontColor = 0; + } + } + if (bKulChange) { + ucTmp = (ucTmp & 0xe0) >> 5; + DBG_DEC_C(ucTmp > 4, ucTmp); + if (ucTmp == 0) { + pFont->usFontStyle &= ~FONT_UNDERLINE; + } else { + pFont->usFontStyle |= FONT_UNDERLINE; + } + } + } +} /* end of vGet2FontInfo */ + +/* + * Fill the picture information block with information from a WinWord 1 file. + * Returns TRUE when successful, otherwise FALSE + */ +static BOOL +bGet1PicInfo(int iFodo, + const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture) +{ + ULONG ulTmp; + UCHAR aucChpx[12]; + + fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL); + + if (tBytes > sizeof(aucChpx)) { + NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); + tBytes = sizeof(aucChpx); + } + + /* Build the CHPX structure */ + (void)memset(aucChpx, 0, sizeof(aucChpx)); + (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); + + ulTmp = ulGetLong(8, aucChpx); + if (ulTmp != 0 && ulTmp < MAX_FILESIZE) { + pPicture->ulPictureOffset = ulTmp; + DBG_HEX(pPicture->ulPictureOffset); + return TRUE; + } + return FALSE; +} /* end of bGet1PicInfo */ + +/* + * Fill the picture information block with information from a WinWord 2 file. + * Returns TRUE when successful, otherwise FALSE + */ +static BOOL +bGet2PicInfo(int iFodo, + const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture) +{ + ULONG ulTmp; + UCHAR aucChpx[18]; + + fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL); + + if (tBytes > sizeof(aucChpx)) { + NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); + tBytes = sizeof(aucChpx); + } + + /* Build the CHPX structure */ + (void)memset(aucChpx, 0, sizeof(aucChpx)); + (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); + + ulTmp = ulGetLong(14, aucChpx); + if (ulTmp != 0 && ulTmp < MAX_FILESIZE) { + pPicture->ulPictureOffset = ulTmp; + DBG_HEX(pPicture->ulPictureOffset); + DBG_DEC(tBytes); + return TRUE; + } + return FALSE; +} /* end of bGet2PicInfo */ + +/* + * Build the lists with Character Information for WinWord 1/2 files + */ +void +vGet2ChrInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +{ + font_block_type tFont; + picture_block_type tPicture; + USHORT *ausCharPage; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; + size_t tCharInfoLen, tOffset, tSize, tChrLen, tCharPageNum; + size_t tLenOld, tLen; + int iIndex, iIndex2, iRun, iFodo; + BOOL bSuccess1, bSuccess2; + USHORT usCharFirstPage, usCount, usIstd; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || aucHeader == NULL); + fail(iWordVersion != 1 && iWordVersion != 2); + + ulBeginCharInfo = ulGetLong(0xa0, aucHeader); /* fcPlcfbteChpx */ + DBG_HEX(ulBeginCharInfo); + tCharInfoLen = (size_t)usGetWord(0xa4, aucHeader); /* cbPlcfbteChpx */ + DBG_DEC(tCharInfoLen); + if (tCharInfoLen < 4) { + DBG_DEC(tCharInfoLen); + return; + } + + aucBuffer = xmalloc(tCharInfoLen); + if (!bReadBytes(aucBuffer, tCharInfoLen, ulBeginCharInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); + + tLen = (tCharInfoLen - 4) / 6; + ausCharPage = xcalloc(tLen, sizeof(USHORT)); + for (iIndex = 0, tOffset = (tLen + 1) * 4; + iIndex < (int)tLen; + iIndex++, tOffset += 2) { + ausCharPage[iIndex] = usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(ausCharPage[iIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + tCharPageNum = (size_t)usGetWord(0x142, aucHeader); /* cpnBteChp */ + DBG_DEC(tCharPageNum); + if (tLen < tCharPageNum) { + /* Replace CharPage by a longer version */ + tLenOld = tLen; + usCharFirstPage = usGetWord(0x13e, aucHeader); /* pnChrFirst */ + NO_DBG_DEC(usCharFirstPage); + tLen += tCharPageNum - 1; + tSize = tLen * sizeof(USHORT); + ausCharPage = xrealloc(ausCharPage, tSize); + /* Add new values */ + usCount = usCharFirstPage + 1; + for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) { + ausCharPage[iIndex] = usCount; + NO_DBG_DEC(ausCharPage[iIndex]); + usCount++; + } + } + + for (iIndex = 0; iIndex < (int)tLen; iIndex++) { + if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE, + (ULONG)ausCharPage[iIndex] * BIG_BLOCK_SIZE, + pFile)) { + break; + } + NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); + iRun = (int)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { + if ((iRun + 1) * 4 + iIndex2 >= BIG_BLOCK_SIZE) { + break; + } + ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); + ulFileOffset = ulCharPos; + iFodo = 2 * (int)ucGetByte( + (iRun + 1) * 4 + iIndex2, aucFpage); + + tChrLen = (size_t)ucGetByte(iFodo, aucFpage); + + usIstd = usGetIstd(ulFileOffset); + vFillFontFromStylesheet(usIstd, &tFont); + if (iFodo != 0) { + if (iWordVersion == 1) { + vGet1FontInfo(iFodo, + aucFpage + 1, tChrLen, &tFont); + } else if (iWordVersion == 2) { + vGet2FontInfo(iFodo, + aucFpage + 1, tChrLen, &tFont); + } + } + tFont.ulFileOffset = ulFileOffset; + vAdd2FontInfoList(&tFont); + + if (iFodo <= 0) { + continue; + } + + (void)memset(&tPicture, 0, sizeof(tPicture)); + bSuccess1 = iWordVersion == 1 && + bGet1PicInfo(iFodo, aucFpage + 1, + tChrLen, &tPicture); + bSuccess2 = iWordVersion == 2 && + bGet2PicInfo(iFodo, aucFpage + 1, + tChrLen, &tPicture); + if (bSuccess1 || bSuccess2) { + tPicture.ulFileOffset = ulFileOffset; + tPicture.ulFileOffsetPicture = + tPicture.ulPictureOffset; + vAdd2PictInfoList(&tPicture); + } + } + } + ausCharPage = xfree(ausCharPage); +} /* end of vGet2ChrInfo */ diff --git a/prop6.c b/prop6.c new file mode 100644 index 0000000..e4c468d --- /dev/null +++ b/prop6.c @@ -0,0 +1,1141 @@ +/* + * prop6.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GPL + * + * Description: + * Read the property information from a MS Word 6 or 7 file + */ + +#include +#include +#include "antiword.h" + + +/* + * iGet6InfoLength - the length of the information for Word 6/7 files + */ +static int +iGet6InfoLength(int iByteNbr, const UCHAR *aucGrpprl) +{ + int iTmp, iDel, iAdd; + + switch (ucGetByte(iByteNbr, aucGrpprl)) { + case 2: case 16: case 17: case 18: case 19: case 21: case 22: + case 26: case 27: case 28: case 30: case 31: case 32: case 33: + case 34: case 35: case 36: case 38: case 39: case 40: case 41: + case 42: case 43: case 45: case 46: case 47: case 48: case 49: + case 69: case 72: case 80: case 93: case 96: case 97: case 99: + case 101: case 105: case 106: case 107: case 109: case 110: case 121: + case 122: case 123: case 124: case 140: case 141: case 144: case 145: + case 148: case 149: case 154: case 155: case 156: case 157: case 160: + case 161: case 164: case 165: case 166: case 167: case 168: case 169: + case 170: case 171: case 182: case 183: case 184: case 189: case 195: + case 197: case 198: + return 1 + 2; + case 3: case 12: case 15: case 81: case 103: case 108: case 188: + case 190: case 191: + return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl); + case 20: case 70: case 74: case 192: case 194: case 196: case 200: + return 1 + 4; + case 23: + iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl); + if (iTmp == 255) { + iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl); + iAdd = (int)ucGetByte( + iByteNbr + 3 + iDel * 4, aucGrpprl); + iTmp = 2 + iDel * 4 + iAdd * 3; + } + return 2 + iTmp; + case 68: case 193: case 199: + return 1 + 5; + case 73: case 95: case 136: case 137: + return 1 + 3; + case 120: case 187: + return 1 + 12; + default: + return 1 + 1; + } +} /* end of iGet6InfoLength */ + +/* + * Build the lists with Document Property Information for Word 6/7 files + */ +void +vGet6DopInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + document_block_type tDocument; + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo, ulTmp; + size_t tDocpInfoLen; + USHORT usTmp; + + ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 28) { + DBG_MSG("No Document information"); + return; + } + + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + + usTmp = usGetWord(0x00, aucBuffer); + tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ + tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ + ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ + tDocument.tCreateDate = tConvertDTTM(ulTmp); + ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ + tDocument.tRevisedDate = tConvertDTTM(ulTmp); + vCreateDocumentInfoList(&tDocument); + + aucBuffer = xfree(aucBuffer); +} /* end of vGet6DopInfo */ + +/* + * Fill the section information block with information + * from a Word 6/7 file. + */ +static void +vGet6SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, + section_block_type *pSection) +{ + UINT uiIndex; + int iFodoOff, iInfoLen, iSize, iTmp; + USHORT usCcol; + UCHAR ucTmp; + + fail(aucGrpprl == NULL || pSection == NULL); + + iFodoOff = 0; + while (tBytes >= (size_t)iFodoOff + 1) { + iInfoLen = 0; + switch (ucGetByte(iFodoOff, aucGrpprl)) { + case 133: /* olstAnm */ + iSize = (int)ucGetByte(iFodoOff + 1, aucGrpprl); + DBG_DEC_C(iSize != 212, iSize); + for (uiIndex = 0, iTmp = iFodoOff + 2; + uiIndex < 9 && iTmp < iFodoOff + 2 + iSize - 15; + uiIndex++, iTmp += 16) { + pSection->aucNFC[uiIndex] = + ucGetByte(iTmp, aucGrpprl); + NO_DBG_DEC(pSection->aucNFC[uiIndex]); + ucTmp = ucGetByte(iTmp + 3, aucGrpprl); + NO_DBG_HEX(ucTmp); + if ((ucTmp & BIT(2)) != 0) { + pSection->usNeedPrevLvl |= + (USHORT)BIT(uiIndex); + } + if ((ucTmp & BIT(3)) != 0) { + pSection->usHangingIndent |= + (USHORT)BIT(uiIndex); + } + } + DBG_HEX(pSection->usNeedPrevLvl); + DBG_HEX(pSection->usHangingIndent); + break; + case 142: /* bkc */ + ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl); + DBG_DEC(ucTmp); + pSection->bNewPage = ucTmp != 0 && ucTmp != 1; + break; + case 144: /* ccolM1 */ + usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl); + DBG_DEC(usCcol); + break; + case 153: /* grpfIhdt */ + pSection->ucHdrFtrSpecification = + ucGetByte(iFodoOff + 1, aucGrpprl); + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = iGet6InfoLength(iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } +} /* end of vGet6SectionInfo */ + +/* + * Build the lists with Section Property Information for Word 6/7 files + */ +void +vGet6SepInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + section_block_type tSection; + ULONG *aulSectPage, *aulCharPos; + UCHAR *aucBuffer, *aucFpage; + ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; + size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; + UCHAR aucTmp[2]; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginSectInfo = ulGetLong(0x88, aucHeader); /* fcPlcfsed */ + DBG_HEX(ulBeginSectInfo); + tSectInfoLen = (size_t)ulGetLong(0x8c, aucHeader); /* lcbPlcfsed */ + DBG_DEC(tSectInfoLen); + if (tSectInfoLen < 4) { + DBG_DEC(tSectInfoLen); + return; + } + + aucBuffer = xmalloc(tSectInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginSectInfo, tSectInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); + + /* Read the Section Descriptors */ + tLen = (tSectInfoLen - 4) / 16; + /* Save the section offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) { + ulTextOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulTextOffset); + aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; + NO_DBG_HEX(aulCharPos[tIndex]); + } + /* Save the Sepx offsets */ + aulSectPage = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = (tLen + 1) * 4; + tIndex < tLen; + tIndex++, tOffset += 12) { + aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); + NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ + } + aucBuffer = xfree(aucBuffer); + + /* Read the Section Properties */ + for (tIndex = 0; tIndex < tLen; tIndex++) { + if (aulSectPage[tIndex] == FC_INVALID) { + vDefault2SectionInfoList(aulCharPos[tIndex]); + continue; + } + /* Get the number of bytes to read */ + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucTmp, aulSectPage[tIndex], 2)) { + continue; + } + tBytes = 2 + (size_t)usGetWord(0, aucTmp); + NO_DBG_DEC(tBytes); + /* Read the bytes */ + aucFpage = xmalloc(tBytes); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, aulSectPage[tIndex], tBytes)) { + aucFpage = xfree(aucFpage); + continue; + } + NO_DBG_PRINT_BLOCK(aucFpage, tBytes); + /* Process the bytes */ + vGetDefaultSection(&tSection); + vGet6SectionInfo(aucFpage + 2, tBytes - 2, &tSection); + vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); + aucFpage = xfree(aucFpage); + } + aulCharPos = xfree(aulCharPos); + aulSectPage = xfree(aulSectPage); +} /* end of vGet6SepInfo */ + +/* + * Build the list with Header/Footer Information for Word 6/7 files + */ +void +vGet6HdrFtrInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + ULONG *aulCharPos; + UCHAR *aucBuffer; + ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; + size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginHdrFtrInfo = ulGetLong(0xb0, aucHeader); /* fcPlcfhdd */ + NO_DBG_HEX(ulBeginHdrFtrInfo); + tHdrFtrInfoLen = (size_t)ulGetLong(0xb4, aucHeader); /* lcbPlcfhdd */ + NO_DBG_DEC(tHdrFtrInfoLen); + if (tHdrFtrInfoLen < 8) { + DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); + return; + } + + aucBuffer = xmalloc(tHdrFtrInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginHdrFtrInfo, tHdrFtrInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); + + tLen = tHdrFtrInfoLen / 4 - 1; + /* Save the header/footer offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; + tIndex < tLen; + tIndex++, tOffset += 4) { + ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulHdrFtrOffset); + aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); + NO_DBG_HEX(aulCharPos[tIndex]); + } + vCreat6HdrFtrInfoList(aulCharPos, tLen); + aulCharPos = xfree(aulCharPos); + aucBuffer = xfree(aucBuffer); +} /* end of vGet6HdrFtrInfo */ + +/* + * Translate the rowinfo to a member of the row_info enumeration + */ +row_info_enum +eGet6RowInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) +{ + int iFodoOff, iInfoLen; + int iIndex, iSize, iCol; + int iPosCurr, iPosPrev; + USHORT usTmp; + BOOL bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound190; + + fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL); + + iFodoOff = 0; + bFound24_0 = FALSE; + bFound24_1 = FALSE; + bFound25_0 = FALSE; + bFound25_1 = FALSE; + bFound190 = FALSE; + while (iBytes >= iFodoOff + 1) { + iInfoLen = 0; + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 24: /* fInTable */ + if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { + bFound24_1 = TRUE; + } else { + bFound24_0 = TRUE; + } + break; + case 25: /* fTtp */ + if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { + bFound25_1 = TRUE; + } else { + bFound25_0 = TRUE; + } + break; + case 38: /* brcTop */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_TOP; + } + break; + case 39: /* brcLeft */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_LEFT; + } + break; + case 40: /* brcBottom */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; + } + break; + case 41: /* brcRight */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + usTmp &= 0x0018; + NO_DBG_DEC(usTmp >> 3); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; + } + break; + case 188: /* cDefTable10 */ + DBG_MSG("188: sprmTDefTable10"); + iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + DBG_DEC(iSize); + break; + case 190: /* cDefTable */ + iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + if (iSize < 6 || iBytes < iFodoOff + 7) { + DBG_DEC(iSize); + DBG_DEC(iFodoOff); + iInfoLen = 1; + break; + } + iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); + if (iCol < 1 || + iBytes < iFodoOff + 3 + (iCol + 1) * 2) { + DBG_DEC(iCol); + DBG_DEC(iFodoOff); + iInfoLen = 1; + break; + } + if (iCol >= (int)elementsof(pRow->asColumnWidth)) { + DBG_DEC(iCol); + werr(1, "The number of columns is corrupt"); + } + pRow->ucNumberOfColumns = (UCHAR)iCol; + iPosPrev = (int)(short)usGetWord( + iFodo + iFodoOff + 4, + aucGrpprl); + for (iIndex = 0; iIndex < iCol; iIndex++) { + iPosCurr = (int)(short)usGetWord( + iFodo + iFodoOff + 6 + iIndex * 2, + aucGrpprl); + pRow->asColumnWidth[iIndex] = + (short)(iPosCurr - iPosPrev); + iPosPrev = iPosCurr; + } + bFound190 = TRUE; + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet6InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } + + if (bFound25_1 && bFound190) { + return found_end_of_row; + } + if (bFound25_0 && !bFound190) { + return found_not_end_of_row; + } + if (bFound24_1) { + return found_a_cell; + } + if (bFound24_0) { + return found_not_a_cell; + } + return found_nothing; +} /* end of eGet6RowInfo */ + +/* + * Fill the style information block with information + * from a Word 6/7 file. + */ +void +vGet6StyleInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) +{ + int iFodoOff, iInfoLen; + int iTmp, iDel, iAdd, iBefore; + short sTmp; + UCHAR ucTmp; + + fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); + + NO_DBG_DEC(pStyle->usIstd); + + iFodoOff = 0; + while (iBytes >= iFodoOff + 1) { + iInfoLen = 0; + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 2: /* istd */ + sTmp = (short)ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(sTmp); + break; + case 5: /* jc */ + pStyle->ucAlignment = ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + break; + case 12: /* anld */ + iTmp = (int)ucGetByte( + iFodo + iFodoOff + 1, aucGrpprl); + DBG_DEC_C(iTmp < 52, iTmp); + if (iTmp >= 1) { + pStyle->ucNFC = ucGetByte( + iFodo + iFodoOff + 2, aucGrpprl); + } + if (pStyle->ucNFC != LIST_BULLETS && iTmp >= 2) { + iBefore = (int)ucGetByte( + iFodo + iFodoOff + 3, aucGrpprl); + } else { + iBefore = 0; + } + if (iTmp >= 12) { + pStyle->usStartAt = usGetWord( + iFodo + iFodoOff + 12, aucGrpprl); + } + if (iTmp >= iBefore + 21) { + pStyle->usListChar = (USHORT)ucGetByte( + iFodo + iFodoOff + iBefore + 22, + aucGrpprl); + NO_DBG_HEX(pStyle->usListChar); + } + break; + case 13: /* nLvlAnm */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + pStyle->ucNumLevel = ucTmp; + pStyle->bNumPause = + eGetNumType(ucTmp) == level_type_pause; + break; + case 15: /* ChgTabsPapx */ + case 23: /* ChgTabs */ + iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (iTmp < 2) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iTmp); + iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (iTmp < 2 + 2 * iDel) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iDel); + iAdd = (int)ucGetByte( + iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl); + if (iTmp < 2 + 2 * iDel + 2 * iAdd) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iAdd); + break; + case 16: /* dxaRight */ + pStyle->sRightIndent = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sRightIndent); + break; + case 17: /* dxaLeft */ + pStyle->sLeftIndent = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent); + break; + case 18: /* Nest dxaLeft */ + sTmp = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + pStyle->sLeftIndent += sTmp; + if (pStyle->sLeftIndent < 0) { + pStyle->sLeftIndent = 0; + } + NO_DBG_DEC(sTmp); + NO_DBG_DEC(pStyle->sLeftIndent); + break; + case 19: /* dxaLeft1 */ + pStyle->sLeftIndent1 = (short)usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent1); + break; + case 21: /* dyaBefore */ + pStyle->usBeforeIndent = usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->usBeforeIndent); + break; + case 22: /* dyaAfter */ + pStyle->usAfterIndent = usGetWord( + iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(pStyle->usAfterIndent); + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet6InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } +} /* end of vGet6StyleInfo */ + +/* + * Build the lists with Paragraph Information for Word 6/7 files + */ +void +vGet6PapInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader) +{ + row_block_type tRow; + style_block_type tStyle; + USHORT *ausParfPage; + UCHAR *aucBuffer; + ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; + ULONG ulBeginParfInfo; + size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen; + size_t tIndex, tIndex2, tRun; + int iFodo, iLen; + row_info_enum eRowInfo; + USHORT usParfFirstPage, usCount, usIstd; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginParfInfo = ulGetLong(0xc0, aucHeader); /* fcPlcfbtePapx */ + NO_DBG_HEX(ulBeginParfInfo); + tParfInfoLen = (size_t)ulGetLong(0xc4, aucHeader); /* lcbPlcfbtePapx */ + NO_DBG_DEC(tParfInfoLen); + if (tParfInfoLen < 4) { + DBG_DEC(tParfInfoLen); + return; + } + + aucBuffer = xmalloc(tParfInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginParfInfo, tParfInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); + + tLen = (tParfInfoLen - 4) / 6; + ausParfPage = xcalloc(tLen, sizeof(USHORT)); + for (tIndex = 0, tOffset = (tLen + 1) * 4; + tIndex < tLen; + tIndex++, tOffset += 2) { + ausParfPage[tIndex] = usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(ausParfPage[tIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + tParfPageNum = (size_t)usGetWord(0x190, aucHeader); /* cpnBtePap */ + DBG_DEC(tParfPageNum); + if (tLen < tParfPageNum) { + /* Replace ParfPage by a longer version */ + tLenOld = tLen; + usParfFirstPage = usGetWord(0x18c, aucHeader); /* pnPapFirst */ + DBG_DEC(usParfFirstPage); + tLen += tParfPageNum - 1; + tSize = tLen * sizeof(USHORT); + ausParfPage = xrealloc(ausParfPage, tSize); + /* Add new values */ + usCount = usParfFirstPage + 1; + for (tIndex = tLenOld; tIndex < tLen; tIndex++) { + ausParfPage[tIndex] = usCount; + NO_DBG_DEC(ausParfPage[tIndex]); + usCount++; + } + } + + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + for (tIndex = 0; tIndex < tLen; tIndex++) { + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, + (ULONG)ausParfPage[tIndex] * BIG_BLOCK_SIZE, + BIG_BLOCK_SIZE)) { + break; + } + tRun = (size_t)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(tRun); + for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) { + NO_DBG_HEX(ulGetLong(tIndex2 * 4, aucFpage)); + iFodo = 2 * (int)ucGetByte( + (tRun + 1) * 4 + tIndex2 * 7, aucFpage); + if (iFodo <= 0) { + continue; + } + + iLen = 2 * (int)ucGetByte(iFodo, aucFpage); + + usIstd = (USHORT)ucGetByte(iFodo + 1, aucFpage); + vFillStyleFromStylesheet(usIstd, &tStyle); + vGet6StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); + ulCharPos = ulGetLong(tIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPos); + tStyle.ulFileOffset = ulCharPos2FileOffsetX( + ulCharPos, &tStyle.eListID); + vAdd2StyleInfoList(&tStyle); + + eRowInfo = eGet6RowInfo(iFodo, + aucFpage + 3, iLen - 3, &tRow); + switch(eRowInfo) { + case found_a_cell: + if (ulCharPosFirst != CP_INVALID) { + break; + } + ulCharPosFirst = ulGetLong( + tIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosFirst); + tRow.ulCharPosStart = ulCharPosFirst; + tRow.ulFileOffsetStart = + ulCharPos2FileOffset(ulCharPosFirst); + DBG_HEX_C(tRow.ulFileOffsetStart == FC_INVALID, + ulCharPosFirst); + break; + case found_end_of_row: + ulCharPosLast = ulGetLong( + tIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosLast); + tRow.ulCharPosEnd = ulCharPosLast; + tRow.ulFileOffsetEnd = + ulCharPos2FileOffset(ulCharPosLast); + DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, + ulCharPosLast); + vAdd2RowInfoList(&tRow); + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + break; + case found_nothing: + break; + default: + DBG_DEC(eRowInfo); + break; + } + } + } + ausParfPage = xfree(ausParfPage); +} /* end of vGet6PapInfo */ + +/* + * Fill the font information block with information + * from a Word 6/7 file. + * Returns TRUE when successful, otherwise FALSE + */ +void +vGet6FontInfo(int iFodo, USHORT usIstd, + const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont) +{ + long lTmp; + int iFodoOff, iInfoLen; + USHORT usTmp; + UCHAR ucTmp; + + TRACE_MSG("vGet6FontInfo"); + + fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); + + iFodoOff = 0; + while (iBytes >= iFodoOff + 1) { + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 65: /* fRMarkDel */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (ucTmp == 0) { + pFont->usFontStyle &= ~FONT_MARKDEL; + } else { + pFont->usFontStyle |= FONT_MARKDEL; + } + break; + case 80: /* cIstd */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + NO_DBG_DEC(usTmp); + break; + case 82: /* cDefault */ + pFont->usFontStyle &= FONT_HIDDEN; + pFont->ucFontColor = FONT_COLOR_DEFAULT; + break; + case 83: /* cPlain */ + DBG_MSG("83: cPlain"); + vFillFontFromStylesheet(usIstd, pFont); + break; + case 85: /* fBold */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_BOLD; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_BOLD; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_BOLD; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 86: /* fItalic */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_ITALIC; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_ITALIC; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_ITALIC; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 87: /* fStrike */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_STRIKE; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_STRIKE; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_STRIKE; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 90: /* fSmallCaps */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_SMALL_CAPITALS; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_SMALL_CAPITALS; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_SMALL_CAPITALS; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 91: /* fCaps */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_CAPITALS; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_CAPITALS; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_CAPITALS; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 92: /* fVanish */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_HIDDEN; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_HIDDEN; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_HIDDEN; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 93: /* cFtc */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + if (usTmp <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usTmp; + } else { + DBG_DEC(usTmp); + DBG_FIXME(); + pFont->ucFontNumber = 0; + } + break; + case 94: /* cKul */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (ucTmp == 0 || ucTmp == 5) { + pFont->usFontStyle &= ~FONT_UNDERLINE; + } else { + NO_DBG_MSG("Underline text"); + pFont->usFontStyle |= FONT_UNDERLINE; + if (ucTmp == 6) { + DBG_MSG("Bold text"); + pFont->usFontStyle |= FONT_BOLD; + } + } + break; + case 95: /* cHps, cHpsPos */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + DBG_DEC(ucTmp); + if (ucTmp != 0) { + pFont->usFontSize = (USHORT)ucTmp; + } + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC(ucTmp); + break; + case 98: /* cIco */ + pFont->ucFontColor = + ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + break; + case 99: /* cHps */ + pFont->usFontSize = + usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + break; + case 100: /* cHpsInc */ + DBG_MSG("100: sprmCHpsInc"); + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + DBG_DEC(ucTmp); + break; + case 103: /* cMajority */ + DBG_MSG("103: sprmCMajority"); + break; + case 104: /* cIss */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + ucTmp &= 0x07; + if (ucTmp == 1) { + pFont->usFontStyle |= FONT_SUPERSCRIPT; + NO_DBG_MSG("Superscript"); + } else if (ucTmp == 2) { + pFont->usFontStyle |= FONT_SUBSCRIPT; + NO_DBG_MSG("Subscript"); + } + break; + case 106: /* cHpsInc1 */ + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + lTmp = (long)pFont->usFontSize + (long)usTmp; + if (lTmp < 8) { + pFont->usFontSize = 8; + } else if (lTmp > 32766) { + pFont->usFontSize = 32766; + } else { + pFont->usFontSize = (USHORT)lTmp; + } + break; + case 108: /* cMajority50 */ + DBG_MSG("108: sprmCMajority50"); + break; + case 109: /* cHpsMul */ + DBG_MSG("109: sprmCHpsMul"); + usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); + DBG_DEC(usTmp); + break; + default: + break; + } + iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + iFodoOff += iInfoLen; + } +} /* end of vGet6FontInfo */ + +/* + * Fill the picture information block with information + * from a Word 6/7 file. + * Returns TRUE when successful, otherwise FALSE + */ +static BOOL +bGet6PicInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) +{ + int iFodoOff, iInfoLen; + BOOL bFound; + UCHAR ucTmp; + + TRACE_MSG("vGet6PicInfo"); + + fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL); + + iFodoOff = 0; + bFound = FALSE; + while (iBytes >= iFodoOff + 1) { + switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { + case 68: /* fcPic */ + pPicture->ulPictureOffset = ulGetLong( + iFodo + iFodoOff + 2, aucGrpprl); + bFound = TRUE; + break; +#if 0 + case 71: /* fData */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (ucTmp == 0x01) { + /* Not a picture, but a form field */ + return FALSE; + } + DBG_DEC_C(ucTmp != 0, ucTmp); + break; +#endif + case 75: /* fOle2 */ + ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); + if (ucTmp == 0x01) { + /* Not a picture, but an OLE object */ + return FALSE; + } + DBG_DEC_C(ucTmp != 0, ucTmp); + break; + default: + break; + } + iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + iFodoOff += iInfoLen; + } + return bFound; +} /* end of bGet6PicInfo */ + +/* + * Build the lists with Character Information for Word 6/7 files + */ +void +vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) +{ + font_block_type tFont; + picture_block_type tPicture; + USHORT *ausCharPage; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; + size_t tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum; + size_t tIndex, tIndex2, tRun; + int iFodo, iLen; + USHORT usCharFirstPage, usCount, usIstd; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginCharInfo = ulGetLong(0xb8, aucHeader); /* fcPlcfbteChpx */ + NO_DBG_HEX(lBeginCharInfo); + tCharInfoLen = (size_t)ulGetLong(0xbc, aucHeader); /* lcbPlcfbteChpx */ + NO_DBG_DEC(tCharInfoLen); + if (tCharInfoLen < 4) { + DBG_DEC(tCharInfoLen); + return; + } + + aucBuffer = xmalloc(tCharInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginCharInfo, tCharInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + + tLen = (tCharInfoLen - 4) / 6; + ausCharPage = xcalloc(tLen, sizeof(USHORT)); + for (tIndex = 0, tOffset = (tLen + 1) * 4; + tIndex < tLen; + tIndex++, tOffset += 2) { + ausCharPage[tIndex] = usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(ausCharPage[tIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + tCharPageNum = (size_t)usGetWord(0x18e, aucHeader); /* cpnBteChp */ + DBG_DEC(tCharPageNum); + if (tLen < tCharPageNum) { + /* Replace CharPage by a longer version */ + tLenOld = tLen; + usCharFirstPage = usGetWord(0x18a, aucHeader); /* pnChrFirst */ + DBG_DEC(usCharFirstPage); + tLen += tCharPageNum - 1; + tSize = tLen * sizeof(USHORT); + ausCharPage = xrealloc(ausCharPage, tSize); + /* Add new values */ + usCount = usCharFirstPage + 1; + for (tIndex = tLenOld; tIndex < tLen; tIndex++) { + ausCharPage[tIndex] = usCount; + NO_DBG_DEC(ausCharPage[tIndex]); + usCount++; + } + } + + for (tIndex = 0; tIndex < tLen; tIndex++) { + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, + (ULONG)ausCharPage[tIndex] * BIG_BLOCK_SIZE, + BIG_BLOCK_SIZE)) { + break; + } + tRun = (size_t)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(tRun); + for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) { + ulCharPos = ulGetLong(tIndex2 * 4, aucFpage); + ulFileOffset = ulCharPos2FileOffset(ulCharPos); + iFodo = 2 * (int)ucGetByte( + (tRun + 1) * 4 + tIndex2, aucFpage); + + iLen = (int)ucGetByte(iFodo, aucFpage); + + usIstd = usGetIstd(ulFileOffset); + vFillFontFromStylesheet(usIstd, &tFont); + if (iFodo != 0) { + vGet6FontInfo(iFodo, usIstd, + aucFpage + 1, iLen - 1, &tFont); + } + tFont.ulFileOffset = ulFileOffset; + vAdd2FontInfoList(&tFont); + + if (iFodo <= 0) { + continue; + } + + (void)memset(&tPicture, 0, sizeof(tPicture)); + if (bGet6PicInfo(iFodo, aucFpage + 1, + iLen - 1, &tPicture)) { + tPicture.ulFileOffset = ulFileOffset; + tPicture.ulFileOffsetPicture = + ulDataPos2FileOffset( + tPicture.ulPictureOffset); + vAdd2PictInfoList(&tPicture); + } + } + } + ausCharPage = xfree(ausCharPage); +} /* end of vGet6ChrInfo */ diff --git a/prop8.c b/prop8.c new file mode 100644 index 0000000..c31204e --- /dev/null +++ b/prop8.c @@ -0,0 +1,1496 @@ +/* + * prop8.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Read the property information from a MS Word 8, 9,10 or 11 file + * + * Word 8 is better known as Word 97 or as Word 98 for Mac + * Word 9 is better known as Word 2000 or as Word 2001 for Mac + * Word 10 is better known as Word 2002 or as Word XP + * Word 11 is better known as Word 2003 + */ + +#include +#include +#include "antiword.h" + +#define DEFAULT_LISTCHAR 0x002e /* A full stop */ + + +/* + * iGet8InfoLength - the length of the information for Word 8/9/10/11 files + */ +static int +iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl) +{ + int iTmp, iDel, iAdd; + USHORT usOpCode; + + usOpCode = usGetWord(iByteNbr, aucGrpprl); + + switch (usOpCode & 0xe000) { + case 0x0000: case 0x2000: + return 3; + case 0x4000: case 0x8000: case 0xa000: + return 4; + case 0xe000: + return 5; + case 0x6000: + return 6; + case 0xc000: + iTmp = (int)ucGetByte(iByteNbr + 2, aucGrpprl); + if (usOpCode == 0xc615 && iTmp == 255) { + iDel = (int)ucGetByte(iByteNbr + 3, aucGrpprl); + iAdd = (int)ucGetByte( + iByteNbr + 4 + iDel * 4, aucGrpprl); + iTmp = 2 + iDel * 4 + iAdd * 3; + } + return 3 + iTmp; + default: + DBG_HEX(usOpCode); + DBG_FIXME(); + return 1; + } +} /* end of iGet8InfoLength */ + +/* + * aucFillInfoBuffer - fill the information buffer + * + * Returns the information buffer when successful, otherwise NULL + */ +static UCHAR * +aucFillInfoBuffer(FILE *pFile, const pps_type *pTable, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + ULONG ulBeginInfo, size_t tInfoLen) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + size_t tBlockDepotLen, tBlockSize; + + fail(pFile == NULL || pTable == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + fail(tInfoLen == 0); + + NO_DBG_DEC(pTable->ulSB); + NO_DBG_HEX(pTable->ulSize); + if (pTable->ulSize == 0) { + DBG_MSG("No information"); + return NULL; + } + + if (pTable->ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tInfoLen); + if (!bReadBuffer(pFile, pTable->ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginInfo, tInfoLen)) { + aucBuffer = xfree(aucBuffer); + return NULL; + } + return aucBuffer; +} /* end of aucFillInfoBuffer */ + +/* + * Build the lists with Document Property Information for Word 8/9/10/11 files + */ +void +vGet8DopInfo(FILE *pFile, const pps_type *pTable, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + document_block_type tDocument; + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo, ulTmp; + size_t tDocpInfoLen; + USHORT usTmp; + + fail(pFile == NULL || pTable == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */ + NO_DBG_HEX(ulBeginSectInfo); + tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */ + NO_DBG_DEC(tSectInfoLen); + if (tDocpInfoLen < 28) { + DBG_MSG("No Document information"); + return; + } + + aucBuffer = aucFillInfoBuffer(pFile, pTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, + ulBeginDocpInfo, tDocpInfoLen); + if (aucBuffer == NULL) { + return; + } + + usTmp = usGetWord(0x00, aucBuffer); + tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ + tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ + ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ + tDocument.tCreateDate = tConvertDTTM(ulTmp); + ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ + tDocument.tRevisedDate = tConvertDTTM(ulTmp); + vCreateDocumentInfoList(&tDocument); + + aucBuffer = xfree(aucBuffer); +} /* end of vGet8DopInfo */ + +/* + * Fill the section information block with information + * from a Word 8/9/10/11 file. + */ +static void +vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, + section_block_type *pSection) +{ + UINT uiIndex; + int iFodoOff, iInfoLen, iSize, iTmp; + USHORT usCcol; + UCHAR ucTmp; + + fail(aucGrpprl == NULL || pSection == NULL); + + iFodoOff = 0; + while (tBytes >= (size_t)iFodoOff + 2) { + iInfoLen = 0; + switch (usGetWord(iFodoOff, aucGrpprl)) { + case 0x3009: /* bkc */ + ucTmp = ucGetByte(iFodoOff + 2, aucGrpprl); + DBG_DEC(ucTmp); + pSection->bNewPage = ucTmp != 0 && ucTmp != 1; + break; + case 0x3014: /* grpfIhdt */ + pSection->ucHdrFtrSpecification = + ucGetByte(iFodoOff + 2, aucGrpprl); + break; + case 0x500b: /* ccolM1 */ + usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl); + DBG_DEC(usCcol); + break; + case 0xd202: /* olstAnm */ + iSize = (int)ucGetByte(iFodoOff + 2, aucGrpprl); + DBG_DEC_C(iSize != 212, iSize); + for (uiIndex = 0, iTmp = iFodoOff + 3; + uiIndex < 9 && iTmp < iFodoOff + 3 + iSize - 15; + uiIndex++, iTmp += 16) { + pSection->aucNFC[uiIndex] = + ucGetByte(iTmp, aucGrpprl); + DBG_DEC(pSection->aucNFC[uiIndex]); + ucTmp = ucGetByte(iTmp + 3, aucGrpprl); + DBG_HEX(ucTmp); + if ((ucTmp & BIT(2)) != 0) { + pSection->usNeedPrevLvl |= + (USHORT)BIT(uiIndex); + } + if ((ucTmp & BIT(3)) != 0) { + pSection->usHangingIndent |= + (USHORT)BIT(uiIndex); + } + } + DBG_HEX(pSection->usNeedPrevLvl); + DBG_HEX(pSection->usHangingIndent); + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = iGet8InfoLength(iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } +} /* end of vGet8SectionInfo */ + +/* + * Build the lists with Section Property Information for Word 8/9/10/11 files + */ +void +vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + section_block_type tSection; + ULONG *aulSectPage, *aulCharPos; + UCHAR *aucBuffer, *aucFpage; + ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; + size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; + UCHAR aucTmp[2]; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ + NO_DBG_HEX(ulBeginOfText); + ulBeginSectInfo = ulGetLong(0xca, aucHeader); /* fcPlcfsed */ + NO_DBG_HEX(ulBeginSectInfo); + tSectInfoLen = (size_t)ulGetLong(0xce, aucHeader); /* lcbPlcfsed */ + NO_DBG_DEC(tSectInfoLen); + if (tSectInfoLen < 4) { + DBG_DEC(tSectInfoLen); + return; + } + + aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, + ulBeginSectInfo, tSectInfoLen); + if (aucBuffer == NULL) { + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); + + /* Read the Section Descriptors */ + tLen = (tSectInfoLen - 4) / 16; + /* Save the section offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; + tIndex < tLen; + tIndex++, tOffset += 4) { + ulTextOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulTextOffset); + aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; + NO_DBG_HEX(aulCharPos[tIndex]); + } + /* Save the Sepx offsets */ + aulSectPage = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = (tLen + 1) * 4; + tIndex < tLen; + tIndex++, tOffset += 12) { + aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); + NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ + } + aucBuffer = xfree(aucBuffer); + + /* Read the Section Properties */ + for (tIndex = 0; tIndex < tLen; tIndex++) { + if (aulSectPage[tIndex] == FC_INVALID) { + vDefault2SectionInfoList(aulCharPos[tIndex]); + continue; + } + /* Get the number of bytes to read */ + if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucTmp, aulSectPage[tIndex], 2)) { + continue; + } + tBytes = 2 + (size_t)usGetWord(0, aucTmp); + NO_DBG_DEC(tBytes); + /* Read the bytes */ + aucFpage = xmalloc(tBytes); + if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, aulSectPage[tIndex], tBytes)) { + aucFpage = xfree(aucFpage); + continue; + } + NO_DBG_PRINT_BLOCK(aucFpage, tBytes); + /* Process the bytes */ + vGetDefaultSection(&tSection); + vGet8SectionInfo(aucFpage + 2, tBytes - 2, &tSection); + vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); + aucFpage = xfree(aucFpage); + } + aulCharPos = xfree(aulCharPos); + aulSectPage = xfree(aulSectPage); +} /* end of vGet8SepInfo */ + +/* + * Build the list with Header/Footer Information for Word 8/9/10/11 files + */ +void +vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + ULONG *aulCharPos; + UCHAR *aucBuffer; + ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; + size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; + + fail(pFile == NULL || pTable == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginHdrFtrInfo = ulGetLong(0xf2, aucHeader); /* fcPlcfhdd */ + NO_DBG_HEX(ulBeginHdrFtrInfo); + tHdrFtrInfoLen = (size_t)ulGetLong(0xf6, aucHeader); /* lcbPlcfhdd */ + NO_DBG_DEC(tHdrFtrInfoLen); + if (tHdrFtrInfoLen < 8) { + DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); + return; + } + + aucBuffer = aucFillInfoBuffer(pFile, pTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, + ulBeginHdrFtrInfo, tHdrFtrInfoLen); + if (aucBuffer == NULL) { + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); + + tLen = tHdrFtrInfoLen / 4 - 1; + DBG_DEC_C(tLen % 12 != 1 && tLen % 12 != 7, tLen); + /* Save the header/footer offsets */ + aulCharPos = xcalloc(tLen, sizeof(ULONG)); + for (tIndex = 0, tOffset = 0; + tIndex < tLen; + tIndex++, tOffset += 4) { + ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); + NO_DBG_HEX(ulHdrFtrOffset); + aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); + NO_DBG_HEX(aulCharPos[tIndex]); + } + vCreat8HdrFtrInfoList(aulCharPos, tLen); + /* Clean up and leave */ + aulCharPos = xfree(aulCharPos); + aucBuffer = xfree(aucBuffer); +} /* end of vGet8HdrFtrInfo */ + +/* + * Translate the rowinfo to a member of the row_info enumeration + */ +row_info_enum +eGet8RowInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) +{ + int iFodoOff, iInfoLen; + int iIndex, iSize, iCol; + int iPosCurr, iPosPrev; + USHORT usTmp; + BOOL bFound2416_0, bFound2416_1, bFound2417_0, bFound2417_1; + BOOL bFound244b_0, bFound244b_1, bFound244c_0, bFound244c_1; + BOOL bFoundd608; + + fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL); + + iFodoOff = 0; + bFound2416_0 = FALSE; + bFound2416_1 = FALSE; + bFound2417_0 = FALSE; + bFound2417_1 = FALSE; + bFound244b_0 = FALSE; + bFound244b_1 = FALSE; + bFound244c_0 = FALSE; + bFound244c_1 = FALSE; + bFoundd608 = FALSE; + while (iBytes >= iFodoOff + 2) { + iInfoLen = 0; + switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { + case 0x2416: /* fInTable */ + if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { + bFound2416_1 = TRUE; + } else { + bFound2416_0 = TRUE; + } + break; + case 0x2417: /* fTtp */ + if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { + bFound2417_1 = TRUE; + } else { + bFound2417_0 = TRUE; + } + break; + case 0x244b: /* sub-table fInTable */ + if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { + bFound244b_1 = TRUE; + } else { + bFound244b_0 = TRUE; + } + break; + case 0x244c: /* sub-table fTtp */ + if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { + bFound244c_1 = TRUE; + } else { + bFound244c_0 = TRUE; + } + break; + case 0x6424: /* brcTop */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + usTmp &= 0xff00; + NO_DBG_DEC(usTmp >> 8); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_TOP; + } + break; + case 0x6425: /* brcLeft */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + usTmp &= 0xff00; + NO_DBG_DEC(usTmp >> 8); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_LEFT; + } + break; + case 0x6426: /* brcBottom */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + usTmp &= 0xff00; + NO_DBG_DEC(usTmp >> 8); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; + } + break; + case 0x6427: /* brcRight */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + usTmp &= 0xff00; + NO_DBG_DEC(usTmp >> 8); + if (usTmp == 0) { + pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; + } else { + pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; + } + break; + case 0xd606: /* cDefTable10 */ + DBG_MSG("0xd606: sprmTDefTable10"); + iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC(iSize); + break; + case 0xd608: /* cDefTable */ + iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + if (iSize < 6 || iBytes < iFodoOff + 8) { + DBG_DEC(iSize); + DBG_DEC(iFodoOff); + iInfoLen = 2; + break; + } + iCol = (int)ucGetByte(iFodo + iFodoOff + 4, aucGrpprl); + if (iCol < 1 || + iBytes < iFodoOff + 4 + (iCol + 1) * 2) { + DBG_DEC(iCol); + DBG_DEC(iFodoOff); + iInfoLen = 2; + break; + } + if (iCol >= (int)elementsof(pRow->asColumnWidth)) { + DBG_DEC(iCol); + werr(1, "The number of columns is corrupt"); + } + pRow->ucNumberOfColumns = (UCHAR)iCol; + iPosPrev = (int)(short)usGetWord( + iFodo + iFodoOff + 5, + aucGrpprl); + for (iIndex = 0; iIndex < iCol; iIndex++) { + iPosCurr = (int)(short)usGetWord( + iFodo + iFodoOff + 7 + iIndex * 2, + aucGrpprl); + pRow->asColumnWidth[iIndex] = + (short)(iPosCurr - iPosPrev); + iPosPrev = iPosCurr; + } + bFoundd608 = TRUE; + break; + default: + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } + + if (bFound2417_1 && bFoundd608) { + return found_end_of_row; + } + if (bFound2417_0 && !bFoundd608) { + return found_not_end_of_row; + } + if (bFound2416_1 || bFound244b_1) { + return found_a_cell; + } + if (bFound2416_0 || bFound244b_0) { + return found_not_a_cell; + } + return found_nothing; +} /* end of eGet8RowInfo */ + +/* + * Fill the style information block with information + * from a Word 8/9/10/11 file. + */ +void +vGet8StyleInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) +{ + list_block_type tList6; + const list_block_type *pList; + int iFodoOff, iInfoLen; + int iTmp, iDel, iAdd, iBefore; + USHORT usOpCode, usTmp; + short sTmp; + + fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); + + NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usIstd); + NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usListIndex); + + (void)memset(&tList6, 0, sizeof(tList6)); + + iFodoOff = 0; + while (iBytes >= iFodoOff + 2) { + iInfoLen = 0; + usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl); + switch (usOpCode) { + case 0x2403: /* jc */ + pStyle->ucAlignment = ucGetByte( + iFodo + iFodoOff + 2, aucGrpprl); + break; + case 0x260a: /* ilvl */ + pStyle->ucListLevel = + ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->ucListLevel); + pStyle->ucNumLevel = pStyle->ucListLevel; + break; + case 0x4600: /* istd */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(usTmp); + break; + case 0x460b: /* ilfo */ + pStyle->usListIndex = + usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->usListIndex); + break; + case 0x4610: /* Nest dxaLeft */ + sTmp = (short)usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + pStyle->sLeftIndent += sTmp; + if (pStyle->sLeftIndent < 0) { + pStyle->sLeftIndent = 0; + } + DBG_DEC(sTmp); + DBG_DEC(pStyle->sLeftIndent); + break; + case 0xc60d: /* ChgTabsPapx */ + case 0xc615: /* ChgTabs */ + iTmp = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (iTmp < 2) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iTmp); + iDel = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); + if (iTmp < 2 + 2 * iDel) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iDel); + iAdd = (int)ucGetByte( + iFodo + iFodoOff + 4 + 2 * iDel, aucGrpprl); + if (iTmp < 2 + 2 * iDel + 2 * iAdd) { + iInfoLen = 1; + break; + } + NO_DBG_DEC(iAdd); + break; + case 0x840e: /* dxaRight */ + pStyle->sRightIndent = (short)usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->sRightIndent); + break; + case 0x840f: /* dxaLeft */ + pStyle->sLeftIndent = (short)usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent); + break; + case 0x8411: /* dxaLeft1 */ + pStyle->sLeftIndent1 = (short)usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->sLeftIndent1); + break; + case 0xa413: /* dyaBefore */ + pStyle->usBeforeIndent = usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->usBeforeIndent); + break; + case 0xa414: /* dyaAfter */ + pStyle->usAfterIndent = usGetWord( + iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pStyle->usAfterIndent); + break; + case 0xc63e: /* anld */ + iTmp = (int)ucGetByte( + iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC_C(iTmp < 84, iTmp); + if (iTmp >= 1) { + tList6.ucNFC = ucGetByte( + iFodo + iFodoOff + 3, aucGrpprl); + } + if (tList6.ucNFC != LIST_BULLETS && iTmp >= 2) { + iBefore = (int)ucGetByte( + iFodo + iFodoOff + 4, aucGrpprl); + } else { + iBefore = 0; + } + if (iTmp >= 12) { + tList6.ulStartAt = (ULONG)usGetWord( + iFodo + iFodoOff + 13, aucGrpprl); + } + if (iTmp >= iBefore + 22) { + tList6.usListChar = usGetWord( + iFodo + iFodoOff + iBefore + 23, + aucGrpprl); + DBG_HEX(tList6.usListChar); + } + break; + default: + NO_DBG_HEX(usOpCode); + break; + } + if (iInfoLen <= 0) { + iInfoLen = + iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + } + iFodoOff += iInfoLen; + } + + if (pStyle->usListIndex == 2047) { + /* Old style list */ + pStyle->usStartAt = (USHORT)tList6.ulStartAt; + pStyle->usListChar = tList6.usListChar; + pStyle->ucNFC = tList6.ucNFC; + } else { + /* New style list */ + pList = pGetListInfo(pStyle->usListIndex, pStyle->ucListLevel); + if (pList != NULL) { + pStyle->bNoRestart = pList->bNoRestart; + fail(pList->ulStartAt > (ULONG)USHRT_MAX); + pStyle->usStartAt = (USHORT)pList->ulStartAt; + pStyle->usListChar = pList->usListChar; + pStyle->ucNFC = pList->ucNFC; + if (pStyle->sLeftIndent <= 0) { + pStyle->sLeftIndent = pList->sLeftIndent; + } + } + } +} /* end of vGet8StyleInfo */ + +/* + * Get the left indentation value from the style information block + * + * Returns the value when found, otherwise 0 + */ +static short +sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes) +{ + int iOffset, iInfoLen; + USHORT usOpCode, usTmp; + + fail(aucGrpprl == NULL); + + iOffset = 0; + while (tBytes >= (size_t)iOffset + 4) { + usOpCode = usGetWord(iOffset, aucGrpprl); + if (usOpCode == 0x840f) { /* dxaLeft */ + usTmp = usGetWord(iOffset + 2, aucGrpprl); + if (usTmp <= 0x7fff) { + NO_DBG_DEC(usTmp); + return (short)usTmp; + } + } + iInfoLen = iGet8InfoLength(iOffset, aucGrpprl); + fail(iInfoLen <= 0); + iOffset += iInfoLen; + } + return 0; +} /* end of sGetLeftIndent */ + +/* + * Build the list with List Information for Word 8/9/10/11 files + */ +void +vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + list_block_type tList; + const ULONG *aulBlockDepot; + UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString; + ULONG ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo; + ULONG ulListID, ulStart; + size_t tBlockDepotLen, tBlockSize; + size_t tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff; + size_t tLstfRecords, tStart, tIndex; + int iNums; + USHORT usIstd; + UCHAR ucTmp, ucListLevel, ucMaxLevel, ucChpxLen; + UCHAR aucLvlfInfo[28], aucXst[2]; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + NO_DBG_DEC(pPPS->tTable.ulSB); + NO_DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No list information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + + /* LFO (List Format Override) */ + ulBeginLfoInfo = ulGetLong(0x2ea, aucHeader); /* fcPlfLfo */ + DBG_HEX(ulBeginLfoInfo); + tLfoInfoLen = (size_t)ulGetLong(0x2ee, aucHeader); /* lcbPlfLfo */ + DBG_DEC(tLfoInfoLen); + if (tLfoInfoLen == 0) { + DBG_MSG("No lists in this document"); + return; + } + + aucLfoInfo = xmalloc(tLfoInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) { + aucLfoInfo = xfree(aucLfoInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucLfoInfo, tLfoInfoLen); + vBuildLfoList(aucLfoInfo, tLfoInfoLen); + aucLfoInfo = xfree(aucLfoInfo); + + /* LSTF (LiST data on File) */ + ulBeginLstfInfo = ulGetLong(0x2e2, aucHeader); /* fcPlcfLst */ + DBG_HEX(ulBeginLstfInfo); + tLstfInfoLen = (size_t)ulGetLong(0x2e6, aucHeader); /* lcbPlcfLst */ + DBG_DEC(tLstfInfoLen); + if (tLstfInfoLen == 0) { + DBG_MSG("No list data on file"); + return; + } + + aucLstfInfo = xmalloc(tLstfInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) { + aucLstfInfo = xfree(aucLstfInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucLstfInfo, tLstfInfoLen); + + tLstfRecords = (size_t)usGetWord(0, aucLstfInfo); + if (2 + tLstfRecords * 28 < tLstfInfoLen) { + DBG_DEC(2 + tLstfRecords * 28); + DBG_DEC(tLstfInfoLen); + aucLstfInfo = xfree(aucLstfInfo); + return; + } + + /* LVLF (List leVeL on File) */ + ulBeginLvlfInfo = ulBeginLstfInfo + tLstfInfoLen; + DBG_HEX(ulBeginLvlfInfo); + + aucXString = NULL; + ulStart = ulBeginLvlfInfo; + + for (tIndex = 0, tStart = 2; + tIndex < tLstfRecords; + tIndex++, tStart += 28) { + ulListID = ulGetLong(tStart, aucLstfInfo); + NO_DBG_HEX(ulListID); + ucTmp = ucGetByte(tStart + 26, aucLstfInfo); + ucMaxLevel = odd(ucTmp) ? 1 : 9; + for (ucListLevel = 0; ucListLevel < ucMaxLevel; ucListLevel++) { + fail(aucXString != NULL); + usIstd = usGetWord( + tStart + 8 + 2 * (size_t)ucListLevel, + aucLstfInfo); + DBG_DEC_C(usIstd != STI_NIL, usIstd); + NO_DBG_HEX(ulStart); + (void)memset(&tList, 0, sizeof(tList)); + /* Read the lvlf (List leVeL on File) */ + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, + tBlockSize, aucLvlfInfo, + ulStart, sizeof(aucLvlfInfo))) { + aucLstfInfo = xfree(aucLstfInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucLvlfInfo, sizeof(aucLvlfInfo)); + if (bAllZero(aucLvlfInfo, sizeof(aucLvlfInfo))) { + tList.ulStartAt = 1; + tList.ucNFC = 0x00; + tList.bNoRestart = FALSE; + } else { + tList.ulStartAt = ulGetLong(0, aucLvlfInfo); + tList.ucNFC = ucGetByte(4, aucLvlfInfo); + ucTmp = ucGetByte(5, aucLvlfInfo); + tList.bNoRestart = (ucTmp & BIT(3)) != 0; + DBG_MSG_C((ucTmp & BIT(4)) != 0 && + (ucTmp & BIT(6)) != 0, "Found one"); + } + ulStart += sizeof(aucLvlfInfo); + tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo); + if (tPapxLen != 0) { + aucPapx = xmalloc(tPapxLen); + /* Read the Papx */ + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, + tBlockSize, aucPapx, + ulStart, tPapxLen)) { + aucPapx = xfree(aucPapx); + aucLstfInfo = xfree(aucLstfInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucPapx, tPapxLen); + tList.sLeftIndent = + sGetLeftIndent(aucPapx, tPapxLen); + aucPapx = xfree(aucPapx); + } + ulStart += tPapxLen; + ucChpxLen = ucGetByte(24, aucLvlfInfo); + ulStart += (ULONG)ucChpxLen; + /* Read the length of the XString */ + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, + tBlockSize, aucXst, + ulStart, sizeof(aucXst))) { + aucLstfInfo = xfree(aucLstfInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucXst, sizeof(aucXst)); + tXstLen = (size_t)usGetWord(0, aucXst); + ulStart += sizeof(aucXst); + if (tXstLen == 0) { + tList.usListChar = DEFAULT_LISTCHAR; + vAdd2ListInfoList(ulListID, + usIstd, + ucListLevel, + &tList); + continue; + } + tXstLen *= 2; /* Length in chars to length in bytes */ + aucXString = xmalloc(tXstLen); + /* Read the XString */ + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, + tBlockSize, aucXString, + ulStart, tXstLen)) { + aucXString = xfree(aucXString); + aucLstfInfo = xfree(aucLstfInfo); + return; + } + NO_DBG_PRINT_BLOCK(aucXString, tXstLen); + tOff = 0; + for (iNums = 6; iNums < 15; iNums++) { + ucTmp = ucGetByte(iNums, aucLvlfInfo); + if (ucTmp == 0) { + break; + } + tOff = (size_t)ucTmp; + } + tOff *= 2; /* Offset in chars to offset in bytes */ + NO_DBG_DEC(tOff); + if (tList.ucNFC == LIST_SPECIAL || + tList.ucNFC == LIST_SPECIAL2 || + tList.ucNFC == LIST_BULLETS) { + tList.usListChar = usGetWord(0, aucXString); + } else if (tOff != 0 && tOff < tXstLen) { + tList.usListChar = usGetWord(tOff, aucXString); + } else { + tList.usListChar = DEFAULT_LISTCHAR; + } + vAdd2ListInfoList(ulListID, + usIstd, + ucListLevel, + &tList); + ulStart += tXstLen; + aucXString = xfree(aucXString); + } + } + aucLstfInfo = xfree(aucLstfInfo); +} /* end of vGet8LstInfo */ + +/* + * Build the lists with Paragraph Information for Word 8/9/10/11 files + */ +void +vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + row_block_type tRow; + style_block_type tStyle; + ULONG *aulParfPage; + UCHAR *aucBuffer; + ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; + ULONG ulBeginParfInfo; + size_t tParfInfoLen, tOffset, tLen; + int iIndex, iIndex2, iRun, iFodo, iLen; + row_info_enum eRowInfo; + USHORT usIstd; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginParfInfo = ulGetLong(0x102, aucHeader); /* fcPlcfbtePapx */ + NO_DBG_HEX(ulBeginParfInfo); + tParfInfoLen = (size_t)ulGetLong(0x106, aucHeader); /* lcbPlcfbtePapx */ + NO_DBG_DEC(tParfInfoLen); + if (tParfInfoLen < 4) { + DBG_DEC(tParfInfoLen); + return; + } + + aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, + ulBeginParfInfo, tParfInfoLen); + if (aucBuffer == NULL) { + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); + + tLen = (tParfInfoLen / 4 - 1) / 2; + aulParfPage = xcalloc(tLen, sizeof(ULONG)); + for (iIndex = 0, tOffset = (tLen + 1) * 4; + iIndex < (int)tLen; + iIndex++, tOffset += 4) { + aulParfPage[iIndex] = ulGetLong(tOffset, aucBuffer); + NO_DBG_DEC(aulParfPage[iIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); + + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + for (iIndex = 0; iIndex < (int)tLen; iIndex++) { + fail(aulParfPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); + if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, + aulParfPage[iIndex] * BIG_BLOCK_SIZE, + BIG_BLOCK_SIZE)) { + break; + } + NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); + iRun = (int)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { + NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); + iFodo = 2 * (int)ucGetByte( + (iRun + 1) * 4 + iIndex2 * 13, aucFpage); + if (iFodo <= 0) { + continue; + } + + iLen = 2 * (int)ucGetByte(iFodo, aucFpage); + if (iLen == 0) { + iFodo++; + iLen = 2 * (int)ucGetByte(iFodo, aucFpage); + } + + usIstd = usGetWord(iFodo + 1, aucFpage); + vFillStyleFromStylesheet(usIstd, &tStyle); + vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); + ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPos); + tStyle.ulFileOffset = ulCharPos2FileOffsetX( + ulCharPos, &tStyle.eListID); + vAdd2StyleInfoList(&tStyle); + + eRowInfo = eGet8RowInfo(iFodo, + aucFpage + 3, iLen - 3, &tRow); + switch (eRowInfo) { + case found_a_cell: + if (ulCharPosFirst != CP_INVALID) { + break; + } + ulCharPosFirst = ulGetLong( + iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosFirst); + tRow.ulCharPosStart = ulCharPosFirst; + tRow.ulFileOffsetStart = + ulCharPos2FileOffset(ulCharPosFirst); + NO_DBG_HEX_C( + tRow.ulFileOffsetStart == FC_INVALID, + ulCharPosFirst); + break; + case found_end_of_row: + ulCharPosLast = ulGetLong( + iIndex2 * 4, aucFpage); + NO_DBG_HEX(ulCharPosLast); + tRow.ulCharPosEnd = ulCharPosLast; + tRow.ulFileOffsetEnd = + ulCharPos2FileOffset(ulCharPosLast); + NO_DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, + ulCharPosLast); + vAdd2RowInfoList(&tRow); + (void)memset(&tRow, 0, sizeof(tRow)); + ulCharPosFirst = CP_INVALID; + break; + case found_nothing: + break; + default: + DBG_DEC(eRowInfo); + break; + } + } + } + aulParfPage = xfree(aulParfPage); +} /* end of vGet8PapInfo */ + +/* + * Fill the font information block with information + * from a Word 8/9/10/11 file. + */ +void +vGet8FontInfo(int iFodo, USHORT usIstd, + const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont) +{ + long lTmp; + int iFodoOff, iInfoLen; + USHORT usFtc0, usFtc1, usFtc2, usTmp; + UCHAR ucTmp; + + fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); + + usFtc0 = USHRT_MAX; + usFtc1 = USHRT_MAX; + usFtc2 = USHRT_MAX; + + iFodoOff = 0; + while (iBytes >= iFodoOff + 2) { + switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { + case 0x0800: /* fRMarkDel */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (ucTmp == 0) { + pFont->usFontStyle &= ~FONT_MARKDEL; + } else { + pFont->usFontStyle |= FONT_MARKDEL; + } + break; + case 0x0835: /* fBold */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_BOLD; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_BOLD; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_BOLD; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x0836: /* fItalic */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_ITALIC; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_ITALIC; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_ITALIC; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x0837: /* fStrike */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_STRIKE; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_STRIKE; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_STRIKE; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x083a: /* fSmallCaps */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_SMALL_CAPITALS; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_SMALL_CAPITALS; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_SMALL_CAPITALS; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x083b: /* fCaps */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_CAPITALS; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_CAPITALS; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_CAPITALS; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x083c: /* fVanish */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + switch (ucTmp) { + case 0: /* Unset */ + pFont->usFontStyle &= ~FONT_HIDDEN; + break; + case 1: /* Set */ + pFont->usFontStyle |= FONT_HIDDEN; + break; + case 128: /* Unchanged */ + break; + case 129: /* Negation */ + pFont->usFontStyle ^= FONT_HIDDEN; + break; + default: + DBG_DEC(ucTmp); + DBG_FIXME(); + break; + } + break; + case 0x2a32: /* cDefault */ + pFont->usFontStyle &= FONT_HIDDEN; + pFont->ucFontColor = FONT_COLOR_DEFAULT; + break; + case 0x2a33: /* cPlain */ + DBG_MSG("2a33: cPlain"); + vFillFontFromStylesheet(usIstd, pFont); + break; + case 0x2a3e: /* cKul */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (ucTmp == 0 || ucTmp == 5) { + pFont->usFontStyle &= ~FONT_UNDERLINE; + } else { + NO_DBG_MSG("Underline text"); + pFont->usFontStyle |= FONT_UNDERLINE; + if (ucTmp == 6) { + DBG_MSG("Bold text"); + pFont->usFontStyle |= FONT_BOLD; + } + } + break; + case 0x2a42: /* cIco */ + pFont->ucFontColor = + ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pFont->ucFontColor); + break; + case 0x2a44: /* cHpsInc */ + DBG_MSG("0x2a44: sprmCHpsInc"); + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC(ucTmp); + break; + case 0x2a48: /* cIss */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + ucTmp &= 0x07; + if (ucTmp == 1) { + pFont->usFontStyle |= FONT_SUPERSCRIPT; + NO_DBG_MSG("Superscript"); + } else if (ucTmp == 2) { + pFont->usFontStyle |= FONT_SUBSCRIPT; + NO_DBG_MSG("Subscript"); + } + break; + case 0x4a30: /* cIstd */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(usTmp); + break; + case 0x4a43: /* cHps */ + pFont->usFontSize = + usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + NO_DBG_DEC(pFont->usFontSize); + break; + case 0x4a4d: /* cHpsMul */ + DBG_MSG("0x4a4d: sprmCHpsMul"); + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC(usTmp); + break; + case 0x4a4f: /* cFtc0 */ + usFtc0 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + break; + case 0x4a50: /* cFtc1 */ + usFtc1 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + break; + case 0x4a51: /* cFtc2 */ + usFtc2 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + break; + case 0xca47: /* cMajority */ + DBG_MSG("0xca47: sprmCMajority"); + break; + case 0xca4a: /* cHpsInc1 */ + usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); + lTmp = (long)pFont->usFontSize + (long)usTmp; + if (lTmp < 8) { + pFont->usFontSize = 8; + } else if (lTmp > 32766) { + pFont->usFontSize = 32766; + } else { + pFont->usFontSize = (USHORT)lTmp; + } + break; + case 0xca4c: /* cMajority50 */ + DBG_MSG("0xca4c: sprmCMajority50"); + break; + case 0xea3f: /* cHps, cHpsPos */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + DBG_DEC(ucTmp); + if (ucTmp != 0) { + pFont->usFontSize = (USHORT)ucTmp; + } + ucTmp = ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); + DBG_DEC(ucTmp); + break; + default: + break; + } + iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + iFodoOff += iInfoLen; + } + + /* Combine the Ftc's to a FontNumber */ + NO_DBG_DEC_C(usFtc0 != USHRT_MAX, usFtc0); + NO_DBG_DEC_C(usFtc2 != USHRT_MAX, usFtc2); + NO_DBG_DEC_C(usFtc1 != USHRT_MAX, usFtc1); + if (usFtc0 <= 0x7fff) { + if (usFtc0 <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usFtc0; + } else { + DBG_DEC(usFtc0); + DBG_FIXME(); + pFont->ucFontNumber = 0; + } + } else if (usFtc2 <= 0x7fff) { + if (usFtc2 <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usFtc2; + } else { + DBG_DEC(usFtc2); + DBG_FIXME(); + pFont->ucFontNumber = 0; + } + } else if (usFtc1 <= 0x7fff) { + if (usFtc1 <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usFtc1; + } else { + DBG_DEC(usFtc1); + DBG_FIXME(); + pFont->ucFontNumber = 0; + } + } +} /* end of vGet8FontInfo */ + +/* + * Fill the picture information block with information + * from a Word 8/9/10/11 file. + * Returns TRUE when successful, otherwise FALSE + */ +static BOOL +bGet8PicInfo(int iFodo, + const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) +{ + ULONG ulTmp; + int iFodoOff, iInfoLen; + BOOL bFound; + UCHAR ucTmp; + + fail(iFodo <= 0 || aucGrpprl == NULL || pPicture == NULL); + + iFodoOff = 0; + bFound = FALSE; + while (iBytes >= iFodoOff + 2) { + switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { +#if 0 + case 0x0806: /* fData */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (ucTmp == 0x01) { + /* Not a picture, but a form field */ + return FALSE; + } + DBG_DEC_C(ucTmp != 0, ucTmp); + break; +#endif + case 0x080a: /* fOle2 */ + ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); + if (ucTmp == 0x01) { + /* Not a picture, but an OLE object */ + return FALSE; + } + DBG_DEC_C(ucTmp != 0, ucTmp); + break; + case 0x680e: /* fcObj */ + ulTmp = ulGetLong(iFodo + iFodoOff + 2, aucGrpprl); + DBG_HEX(ulTmp); + break; + case 0x6a03: /* fcPic */ + pPicture->ulPictureOffset = ulGetLong( + iFodo + iFodoOff + 2, aucGrpprl); + bFound = TRUE; + break; + default: + break; + } + iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); + fail(iInfoLen <= 0); + iFodoOff += iInfoLen; + } + return bFound; +} /* end of bGet8PicInfo */ + +/* + * Build the lists with Character Information for Word 8/9/10/11 files + */ +void +vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + font_block_type tFont; + picture_block_type tPicture; + ULONG *aulCharPage; + UCHAR *aucBuffer; + ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; + size_t tCharInfoLen, tOffset, tLen; + int iIndex, iIndex2, iRun, iFodo, iLen; + USHORT usIstd; + UCHAR aucFpage[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginCharInfo = ulGetLong(0xfa, aucHeader); /* fcPlcfbteChpx */ + NO_DBG_HEX(ulBeginCharInfo); + tCharInfoLen = (size_t)ulGetLong(0xfe, aucHeader); /* lcbPlcfbteChpx */ + NO_DBG_DEC(tCharInfoLen); + if (tCharInfoLen < 4) { + DBG_DEC(tCharInfoLen); + return; + } + + aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, + ulBeginCharInfo, tCharInfoLen); + if (aucBuffer == NULL) { + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); + + tLen = (tCharInfoLen / 4 - 1) / 2; + aulCharPage = xcalloc(tLen, sizeof(ULONG)); + for (iIndex = 0, tOffset = (tLen + 1) * 4; + iIndex < (int)tLen; + iIndex++, tOffset += 4) { + aulCharPage[iIndex] = ulGetLong(tOffset, aucBuffer); + NO_DBG_DEC(aulCharPage[iIndex]); + } + DBG_HEX(ulGetLong(0, aucBuffer)); + aucBuffer = xfree(aucBuffer); + NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); + + for (iIndex = 0; iIndex < (int)tLen; iIndex++) { + fail(aulCharPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); + if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucFpage, + aulCharPage[iIndex] * BIG_BLOCK_SIZE, + BIG_BLOCK_SIZE)) { + break; + } + NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); + iRun = (int)ucGetByte(0x1ff, aucFpage); + NO_DBG_DEC(iRun); + for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { + ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); + ulFileOffset = ulCharPos2FileOffset(ulCharPos); + iFodo = 2 * (int)ucGetByte( + (iRun + 1) * 4 + iIndex2, aucFpage); + + iLen = (int)ucGetByte(iFodo, aucFpage); + + usIstd = usGetIstd(ulFileOffset); + vFillFontFromStylesheet(usIstd, &tFont); + if (iFodo != 0) { + vGet8FontInfo(iFodo, usIstd, + aucFpage + 1, iLen - 1, &tFont); + } + tFont.ulFileOffset = ulFileOffset; + vAdd2FontInfoList(&tFont); + + if (iFodo <= 0) { + continue; + } + + (void)memset(&tPicture, 0, sizeof(tPicture)); + if (bGet8PicInfo(iFodo, aucFpage + 1, + iLen - 1, &tPicture)) { + tPicture.ulFileOffset = ulFileOffset; + tPicture.ulFileOffsetPicture = + ulDataPos2FileOffset( + tPicture.ulPictureOffset); + vAdd2PictInfoList(&tPicture); + } + } + } + aulCharPage = xfree(aulCharPage); +} /* end of vGet8ChrInfo */ diff --git a/properties.c b/properties.c new file mode 100644 index 0000000..28087a4 --- /dev/null +++ b/properties.c @@ -0,0 +1,198 @@ +/* + * properties.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Read the properties information from a MS Word file + */ + +#include +#include +#include "antiword.h" + + +/* + * Build the lists with Property Information + */ +void +vGetPropertyInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader, int iWordVersion) +{ + options_type tOptions; + + TRACE_MSG("vGetPropertyInfo"); + + fail(pFile == NULL); + fail(pPPS == NULL && iWordVersion >= 6); + fail(aulBBD == NULL && tBBDLen != 0); + fail(aulSBD == NULL && tSBDLen != 0); + fail(aucHeader == NULL); + + /* Get the options */ + vGetOptions(&tOptions); + + /* Get the property information per Word version */ + switch (iWordVersion) { + case 0: + vGet0DopInfo(pFile, aucHeader); + vGet0SepInfo(pFile, aucHeader); + vGet0PapInfo(pFile, aucHeader); + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_xml || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_pdf) { + vGet0ChrInfo(pFile, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vCreate0FontTable(); + } + vSet0SummaryInfo(pFile, aucHeader); + break; + case 1: + case 2: + vGet2Stylesheet(pFile, iWordVersion, aucHeader); + vGet2DopInfo(pFile, aucHeader); + vGet2SepInfo(pFile, aucHeader); + vGet2PapInfo(pFile, aucHeader); + if (tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vGet2HdrFtrInfo(pFile, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_xml || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_pdf) { + vGet2ChrInfo(pFile, iWordVersion, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vCreate2FontTable(pFile, iWordVersion, aucHeader); + } + vSet2SummaryInfo(pFile, iWordVersion, aucHeader); + break; + case 4: + case 5: + break; + case 6: + case 7: + vGet6Stylesheet(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + vGet6DopInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + vGet6SepInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + vGet6PapInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + if (tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vGet6HdrFtrInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_xml || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_pdf) { + vGet6ChrInfo(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vCreate6FontTable(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + } + vSet6SummaryInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + break; + case 8: + vGet8LstInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8Stylesheet(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8DopInfo(pFile, &pPPS->tTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8SepInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + vGet8PapInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + if (tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vGet8HdrFtrInfo(pFile, &pPPS->tTable, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_xml || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_pdf) { + vGet8ChrInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + } + if (tOptions.eConversionType == conversion_draw || + tOptions.eConversionType == conversion_ps || + tOptions.eConversionType == conversion_pdf) { + vCreate8FontTable(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + } + vSet8SummaryInfo(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + break; + default: + DBG_DEC(iWordVersion); + DBG_FIXME(); + werr(0, "Sorry, no property information"); + break; + } + + /* Temporarily: Correct the font table */ + vCorrectFontTable(tOptions.eConversionType, tOptions.eEncoding); +} /* end of vGetPropertyInfo */ + +/* + * ePropMod2RowInfo - Turn the Property Modifier into row information + * + * Returns: the row information + */ +row_info_enum +ePropMod2RowInfo(USHORT usPropMod, int iWordVersion) +{ + row_block_type tRow; + const UCHAR *aucPropMod; + int iLen; + + TRACE_MSG("ePropMod2RowInfo"); + + aucPropMod = aucReadPropModListItem(usPropMod); + if (aucPropMod == NULL) { + return found_nothing; + } + iLen = (int)usGetWord(0, aucPropMod); + + switch (iWordVersion) { + case 0: + return found_nothing; + case 1: + case 2: + return eGet2RowInfo(0, aucPropMod + 2, iLen, &tRow); + case 4: + case 5: + return found_nothing; + case 6: + case 7: + return eGet6RowInfo(0, aucPropMod + 2, iLen, &tRow); + case 8: + return eGet8RowInfo(0, aucPropMod + 2, iLen, &tRow); + default: + DBG_DEC(iWordVersion); + DBG_FIXME(); + return found_nothing; + } +} /* end of ePropMod2RowInfo */ diff --git a/propmod.c b/propmod.c new file mode 100644 index 0000000..7a3cdbb --- /dev/null +++ b/propmod.c @@ -0,0 +1,110 @@ +/* + * propmod.c + * Copyright (C) 2001-2003 A.J. van Os; Released under GPL + * + * Description: + * Build, read and destroy a list (array) of Word property modifiers + */ + +#include +#include +#include "antiword.h" + +#if defined(DEBUG) +#define ELEMENTS_TO_ADD 3 +#else +#define ELEMENTS_TO_ADD 30 +#endif /* DEBUG */ + +/* Variables needed to write the property modifier list */ +static UCHAR **ppAnchor = NULL; +static size_t tNextFree = 0; +static size_t tMaxElements = 0; + + +/* + * vDestroyPropModList - destroy the property modifier list + */ +void +vDestroyPropModList(void) +{ + size_t tIndex; + + DBG_MSG("vDestroyPropModList"); + + /* Free all the elements of the list */ + for (tIndex = 0; tIndex < tNextFree; tIndex++) { + ppAnchor[tIndex] = xfree(ppAnchor[tIndex]); + } + /* Free the list itself */ + ppAnchor = xfree(ppAnchor); + /* Reset all control variables */ + tNextFree = 0; + tMaxElements = 0; +} /* end of vDestroyPropModList */ + +/* + * vAdd2PropModList - add an element to the property modifier list + */ +void +vAdd2PropModList(const UCHAR *aucPropMod) +{ + size_t tSize, tLen; + + fail(aucPropMod == NULL); + + NO_DBG_MSG("vAdd2PropModList"); + + if (tNextFree >= tMaxElements) { + tMaxElements += ELEMENTS_TO_ADD; + tSize = tMaxElements * sizeof(UCHAR **); + ppAnchor = xrealloc(ppAnchor, tSize); + } + NO_DBG_DEC(tNextFree); + + tLen = 2 + (size_t)usGetWord(0, aucPropMod); + NO_DBG_HEX(tLen); + NO_DBG_PRINT_BLOCK(pucPropMod, tLen); + ppAnchor[tNextFree] = xmalloc(tLen); + memcpy(ppAnchor[tNextFree], aucPropMod, tLen); + tNextFree++; +} /* end of vAdd2PropModList */ + +/* + * aucReadPropModListItem - get an item of the property modifier list + */ +const UCHAR * +aucReadPropModListItem(USHORT usPropMod) +{ + static UCHAR aucBuffer[4]; + size_t tIndex; + + if (usPropMod == IGNORE_PROPMOD) { + /* This Properties Modifier must be ignored */ + return NULL; + } + + if (!odd(usPropMod)) { + /* Variant 1: The information is in the input ifself */ + aucBuffer[0] = 2; + aucBuffer[1] = 0; + aucBuffer[2] = (UCHAR)((usPropMod & 0x00fe) >> 1); + aucBuffer[3] = (UCHAR)((usPropMod & 0xff00) >> 8); + return aucBuffer; + } + + if (ppAnchor == NULL) { + /* No information available */ + return NULL; + } + + /* Variant 2: The input contains an index */ + tIndex = (size_t)(usPropMod >> 1); + if (tIndex >= tNextFree) { + DBG_HEX(usPropMod); + DBG_DEC(tIndex); + DBG_DEC(tNextFree); + return NULL; + } + return ppAnchor[tIndex]; +} /* end of aucGetPropModListItem */ diff --git a/riscos.c b/riscos.c new file mode 100644 index 0000000..78bd0fd --- /dev/null +++ b/riscos.c @@ -0,0 +1,251 @@ +/* + * riscos.c + * Copyright (C) 2001,2002 A.J. van Os; Released under GPL + * + * Description: + * RISC OS only functions + */ + +#include +#include +#include +#include "DeskLib:Error.h" +#include "DeskLib:SWI.h" +#include "antiword.h" + +#if !defined(DrawFile_Render) +#define DrawFile_Render 0x045540 +#endif /* !DrawFile_Render */ +#if !defined(JPEG_Info) +#define JPEG_Info 0x049980 +#endif /* !JPEG_Info */ + +/* + * werr - write an error message and exit if needed + */ +void +werr(int iFatal, const char *szFormat, ...) +{ + va_list tArg; + + va_start(tArg, szFormat); + Error_Report(iFatal, (char *)szFormat, tArg); + va_end(tArg); + switch (iFatal) { + case 0: /* The message is just a warning, so no exit */ + return; + case 1: /* Fatal error with a standard exit */ + exit(EXIT_FAILURE); + default: /* Fatal error with a non-standard exit */ + exit(iFatal); + } +} /* end of werr */ + +/* + * iGetFiletype + * This function will get the filetype of the given file. + * returns the filetype. + */ +int +iGetFiletype(const char *szFilename) +{ + os_error *e; + int iType; + + fail(szFilename == NULL || szFilename[0] == '\0'); + + e = SWI(2, 7, SWI_OS_File | XOS_Bit, + 23, szFilename, + NULL, NULL, NULL, NULL, NULL, NULL, &iType); + if (e == NULL) { + return iType; + } + werr(0, "Get Filetype error %d: %s", e->errnum, e->errmess); + return -1; +} /* end of iGetFiletype */ + +/* + * vSetFiletype + * This procedure will set the filetype of the given file to the given + * type. + */ +void +vSetFiletype(const char *szFilename, int iFiletype) +{ + os_error *e; + + fail(szFilename == NULL || szFilename[0] == '\0'); + + if (iFiletype < 0x000 || iFiletype > 0xfff) { + return; + } + e = SWI(3, 0, SWI_OS_File | XOS_Bit, + 18, szFilename, iFiletype); + if (e != NULL) { + switch (e->errnum) { + case 0x000113: /* ROM */ + case 0x0104e1: /* Read-only floppy DOSFS */ + case 0x0108c9: /* Read-only floppy ADFS */ + case 0x013803: /* Read-only ArcFS */ + case 0x80344a: /* CD-ROM */ + break; + default: + werr(0, "Set Filetype error %d: %s", + e->errnum, e->errmess); + break; + } + } +} /* end of vSetFileType */ + +/* + * Check if the directory part of the given file exists, make the directory + * if it does not exist yet. + * Returns TRUE in case of success, otherwise FALSE. + */ +BOOL +bMakeDirectory(const char *szFilename) +{ + os_error *e; + char *pcLastDot; + int iObjectType; + char szDirectory[PATH_MAX+1]; + + DBG_MSG("bMakeDirectory"); + fail(szFilename == NULL || szFilename[0] == '\0'); + DBG_MSG(szFilename); + + if (strlen(szFilename) >= sizeof(szDirectory)) { + DBG_DEC(strlen(szFilename)); + return FALSE; + } + strcpy(szDirectory, szFilename); + pcLastDot = strrchr(szDirectory, '.'); + if (pcLastDot == NULL) { + /* No directory equals current directory */ + DBG_MSG("No directory part given"); + return TRUE; + } + *pcLastDot = '\0'; + DBG_MSG(szDirectory); + /* Check if the name exists */ + e = SWI(2, 1, SWI_OS_File | XOS_Bit, + 17, szDirectory, + &iObjectType); + if (e != NULL) { + werr(0, "Directory check %d: %s", e->errnum, e->errmess); + return FALSE; + } + if (iObjectType == 2) { + /* The name exists and it is a directory */ + DBG_MSG("The directory already exists"); + return TRUE; + } + if (iObjectType != 0) { + /* The name exists and it is not a directory */ + DBG_DEC(iObjectType); + return FALSE; + } + /* The name does not exist, make the directory */ + e = SWI(5, 0, SWI_OS_File | XOS_Bit, + 8, szDirectory, 0, 0, 0); + if (e != NULL) { + werr(0, "I can't make a directory %d: %s", + e->errnum, e->errmess); + return FALSE; + } + return TRUE; +} /* end of bMakeDirectory */ + +/* + * iReadCurrentAlphabetNumber + * This function reads the current Alphabet number. + * Returns the current Alphabet number when successful, otherwise -1 + */ +int +iReadCurrentAlphabetNumber(void) +{ + os_error *e; + int iAlphabetNumber; + + e = SWI(2, 2, SWI_OS_Byte | XOS_Bit, + 71, 127, + NULL, &iAlphabetNumber); + if (e == NULL) { + return iAlphabetNumber; + } + werr(0, "Read alphabet error %d: %s", e->errnum, e->errmess); + return -1; +} /* end of iReadCurrentAlphabetNumber */ + +/* + * iGetRiscOsVersion - get the RISC OS version number + * + * returns the RISC OS version * 100 + */ +int +iGetRiscOsVersion(void) +{ + os_error *e; + int iVersion; + + e = SWI(3, 2, SWI_OS_Byte | XOS_Bit, + 129, 0, 0xff, + NULL, &iVersion); + if (e != NULL) { + werr(0, "Read RISC OS version error %d: %s", + e->errnum, e->errmess); + return 0; + } + switch (iVersion) { + case 0xa0: /* Arthur 1.20 */ + return 120; + case 0xa1: /* RISC OS 2.00 */ + return 200; + case 0xa2: /* RISC OS 2.01 */ + return 201; + case 0xa3: /* RISC OS 3.00 */ + return 300; + case 0xa4: /* RISC OS 3.1x */ + return 310; + case 0xa5: /* RISC OS 3.50 */ + return 350; + case 0xa6: /* RISC OS 3.60 */ + return 360; + case 0xa7: /* RISC OS 3.7x */ + return 370; + case 0xa8: /* RISC OS 4.0x */ + return 400; + default: + if (iVersion >= 0xa9 && iVersion <= 0xaf) { + /* RISC OS 4.10 and up */ + return 410; + } + /* Unknown version */ + return 0; + } +} /* end of iGetRiscOsVersion */ + +#if defined(DEBUG) +BOOL +bGetJpegInfo(UCHAR *pucJpeg, size_t tJpegSize) +{ + os_error *e; + int iReg0, iReg4, iReg5; + + e = SWI(3, 6, JPEG_Info | XOS_Bit, + 0x00, pucJpeg, tJpegSize, + &iReg0, NULL, NULL, NULL, &iReg4, &iReg5); + if (e == NULL) { + if (iReg0 & BIT(2)) { + DBG_MSG("Pixel density is a simple ratio"); + } else { + DBG_MSG("Pixel density is in dpi"); + } + DBG_DEC(iReg4); + DBG_DEC(iReg5); + return TRUE; + } + werr(0, "JPEG Info error %d: %s", e->errnum, e->errmess); + return FALSE; +} /* end of bGetJpegInfo */ +#endif /* DEBUG */ diff --git a/rowlist.c b/rowlist.c new file mode 100644 index 0000000..a3dd2fb --- /dev/null +++ b/rowlist.c @@ -0,0 +1,117 @@ +/* + * rowlist.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GPL + * + * Description: + * Build, read and destroy a list of Word table-row information + */ + +#include +#include +#include "antiword.h" + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct row_desc_tag { + row_block_type tInfo; + struct row_desc_tag *pNext; +} row_desc_type; + +/* Variables needed to write the Row Information List */ +static row_desc_type *pAnchor = NULL; +static row_desc_type *pRowLast = NULL; +/* Variable needed to read the Row Information List */ +static row_desc_type *pRowCurrent = NULL; + + +/* + * vDestroyRowInfoList - destroy the Row Information List + */ +void +vDestroyRowInfoList(void) +{ + row_desc_type *pCurr, *pNext; + + DBG_MSG("vDestroyRowInfoList"); + + /* Free the Row Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pRowLast = NULL; + pRowCurrent = NULL; +} /* end of vDestroyRowInfoList */ + +/* + * vAdd2RowInfoList - Add an element to the Row Information List + */ +void +vAdd2RowInfoList(const row_block_type *pRowBlock) +{ + row_desc_type *pListMember; + short *psTmp; + int iIndex; + + fail(pRowBlock == NULL); + + if (pRowBlock->ulFileOffsetStart == FC_INVALID || + pRowBlock->ulFileOffsetEnd == FC_INVALID || + pRowBlock->ulFileOffsetStart == pRowBlock->ulFileOffsetEnd) { + DBG_HEX_C(pRowBlock->ulFileOffsetStart != FC_INVALID, + pRowBlock->ulFileOffsetStart); + DBG_HEX_C(pRowBlock->ulFileOffsetEnd != FC_INVALID, + pRowBlock->ulFileOffsetEnd); + return; + } + + NO_DBG_HEX(pRowBlock->ulFileOffsetStart); + NO_DBG_HEX(pRowBlock->ulFileOffsetEnd); + NO_DBG_DEC(pRowBlock->ucNumberOfColumns); + + /* Create the new list member */ + pListMember = xmalloc(sizeof(row_desc_type)); + /* Fill the new list member */ + pListMember->tInfo = *pRowBlock; + pListMember->pNext = NULL; + /* Correct the values where needed */ + for (iIndex = 0, psTmp = pListMember->tInfo.asColumnWidth; + iIndex < (int)pListMember->tInfo.ucNumberOfColumns; + iIndex++, psTmp++) { + if (*psTmp < 0) { + *psTmp = 0; + DBG_MSG("The column width was negative"); + } + } + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + pRowCurrent = pListMember; + } else { + fail(pRowLast == NULL); + pRowLast->pNext = pListMember; + } + pRowLast = pListMember; +} /* end of vAdd2RowInfoList */ + +/* + * Get the next item in the Row Information List + */ +const row_block_type * +pGetNextRowInfoListItem(void) +{ + const row_block_type *pItem; + + if (pRowCurrent == NULL) { + return NULL; + } + pItem = &pRowCurrent->tInfo; + pRowCurrent = pRowCurrent->pNext; + return pItem; +} /* end of pGetNextRowInfoListItem */ diff --git a/saveas.c b/saveas.c new file mode 100644 index 0000000..678ff04 --- /dev/null +++ b/saveas.c @@ -0,0 +1,387 @@ +/* + * saveas.c + * Copyright (C) 1998-2001 A.J. van Os; Released under GPL + * + * Description: + * Functions to save the results as a textfile or a drawfile + */ + +#include +#include +#include "DeskLib:Menu.h" +#include "DeskLib:Save.h" +#include "DeskLib:Template.h" +#include "DeskLib:Window.h" +#include "drawfile.h" +#include "antiword.h" + +/* The window handle of the save window */ +static window_handle tSaveWindow = 0; + +/* Xfer_send box fields */ +#define DRAG_SPRITE 3 +#define OK_BUTTON 0 +#define CANCEL_BUTTON (-1) +#define FILENAME_ICON 2 + + +/* + * saveas - a wrapper around Save_InitSaveWindowhandler + */ +static void +saveas(int iFileType, char *szOutfile, size_t tEstSize, + save_filesaver save_function, void *pvReference) +{ + TRACE_MSG("saveas"); + + if (tSaveWindow == 0) { + tSaveWindow = Window_Create("xfer_send", template_TITLEMIN); + } + Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile); + Window_Show(tSaveWindow, open_UNDERPOINTER); + (void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE, + DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON, + save_function, NULL, NULL, tEstSize, iFileType, pvReference); +} /* end of saveas */ + +static BOOL +bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename) +{ + if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) { + werr(0, "I can't write to '%s'", szFilename); + return FALSE; + } + return TRUE; +} /* end of bWrite2File */ + +/* + * bText2File - Save the generated draw file to a Text file + */ +static BOOL +bText2File(char *szFilename, void *pvHandle) +{ + FILE *pFile; + diagram_type *pDiag; + drawfile_object *pObj; + drawfile_text *pText; + const char *pcTmp; + int iToGo, iX, iYtopPrev, iHeight, iLines; + BOOL bFirst, bIndent, bSuccess; + + TRACE_MSG("bText2File"); + + fail(szFilename == NULL || szFilename[0] == '\0'); + fail(pvHandle == NULL); + + DBG_MSG(szFilename); + + pDiag = (diagram_type *)pvHandle; + pFile = fopen(szFilename, "w"); + if (pFile == NULL) { + werr(0, "I can't open '%s' for writing", szFilename); + return FALSE; + } + bFirst = TRUE; + iYtopPrev = 0; + iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE); + bSuccess = TRUE; + fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects)); + iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects); + DBG_DEC(iToGo); + pcTmp = (const char *)pDiag->tInfo.data + + offsetof(drawfile_diagram, objects); + while (iToGo > 0 && bSuccess) { + pObj = (drawfile_object *)pcTmp; + switch (pObj->type) { + case drawfile_TYPE_TEXT: + pText = &pObj->data.text; + /* Compute the number of lines */ + iLines = (iYtopPrev - pText->bbox.max.y + + iHeight / 2) / iHeight; + DBG_DEC_C(iLines < 0, iYtopPrev); + DBG_DEC_C(iLines < 0, pText->bbox.max.y); + fail(iLines < 0); + bIndent = iLines > 0 || bFirst; + bFirst = FALSE; + /* Print the newlines */ + while (iLines > 0 && bSuccess) { + bSuccess = bWrite2File("\n", + 1, pFile, szFilename); + iLines--; + } + /* Print the indentation */ + if (bIndent && bSuccess) { + for (iX = Drawfile_ScreenToDraw(8); + iX <= pText->bbox.min.x && bSuccess; + iX += Drawfile_ScreenToDraw(16)) { + bSuccess = bWrite2File(" ", + 1, pFile, szFilename); + } + } + if (!bSuccess) { + break; + } + /* Print the text object */ + bSuccess = bWrite2File(pText->text, + strlen(pText->text), pFile, szFilename); + /* Setup for the next object */ + iYtopPrev = pText->bbox.max.y; + iHeight = pText->bbox.max.y - pText->bbox.min.y; + break; + case drawfile_TYPE_FONT_TABLE: + case drawfile_TYPE_PATH: + case drawfile_TYPE_SPRITE: + case drawfile_TYPE_JPEG: + /* These are not relevant in a textfile */ + break; + default: + DBG_DEC(pObj->type); + bSuccess = FALSE; + break; + } + pcTmp += pObj->size; + iToGo -= pObj->size; + } + DBG_DEC_C(iToGo != 0, iToGo); + if (bSuccess) { + bSuccess = bWrite2File("\n", 1, pFile, szFilename); + } + (void)fclose(pFile); + if (bSuccess) { + vSetFiletype(szFilename, FILETYPE_TEXT); + } else { + (void)remove(szFilename); + werr(0, "Unable to save textfile '%s'", szFilename); + } + return bSuccess; +} /* end of bText2File */ + +/* + * bSaveTextfile - save the diagram as a text file + */ +BOOL +bSaveTextfile(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + size_t tRecLen, tNbrRecs, tEstSize; + + TRACE_MSG("bSaveTextfile"); + + fail(pEvent == NULL); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + switch (pEvent->type) { + case event_SEND: /* From a menu */ + fail(pEvent->data.message.header.action != message_MENUWARN); + if (menu_currentopen != pDiag->pSaveMenu || + pEvent->data.message.data.menuwarn.selection[0] != + SAVEMENU_SAVETEXT) { + return FALSE; + } + break; + case event_KEY: /* From a key short cut */ + if (pEvent->data.key.caret.window != pDiag->tMainWindow) { + return FALSE; + } + break; + default: + DBG_DEC(pEvent->type); + return FALSE; + } + + tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3; + tNbrRecs = pDiag->tInfo.length / tRecLen + 1; + tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3; + DBG_DEC(tEstSize); + + saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag); + return TRUE; +} /* end of bSaveTextfile */ + +/* + * bDraw2File - Save the generated draw file to a Draw file + * + * Remark: This is not a simple copy action. The origin of the + * coordinates (0,0) must move from the top-left corner to the + * bottom-left corner. + */ +static BOOL +bDraw2File(char *szFilename, void *pvHandle) +{ + FILE *pFile; + diagram_type *pDiagram; + wimp_box *pBbox; + drawfile_object *pObj; + drawfile_text *pText; + drawfile_path *pPath; + drawfile_sprite *pSprite; + drawfile_jpeg *pJpeg; + int *piPath; + char *pcTmp; + int iYadd, iToGo, iSize; + BOOL bSuccess; + + TRACE_MSG("bDraw2File"); + + fail(szFilename == NULL || szFilename[0] == '\0'); + fail(pvHandle == NULL); + + NO_DBG_MSG(szFilename); + + pDiagram = (diagram_type *)pvHandle; + pFile = fopen(szFilename, "wb"); + if (pFile == NULL) { + werr(0, "I can't open '%s' for writing", szFilename); + return FALSE; + } + iToGo = pDiagram->tInfo.length; + DBG_DEC(iToGo); + pcTmp = pDiagram->tInfo.data; + bSuccess = bWrite2File(pcTmp, + offsetof(drawfile_diagram, bbox), pFile, szFilename); + if (bSuccess) { + pcTmp += offsetof(drawfile_diagram, bbox); + iToGo -= offsetof(drawfile_diagram, bbox); + pBbox = (wimp_box *)pcTmp; + iYadd = -pBbox->min.y; + pBbox->min.y += iYadd; + pBbox->max.y += iYadd; + bSuccess = bWrite2File(pcTmp, + sizeof(*pBbox), pFile, szFilename); + iToGo -= sizeof(*pBbox); + DBG_DEC(iToGo); + pcTmp += sizeof(*pBbox); + } else { + iYadd = 0; + } + while (iToGo > 0 && bSuccess) { + pObj = (drawfile_object *)pcTmp; + iSize = pObj->size; + switch (pObj->type) { + case drawfile_TYPE_FONT_TABLE: + bSuccess = bWrite2File(pcTmp, + iSize, pFile, szFilename); + pcTmp += iSize; + iToGo -= iSize; + break; + case drawfile_TYPE_TEXT: + pText = &pObj->data.text; + /* First correct the coordinates */ + pText->bbox.min.y += iYadd; + pText->bbox.max.y += iYadd; + pText->base.y += iYadd; + /* Now write the information to file */ + bSuccess = bWrite2File(pcTmp, + iSize, pFile, szFilename); + pcTmp += pObj->size; + iToGo -= pObj->size; + break; + case drawfile_TYPE_PATH: + pPath = &pObj->data.path; + /* First correct the coordinates */ + pPath->bbox.min.y += iYadd; + pPath->bbox.max.y += iYadd; + /* Now write the information to file */ + bSuccess = bWrite2File(pPath, + sizeof(*pPath), pFile, szFilename); + pcTmp += sizeof(*pPath); + iSize = pObj->size - sizeof(*pPath); + fail(iSize < 14 * sizeof(int)); + /* Second correct the path coordinates */ + piPath = xmalloc(iSize); + memcpy(piPath, pcTmp, iSize); + piPath[ 2] += iYadd; + piPath[ 5] += iYadd; + piPath[ 8] += iYadd; + piPath[11] += iYadd; + if (bSuccess) { + bSuccess = bWrite2File(piPath, + iSize, pFile, szFilename); + pcTmp += iSize; + } + piPath = xfree(piPath); + iToGo -= pObj->size; + break; + case drawfile_TYPE_SPRITE: + pSprite = &pObj->data.sprite; + /* First correct the coordinates */ + pSprite->bbox.min.y += iYadd; + pSprite->bbox.max.y += iYadd; + /* Now write the information to file */ + bSuccess = bWrite2File(pcTmp, + iSize, pFile, szFilename); + pcTmp += pObj->size; + iToGo -= pObj->size; + break; + case drawfile_TYPE_JPEG: + pJpeg = &pObj->data.jpeg; + /* First correct the coordinates */ + pJpeg->bbox.min.y += iYadd; + pJpeg->bbox.max.y += iYadd; + pJpeg->trfm.entries[2][1] += iYadd; + /* Now write the information to file */ + bSuccess = bWrite2File(pcTmp, + iSize, pFile, szFilename); + pcTmp += pObj->size; + iToGo -= pObj->size; + break; + default: + DBG_DEC(pObj->type); + bSuccess = FALSE; + break; + } + } + DBG_DEC_C(iToGo != 0, iToGo); + (void)fclose(pFile); + if (bSuccess) { + vSetFiletype(szFilename, FILETYPE_DRAW); + } else { + (void)remove(szFilename); + werr(0, "Unable to save drawfile '%s'", szFilename); + } + return bSuccess; +} /* end of bDraw2File */ + +/* + * bSaveDrawfile - save the diagram as a draw file + */ +BOOL +bSaveDrawfile(event_pollblock *pEvent, void *pvReference) +{ + diagram_type *pDiag; + size_t tEstSize; + + TRACE_MSG("bSaveDrawfile"); + + fail(pEvent == NULL); + fail(pvReference == NULL); + + pDiag = (diagram_type *)pvReference; + + switch (pEvent->type) { + case event_SEND: /* From a menu */ + fail(pEvent->data.message.header.action != message_MENUWARN); + if (menu_currentopen != pDiag->pSaveMenu || + pEvent->data.message.data.menuwarn.selection[0] != + SAVEMENU_SAVEDRAW) { + return FALSE; + } + break; + case event_KEY: /* From a key short cut */ + if (pEvent->data.key.caret.window != pDiag->tMainWindow) { + return FALSE; + } + break; + default: + DBG_DEC(pEvent->type); + return FALSE; + } + + tEstSize = pDiag->tInfo.length; + DBG_DEC(tEstSize); + + saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag); + return TRUE; +} /* end of bSaveDrawfile */ diff --git a/sectlist.c b/sectlist.c new file mode 100644 index 0000000..016d1b8 --- /dev/null +++ b/sectlist.c @@ -0,0 +1,165 @@ +/* + * sectlist.c + * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy list(s) of Word section information + */ + +#include +#include +#include "antiword.h" + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct section_mem_tag { + section_block_type tInfo; + ULONG ulCharPos; + struct section_mem_tag *pNext; +} section_mem_type; + +/* Variables needed to write the Section Information List */ +static section_mem_type *pAnchor = NULL; +static section_mem_type *pSectionLast = NULL; + + +/* + * vDestroySectionInfoList - destroy the Section Information List + */ +void +vDestroySectionInfoList(void) +{ + section_mem_type *pCurr, *pNext; + + DBG_MSG("vDestroySectionInfoList"); + + /* Free the Section Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pSectionLast = NULL; +} /* end of vDestroySectionInfoList */ + +/* + * vAdd2SectionInfoList - Add an element to the Section Information List + */ +void +vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulCharPos) +{ + section_mem_type *pListMember; + + fail(pSection == NULL); + + /* Create list member */ + pListMember = xmalloc(sizeof(section_mem_type)); + /* Fill the list member */ + pListMember->tInfo = *pSection; + pListMember->ulCharPos = ulCharPos; + pListMember->pNext = NULL; + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + } else { + fail(pSectionLast == NULL); + pSectionLast->pNext = pListMember; + } + pSectionLast = pListMember; +} /* vAdd2SectionInfoList */ + +/* + * vGetDefaultSection - fill the section struct with default values + */ +void +vGetDefaultSection(section_block_type *pSection) +{ + (void)memset(pSection, 0, sizeof(*pSection)); + pSection->bNewPage = TRUE; +} /* end of vGetDefaultSection */ + +/* + * vDefault2SectionInfoList - Add a default to the Section Information List + */ +void +vDefault2SectionInfoList(ULONG ulCharPos) +{ + section_block_type tSection; + + vGetDefaultSection(&tSection); + vAdd2SectionInfoList(&tSection, ulCharPos); +} /* end of vDefault2SectionInfoList */ + +/* + * pGetSectionInfo - get the section information + */ +const section_block_type * +pGetSectionInfo(const section_block_type *pOld, ULONG ulCharPos) +{ + const section_mem_type *pCurr; + + if (pOld == NULL || ulCharPos == 0) { + if (pAnchor == NULL) { + /* There are no records, make one */ + vDefault2SectionInfoList(0); + fail(pAnchor == NULL); + } + /* The first record */ + NO_DBG_MSG("First record"); + return &pAnchor->tInfo; + } + + NO_DBG_HEX(ulCharPos); + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + NO_DBG_HEX(pCurr->ulCharPos); + if (ulCharPos == pCurr->ulCharPos || + ulCharPos + 1 == pCurr->ulCharPos) { + NO_DBG_HEX(pCurr->ulCharPos); + return &pCurr->tInfo; + } + } + return pOld; +} /* end of pGetSectionInfo */ + +/* + * tGetNumberOfSections - get the number of sections + */ +size_t +tGetNumberOfSections(void) +{ + const section_mem_type *pCurr; + size_t tCounter; + + for (tCounter = 0, pCurr = pAnchor; + pCurr != NULL; + tCounter++, pCurr = pCurr->pNext) + ; /* Empty */ + return tCounter; +} /* end of tGetNumberOfSections */ + +/* + * ucGetSepHdrFtrSpecification - get the Heder/footer specification + */ +UCHAR +ucGetSepHdrFtrSpecification(size_t tSectionNumber) +{ + const section_mem_type *pCurr; + size_t tIndex; + + for (tIndex = 0, pCurr = pAnchor; + tIndex < tSectionNumber && pCurr != NULL; + tIndex++, pCurr = pCurr->pNext) + ; /* Empty */ + if (pCurr == NULL) { + DBG_DEC(tSectionNumber); + DBG_FIXME(); + return 0x00; + } + return pCurr->tInfo.ucHdrFtrSpecification; +} /* end of ucGetSepHdrFtrSpecification */ diff --git a/startup.c b/startup.c new file mode 100644 index 0000000..7e1b6d7 --- /dev/null +++ b/startup.c @@ -0,0 +1,145 @@ +/* + * startup.c + * Copyright (C) 1998-2001 A.J. van Os; Released under GPL + * + * Description: + * Try to force a single startup of !Antiword + */ + +#include +#include +#include +#include "DeskLib:Error.h" +#include "DeskLib:Event.h" +#include "DeskLib:SWI.h" +#include "antiword.h" + + +#if !defined(TaskManager_EnumerateTasks) +#define TaskManager_EnumerateTasks 0x042681 +#endif /* TaskManager_EnumerateTasks */ + +/* + * bIsMatch - decide whether the two strings match + * + * like strcmp, but this one ignores case + */ +static BOOL +bIsMatch(const char *szStr1, const char *szStr2) +{ + const char *pcTmp1, *pcTmp2; + + for (pcTmp1 = szStr1, pcTmp2 = szStr2; + *pcTmp1 != '\0'; + pcTmp1++, pcTmp2++) { + if (toupper(*pcTmp1) != toupper(*pcTmp2)) { + return FALSE; + } + } + return *pcTmp2 == '\0'; +} /* end of bIsMatch */ + +/* + * tGetTaskHandle - get the task handle of the given task + * + * returns the task handle when found, otherwise 0 + */ +static task_handle +tGetTaskHandle(const char *szTaskname) +{ + const char *pcTmp; + int iReg0, iIndex; + int aiBuffer[4]; + char szTmp[21]; + + iReg0 = 0; + do { + /* Get info on the next task */ + Error_CheckFatal(SWI(3, 1, TaskManager_EnumerateTasks | XOS_Bit, + iReg0, aiBuffer, sizeof(aiBuffer), &iReg0)); + /* Copy the (control character terminated) task name */ + for (iIndex = 0, pcTmp = (const char *)aiBuffer[1]; + iIndex < elementsof(szTmp); + iIndex++, pcTmp++) { + if (iscntrl(*pcTmp)) { + szTmp[iIndex] = '\0'; + break; + } + szTmp[iIndex] = *pcTmp; + } + szTmp[elementsof(szTmp) - 1] = '\0'; + if (bIsMatch(szTmp, szTaskname)) { + /* Task found */ + return (task_handle)aiBuffer[0]; + } + } while (iReg0 >= 0); + + /* Task not found */ + return 0; +} /* end of tGetTaskHandle */ + +int +main(int argc, char **argv) +{ + message_block tMsg; + task_handle tTaskHandle; + size_t tArgLen; + int aiMessages[] = {0}; + char szCommand[512]; + + Event_Initialise3("StartUp", 310, aiMessages); + + if (argc > 1) { + tArgLen = strlen(argv[1]); + } else { + tArgLen = 0; + } + if (tArgLen >= sizeof(tMsg.data.dataload.filename)) { + werr(1, "Input filename too long"); + return EXIT_FAILURE; + } + + tTaskHandle = tGetTaskHandle("antiword"); + + if (tTaskHandle == 0) { + /* Antiword is not active */ + strcpy(szCommand, "chain:.!Antiword"); + if (argc > 1) { + strcat(szCommand, " "); + strcat(szCommand, argv[1]); + } +#if defined(DEBUG) + strcat(szCommand, " "); + strcat(szCommand, "2>.Debug"); +#endif /* DEBUG */ + system(szCommand); + /* If we reach here something has gone wrong */ + return EXIT_FAILURE; + } + + /* Antiword is active */ + if (argc > 1) { + /* + * Send the argument to Antiword by imitating a + * drag-and-drop to Antiword's iconbar icon + */ + memset(&tMsg, 0, sizeof(tMsg)); + tMsg.header.size = ROUND4(offsetof(message_block, data) + + offsetof(message_dataload, filename) + + 1 + tArgLen); + tMsg.header.yourref = 0; + tMsg.header.action = message_DATALOAD; + tMsg.data.dataload.window = window_ICONBAR; + tMsg.data.dataload.icon = -1; + tMsg.data.dataload.size = 0; + tMsg.data.dataload.filetype = FILETYPE_MSWORD; + strcpy(tMsg.data.dataload.filename, argv[1]); + Error_CheckFatal(Wimp_SendMessage(event_SEND, + &tMsg, tTaskHandle, 0)); + return EXIT_SUCCESS; + } else { + /* Give an error message and return */ + werr(1, "Antiword is already running"); + return EXIT_FAILURE; + } +} /* end of main */ diff --git a/stylelist.c b/stylelist.c new file mode 100644 index 0000000..09b5ab5 --- /dev/null +++ b/stylelist.c @@ -0,0 +1,487 @@ +/* + * stylelist.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy a list of Word style information + */ + +#include +#include +#include +#include "antiword.h" + + +/* + * Private structure to hide the way the information + * is stored from the rest of the program + */ +typedef struct style_mem_tag { + style_block_type tInfo; + ULONG ulSequenceNumber; + struct style_mem_tag *pNext; +} style_mem_type; + +/* Variables needed to write the Style Information List */ +static style_mem_type *pAnchor = NULL; +static style_mem_type *pStyleLast = NULL; +/* The type of conversion */ +static conversion_type eConversionType = conversion_unknown; +/* The character set encoding */ +static encoding_type eEncoding = encoding_neutral; +/* Values for efficiency reasons */ +static const style_mem_type *pMidPtr = NULL; +static BOOL bMoveMidPtr = FALSE; +static BOOL bInSequence = TRUE; + + +/* + * vDestroyStyleInfoList - destroy the Style Information List + */ +void +vDestroyStyleInfoList(void) +{ + style_mem_type *pCurr, *pNext; + + DBG_MSG("vDestroyStyleInfoList"); + + /* Free the Style Information List */ + pCurr = pAnchor; + while (pCurr != NULL) { + pNext = pCurr->pNext; + pCurr = xfree(pCurr); + pCurr = pNext; + } + pAnchor = NULL; + /* Reset all control variables */ + pStyleLast = NULL; + pMidPtr = NULL; + bMoveMidPtr = FALSE; + bInSequence = TRUE; +} /* end of vDestroyStyleInfoList */ + +/* + * vConvertListCharacter - convert the list character + */ +static void +vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar) +{ + options_type tOptions; + size_t tLen; + + fail(szListChar == NULL); + fail(szListChar[0] != '\0'); + + if (usListChar < 0x80 && isprint((int)usListChar)) { + DBG_CHR_C(isalnum((int)usListChar), usListChar); + szListChar[0] = (char)usListChar; + szListChar[1] = '\0'; + return; + } + + if (ucNFC != LIST_SPECIAL && + ucNFC != LIST_SPECIAL2 && + ucNFC != LIST_BULLETS) { + szListChar[0] = '.'; + szListChar[1] = '\0'; + return; + } + + if (eConversionType == conversion_unknown || + eEncoding == encoding_neutral) { + vGetOptions(&tOptions); + eConversionType = tOptions.eConversionType; + eEncoding = tOptions.eEncoding; + } + + switch (usListChar) { + case 0x0000: case 0x00b7: case 0x00fe: case 0xf021: case 0xf043: + case 0xf06c: case 0xf093: case 0xf0b7: + usListChar = 0x2022; /* BULLET */ + break; + case 0x0096: case 0xf02d: + usListChar = 0x2013; /* EN DASH */ + break; + case 0x00a8: + usListChar = 0x2666; /* BLACK DIAMOND SUIT */ + break; + case 0x00de: + usListChar = 0x21d2; /* RIGHTWARDS DOUBLE ARROW */ + break; + case 0x00e0: case 0xf074: + usListChar = 0x25ca; /* LOZENGE */ + break; + case 0x00e1: + usListChar = 0x2329; /* LEFT ANGLE BRACKET */ + break; + case 0xf020: + usListChar = 0x0020; /* SPACE */ + break; + case 0xf041: + usListChar = 0x270c; /* VICTORY HAND */ + break; + case 0xf066: + usListChar = 0x03d5; /* GREEK PHI SYMBOL */ + break; + case 0xf06e: + usListChar = 0x25a0; /* BLACK SQUARE */ + break; + case 0xf06f: case 0xf070: case 0xf0a8: + usListChar = 0x25a1; /* WHITE SQUARE */ + break; + case 0xf071: + usListChar = 0x2751; /* LOWER RIGHT SHADOWED WHITE SQUARE */ + break; + case 0xf075: case 0xf077: + usListChar = 0x25c6; /* BLACK DIAMOND */ + break; + case 0xf076: + usListChar = 0x2756; /* BLACK DIAMOND MINUS WHITE X */ + break; + case 0xf0a7: + usListChar = 0x25aa; /* BLACK SMALL SQUARE */ + break; + case 0xf0d8: + usListChar = 0x27a2; /* RIGHTWARDS ARROWHEAD */ + break; + case 0xf0e5: + usListChar = 0x2199; /* SOUTH WEST ARROW */ + break; + case 0xf0f0: + usListChar = 0x21e8; /* RIGHTWARDS WHITE ARROW */ + break; + case 0xf0fc: + usListChar = 0x2713; /* CHECK MARK */ + break; + default: + if ((usListChar >= 0xe000 && usListChar < 0xf900) || + (usListChar < 0x80 && !isprint((int)usListChar))) { + /* + * All remaining private area characters and all + * remaining non-printable ASCII characters to their + * default bullet character + */ + DBG_HEX(usListChar); + DBG_FIXME(); + if (ucNFC == LIST_SPECIAL || ucNFC == LIST_SPECIAL2) { + usListChar = 0x2190; /* LEFTWARDS ARROW */ + } else { + usListChar = 0x2022; /* BULLET */ + } + } + break; + } + + if (eEncoding == encoding_utf_8) { + tLen = tUcs2Utf8(usListChar, szListChar, 4); + szListChar[tLen] = '\0'; + } else { + switch (usListChar) { + case 0x03d5: case 0x25a1: case 0x25c6: case 0x25ca: + case 0x2751: + szListChar[0] = 'o'; + break; + case 0x2013: case 0x2500: + szListChar[0] = '-'; + break; + case 0x2190: case 0x2199: case 0x2329: + szListChar[0] = '<'; + break; + case 0x21d2: + szListChar[0] = '='; + break; + case 0x21e8: case 0x27a2: + szListChar[0] = '>'; + break; + case 0x25a0: case 0x25aa: + szListChar[0] = '.'; + break; + case 0x2666: + szListChar[0] = OUR_DIAMOND; + break; + case 0x270c: + szListChar[0] = 'x'; + break; + case 0x2713: + szListChar[0] = 'V'; + break; + case 0x2756: + szListChar[0] = '*'; + break; + case 0x2022: + default: + vGetBulletValue(eConversionType, eEncoding, + szListChar, 2); + break; + } + tLen = 1; + } + szListChar[tLen] = '\0'; +} /* end of vConvertListCharacter */ + +/* + * eGetNumType - get the level type from the given level number + * + * Returns the level type + */ +level_type_enum +eGetNumType(UCHAR ucNumLevel) +{ + switch (ucNumLevel) { + case 1: case 2: case 3: case 4: case 5: + case 6: case 7: case 8: case 9: + return level_type_outline; + case 10: + return level_type_numbering; + case 11: + return level_type_sequence; + case 12: + return level_type_pause; + default: + return level_type_none; + } +} /* end of eGetNumType */ + +/* + * vCorrectStyleValues - correct style values that Antiword can't use + */ +void +vCorrectStyleValues(style_block_type *pStyleBlock) +{ + if (pStyleBlock->usBeforeIndent > 0x7fff) { + pStyleBlock->usBeforeIndent = 0; + } else if (pStyleBlock->usBeforeIndent > 2160) { + /* 2160 twips = 1.5 inches or 38.1 mm */ + DBG_DEC(pStyleBlock->usBeforeIndent); + pStyleBlock->usBeforeIndent = 2160; + } + if (pStyleBlock->usIstd >= 1 && + pStyleBlock->usIstd <= 9 && + pStyleBlock->usBeforeIndent < HEADING_GAP) { + NO_DBG_DEC(pStyleBlock->usBeforeIndent); + pStyleBlock->usBeforeIndent = HEADING_GAP; + } + + if (pStyleBlock->usAfterIndent > 0x7fff) { + pStyleBlock->usAfterIndent = 0; + } else if (pStyleBlock->usAfterIndent > 2160) { + /* 2160 twips = 1.5 inches or 38.1 mm */ + DBG_DEC(pStyleBlock->usAfterIndent); + pStyleBlock->usAfterIndent = 2160; + } + if (pStyleBlock->usIstd >= 1 && + pStyleBlock->usIstd <= 9 && + pStyleBlock->usAfterIndent < HEADING_GAP) { + NO_DBG_DEC(pStyleBlock->usAfterIndent); + pStyleBlock->usAfterIndent = HEADING_GAP; + } + + if (pStyleBlock->sLeftIndent < 0) { + pStyleBlock->sLeftIndent = 0; + } + if (pStyleBlock->sRightIndent > 0) { + pStyleBlock->sRightIndent = 0; + } + vConvertListCharacter(pStyleBlock->ucNFC, + pStyleBlock->usListChar, + pStyleBlock->szListChar); +} /* end of vCorrectStyleValues */ + +/* + * vAdd2StyleInfoList - Add an element to the Style Information List + */ +void +vAdd2StyleInfoList(const style_block_type *pStyleBlock) +{ + style_mem_type *pListMember; + + fail(pStyleBlock == NULL); + + NO_DBG_MSG("bAdd2StyleInfoList"); + + if (pStyleBlock->ulFileOffset == FC_INVALID) { + NO_DBG_DEC(pStyleBlock->usIstd); + return; + } + + NO_DBG_HEX(pStyleBlock->ulFileOffset); + NO_DBG_DEC_C(pStyleBlock->sLeftIndent != 0, + pStyleBlock->sLeftIndent); + NO_DBG_DEC_C(pStyleBlock->sRightIndent != 0, + pStyleBlock->sRightIndent); + NO_DBG_DEC_C(pStyleBlock->bNumPause, pStyleBlock->bNumPause); + NO_DBG_DEC_C(pStyleBlock->usIstd != 0, pStyleBlock->usIstd); + NO_DBG_DEC_C(pStyleBlock->usStartAt != 1, pStyleBlock->usStartAt); + NO_DBG_DEC_C(pStyleBlock->usAfterIndent != 0, + pStyleBlock->usAfterIndent); + NO_DBG_DEC_C(pStyleBlock->ucAlignment != 0, pStyleBlock->ucAlignment); + NO_DBG_DEC(pStyleBlock->ucNFC); + NO_DBG_HEX(pStyleBlock->usListChar); + + if (pStyleLast != NULL && + pStyleLast->tInfo.ulFileOffset == pStyleBlock->ulFileOffset) { + /* + * If two consecutive styles share the same + * offset, remember only the last style + */ + fail(pStyleLast->pNext != NULL); + pStyleLast->tInfo = *pStyleBlock; + /* Correct the values where needed */ + vCorrectStyleValues(&pStyleLast->tInfo); + return; + } + + /* Create list member */ + pListMember = xmalloc(sizeof(style_mem_type)); + /* Fill the list member */ + pListMember->tInfo = *pStyleBlock; + pListMember->pNext = NULL; + /* Add the sequence number */ + pListMember->ulSequenceNumber = + ulGetSeqNumber(pListMember->tInfo.ulFileOffset); + /* Correct the values where needed */ + vCorrectStyleValues(&pListMember->tInfo); + /* Add the new member to the list */ + if (pAnchor == NULL) { + pAnchor = pListMember; + /* For efficiency */ + pMidPtr = pAnchor; + bMoveMidPtr = FALSE; + bInSequence = TRUE; + } else { + fail(pStyleLast == NULL); + pStyleLast->pNext = pListMember; + /* For efficiency */ + if (bMoveMidPtr) { + pMidPtr = pMidPtr->pNext; + bMoveMidPtr = FALSE; + } else { + bMoveMidPtr = TRUE; + } + if (bInSequence) { + bInSequence = pListMember->ulSequenceNumber > + pStyleLast->ulSequenceNumber; + } + } + pStyleLast = pListMember; +} /* end of vAdd2StyleInfoList */ + +/* + * Get the record that follows the given recored in the Style Information List + */ +const style_block_type * +pGetNextStyleInfoListItem(const style_block_type *pCurr) +{ + const style_mem_type *pRecord; + size_t tOffset; + + if (pCurr == NULL) { + if (pAnchor == NULL) { + /* There are no records */ + return NULL; + } + /* The first record is the only one without a predecessor */ + return &pAnchor->tInfo; + } + tOffset = offsetof(style_mem_type, tInfo); + /* Many casts to prevent alignment warnings */ + pRecord = (style_mem_type *)(void *)((char *)pCurr - tOffset); + fail(pCurr != &pRecord->tInfo); + if (pRecord->pNext == NULL) { + /* The last record has no successor */ + return NULL; + } + return &pRecord->pNext->tInfo; +} /* end of pGetNextStyleInfoListItem */ + +/* + * Get the next text style + */ +const style_block_type * +pGetNextTextStyle(const style_block_type *pCurr) +{ + const style_block_type *pRecord; + + pRecord = pCurr; + do { + pRecord = pGetNextStyleInfoListItem(pRecord); + } while (pRecord != NULL && + (pRecord->eListID == hdrftr_list || + pRecord->eListID == macro_list || + pRecord->eListID == annotation_list)); + return pRecord; +} /* end of pGetNextTextStyle */ + +/* + * usGetIstd - get the istd that belongs to the given file offset + */ +USHORT +usGetIstd(ULONG ulFileOffset) +{ + const style_mem_type *pCurr, *pBest, *pStart; + ULONG ulSeq, ulBest; + + ulSeq = ulGetSeqNumber(ulFileOffset); + if (ulSeq == FC_INVALID) { + return ISTD_NORMAL; + } + NO_DBG_HEX(ulFileOffset); + NO_DBG_DEC(ulSeq); + + if (bInSequence && + pMidPtr != NULL && + ulSeq > pMidPtr->ulSequenceNumber) { + /* The istd is in the second half of the chained list */ + pStart = pMidPtr; + } else { + pStart = pAnchor; + } + + pBest = NULL; + ulBest = 0; + for (pCurr = pStart; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->ulSequenceNumber != FC_INVALID && + (pBest == NULL || pCurr->ulSequenceNumber > ulBest) && + pCurr->ulSequenceNumber <= ulSeq) { + pBest = pCurr; + ulBest = pCurr->ulSequenceNumber; + } + if (bInSequence && pCurr->ulSequenceNumber > ulSeq) { + break; + } + } + NO_DBG_DEC(ulBest); + + if (pBest == NULL) { + return ISTD_NORMAL; + } + + NO_DBG_DEC(pBest->tInfo.usIstd); + return pBest->tInfo.usIstd; +} /* end of usGetIstd */ + +/* + * bStyleImpliesList - does style info implies being part of a list + * + * Decide whether the style information implies that the given paragraph is + * part of a list + * + * Returns TRUE when the paragraph is part of a list, otherwise FALSE + */ +BOOL +bStyleImpliesList(const style_block_type *pStyle, int iWordVersion) +{ + fail(pStyle == NULL); + fail(iWordVersion < 0); + + if (pStyle->usIstd >= 1 && pStyle->usIstd <= 9) { + /* These are heading levels */ + return FALSE; + } + if (iWordVersion < 8) { + /* Check for old style lists */ + return pStyle->ucNumLevel != 0; + } + /* Check for new style lists */ + return pStyle->usListIndex != 0; +} /* end of bStyleImpliesList */ diff --git a/stylesheet.c b/stylesheet.c new file mode 100644 index 0000000..0cb4cc3 --- /dev/null +++ b/stylesheet.c @@ -0,0 +1,838 @@ +/* + * stylesheet.c + * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Build, read and destroy a list of stylesheet information + * + */ + +#include +#include "antiword.h" + + +#define SGC_PAP 1 +#define SGC_CHP 2 + +/* Variables needed to describe the stylesheet list */ +static style_block_type *atStyleInfo = NULL; +static font_block_type *atFontInfo = NULL; +static BOOL *abFilled = NULL; +static size_t tStdCount = 0; + + +/* + * vDestroyStylesheetList - destroy the stylesheet list + */ +void +vDestroyStylesheetList(void) +{ + DBG_MSG("vDestroyStylesheetList"); + + tStdCount = 0; + atStyleInfo = xfree(atStyleInfo); + atFontInfo = xfree(atFontInfo); + abFilled = xfree(abFilled); +} /* end of vDestroyStylesheetList */ + +/* + * vGetDefaultStyle - fill the style struct with default values + */ +static void +vGetDefaultStyle(style_block_type *pStyle) +{ + (void)memset(pStyle, 0, sizeof(*pStyle)); + pStyle->usIstd = ISTD_INVALID; + pStyle->usIstdNext = ISTD_INVALID; + pStyle->usStartAt = 1; + pStyle->ucListLevel = 9; +} /* end of vGetDefaultStyle */ + +/* + * vGetDefaultFont - fill the font struct with default values + */ +static void +vGetDefaultFont(font_block_type *pFont, USHORT usDefaultFontNumber) +{ + (void)memset(pFont, 0, sizeof(*pFont)); + pFont->usFontSize = DEFAULT_FONT_SIZE; + if (usDefaultFontNumber <= (USHORT)UCHAR_MAX) { + pFont->ucFontNumber = (UCHAR)usDefaultFontNumber; + } else { + DBG_DEC(usDefaultFontNumber); + DBG_FIXME(); + pFont->ucFontNumber = 0; + } +} /* end of vGetDefaultFont */ + +/* + * iGetStyleIndex - get the index of the record with the specified istd + * + * returns the index when found, otherwise -1 + */ +static int +iGetStyleIndex(USHORT usIstd) +{ + int iIndex; + + fail(abFilled == NULL); + + if (usIstd == ISTD_INVALID || abFilled == NULL) { + return -1; + } + + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (abFilled[iIndex] && atStyleInfo[iIndex].usIstd == usIstd) { + /* The record is filled and the istd matches */ + return iIndex; + } + } + return -1; +} /* end of iGetStyleIndex */ + +/* + * Get a build-in style for Winword 1/2 + */ +static void +vGetBuildinStyle(UCHAR ucStc, style_block_type *pStyle) +{ + fail(pStyle == NULL); + + /* Start with de defaults */ + vGetDefaultStyle(pStyle); + + /* Add the build-in style info */ + switch (ucStc) { + case 246: + case 247: + case 248: + case 249: + case 250: + case 255: + pStyle->sLeftIndent = 720; + break; + case 251: + case 252: + pStyle->sLeftIndent = 360; + break; + case 253: + pStyle->usBeforeIndent = 120; + break; + case 254: + pStyle->usBeforeIndent = 240; + break; + default: + if (ucStc >= 233 && ucStc <= 239) { + pStyle->sLeftIndent = (239 - (short)ucStc) * 360; + } + if (ucStc >= 225 && ucStc <= 232) { + pStyle->sLeftIndent = (232 - (short)ucStc) * 720; + pStyle->sRightIndent = 720; + } + break; + } +} /* end of vGetBuildinStyle */ + +/* + * Get a build-in fontstyle for Winword 1/2 + */ +static void +vGetBuildinFont(UCHAR ucStc, font_block_type *pFont) +{ + fail(pFont == NULL); + + /* Start with de defaults */ + vGetDefaultFont(pFont, 0); + + /* Add the build-in fontstyle info */ + switch (ucStc) { + case 223: + case 244: + pFont->usFontSize = 16; + break; + case 246: + case 247: + case 248: + pFont->usFontStyle |= FONT_ITALIC; + break; + case 249: + pFont->usFontStyle |= FONT_UNDERLINE; + break; + case 250: + pFont->usFontStyle |= FONT_BOLD; + break; + case 251: + pFont->usFontStyle |= FONT_UNDERLINE; + pFont->usFontSize = 24; + break; + case 252: + pFont->usFontStyle |= FONT_BOLD; + pFont->usFontSize = 24; + break; + case 253: + pFont->ucFontNumber = 2; + pFont->usFontStyle |= FONT_BOLD; + pFont->usFontSize = 24; + break; + case 254: + pFont->ucFontNumber = 2; + pFont->usFontStyle |= (FONT_BOLD|FONT_UNDERLINE); + pFont->usFontSize = 24; + break; + default: + break; + } +} /* end of vGetBuildinFont */ + +/* + * Convert a stylecode (stc) as used by WinWord 1/2 into a styleindex (istd) + * as used by Word 6 and up + */ +USHORT +usStc2istd(UCHAR ucStc) +{ + /* Old nil style to new nil style */ + if (ucStc == 222) { + return STI_NIL; + } + + /* Heading 1 through 9 must become istd 1 through 9 */ + /* so 254 through 246 must become 1 through 9 and vice versa */ + if ((ucStc >= 1 && ucStc <= 9) || + (ucStc >= 246 && ucStc <= 254)) { + return 255 - (USHORT)ucStc; + } + return (USHORT)ucStc; +} /* end of usStd2istd */ + +/* + * Build the lists with Stylesheet Information for WinWord 1/2 files + */ +void +vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +{ + style_block_type *pStyle; + font_block_type *pFont; + UCHAR *aucBuffer; + ULONG ulBeginStshInfo; + size_t tStshInfoLen, tName, tChpx, tPapx, tMaxIndex; + int iStIndex, iChpxIndex, iPapxIndex, iSt, iChpx, iPapx; + int iStd, iIndex, iBaseStyleIndex, iCounter; + USHORT usBaseStyle; + UCHAR ucStc, ucStcNext, ucStcBase; + + fail(pFile == NULL || aucHeader == NULL); + fail(iWordVersion != 1 && iWordVersion != 2); + + ulBeginStshInfo = ulGetLong(0x5e, aucHeader); /* fcStshf */ + NO_DBG_HEX(ulBeginStshInfo); + tStshInfoLen = (size_t)usGetWord(0x62, aucHeader); /* cbStshf */ + NO_DBG_DEC(tStshInfoLen); + + aucBuffer = xmalloc(tStshInfoLen); + if (!bReadBytes(aucBuffer, tStshInfoLen, ulBeginStshInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen); + + fail(2 > tStshInfoLen); + iStd = (int)usGetWord(0, aucBuffer); + + fail(2 + 2 > tStshInfoLen); + tName = (size_t)usGetWord(2, aucBuffer); + + fail(2 + tName + 2 > tStshInfoLen); + tChpx = (size_t)usGetWord(2 + tName, aucBuffer); + + fail(2 + tName + tChpx + 2 > tStshInfoLen); + tPapx = (size_t)usGetWord(2 + tName + tChpx, aucBuffer); + + fail(2 + tName + tChpx + tPapx + 2 > tStshInfoLen); + tStdCount = (size_t)usGetWord(2 + tName + tChpx + tPapx, aucBuffer); + + NO_DBG_HEX(tStdCount); + + atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type)); + atFontInfo = xcalloc(tStdCount, sizeof(font_block_type)); + abFilled = xcalloc(tStdCount, sizeof(BOOL)); + + do { + iCounter = 0; + iStIndex = 2 + 2; + iChpxIndex = 2 + (int)tName + 2; + iPapxIndex = 2 + (int)tName + (int)tChpx + 2; + tMaxIndex = 2 + tName + tChpx + tPapx + 2; + /* Read the styles one-by-one */ + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + pStyle = &atStyleInfo[iIndex]; + pFont = &atFontInfo[iIndex]; + iSt = (int)ucGetByte(iStIndex, aucBuffer); + iChpx = (int)ucGetByte(iChpxIndex, aucBuffer); + iPapx = (int)ucGetByte(iPapxIndex, aucBuffer); + NO_DBG_HEX(iSt); + NO_DBG_HEX(iChpx); + NO_DBG_HEX(iPapx); + if (iSt == 0xff || tMaxIndex + 1 >= tStshInfoLen) { + /* Undefined style or no information */ + iStIndex++; + iChpxIndex++; + iPapxIndex++; + tMaxIndex += 2; + if (!abFilled[iIndex]) { + DBG_HEX_C(iChpx != 0xff, iChpx); + DBG_HEX_C(iPapx != 0xff, iPapx); + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, 0); + abFilled[iIndex] = TRUE; + } + continue; + } + + NO_DBG_STRN(aucBuffer + iStIndex + 1, iSt); + iStIndex += iSt + 1; + + ucStcNext = ucGetByte(tMaxIndex, aucBuffer); + ucStcBase = ucGetByte(tMaxIndex + 1, aucBuffer); + ucStc = (UCHAR)((iIndex - iStd) & 0xff); + NO_DBG_DEC(ucStc); + + if (iChpx == 0xff || iPapx == 0xff) { + /* Use a build-in style */ + iChpxIndex++; + iPapxIndex++; + tMaxIndex += 2; + if (!abFilled[iIndex]) { + DBG_HEX_C(iChpx != 0xff, iChpx); + DBG_HEX_C(iPapx != 0xff, iPapx); + vGetBuildinStyle(ucStc, pStyle); + pStyle->usIstd = usStc2istd(ucStc); + pStyle->usIstdNext = + usStc2istd(ucStcNext); + vGetBuildinFont(ucStc, pFont); + abFilled[iIndex] = TRUE; + } + continue; + } + + if (abFilled[iIndex]) { + /* This record has already been filled */ + iChpxIndex += iChpx + 1; + iPapxIndex += iPapx + 1; + tMaxIndex += 2; + continue; + } + + usBaseStyle = usStc2istd(ucStcBase); + + if (usBaseStyle == STI_NIL) { + /* Based on the Nil style */ + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, 0); + } else { + iBaseStyleIndex = iGetStyleIndex(usBaseStyle); + NO_DBG_DEC(iBaseStyleIndex); + if (iBaseStyleIndex < 0) { + /* This style is not known yet */ + iChpxIndex += iChpx + 1; + iPapxIndex += iPapx + 1; + tMaxIndex += 2; + continue; + } + fail(iBaseStyleIndex >= (int)tStdCount); + fail(!abFilled[iBaseStyleIndex]); + /* Based on the specified base style */ + *pStyle = atStyleInfo[iBaseStyleIndex]; + *pFont = atFontInfo[iBaseStyleIndex]; + } + pStyle->usIstd = usStc2istd(ucStc); + pStyle->usIstdNext = usStc2istd(ucStcNext); + + abFilled[iIndex] = TRUE; + iCounter++; + + /* Add the changes if any */ + switch (iChpx) { + case 0x00: + case 0xff: + iChpxIndex++; + break; + default: + NO_DBG_PRINT_BLOCK(aucBuffer + iChpxIndex + 1, + iChpx); + if (iWordVersion == 1) { + vGet1FontInfo(0, + aucBuffer + iChpxIndex + 1, + (size_t)iChpx, pFont); + } else { + vGet2FontInfo(0, + aucBuffer + iChpxIndex + 1, + (size_t)iChpx, pFont); + } + iChpxIndex += iChpx + 1; + break; + } + + switch (iPapx) { + case 0x00: + case 0xff: + iPapxIndex++; + break; + default: + NO_DBG_PRINT_BLOCK(aucBuffer + iPapxIndex + 8, + iPapx - 7); + vGet2StyleInfo(0, aucBuffer + iPapxIndex + 8, + iPapx - 7, pStyle); + iPapxIndex += iPapx + 1; + break; + } + tMaxIndex += 2; + + } + NO_DBG_DEC(iCounter); + } while (iCounter > 0); + + /* Fill records that are still empty */ + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (!abFilled[iIndex]) { + NO_DBG_DEC(iIndex); + vGetDefaultStyle(&atStyleInfo[iIndex]); + vGetDefaultFont(&atFontInfo[iIndex], 0); + } + } + + /* Clean up before you leave */ + abFilled = xfree(abFilled); + aucBuffer = xfree(aucBuffer); +} /* end of vGet2Stylesheet */ + +/* + * Build the lists with Stylesheet Information for Word 6/7 files + */ +void +vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) +{ + style_block_type *pStyle; + font_block_type *pFont; + UCHAR *aucBuffer; + ULONG ulBeginStshInfo; + size_t tStshInfoLen, tOffset, tStdLen, tStdBaseInFile; + size_t tPos, tNameLen, tUpxLen; + int iIndex, iBaseStyleIndex, iCounter; + USHORT usTmp, usUpxCount, usStyleType, usBaseStyle; + USHORT usFtcStandardChpStsh; + + fail(pFile == NULL || aucHeader == NULL); + fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); + fail(aulBBD == NULL); + + ulBeginStshInfo = ulGetLong(0x60, aucHeader); /* fcStshf */ + NO_DBG_HEX(ulBeginStshInfo); + tStshInfoLen = (size_t)ulGetLong(0x64, aucHeader); /* lcbStshf */ + NO_DBG_DEC(tStshInfoLen); + + aucBuffer = xmalloc(tStshInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginStshInfo, tStshInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen); + + tStdCount = (size_t)usGetWord(2, aucBuffer); + NO_DBG_DEC(tStdCount); + tStdBaseInFile = (size_t)usGetWord(4, aucBuffer); + usFtcStandardChpStsh = usGetWord(14, aucBuffer); + NO_DBG_DEC(usFtcStandardChpStsh); + + atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type)); + atFontInfo = xcalloc(tStdCount, sizeof(font_block_type)); + abFilled = xcalloc(tStdCount, sizeof(BOOL)); + + do { + iCounter = 0; + /* Read the styles one-by-one */ + for (iIndex = 0, tOffset = 2 + (size_t)usGetWord(0, aucBuffer); + iIndex < (int)tStdCount; + iIndex++, tOffset += 2 + tStdLen) { + NO_DBG_DEC(tOffset); + tStdLen = (size_t)usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(tStdLen); + if (abFilled[iIndex]) { + /* This record has already been filled */ + continue; + } + pStyle = &atStyleInfo[iIndex]; + pFont = &atFontInfo[iIndex]; + if (tStdLen == 0) { + /* Empty record */ + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, usFtcStandardChpStsh); + abFilled[iIndex] = TRUE; + continue; + } + usTmp = usGetWord(tOffset + 4, aucBuffer); + usStyleType = usTmp % 16; + usBaseStyle = usTmp / 16; + NO_DBG_DEC(usStyleType); + NO_DBG_DEC(usBaseStyle); + if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) { + /* Based on the Nil style */ + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, usFtcStandardChpStsh); + } else { + iBaseStyleIndex = iGetStyleIndex(usBaseStyle); + NO_DBG_DEC(iBaseStyleIndex); + if (iBaseStyleIndex < 0) { + /* This base style is not known yet */ + continue; + } + fail(iBaseStyleIndex >= (int)tStdCount); + fail(!abFilled[iBaseStyleIndex]); + /* Based on the specified base style */ + *pStyle = atStyleInfo[iBaseStyleIndex]; + pStyle->usIstd = ISTD_INVALID; + *pFont = atFontInfo[iBaseStyleIndex]; + } + abFilled[iIndex] = TRUE; + iCounter++; + /* STD */ + usTmp = usGetWord(tOffset + 6, aucBuffer); + usUpxCount = usTmp % 16; + pStyle->usIstdNext = usTmp / 16;; + NO_DBG_DEC(usUpxCount); + tPos = 2 + tStdBaseInFile; + NO_DBG_DEC(tPos); + tNameLen = (size_t)ucGetByte(tOffset + tPos, aucBuffer); + NO_DBG_DEC(tNameLen); + NO_DBG_STRN(aucBuffer + tOffset + tPos + 1, tNameLen); + tNameLen++; /* Include the ASCII NULL character */ + tPos += 1 + tNameLen; + if (odd(tPos)) { + tPos++; + } + NO_DBG_DEC(tPos); + if (tPos >= tStdLen) { + continue; + } + tUpxLen = (size_t)usGetWord(tOffset + tPos, aucBuffer); + NO_DBG_DEC(tUpxLen); + if (tPos + tUpxLen > tStdLen) { + /* UPX length too large to be a record */ + DBG_DEC_C(tPos + tUpxLen > tStdLen, + tPos + tUpxLen); + continue; + } + if (usStyleType == SGC_PAP && usUpxCount >= 1) { + if (tUpxLen >= 2) { + NO_DBG_PRINT_BLOCK( + aucBuffer + tOffset + tPos + 2, + tUpxLen); + pStyle->usIstd = usGetWord( + tOffset + tPos + 2, aucBuffer); + NO_DBG_DEC(pStyle->usIstd); + NO_DBG_DEC(pStyle->usIstdNext); + vGet6StyleInfo(0, + aucBuffer + tOffset + tPos + 4, + tUpxLen - 2, pStyle); + NO_DBG_DEC(pStyle->sLeftIndent); + NO_DBG_DEC(pStyle->sRightIndent); + NO_DBG_HEX(pStyle->ucAlignment); + } + tPos += 2 + tUpxLen; + if (odd(tPos)) { + tPos++; + } + NO_DBG_DEC(tPos); + tUpxLen = (size_t)usGetWord( + tOffset + tPos, aucBuffer); + NO_DBG_DEC(tUpxLen); + } + if (tUpxLen == 0 || tPos + tUpxLen > tStdLen) { + /* Too small or too large to be a record */ + DBG_DEC_C(tPos + tUpxLen > tStdLen, + tPos + tUpxLen); + continue; + } + if ((usStyleType == SGC_PAP && usUpxCount >= 2) || + (usStyleType == SGC_CHP && usUpxCount >= 1)) { + NO_DBG_PRINT_BLOCK( + aucBuffer + tOffset + tPos + 2, + tUpxLen); + vGet6FontInfo(0, ISTD_INVALID, + aucBuffer + tOffset + tPos + 2, + (int)tUpxLen, pFont); + NO_DBG_DEC(pFont->usFontSize); + NO_DBG_DEC(pFont->ucFontcolor); + NO_DBG_HEX(pFont->usFontStyle); + } + } + NO_DBG_DEC(iCounter); + } while (iCounter > 0); + + /* Fill records that are still empty */ + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (!abFilled[iIndex]) { + NO_DBG_DEC(iIndex); + vGetDefaultStyle(&atStyleInfo[iIndex]); + vGetDefaultFont(&atFontInfo[iIndex], + usFtcStandardChpStsh); + } + } + + /* Clean up before you leave */ + abFilled = xfree(abFilled); + aucBuffer = xfree(aucBuffer); +} /* end of vGet6Stylesheet */ + +/* + * Build the lists with Stylesheet Information for Word 8/9/10 files + */ +void +vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + style_block_type *pStyle; + font_block_type *pFont; + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulBeginStshInfo; + size_t tStshInfoLen, tBlockDepotLen, tOffset, tStdLen, tStdBaseInFile; + size_t tBlockSize, tPos, tNameLen, tUpxLen; + int iIndex, iBaseStyleIndex, iCounter; + USHORT usTmp, usUpxCount, usStyleType, usBaseStyle; + USHORT usFtcStandardChpStsh; + + fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + ulBeginStshInfo = ulGetLong(0xa2, aucHeader); /* fcStshf */ + NO_DBG_HEX(ulBeginStshInfo); + tStshInfoLen = (size_t)ulGetLong(0xa6, aucHeader); /* lcbStshf */ + NO_DBG_DEC(tStshInfoLen); + + NO_DBG_DEC(pPPS->tTable.ulSB); + NO_DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No stylesheet information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tStshInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginStshInfo, tStshInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen); + + tStdCount = (size_t)usGetWord(2, aucBuffer); + NO_DBG_DEC(tStdCount); + tStdBaseInFile = (size_t)usGetWord(4, aucBuffer); + usFtcStandardChpStsh = usGetWord(14, aucBuffer); + NO_DBG_DEC(usFtcStandardChpStsh); + + atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type)); + atFontInfo = xcalloc(tStdCount, sizeof(font_block_type)); + abFilled = xcalloc(tStdCount, sizeof(BOOL)); + + do { + iCounter = 0; + /* Read the styles one-by-one */ + for (iIndex = 0, tOffset = 2 + (size_t)usGetWord(0, aucBuffer); + iIndex < (int)tStdCount; + iIndex++, tOffset += 2 + tStdLen) { + NO_DBG_DEC(tOffset); + tStdLen = (size_t)usGetWord(tOffset, aucBuffer); + NO_DBG_DEC(tStdLen); + if (abFilled[iIndex]) { + /* This record has already been filled */ + continue; + } + pStyle = &atStyleInfo[iIndex]; + pFont = &atFontInfo[iIndex]; + if (tStdLen == 0) { + /* Empty record */ + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, usFtcStandardChpStsh); + abFilled[iIndex] = TRUE; + continue; + } + usTmp = usGetWord(tOffset + 4, aucBuffer); + usStyleType = usTmp % 16; + usBaseStyle = usTmp / 16; + NO_DBG_DEC(usStyleType); + NO_DBG_DEC(usBaseStyle); + if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) { + /* Based on the Nil style */ + vGetDefaultStyle(pStyle); + vGetDefaultFont(pFont, usFtcStandardChpStsh); + } else { + iBaseStyleIndex = iGetStyleIndex(usBaseStyle); + NO_DBG_DEC(iBaseStyleIndex); + if (iBaseStyleIndex < 0) { + /* This base style is not known yet */ + continue; + } + fail(iBaseStyleIndex >= (int)tStdCount); + fail(!abFilled[iBaseStyleIndex]); + /* Based on the specified base style */ + *pStyle = atStyleInfo[iBaseStyleIndex]; + pStyle->usIstd = ISTD_INVALID; + *pFont = atFontInfo[iBaseStyleIndex]; + } + abFilled[iIndex] = TRUE; + iCounter++; + /* STD */ + usTmp = usGetWord(tOffset + 6, aucBuffer); + usUpxCount = usTmp % 16; + pStyle->usIstdNext = usTmp / 16; + NO_DBG_DEC(usUpxCount); + tPos = 2 + tStdBaseInFile; + NO_DBG_DEC(tPos); + tNameLen = (size_t)usGetWord(tOffset + tPos, aucBuffer); + NO_DBG_DEC(tNameLen); + tNameLen *= 2; /* From Unicode characters to bytes */ + NO_DBG_UNICODE_N(aucBuffer + tOffset + tPos + 2, + tNameLen); + tNameLen += 2; /* Include the Unicode NULL character */ + tPos += 2 + tNameLen; + if (odd(tPos)) { + tPos++; + } + NO_DBG_DEC(tPos); + if (tPos >= tStdLen) { + continue; + } + tUpxLen = (size_t)usGetWord(tOffset + tPos, aucBuffer); + NO_DBG_DEC(tUpxLen); + if (tPos + tUpxLen > tStdLen) { + /* UPX length too large to be a record */ + DBG_DEC_C(tPos + tUpxLen > tStdLen, + tPos + tUpxLen); + continue; + } + if (usStyleType == SGC_PAP && usUpxCount >= 1) { + if (tUpxLen >= 2) { + NO_DBG_PRINT_BLOCK( + aucBuffer + tOffset + tPos + 2, + tUpxLen); + pStyle->usIstd = usGetWord( + tOffset + tPos + 2, aucBuffer); + NO_DBG_DEC(pStyle->usIstd); + NO_DBG_DEC(pStyle->usIstdNext); + vGet8StyleInfo(0, + aucBuffer + tOffset + tPos + 4, + tUpxLen - 2, pStyle); + NO_DBG_DEC(pStyle->sLeftIndent); + NO_DBG_DEC(pStyle->sRightIndent); + NO_DBG_HEX(pStyle->ucAlignment); + } + tPos += 2 + tUpxLen; + if (odd(tPos)) { + tPos++; + } + NO_DBG_DEC(tPos); + tUpxLen = (size_t)usGetWord( + tOffset + tPos, aucBuffer); + NO_DBG_DEC(tUpxLen); + } + if (tUpxLen == 0 || tPos + tUpxLen > tStdLen) { + /* Too small or too large to be a record */ + DBG_DEC_C(tPos + tUpxLen > tStdLen, + tPos + tUpxLen); + continue; + } + if ((usStyleType == SGC_PAP && usUpxCount >= 2) || + (usStyleType == SGC_CHP && usUpxCount >= 1)) { + NO_DBG_PRINT_BLOCK( + aucBuffer + tOffset + tPos + 2, + tUpxLen); + vGet8FontInfo(0, ISTD_INVALID, + aucBuffer + tOffset + tPos + 2, + (int)tUpxLen, pFont); + NO_DBG_DEC(pFont->usFontSize); + NO_DBG_DEC(pFont->ucFontcolor); + NO_DBG_HEX(pFont->usFontStyle); + } + } + NO_DBG_DEC(iCounter); + } while (iCounter > 0); + + /* Fill records that are still empty */ + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (!abFilled[iIndex]) { + NO_DBG_DEC(iIndex); + vGetDefaultStyle(&atStyleInfo[iIndex]); + vGetDefaultFont(&atFontInfo[iIndex], + usFtcStandardChpStsh); + } + } + + /* Clean up before you leave */ + abFilled = xfree(abFilled); + aucBuffer = xfree(aucBuffer); +} /* end of vGet8Stylesheet */ + +/* + * vFillStyleFromStylesheet - fill a style struct with stylesheet info + */ +void +vFillStyleFromStylesheet(USHORT usIstd, style_block_type *pStyle) +{ + int iIndex; + + fail(pStyle == NULL); + + if (usIstd != ISTD_INVALID && usIstd != STI_NIL && usIstd != STI_USER) { + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (atStyleInfo[iIndex].usIstd == usIstd) { + /* Right index found; return style */ + *pStyle = atStyleInfo[iIndex]; + return; + } + } + } + + vGetDefaultStyle(pStyle); + pStyle->usIstd = usIstd; +} /* end of vFillStyleFromStylesheet */ + +/* + * vFillFontFromStylesheet - fill a font struct with stylesheet info + */ +void +vFillFontFromStylesheet(USHORT usIstd, font_block_type *pFont) +{ + int iIndex; + + fail(pFont == NULL); + + if (usIstd != ISTD_INVALID && usIstd != STI_NIL && usIstd != STI_USER) { + for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { + if (atStyleInfo[iIndex].usIstd == usIstd) { + /* Right index found; return font */ + *pFont = atFontInfo[iIndex]; + return; + } + } + } + + vGetDefaultFont(pFont, 0); +} /* end of vFillFontFromStylesheet */ diff --git a/summary.c b/summary.c new file mode 100644 index 0000000..d9ee687 --- /dev/null +++ b/summary.c @@ -0,0 +1,888 @@ +/* + * summary.c + * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Read the summary information of a Word document + */ + +#include +#include +#include "antiword.h" + +#define P_HEADER_SZ 28 +#define P_SECTIONLIST_SZ 20 +#define P_LENGTH_SZ 4 +#define P_SECTION_MAX_SZ (2 * P_SECTIONLIST_SZ + P_LENGTH_SZ) +#define P_SECTION_SZ(x) ((x) * P_SECTIONLIST_SZ + P_LENGTH_SZ) + +#define PID_TITLE 2 +#define PID_SUBJECT 3 +#define PID_AUTHOR 4 +#define PID_CREATE_DTM 12 +#define PID_LASTSAVE_DTM 13 +#define PID_APPNAME 18 + +#define PIDD_MANAGER 14 +#define PIDD_COMPANY 15 + +#define VT_LPSTR 30 +#define VT_FILETIME 64 + +#define TIME_OFFSET_HI 0x019db1de +#define TIME_OFFSET_LO 0xd53e8000 + +static char *szTitle = NULL; +static char *szSubject = NULL; +static char *szAuthor = NULL; +static time_t tCreateDtm = (time_t)-1; +static time_t tLastSaveDtm= (time_t)-1; +static char *szAppName = NULL; +static char *szManager = NULL; +static char *szCompany = NULL; +static USHORT usLid = (USHORT)-1; + + +/* + * vDestroySummaryInfo - destroy the summary information + */ +void +vDestroySummaryInfo(void) +{ + TRACE_MSG("vDestroySummaryInfo"); + + szTitle = xfree(szTitle); + szSubject = xfree(szSubject); + szAuthor = xfree(szAuthor); + tCreateDtm = (time_t)-1; + tLastSaveDtm = (time_t)-1; + szAppName = xfree(szAppName); + szManager = xfree(szManager); + szCompany = xfree(szCompany); + usLid = (USHORT)-1; +} /* end of vDestroySummaryInfo */ + +/* + * tConvertDosDate - convert DOS date format + * + * returns Unix time_t or -1 + */ +static time_t +tConvertDosDate(const char *szDosDate) +{ + struct tm tTime; + const char *pcTmp; + time_t tResult; + + memset(&tTime, 0, sizeof(tTime)); + pcTmp = szDosDate; + /* Get the month */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_mon = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_mon *= 10; + tTime.tm_mon += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Get the first separater */ + if (isalnum(*pcTmp)) { + return (time_t)-1; + } + pcTmp++; + /* Get the day */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_mday = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_mday *= 10; + tTime.tm_mday += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Get the second separater */ + if (isalnum(*pcTmp)) { + return (time_t)-1; + } + pcTmp++; + /* Get the year */ + if (!isdigit(*pcTmp)) { + return (time_t)-1; + } + tTime.tm_year = (int)(*pcTmp - '0'); + pcTmp++; + if (isdigit(*pcTmp)) { + tTime.tm_year *= 10; + tTime.tm_year += (int)(*pcTmp - '0'); + pcTmp++; + } + /* Check the values */ + if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) { + return (time_t)-1; + } + /* Correct the values */ + tTime.tm_mon--; /* From 01-12 to 00-11 */ + if (tTime.tm_year < 80) { + tTime.tm_year += 100; /* 00 means 2000 is 100 */ + } + tTime.tm_isdst = -1; + tResult = mktime(&tTime); + NO_DBG_MSG(ctime(&tResult)); + return tResult; +} /* end of tConvertDosDate */ + +/* + * szLpstr - get a zero terminate string property + */ +static char * +szLpstr(ULONG ulOffset, const UCHAR *aucBuffer) +{ + char *szStart, *szResult, *szTmp; + size_t tSize; + + tSize = (size_t)ulGetLong(ulOffset + 4, aucBuffer); + NO_DBG_DEC(tSize); + if (tSize == 0) { + return NULL; + } + /* Remove white space from the start of the string */ + szStart = (char *)aucBuffer + ulOffset + 8; + NO_DBG_MSG(szStart); + fail(strlen(szStart) >= tSize); + while (isspace(*szStart)) { + szStart++; + } + if (szStart[0] == '\0') { + return NULL; + } + szResult = xstrdup(szStart); + /* Remove white space from the end of the string */ + szTmp = szResult + strlen(szResult) - 1; + while (isspace(*szTmp)) { + *szTmp = '\0'; + szTmp--; + } + NO_DBG_MSG(szResult); + return szResult; +} /* end of szLpstr */ + +/* + * tFiletime - get a filetime property + */ +static time_t +tFiletime(ULONG ulOffset, const UCHAR *aucBuffer) +{ + double dHi, dLo, dTmp; + ULONG ulHi, ulLo; + time_t tResult; + + ulLo = ulGetLong(ulOffset + 4, aucBuffer); + ulHi = ulGetLong(ulOffset + 8, aucBuffer); + NO_DBG_HEX(ulHi); + NO_DBG_HEX(ulLo); + + /* Move the starting point from 01 Jan 1601 to 01 Jan 1970 */ + dHi = (double)ulHi - (double)TIME_OFFSET_HI; + dLo = (double)ulLo - (double)TIME_OFFSET_LO; + NO_DBG_FLT(dHi); + NO_DBG_FLT(dLo); + + /* Combine the values and divide by 10^7 to get seconds */ + dTmp = dLo / 10000000.0; /* 10^7 */ + dTmp += dHi * 429.4967926; /* 2^32 / 10^7 */ + NO_DBG_FLT(dTmp); + + /* Make a time_t */ + if (dTmp - 0.5 < TIME_T_MIN || dTmp + 0.5 > TIME_T_MAX) { + return (time_t)-1; + } + tResult = dTmp < 0.0 ? (time_t)(dTmp - 0.5) : (time_t)(dTmp + 0.5); + NO_DBG_MSG(ctime(&tResult)); + return tResult; +} /* end of tFiletime */ + +/* + * vAnalyseSummaryInfo - analyse the summary information + */ +static void +vAnalyseSummaryInfo(const UCHAR *aucBuffer) +{ + ULONG ulOffset; + size_t tIndex, tCount, tPropID, tPropType; + + tCount = (size_t)ulGetLong(4, aucBuffer); + DBG_DEC(tCount); + for (tIndex = 0; tIndex < tCount; tIndex++) { + tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer); + ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer); + NO_DBG_DEC(tPropID); + NO_DBG_HEX(ulOffset); + tPropType = (size_t)ulGetLong(ulOffset, aucBuffer); + NO_DBG_DEC(tPropType); + switch (tPropID) { + case PID_TITLE: + if (tPropType == VT_LPSTR && szTitle == NULL) { + szTitle = szLpstr(ulOffset, aucBuffer); + } + break; + case PID_SUBJECT: + if (tPropType == VT_LPSTR && szSubject == NULL) { + szSubject = szLpstr(ulOffset, aucBuffer); + } + break; + case PID_AUTHOR: + if (tPropType == VT_LPSTR && szAuthor == NULL) { + szAuthor = szLpstr(ulOffset, aucBuffer); + } + break; + case PID_CREATE_DTM: + if (tPropType == VT_FILETIME && + tCreateDtm == (time_t)-1) { + tCreateDtm = tFiletime(ulOffset, aucBuffer); + } + break; + case PID_LASTSAVE_DTM: + if (tPropType == VT_FILETIME && + tLastSaveDtm == (time_t)-1) { + tLastSaveDtm = tFiletime(ulOffset, aucBuffer); + } + break; + case PID_APPNAME: + if (tPropType == VT_LPSTR && szAppName == NULL) { + szAppName = szLpstr(ulOffset, aucBuffer); + } + break; + default: + break; + } + } +} /* end of vAnalyseSummaryInfo */ + +/* + * vAnalyseDocumentSummaryInfo - analyse the document summary information + */ +static void +vAnalyseDocumentSummaryInfo(const UCHAR *aucBuffer) +{ + ULONG ulOffset; + size_t tIndex, tCount, tPropID, tPropType; + + tCount = (size_t)ulGetLong(4, aucBuffer); + DBG_DEC(tCount); + for (tIndex = 0; tIndex < tCount; tIndex++) { + tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer); + ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer); + NO_DBG_DEC(tPropID); + NO_DBG_HEX(ulOffset); + tPropType = (size_t)ulGetLong(ulOffset, aucBuffer); + NO_DBG_DEC(tPropType); + switch (tPropID) { + case PIDD_MANAGER: + if (tPropType == VT_LPSTR && szManager == NULL) { + szManager = szLpstr(ulOffset, aucBuffer); + } + break; + case PIDD_COMPANY: + if (tPropType == VT_LPSTR && szCompany == NULL) { + szCompany = szLpstr(ulOffset, aucBuffer); + } + break; + default: + break; + } + } +} /* end of vAnalyseDocumentSummaryInfo */ + +/* + * pucAnalyseSummaryInfoHeader- + */ +static UCHAR * +pucAnalyseSummaryInfoHeader(FILE *pFile, + ULONG ulStartBlock, ULONG ulSize, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + size_t tBlockDepotLen, tBlockSize, tSectionCount, tLength; + ULONG ulTmp, ulOffset; + USHORT usLittleEndian, usEmpty, usOS, usVersion; + UCHAR aucHdr[P_HEADER_SZ], aucSecLst[P_SECTION_MAX_SZ]; + + if (ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + + if (tBlockDepotLen == 0) { + DBG_MSG("The Block Depot length is zero"); + return NULL; + } + + /* Read the Summery Information header */ + if (!bReadBuffer(pFile, ulStartBlock, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucHdr, 0, P_HEADER_SZ)) { + return NULL; + } + NO_DBG_PRINT_BLOCK(aucHdr, P_HEADER_SZ); + + /* Analyse the Summery Information header */ + usLittleEndian = usGetWord(0, aucHdr); + if (usLittleEndian != 0xfffe) { + DBG_HEX(usLittleEndian); + DBG_MSG_C(usLittleEndian == 0xfeff, "Big endian"); + return NULL; + } + usEmpty = usGetWord(2, aucHdr); + if (usEmpty != 0x0000) { + DBG_DEC(usEmpty); + return NULL; + } + ulTmp = ulGetLong(4, aucHdr); + DBG_HEX(ulTmp); + usOS = (USHORT)(ulTmp >> 16); + usVersion = (USHORT)(ulTmp & 0xffff); + switch (usOS) { + case 0: + DBG_MSG("Win16"); + DBG_HEX(usVersion); + break; + case 1: + DBG_MSG("MacOS"); + DBG_HEX(usVersion); + break; + case 2: + DBG_MSG("Win32"); + DBG_HEX(usVersion); + break; + default: + DBG_DEC(usOS); + DBG_HEX(usVersion); + break; + } + tSectionCount = (size_t)ulGetLong(24, aucHdr); + DBG_DEC_C(tSectionCount != 1 && tSectionCount != 2, tSectionCount); + if (tSectionCount != 1 && tSectionCount != 2) { + return NULL; + } + + /* Read the Summery Information Section Lists */ + if (!bReadBuffer(pFile, ulStartBlock, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucSecLst, P_HEADER_SZ, P_SECTION_SZ(tSectionCount))) { + return NULL; + } + NO_DBG_PRINT_BLOCK(aucSecLst, P_SECTION_SZ(tSectionCount)); + + ulTmp = ulGetLong(0, aucSecLst); + DBG_HEX(ulTmp); + ulTmp = ulGetLong(4, aucSecLst); + DBG_HEX(ulTmp); + ulTmp = ulGetLong(8, aucSecLst); + DBG_HEX(ulTmp); + ulTmp = ulGetLong(12, aucSecLst); + DBG_HEX(ulTmp); + ulOffset = ulGetLong(16, aucSecLst); + DBG_DEC_C(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && + ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ, + ulOffset); + fail(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && + ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ); + tLength = + (size_t)ulGetLong(tSectionCount * P_SECTIONLIST_SZ, aucSecLst); + NO_DBG_HEX(tLength); + fail(ulOffset + tLength > ulSize); + + /* Read the Summery Information */ + aucBuffer = xmalloc(tLength); + if (!bReadBuffer(pFile, ulStartBlock, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulOffset, tLength)) { + aucBuffer = xfree(aucBuffer); + return NULL; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tLength); + return aucBuffer; +} /* end of pucAnalyseSummaryInfoHeader */ + +/* + * vSet0SummaryInfo - set summary information from a Word for DOS file + */ +void +vSet0SummaryInfo(FILE *pFile, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginSumdInfo, ulBeginNextBlock; + size_t tLen; + USHORT usCodepage, usOffset; + + TRACE_MSG("vSet0SummaryInfo"); + + fail(pFile == NULL || aucHeader == NULL); + + /* First check the header */ + usCodepage = usGetWord(0x7e, aucHeader); + DBG_DEC(usCodepage); + switch (usCodepage) { + case 850: usLid = 0x0809; break; /* Latin1 -> British English */ + case 862: usLid = 0x040d; break; /* Hebrew */ + case 866: usLid = 0x0419; break; /* Russian */ + case 0: + case 437: + default: usLid = 0x0409; break; /* ASCII -> American English */ + } + + /* Second check the summary information block */ + ulBeginSumdInfo = 128 * (ULONG)usGetWord(0x1c, aucHeader); + DBG_HEX(ulBeginSumdInfo); + ulBeginNextBlock = 128 * (ULONG)usGetWord(0x6a, aucHeader); + DBG_HEX(ulBeginNextBlock); + + if (ulBeginSumdInfo >= ulBeginNextBlock || ulBeginNextBlock == 0) { + /* There is no summary information block */ + return; + } + tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo); + aucBuffer = xmalloc(tLen); + /* Read the summary information block */ + if (!bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) { + return; + } + usOffset = usGetWord(0, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_MSG(aucBuffer + usOffset); + szTitle = xstrdup((char *)aucBuffer + usOffset); + } + usOffset = usGetWord(2, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_MSG(aucBuffer + usOffset); + szAuthor = xstrdup((char *)aucBuffer + usOffset); + } + usOffset = usGetWord(12, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_STRN(aucBuffer + usOffset, 8); + tLastSaveDtm = tConvertDosDate((char *)aucBuffer + usOffset); + } + usOffset = usGetWord(14, aucBuffer); + if (aucBuffer[usOffset] != 0) { + NO_DBG_STRN(aucBuffer + usOffset, 8); + tCreateDtm = tConvertDosDate((char *)aucBuffer + usOffset); + } + aucBuffer = xfree(aucBuffer); +} /* end of vSet0SummaryInfo */ + +/* + * vSet2SummaryInfo - set summary information from a WinWord 1/2 file + */ +void +vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginSumdInfo, ulBeginDocpInfo, ulTmp; + size_t tSumdInfoLen, tDocpInfoLen, tLen, tCounter, tStart; + + TRACE_MSG("vSet2SummaryInfo"); + + fail(pFile == NULL || aucHeader == NULL); + fail(iWordVersion != 1 && iWordVersion != 2); + + /* First check the header */ + usLid = usGetWord(0x06, aucHeader); /* Language IDentification */ + DBG_HEX(usLid); + if (usLid < 999 && iWordVersion == 1) { + switch (usLid) { + case 1: usLid = 0x0409; break; /* American English */ + case 2: usLid = 0x0c0c; break; /* Canadian French */ + case 31: usLid = 0x0413; break; /* Dutch */ + case 33: usLid = 0x040c; break; /* French */ + case 34: usLid = 0x040a; break; /* Spanish */ + case 36: usLid = 0x040e; break; /* Hungarian */ + case 39: usLid = 0x0410; break; /* Italian */ + case 44: usLid = 0x0809; break; /* British English */ + case 45: usLid = 0x0406; break; /* Danish */ + case 46: usLid = 0x041f; break; /* Swedish */ + case 47: usLid = 0x0414; break; /* Norwegian */ + case 48: usLid = 0x0415; break; /* Polish */ + case 49: usLid = 0x0407; break; /* German */ + case 351: usLid = 0x0816; break; /* Portuguese */ + case 358: usLid = 0x040b; break; /* Finnish */ + default: + DBG_DEC(usLid); + DBG_FIXME(); + usLid = 0x0409; /* American English */ + break; + } + } + + if (iWordVersion != 2) { + /* Unknown where to find the associated strings */ + return; + } + + /* Second check the associated strings */ + ulBeginSumdInfo = ulGetLong(0x118, aucHeader); /* fcSttbfAssoc */ + DBG_HEX(ulBeginSumdInfo); + tSumdInfoLen = (size_t)usGetWord(0x11c, aucHeader); /* cbSttbfAssoc */ + DBG_DEC(tSumdInfoLen); + + if (tSumdInfoLen == 0) { + /* There is no summary information */ + return; + } + + aucBuffer = xmalloc(tSumdInfoLen); + if (!bReadBytes(aucBuffer, tSumdInfoLen, ulBeginSumdInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + NO_DBG_PRINT_BLOCK(aucBuffer, tSumdInfoLen); + tLen = (size_t)ucGetByte(0, aucBuffer); + DBG_DEC_C(tSumdInfoLen != tLen, tSumdInfoLen); + DBG_DEC_C(tSumdInfoLen != tLen, tLen); + tStart = 1; + for (tCounter = 0; tCounter < 17; tCounter++) { + if (tStart >= tSumdInfoLen) { + break; + } + tLen = (size_t)ucGetByte(tStart, aucBuffer); + if (tLen != 0) { + NO_DBG_DEC(tCounter); + NO_DBG_STRN(aucBuffer + tStart + 1, tLen); + switch (tCounter) { + case 3: + szTitle = xmalloc(tLen + 1); + strncpy(szTitle, + (char *)aucBuffer + tStart + 1, tLen); + szTitle[tLen] = '\0'; + break; + case 4: + szSubject = xmalloc(tLen + 1); + strncpy(szSubject, + (char *)aucBuffer + tStart + 1, tLen); + szSubject[tLen] = '\0'; + break; + case 7: + szAuthor = xmalloc(tLen + 1); + strncpy(szAuthor, + (char *)aucBuffer + tStart + 1, tLen); + szAuthor[tLen] = '\0'; + break; + default: + break; + } + } + tStart += tLen + 1; + } + aucBuffer = xfree(aucBuffer); + + /* Third check the document properties */ + ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 12) { + return; + } + + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ + tCreateDtm = tConvertDTTM(ulTmp); + ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ + tLastSaveDtm = tConvertDTTM(ulTmp); + aucBuffer = xfree(aucBuffer); +} /* end of vSet2SummaryInfo */ + +/* + * vSetSummaryInfoOLE - set summary information from a Word 6+ file + */ +static void +vSetSummaryInfoOLE(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen) +{ + UCHAR *pucBuffer; + + fail(pFile == NULL || pPPS == NULL); + fail(aulBBD == NULL || aulSBD == NULL); + + /* Summary Information */ + pucBuffer = pucAnalyseSummaryInfoHeader(pFile, + pPPS->tSummaryInfo.ulSB, pPPS->tSummaryInfo.ulSize, + aulBBD, tBBDLen, aulSBD, tSBDLen); + if (pucBuffer != NULL) { + vAnalyseSummaryInfo(pucBuffer); + pucBuffer = xfree(pucBuffer); + } + + /* Document Summary Information */ + pucBuffer = pucAnalyseSummaryInfoHeader(pFile, + pPPS->tDocSummaryInfo.ulSB, pPPS->tDocSummaryInfo.ulSize, + aulBBD, tBBDLen, aulSBD, tSBDLen); + if (pucBuffer != NULL) { + vAnalyseDocumentSummaryInfo(pucBuffer); + pucBuffer = xfree(pucBuffer); + } +} /* end of vSetSummaryInfoOLE */ + +/* + * vSet6SummaryInfo - set summary information from a Word 6/7 file + */ +void +vSet6SummaryInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + TRACE_MSG("vSet6SummaryInfo"); + + /* Header Information */ + usLid = usGetWord(0x06, aucHeader); /* Language IDentification */ + DBG_HEX(usLid); + + /* Summery Information */ + vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen); +} /* end of vSet6SummaryInfo */ + +/* + * vSet8SummaryInfo - set summary information a Word 8/9/10 file + */ +void +vSet8SummaryInfo(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + USHORT usTmp; + + TRACE_MSG("vSet8SummaryInfo"); + + /* Header Information */ + usTmp = usGetWord(0x0a, aucHeader); + if (usTmp & BIT(14)) { + /* Language IDentification Far East */ + usLid = usGetWord(0x3c, aucHeader); + } else { + /* Language IDentification */ + usLid = usGetWord(0x06, aucHeader); + } + DBG_HEX(usLid); + + /* Summery Information */ + vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen); +} /* end of vSet8SummaryInfo */ + +/* + * szGetTitle - get the title field + */ +const char * +szGetTitle(void) +{ + return szTitle; +} /* end of szGetTitle */ + +/* + * szGetSubject - get the subject field + */ +const char * +szGetSubject(void) +{ + return szSubject; +} /* end of szGetSubject */ + +/* + * szGetAuthor - get the author field + */ +const char * +szGetAuthor(void) +{ + return szAuthor; +} /* end of szGetAuthor */ + +/* + * szGetLastSaveDtm - get the last save date field + */ +const char * +szGetLastSaveDtm(void) +{ + static char szTime[12]; + struct tm *pTime; + + if (tLastSaveDtm == (time_t)-1) { + return NULL; + } + pTime = localtime(&tLastSaveDtm); + if (pTime == NULL) { + return NULL; + } + sprintf(szTime, "%04d-%02d-%02d", + pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday); + return szTime; +} /* end of szGetLastSaveDtm */ + +/* + * szGetModDate - get the last save date field + */ +const char * +szGetModDate(void) +{ + static char szTime[20]; + struct tm *pTime; + + if (tLastSaveDtm == (time_t)-1) { + return NULL; + } + pTime = localtime(&tLastSaveDtm); + if (pTime == NULL) { + return NULL; + } + sprintf(szTime, "D:%04d%02d%02d%02d%02d", + pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday, + pTime->tm_hour, pTime->tm_min); + return szTime; +} /* end of szGetModDate */ + +/* + * szGetCreationDate - get the last save date field + */ +const char * +szGetCreationDate(void) +{ + static char szTime[20]; + struct tm *pTime; + + if (tCreateDtm == (time_t)-1) { + return NULL; + } + pTime = localtime(&tCreateDtm); + if (pTime == NULL) { + return NULL; + } + sprintf(szTime, "D:%04d%02d%02d%02d%02d", + pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday, + pTime->tm_hour, pTime->tm_min); + return szTime; +} /* end of szGetCreationDate */ + +/* + * szGetCompany - get the company field + */ +const char * +szGetCompany(void) +{ + return szCompany; +} /* end of szGetCompany */ + +/* + * szGetLanguage - get de language field + */ +const char * +szGetLanguage(void) +{ + if (usLid == (USHORT)-1) { + /* No Language IDentification */ + return NULL; + } + if (usLid < 999) { + /* This is a Locale, not a Language IDentification */ + DBG_DEC(usLid); + return NULL; + } + + /* Exceptions to the general rule */ + switch (usLid) { + case 0x0404: return "zh_TW"; /* Traditional Chinese */ + case 0x0804: return "zh_CN"; /* Simplified Chinese */ + case 0x0c04: return "zh_HK"; /* Hong Kong Chinese */ + case 0x1004: return "zh_SG"; /* Singapore Chinese */ + case 0x0807: return "de_CH"; /* Swiss German */ + case 0x0409: return "en_US"; /* American English */ + case 0x0809: return "en_GB"; /* British English */ + case 0x0c09: return "en_AU"; /* Australian English */ + case 0x080a: return "es_MX"; /* Mexican Spanish */ + case 0x080c: return "fr_BE"; /* Belgian French */ + case 0x0c0c: return "fr_CA"; /* Canadian French */ + case 0x100c: return "fr_CH"; /* Swiss French */ + case 0x0810: return "it_CH"; /* Swiss Italian */ + case 0x0813: return "nl_BE"; /* Belgian Dutch */ + case 0x0416: return "pt_BR"; /* Brazilian Portuguese */ + case 0x081a: + case 0x0c1a: return "sr"; /* Serbian */ + case 0x081d: return "sv_FI"; /* Finland Swedish */ + default: + break; + } + + /* The general rule */ + switch (usLid & 0x00ff) { + case 0x01: return "ar"; /* Arabic */ + case 0x02: return "bg"; /* Bulgarian */ + case 0x03: return "ca"; /* Catalan */ + case 0x04: return "zh"; /* Chinese */ + case 0x05: return "cs"; /* Czech */ + case 0x06: return "da"; /* Danish */ + case 0x07: return "de"; /* German */ + case 0x08: return "el"; /* Greek */ + case 0x09: return "en"; /* English */ + case 0x0a: return "es"; /* Spanish */ + case 0x0b: return "fi"; /* Finnish */ + case 0x0c: return "fr"; /* French */ + case 0x0d: return "he"; /* Hebrew */ + case 0x0e: return "hu"; /* Hungarian */ + case 0x0f: return "is"; /* Icelandic */ + case 0x10: return "it"; /* Italian */ + case 0x11: return "ja"; /* Japanese */ + case 0x12: return "ko"; /* Korean */ + case 0x13: return "nl"; /* Dutch */ + case 0x14: return "no"; /* Norwegian */ + case 0x15: return "pl"; /* Polish */ + case 0x16: return "pt"; /* Portuguese */ + case 0x17: return "rm"; /* Rhaeto-Romance */ + case 0x18: return "ro"; /* Romanian */ + case 0x19: return "ru"; /* Russian */ + case 0x1a: return "hr"; /* Croatian */ + case 0x1b: return "sk"; /* Slovak */ + case 0x1c: return "sq"; /* Albanian */ + case 0x1d: return "sv"; /* Swedish */ + case 0x1e: return "th"; /* Thai */ + case 0x1f: return "tr"; /* Turkish */ + case 0x20: return "ur"; /* Urdu */ + case 0x21: return "id"; /* Indonesian */ + case 0x22: return "uk"; /* Ukrainian */ + case 0x23: return "be"; /* Belarusian */ + case 0x24: return "sl"; /* Slovenian */ + case 0x25: return "et"; /* Estonian */ + case 0x26: return "lv"; /* Latvian */ + case 0x27: return "lt"; /* Lithuanian */ + case 0x29: return "fa"; /* Farsi */ + case 0x2a: return "vi"; /* Viet Nam */ + case 0x2b: return "hy"; /* Armenian */ + case 0x2c: return "az"; /* Azeri */ + case 0x2d: return "eu"; /* Basque */ + case 0x2f: return "mk"; /* Macedonian */ + case 0x36: return "af"; /* Afrikaans */ + case 0x37: return "ka"; /* Georgian */ + case 0x38: return "fo"; /* Faeroese */ + case 0x39: return "hi"; /* Hindi */ + case 0x3e: return "ms"; /* Malay */ + case 0x3f: return "kk"; /* Kazakh */ + default: + DBG_HEX(usLid); + DBG_FIXME(); + return NULL; + } +} /* end of szGetLanguage */ diff --git a/tabstop.c b/tabstop.c new file mode 100644 index 0000000..604d949 --- /dev/null +++ b/tabstop.c @@ -0,0 +1,212 @@ +/* + * tabstops.c + * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Read the tab stop information from a MS Word file + */ + +#include +#include "antiword.h" + +#define HALF_INCH 36000L /* In millipoints */ + +static long lDefaultTabWidth = HALF_INCH; + + +/* + * vSet0DefaultTabWidth - + */ +static void +vSet0DefaultTabWidth(const UCHAR *aucHeader) +{ + USHORT usTmp; + + fail(aucHeader == NULL); + + usTmp = usGetWord(0x70, aucHeader); /* dxaTab */ + DBG_DEC(usTmp); + lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp); + DBG_DEC(lDefaultTabWidth); +} /* end of vSet0DefaultTabWidth */ + +/* + * vSet2DefaultTabWidth - + */ +static void +vSet2DefaultTabWidth(FILE *pFile, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo; + size_t tDocpInfoLen; + USHORT usTmp; + + fail(pFile == NULL || aucHeader == NULL); + + ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 12) { + DBG_MSG("No TAB information"); + return; + } + + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { + aucBuffer = xfree(aucBuffer); + return; + } + usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */ + lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp); + DBG_DEC(lDefaultTabWidth); + aucBuffer = xfree(aucBuffer); +} /* end of vSet2DefaultTabWidth */ + +/* + * vSet6DefaultTabWidth - + */ +static void +vSet6DefaultTabWidth(FILE *pFile, ULONG ulStartBlock, + const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) +{ + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo; + size_t tDocpInfoLen; + USHORT usTmp; + + ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 12) { + DBG_MSG("No TAB information"); + return; + } + + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBuffer(pFile, ulStartBlock, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */ + lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp); + DBG_DEC(lDefaultTabWidth); + aucBuffer = xfree(aucBuffer); +} /* end of vSet6DefaultTabWidth */ + +/* + * vSet8DefaultTabWidth - + */ +static void +vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader) +{ + const ULONG *aulBlockDepot; + UCHAR *aucBuffer; + ULONG ulBeginDocpInfo; + size_t tDocpInfoLen, tBlockDepotLen, tBlockSize; + USHORT usTmp; + + ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */ + DBG_HEX(ulBeginDocpInfo); + tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */ + DBG_DEC(tDocpInfoLen); + if (tDocpInfoLen < 12) { + DBG_MSG("No TAB information"); + return; + } + + DBG_DEC(pPPS->tTable.ulSB); + DBG_HEX(pPPS->tTable.ulSize); + if (pPPS->tTable.ulSize == 0) { + DBG_MSG("No TAB information"); + return; + } + + if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { + /* Use the Small Block Depot */ + aulBlockDepot = aulSBD; + tBlockDepotLen = tSBDLen; + tBlockSize = SMALL_BLOCK_SIZE; + } else { + /* Use the Big Block Depot */ + aulBlockDepot = aulBBD; + tBlockDepotLen = tBBDLen; + tBlockSize = BIG_BLOCK_SIZE; + } + aucBuffer = xmalloc(tDocpInfoLen); + if (!bReadBuffer(pFile, pPPS->tTable.ulSB, + aulBlockDepot, tBlockDepotLen, tBlockSize, + aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) { + aucBuffer = xfree(aucBuffer); + return; + } + usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */ + lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp); + DBG_DEC(lDefaultTabWidth); + aucBuffer = xfree(aucBuffer); +} /* end of vSet8DefaultTabWidth */ + +/* + * vSetDefaultTabWidth - + */ +void +vSetDefaultTabWidth(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader, int iWordVersion) +{ + fail(pFile == NULL && iWordVersion >= 1); + fail(pPPS == NULL && iWordVersion >= 6); + fail(aulBBD == NULL && tBBDLen != 0); + fail(aulSBD == NULL && tSBDLen != 0); + fail(aucHeader == NULL); + + /* Reset to the default default value */ + lDefaultTabWidth = HALF_INCH; + + switch (iWordVersion) { + case 0: + vSet0DefaultTabWidth(aucHeader); + break; + case 1: + case 2: + vSet2DefaultTabWidth(pFile, aucHeader); + break; + case 4: + case 5: + break; + case 6: + case 7: + vSet6DefaultTabWidth(pFile, pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, aucHeader); + break; + case 8: + vSet8DefaultTabWidth(pFile, pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); + break; + default: + werr(0, "Sorry, no TAB information"); + break; + } +} /* end of vSetDefaultTabWidth */ + +#if 0 +/* + * lGetDefaultTabWidth - Get the default tabwidth in millipoints + */ +long +lGetDefaultTabWidth(void) +{ + if (lDefaultTabWidth <= 0) { + DBG_DEC(lDefaultTabWidth); + return lTwips2MilliPoints(1); + } + return lDefaultTabWidth; +} /* end of lGetDefaultTabWidth */ +#endif diff --git a/text.c b/text.c new file mode 100644 index 0000000..bd3dc92 --- /dev/null +++ b/text.c @@ -0,0 +1,182 @@ +/* + * text.c + * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with the Text format + * + */ + +#include +#include "antiword.h" + +/* The character set */ +static encoding_type eEncoding = encoding_neutral; +/* Current vertical position information */ +static long lYtopCurr = 0; +/* Local representation of the non-breaking space */ +static UCHAR ucNbsp = 0; + + +/* + * vPrologueTXT - set options and perform the Text initialization + */ +void +vPrologueTXT(diagram_type *pDiag, const options_type *pOptions) +{ + fail(pDiag == NULL); + fail(pOptions == NULL); + + eEncoding = pOptions->eEncoding; + pDiag->lXleft = 0; + pDiag->lYtop = 0; + lYtopCurr = 0; +} /* end of vPrologueTXT */ + +/* + * vEpilogueTXT - clean up after everything is done + */ +void +vEpilogueTXT(FILE *pOutFile) +{ + fail(pOutFile == NULL); + + fprintf(pOutFile, "\n"); +} /* end of vEpilogueTXT */ + +/* + * vPrintTXT - print a Text string + */ +static void +vPrintTXT(FILE *pFile, const char *szString, size_t tStringLength) +{ + const UCHAR *ucBytes; + size_t tCount; + + fail(szString == NULL); + + if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { + return; + } + + if (eEncoding == encoding_utf_8) { + fprintf(pFile, "%.*s", (int)tStringLength, szString); + return; + } + + if (ucNbsp == 0) { + ucNbsp = ucGetNbspCharacter(); + DBG_HEX_C(ucNbsp != 0xa0, ucNbsp); + } + + ucBytes = (UCHAR *)szString; + for (tCount = 0; tCount < tStringLength ; tCount++) { + if (ucBytes[tCount] == ucNbsp) { + (void)putc(' ', pFile); + } else { + (void)putc(szString[tCount], pFile); + } + } +} /* end of vPrintTXT */ + +/* + * vMoveTo - move to the given X,Y coordinates + * + * Move the current position of the given diagram to its X,Y coordinates, + * start on a new page if needed + */ +static void +vMoveTo(diagram_type *pDiag) +{ + int iCount, iNbr; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + if (pDiag->lYtop != lYtopCurr) { + iNbr = iDrawUnits2Char(pDiag->lXleft); + for (iCount = 0; iCount < iNbr; iCount++) { + (void)putc(FILLER_CHAR, pDiag->pOutFile); + } + lYtopCurr = pDiag->lYtop; + } +} /* end of vMoveTo */ + +/* + * vMove2NextLineTXT - move to the next line + */ +void +vMove2NextLineTXT(diagram_type *pDiag) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + pDiag->lYtop++; + (void)fprintf(pDiag->pOutFile, "\n"); +} /* end of vMove2NextLineTXT */ + +/* + * vSubstringTXT - print a sub string + */ +void +vSubstringTXT(diagram_type *pDiag, + const char *szString, size_t tStringLength, long lStringWidth) +{ + fail(pDiag == NULL || szString == NULL); + fail(pDiag->pOutFile == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + vMoveTo(pDiag); + vPrintTXT(pDiag->pOutFile, szString, tStringLength); + pDiag->lXleft += lStringWidth; +} /* end of vSubstringTXT */ + +/* + * Create an start of paragraph by moving the y-top mark + */ +void +vStartOfParagraphTXT(diagram_type *pDiag, long lBeforeIndentation) +{ + fail(pDiag == NULL); + fail(lBeforeIndentation < 0); + + if (lBeforeIndentation >= lTwips2MilliPoints(HEADING_GAP)) { + /* A large gap is replaced by an empty line */ + vMove2NextLineTXT(pDiag); + } +} /* end of vStartOfParagraphTXT */ + +/* + * Create an end of paragraph by moving the y-top mark + */ +void +vEndOfParagraphTXT(diagram_type *pDiag, long lAfterIndentation) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(lAfterIndentation < 0); + + if (pDiag->lXleft > 0) { + /* To the start of the line */ + vMove2NextLineTXT(pDiag); + } + + if (lAfterIndentation >= lTwips2MilliPoints(HEADING_GAP)) { + /* A large gap is replaced by an empty line */ + vMove2NextLineTXT(pDiag); + } +} /* end of vEndOfParagraphTXT */ + +/* + * Create an end of page + */ +void +vEndOfPageTXT(diagram_type *pDiag, long lAfterIndentation) +{ + vEndOfParagraphTXT(pDiag, lAfterIndentation); +} /* end of vEndOfPageTXT */ diff --git a/unix.c b/unix.c new file mode 100644 index 0000000..3da3964 --- /dev/null +++ b/unix.c @@ -0,0 +1,45 @@ +/* + * unix.c + * Copyright (C) 1998-2000 A.J. van Os; Released under GPL + * + * Description: + * Unix approximations of RISC-OS functions + */ + +#include +#include +#include +#include "antiword.h" + + +/* + * werr - write an error message and exit if needed + */ +void +werr(int iFatal, const char *szFormat, ...) +{ + va_list tArg; + + va_start(tArg, szFormat); + (void)vfprintf(stderr, szFormat, tArg); + va_end(tArg); + fprintf(stderr, "\n"); + switch (iFatal) { + case 0: /* The message is just a warning, so no exit */ + return; + case 1: /* Fatal error with a standard exit */ + exit(EXIT_FAILURE); + default: /* Fatal error with a non-standard exit */ + exit(iFatal); + } +} /* end of werr */ + +void +Hourglass_On(void) +{ +} /* end of Hourglass_On */ + +void +Hourglass_Off(void) +{ +} /* end of Hourglass_Off */ diff --git a/utf8.c b/utf8.c new file mode 100644 index 0000000..2cc2191 --- /dev/null +++ b/utf8.c @@ -0,0 +1,260 @@ +/* + * utf8.c + * Copyright (C) 2001-2004 A.J. van Os; Released under GPL + * + *==================================================================== + * This part of the software is based on: + * An implementation of wcwidth() as defined in + * "The Single UNIX Specification, Version 2, The Open Group, 1997" + * + * Markus Kuhn -- 2001-01-12 -- public domain + *==================================================================== + * The credit should go to him, but all the bugs are mine. + */ + +#include +#include +#include "antiword.h" + +struct interval { + USHORT first; + USHORT last; +}; +/* Sorted list of non-overlapping intervals of non-spacing characters */ +static const struct interval combining[] = { + { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 }, + { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, + { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, + { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, + { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, + { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, + { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, + { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, + { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, + { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, + { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, + { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F }, + { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A }, + { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB } +}; + +/* Auxiliary function for binary search in interval table */ +static BOOL +bIsZeroWidthChar(ULONG ucs) +{ + int low = 0; + int high = elementsof(combining) - 1; + int mid; + + if (ucs < (ULONG)combining[low].first || + ucs > (ULONG)combining[high].last) { + return FALSE; + } + + while (high >= low) { + mid = (low + high) / 2; + if (ucs > (ULONG)combining[mid].last) { + low = mid + 1; + } else if (ucs < (ULONG)combining[mid].first) { + high = mid - 1; + } else { + return TRUE; + } + } + return FALSE; +} /* end of bIsZeroWidthChar */ + +/* The following functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * FullWidth (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that all characters are encoded + * in ISO 10646. + * + * This function is not named wcwidth() to prevent name clashes + */ +static int +iWcWidth(ULONG ucs) +{ + /* Test for 8-bit control characters */ + if (ucs == 0) { + return 0; + } + if (ucs < 0x20 || (ucs >= 0x7f && ucs < 0xa0)) { + NO_DBG_HEX(ucs); + return -1; + } + + /* Binary search in table of non-spacing characters */ + if (bIsZeroWidthChar(ucs)) { + return 0; + } + + /* Ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2ffff))); +} /* end of iWcWidth */ + +/* + * utf8_to_ucs - convert from UTF-8 to UCS + * + * Returns the UCS character, + * Fills in the number of bytes in the UTF-8 character + */ +static ULONG +utf8_to_ucs(const char *p, int iStrLen, int *piUtfLen) +{ + ULONG ulUcs; + int iIndex, iCharLen; + + fail(p == NULL || piUtfLen == NULL); + fail(iStrLen < 1); + + ulUcs = (ULONG)(UCHAR)p[0]; + + if (ulUcs < 0x80) { + *piUtfLen = 1; + return ulUcs; + } + + if (ulUcs < 0xe0){ + iCharLen = 2; + ulUcs &= 0x1f; + } else if (ulUcs < 0xf0){ + iCharLen = 3; + ulUcs &= 0x0f; + } else if (ulUcs < 0xf8){ + iCharLen = 4; + ulUcs &= 0x07; + } else if (ulUcs < 0xfc){ + iCharLen = 5; + ulUcs &= 0x03; + } else { + iCharLen = 6; + ulUcs &= 0x01; + } + for (iIndex = 1; iIndex < iCharLen; iIndex++) { + ulUcs <<= 6; + if (iIndex < iStrLen) { + ulUcs |= (ULONG)(UCHAR)p[iIndex] & 0x3f; + } + } + *piUtfLen = iCharLen; + return ulUcs; +} /* end of utf8_to_ucs */ + +/* + * utf8_strwidth - compute the string width of an UTF-8 string + * + * Returns the string width in columns + */ +long +utf8_strwidth(const char *pcString, size_t tNumchars) +{ + ULONG ulUcs; + long lTotal; + int iToGo, iWidth, iUtflen; + + fail(pcString == NULL || tNumchars > (size_t)INT_MAX); + + lTotal = 0; + iToGo = (int)tNumchars; + + while (iToGo > 0 && *pcString != '\0') { + ulUcs = utf8_to_ucs(pcString, iToGo, &iUtflen); + iWidth = iWcWidth(ulUcs); + if (iWidth > 0) { + lTotal += iWidth; + } + pcString += iUtflen; + iToGo -= iUtflen; + } + NO_DBG_DEC(lTotal); + return lTotal; +} /* end of utf8_strwidth */ + +/* + * utf8_chrlength - get the number of bytes in an UTF-8 character + * + * Returns the number of bytes + */ +int +utf8_chrlength(const char *p) +{ + int iUtflen; + + fail(p == NULL); + + iUtflen = -1; /* Just to make sure */ + (void)utf8_to_ucs(p, INT_MAX, &iUtflen); + NO_DBG_DEC(iUtflen); + return iUtflen; +} /* end of utf8_chrlength */ + +/* + * is_locale_utf8 - return TRUE if the locale is UTF-8 + */ +BOOL +is_locale_utf8(void) +{ + char szCodeset[20]; + + szCodeset[0] = '\0'; + if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), NULL)) { + return FALSE; + } + DBG_MSG(szCodeset); + return STREQ(szCodeset, "utf8"); +} /* end of is_locale_utf8 */ diff --git a/version.h b/version.h new file mode 100644 index 0000000..01ed709 --- /dev/null +++ b/version.h @@ -0,0 +1,37 @@ +/* + * version.h + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Version and release information + */ + +#if !defined(__version_h) +#define __version_h 1 + +/* Strings for the info box */ +#define PURPOSESTRING "Display MS-Word files" + +#if defined(__riscos) +#define AUTHORSTRING "© 1998-2005 Adri van Os" +#else +#define AUTHORSTRING "(C) 1998-2005 Adri van Os" +#endif /* __riscos */ + +#define VERSIONSTRING "0.37 (21 Oct 2005)" + +#if defined(__dos) +#if defined(__DJGPP__) +#define VERSIONSTRING2 " # 32-bit Protected Mode" +#else +#define VERSIONSTRING2 " # 16-bit Real Mode" +#endif /* __DJGPP__ */ +#endif /* __dos */ + +#if defined(DEBUG) +#define STATUSSTRING "DEBUG version" +#else +#define STATUSSTRING "GNU General Public License" +#endif /* DEBUG */ + +#endif /* __version_h */ diff --git a/word2text.c b/word2text.c new file mode 100644 index 0000000..62b8964 --- /dev/null +++ b/word2text.c @@ -0,0 +1,1505 @@ +/* + * word2text.c + * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * MS Word to "text" functions + */ + +#include +#include +#include +#include +#if defined(__riscos) +#include "DeskLib:Hourglass.h" +#include "drawfile.h" +#endif /* __riscos */ +#include "antiword.h" + + +#define INITIAL_SIZE 40 +#define EXTENTION_SIZE 20 + + +/* Macros to make sure all such statements will be identical */ +#define OUTPUT_LINE() \ + do {\ + vAlign2Window(pDiag, pAnchor, lWidthMax, ucAlignment);\ + TRACE_MSG("after vAlign2Window");\ + pAnchor = pStartNewOutput(pAnchor, NULL);\ + pOutput = pAnchor;\ + } while(0) + +#define RESET_LINE() \ + do {\ + pAnchor = pStartNewOutput(pAnchor, NULL);\ + pOutput = pAnchor;\ + } while(0) + +#if defined(__riscos) +/* Length of the document in characters */ +static ULONG ulDocumentLength; +/* Number of characters processed so far */ +static ULONG ulCharCounter; +static int iCurrPct, iPrevPct; +#endif /* __riscos */ +/* The document is in the format belonging to this version of Word */ +static int iWordVersion = -1; +/* Special treatment for files from Word 4/5/6 on an Apple Macintosh */ +static BOOL bOldMacFile = FALSE; +/* Section Information */ +static const section_block_type *pSection = NULL; +static const section_block_type *pSectionNext = NULL; +/* All the (command line) options */ +static options_type tOptions; +/* Needed for reading a complete table row */ +static const row_block_type *pRowInfo = NULL; +static BOOL bStartRow = FALSE; +static BOOL bEndRowNorm = FALSE; +static BOOL bEndRowFast = FALSE; +static BOOL bIsTableRow = FALSE; +/* Index of the next style and font information */ +static USHORT usIstdNext = ISTD_NORMAL; +/* Needed for finding the start of a style */ +static const style_block_type *pStyleInfo = NULL; +static style_block_type tStyleNext; +static BOOL bStartStyle = FALSE; +static BOOL bStartStyleNext = FALSE; +/* Needed for finding the start of a font */ +static const font_block_type *pFontInfo = NULL; +static font_block_type tFontNext; +static BOOL bStartFont = FALSE; +static BOOL bStartFontNext = FALSE; +/* Needed for finding an image */ +static ULONG ulFileOffsetImage = FC_INVALID; + + +/* + * vUpdateCounters - Update the counters for the hourglass + */ +static void +vUpdateCounters(void) +{ +#if defined(__riscos) + ulCharCounter++; + iCurrPct = (int)((ulCharCounter * 100) / ulDocumentLength); + if (iCurrPct != iPrevPct) { + Hourglass_Percentage(iCurrPct); + iPrevPct = iCurrPct; + } +#endif /* __riscos */ +} /* end of vUpdateCounters */ + +/* + * bOutputContainsText - see if the output contains more than white space + */ +BOOL +bOutputContainsText(const output_type *pAnchor) +{ + const output_type *pCurr; + size_t tIndex; + + fail(pAnchor == NULL); + + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + fail(pCurr->lStringWidth < 0); + for (tIndex = 0; tIndex < pCurr->tNextFree; tIndex++) { + if (isspace((int)(UCHAR)pCurr->szStorage[tIndex])) { + continue; + } +#if defined(DEBUG) + if (pCurr->szStorage[tIndex] == FILLER_CHAR) { + continue; + } +#endif /* DEBUG */ + return TRUE; + } + } + return FALSE; +} /* end of bOutputContainsText */ + +/* + * lTotalStringWidth - compute the total width of the output string + */ +static long +lTotalStringWidth(const output_type *pAnchor) +{ + const output_type *pCurr; + long lTotal; + + lTotal = 0; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + DBG_DEC_C(pCurr->lStringWidth < 0, pCurr->lStringWidth); + fail(pCurr->lStringWidth < 0); + lTotal += pCurr->lStringWidth; + } + return lTotal; +} /* end of lTotalStringWidth */ + +/* + * vStoreByte - store one byte + */ +static void +vStoreByte(UCHAR ucChar, output_type *pOutput) +{ + fail(pOutput == NULL); + + if (ucChar == 0) { + pOutput->szStorage[pOutput->tNextFree] = '\0'; + return; + } + + while (pOutput->tNextFree + 2 > pOutput->tStorageSize) { + pOutput->tStorageSize += EXTENTION_SIZE; + pOutput->szStorage = xrealloc(pOutput->szStorage, + pOutput->tStorageSize); + } + pOutput->szStorage[pOutput->tNextFree] = (char)ucChar; + pOutput->szStorage[pOutput->tNextFree + 1] = '\0'; + pOutput->tNextFree++; +} /* end of vStoreByte */ + +/* + * vStoreChar - store a character as one or more bytes + */ +static void +vStoreChar(ULONG ulChar, BOOL bChangeAllowed, output_type *pOutput) +{ + char szResult[4]; + size_t tIndex, tLen; + + fail(pOutput == NULL); + + if (tOptions.eEncoding == encoding_utf_8 && bChangeAllowed) { + DBG_HEX_C(ulChar > 0xffff, ulChar); + fail(ulChar > 0xffff); + tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); + for (tIndex = 0; tIndex < tLen; tIndex++) { + vStoreByte((UCHAR)szResult[tIndex], pOutput); + } + } else { + DBG_HEX_C(ulChar > 0xff, ulChar); + fail(ulChar > 0xff); + vStoreByte((UCHAR)ulChar, pOutput); + tLen = 1; + } + pOutput->lStringWidth += lComputeStringWidth( + pOutput->szStorage + pOutput->tNextFree - tLen, + tLen, + pOutput->tFontRef, + pOutput->usFontSize); +} /* end of vStoreChar */ + +/* + * vStoreCharacter - store one character + */ +static void +vStoreCharacter(ULONG ulChar, output_type *pOutput) +{ + vStoreChar(ulChar, TRUE, pOutput); +} /* end of vStoreCharacter */ + +/* + * vStoreString - store a string + */ +static void +vStoreString(const char *szString, size_t tStringLength, output_type *pOutput) +{ + size_t tIndex; + + fail(szString == NULL || pOutput == NULL); + + for (tIndex = 0; tIndex < tStringLength; tIndex++) { + vStoreCharacter((ULONG)(UCHAR)szString[tIndex], pOutput); + } +} /* end of vStoreString */ + +/* + * vStoreNumberAsDecimal - store a number as a decimal number + */ +static void +vStoreNumberAsDecimal(UINT uiNumber, output_type *pOutput) +{ + size_t tLen; + char szString[3 * sizeof(UINT) + 1]; + + fail(uiNumber == 0); + fail(pOutput == NULL); + + tLen = (size_t)sprintf(szString, "%u", uiNumber); + vStoreString(szString, tLen, pOutput); +} /* end of vStoreNumberAsDecimal */ + +/* + * vStoreNumberAsRoman - store a number as a roman numerical + */ +static void +vStoreNumberAsRoman(UINT uiNumber, output_type *pOutput) +{ + size_t tLen; + char szString[15]; + + fail(uiNumber == 0); + fail(pOutput == NULL); + + tLen = tNumber2Roman(uiNumber, FALSE, szString); + vStoreString(szString, tLen, pOutput); +} /* end of vStoreNumberAsRoman */ + +/* + * vStoreStyle - store a style + */ +static void +vStoreStyle(diagram_type *pDiag, output_type *pOutput, + const style_block_type *pStyle) +{ + size_t tLen; + char szString[120]; + + fail(pDiag == NULL); + fail(pOutput == NULL); + fail(pStyle == NULL); + + if (tOptions.eConversionType == conversion_xml) { + vSetHeaders(pDiag, pStyle->usIstd); + } else { + tLen = tStyle2Window(szString, sizeof(szString), + pStyle, pSection); + vStoreString(szString, tLen, pOutput); + } +} /* end of vStoreStyle */ + +/* + * vPutIndentation - output the specified amount of indentation + */ +static void +vPutIndentation(diagram_type *pDiag, output_type *pOutput, + BOOL bNoMarks, BOOL bFirstLine, + UINT uiListNumber, UCHAR ucNFC, const char *szListChar, + long lLeftIndentation, long lLeftIndentation1) +{ + long lWidth; + size_t tIndex, tNextFree; + char szLine[30]; + + fail(pDiag == NULL); + fail(pOutput == NULL); + fail(szListChar == NULL); + fail(lLeftIndentation < 0); + + if (tOptions.eConversionType == conversion_xml) { + /* XML does its own indentation at rendering time */ + return; + } + + if (bNoMarks) { + if (bFirstLine) { + lLeftIndentation += lLeftIndentation1; + } + if (lLeftIndentation < 0) { + lLeftIndentation = 0; + } + vSetLeftIndentation(pDiag, lLeftIndentation); + return; + } + if (lLeftIndentation <= 0) { + DBG_HEX_C(ucNFC != 0x00, ucNFC); + vSetLeftIndentation(pDiag, 0); + return; + } + +#if defined(DEBUG) + if (tOptions.eEncoding == encoding_utf_8) { + fail(strlen(szListChar) > 3); + } else { + DBG_HEX_C(iscntrl((int)szListChar[0]), szListChar[0]); + fail(iscntrl((int)szListChar[0])); + fail(szListChar[1] != '\0'); + } +#endif /* DEBUG */ + + switch (ucNFC) { + case LIST_ARABIC_NUM: + case LIST_NUMBER_TXT: + tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber); + break; + case LIST_UPPER_ROMAN: + case LIST_LOWER_ROMAN: + tNextFree = tNumber2Roman(uiListNumber, + ucNFC == LIST_UPPER_ROMAN, szLine); + break; + case LIST_UPPER_ALPHA: + case LIST_LOWER_ALPHA: + tNextFree = tNumber2Alpha(uiListNumber, + ucNFC == LIST_UPPER_ALPHA, szLine); + break; + case LIST_ORDINAL_NUM: + case LIST_ORDINAL_TXT: + if (uiListNumber % 10 == 1 && uiListNumber != 11) { + tNextFree = + (size_t)sprintf(szLine, "%ust", uiListNumber); + } else if (uiListNumber % 10 == 2 && uiListNumber != 12) { + tNextFree = + (size_t)sprintf(szLine, "%und", uiListNumber); + } else if (uiListNumber % 10 == 3 && uiListNumber != 13) { + tNextFree = + (size_t)sprintf(szLine, "%urd", uiListNumber); + } else { + tNextFree = + (size_t)sprintf(szLine, "%uth", uiListNumber); + } + break; + case LIST_OUTLINE_NUM: + tNextFree = (size_t)sprintf(szLine, "%02u", uiListNumber); + break; + case LIST_SPECIAL: + case LIST_SPECIAL2: + case LIST_BULLETS: + tNextFree = 0; + break; + default: + DBG_HEX(ucNFC); + DBG_FIXME(); + tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber); + break; + } + tNextFree += (size_t)sprintf(szLine + tNextFree, "%.3s", szListChar); + szLine[tNextFree++] = ' '; + szLine[tNextFree] = '\0'; + lWidth = lComputeStringWidth(szLine, tNextFree, + pOutput->tFontRef, pOutput->usFontSize); + lLeftIndentation -= lWidth; + if (lLeftIndentation < 0) { + lLeftIndentation = 0; + } + vSetLeftIndentation(pDiag, lLeftIndentation); + for (tIndex = 0; tIndex < tNextFree; tIndex++) { + vStoreChar((ULONG)(UCHAR)szLine[tIndex], FALSE, pOutput); + } +} /* end of vPutIndentation */ + +/* + * vPutSeparatorLine - output a separator line + * + * A separator line is a horizontal line two inches long. + * Two inches equals 144000 millipoints. + */ +static void +vPutSeparatorLine(output_type *pOutput) +{ + long lCharWidth; + int iCounter, iChars; + char szOne[2]; + + fail(pOutput == NULL); + + szOne[0] = OUR_EM_DASH; + szOne[1] = '\0'; + lCharWidth = lComputeStringWidth(szOne, 1, + pOutput->tFontRef, pOutput->usFontSize); + NO_DBG_DEC(lCharWidth); + iChars = (int)((144000 + lCharWidth / 2) / lCharWidth); + NO_DBG_DEC(iChars); + for (iCounter = 0; iCounter < iChars; iCounter++) { + vStoreCharacter((ULONG)(UCHAR)OUR_EM_DASH, pOutput); + } +} /* end of vPutSeparatorLine */ + +/* + * pStartNextOutput - start the next output record + * + * returns a pointer to the next record + */ +static output_type * +pStartNextOutput(output_type *pCurrent) +{ + output_type *pNew; + + TRACE_MSG("pStartNextOutput"); + + if (pCurrent->tNextFree == 0) { + /* The current record is empty, re-use */ + fail(pCurrent->szStorage[0] != '\0'); + fail(pCurrent->lStringWidth != 0); + return pCurrent; + } + /* The current record is in use, make a new one */ + pNew = xmalloc(sizeof(*pNew)); + pCurrent->pNext = pNew; + pNew->tStorageSize = INITIAL_SIZE; + pNew->szStorage = xmalloc(pNew->tStorageSize); + pNew->szStorage[0] = '\0'; + pNew->tNextFree = 0; + pNew->lStringWidth = 0; + pNew->ucFontColor = FONT_COLOR_DEFAULT; + pNew->usFontStyle = FONT_REGULAR; + pNew->tFontRef = (drawfile_fontref)0; + pNew->usFontSize = DEFAULT_FONT_SIZE; + pNew->pPrev = pCurrent; + pNew->pNext = NULL; + return pNew; +} /* end of pStartNextOutput */ + +/* + * pStartNewOutput + */ +static output_type * +pStartNewOutput(output_type *pAnchor, output_type *pLeftOver) +{ + output_type *pCurr, *pNext; + USHORT usFontStyle, usFontSize; + drawfile_fontref tFontRef; + UCHAR ucFontColor; + + TRACE_MSG("pStartNewOutput"); + + ucFontColor = FONT_COLOR_DEFAULT; + usFontStyle = FONT_REGULAR; + tFontRef = (drawfile_fontref)0; + usFontSize = DEFAULT_FONT_SIZE; + /* Free the old output space */ + pCurr = pAnchor; + while (pCurr != NULL) { + TRACE_MSG("Free the old output space"); + pNext = pCurr->pNext; + pCurr->szStorage = xfree(pCurr->szStorage); + if (pCurr->pNext == NULL) { + ucFontColor = pCurr->ucFontColor; + usFontStyle = pCurr->usFontStyle; + tFontRef = pCurr->tFontRef; + usFontSize = pCurr->usFontSize; + } + pCurr = xfree(pCurr); + pCurr = pNext; + } + if (pLeftOver == NULL) { + /* Create new output space */ + TRACE_MSG("Create new output space"); + pLeftOver = xmalloc(sizeof(*pLeftOver)); + pLeftOver->tStorageSize = INITIAL_SIZE; + NO_DBG_DEC(pLeftOver->tStorageSize); + TRACE_MSG("before 2nd xmalloc"); + pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); + TRACE_MSG("after 2nd xmalloc"); + pLeftOver->szStorage[0] = '\0'; + pLeftOver->tNextFree = 0; + pLeftOver->lStringWidth = 0; + pLeftOver->ucFontColor = ucFontColor; + pLeftOver->usFontStyle = usFontStyle; + pLeftOver->tFontRef = tFontRef; + pLeftOver->usFontSize = usFontSize; + pLeftOver->pPrev = NULL; + pLeftOver->pNext = NULL; + } + fail(!bCheckDoubleLinkedList(pLeftOver)); + return pLeftOver; +} /* end of pStartNewOutput */ + +/* + * ulGetChar - get the next character from the specified list + * + * returns the next character of EOF + */ +static ULONG +ulGetChar(FILE *pFile, list_id_enum eListID) +{ + const font_block_type *pCurr; + ULONG ulChar, ulFileOffset, ulCharPos; + row_info_enum eRowInfo; + USHORT usChar, usPropMod; + BOOL bSkip; + + fail(pFile == NULL); + + pCurr = pFontInfo; + bSkip = FALSE; + for (;;) { + usChar = usNextChar(pFile, eListID, + &ulFileOffset, &ulCharPos, &usPropMod); + if (usChar == (USHORT)EOF) { + return (ULONG)EOF; + } + + vUpdateCounters(); + + eRowInfo = ePropMod2RowInfo(usPropMod, iWordVersion); + if (!bStartRow) { +#if 0 + bStartRow = eRowInfo == found_a_cell || + (pRowInfo != NULL && + ulFileOffset == pRowInfo->ulFileOffsetStart && + eRowInfo != found_not_a_cell); +#else + bStartRow = pRowInfo != NULL && + ulFileOffset == pRowInfo->ulFileOffsetStart; +#endif + NO_DBG_HEX_C(bStartRow, pRowInfo->ulFileOffsetStart); + } + if (!bEndRowNorm) { +#if 0 + bEndRow = eRowInfo == found_end_of_row || + (pRowInfo != NULL && + ulFileOffset == pRowInfo->ulFileOffsetEnd && + eRowInfo != found_not_end_of_row); +#else + bEndRowNorm = pRowInfo != NULL && + ulFileOffset == pRowInfo->ulFileOffsetEnd; +#endif + NO_DBG_HEX_C(bEndRowNorm, pRowInfo->ulFileOffsetEnd); + } + if (!bEndRowFast) { + bEndRowFast = eRowInfo == found_end_of_row; + NO_DBG_HEX_C(bEndRowFast, pRowInfo->ulFileOffsetEnd); + } + + if (!bStartStyle) { + bStartStyle = pStyleInfo != NULL && + ulFileOffset == pStyleInfo->ulFileOffset; + NO_DBG_HEX_C(bStartStyle, ulFileOffset); + } + if (pCurr != NULL && ulFileOffset == pCurr->ulFileOffset) { + bStartFont = TRUE; + NO_DBG_HEX(ulFileOffset); + pFontInfo = pCurr; + pCurr = pGetNextFontInfoListItem(pCurr); + } + + /* Skip embedded characters */ + if (usChar == START_EMBEDDED) { + bSkip = TRUE; + continue; + } + if (usChar == END_IGNORE || usChar == END_EMBEDDED) { + bSkip = FALSE; + continue; + } + if (bSkip) { + continue; + } + ulChar = ulTranslateCharacters(usChar, + ulFileOffset, + iWordVersion, + tOptions.eConversionType, + tOptions.eEncoding, + bOldMacFile); + if (ulChar == IGNORE_CHARACTER) { + continue; + } + if (ulChar == PICTURE) { + ulFileOffsetImage = ulGetPictInfoListItem(ulFileOffset); + } else { + ulFileOffsetImage = FC_INVALID; + } + if (ulChar == PAR_END) { + /* End of paragraph seen, prepare for the next */ + vFillStyleFromStylesheet(usIstdNext, &tStyleNext); + vCorrectStyleValues(&tStyleNext); + bStartStyleNext = TRUE; + vFillFontFromStylesheet(usIstdNext, &tFontNext); + vCorrectFontValues(&tFontNext); + bStartFontNext = TRUE; + } + if (ulChar == PAGE_BREAK) { + /* Might be the start of a new section */ + pSectionNext = pGetSectionInfo(pSection, ulCharPos); + } + return ulChar; + } +} /* end of ulGetChar */ + +/* + * lGetWidthMax - get the maximum line width from the paragraph break value + * + * Returns the maximum line width in millipoints + */ +static long +lGetWidthMax(int iParagraphBreak) +{ + fail(iParagraphBreak < 0); + + if (iParagraphBreak == 0) { + return LONG_MAX; + } + if (iParagraphBreak < MIN_SCREEN_WIDTH) { + return lChar2MilliPoints(MIN_SCREEN_WIDTH); + } + if (iParagraphBreak > MAX_SCREEN_WIDTH) { + return lChar2MilliPoints(MAX_SCREEN_WIDTH); + } + return lChar2MilliPoints(iParagraphBreak); +} /* end of lGetWidthMax */ + +/* + * bWordDecryptor - turn Word to something more useful + * + * returns TRUE when succesful, otherwise FALSE + */ +BOOL +bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag) +{ + imagedata_type tImage; + const style_block_type *pStyleTmp; + const font_block_type *pFontTmp; + const char *szListChar; + output_type *pAnchor, *pOutput, *pLeftOver; + ULONG ulChar; + long lBeforeIndentation, lAfterIndentation; + long lLeftIndentation, lLeftIndentation1, lRightIndentation; + long lWidthCurr, lWidthMax, lDefaultTabWidth, lHalfSpaceWidth, lTmp; + list_id_enum eListID; + image_info_enum eRes; + UINT uiFootnoteNumber, uiEndnoteNumber, uiTmp; + int iListSeqNumber; + BOOL bWasTableRow, bTableFontClosed, bWasEndOfParagraph; + BOOL bInList, bWasInList, bNoMarks, bFirstLine; + BOOL bAllCapitals, bHiddenText, bMarkDelText, bSuccess; + USHORT usListNumber; + USHORT usFontStyle, usFontStyleMinimal, usFontSize, usTmp; + UCHAR ucFontNumber, ucFontColor; + UCHAR ucNFC, ucAlignment; + + fail(pFile == NULL || lFilesize <= 0 || pDiag == NULL); + + TRACE_MSG("bWordDecryptor"); + + iWordVersion = iInitDocument(pFile, lFilesize); + if (iWordVersion < 0) { + DBG_DEC(iWordVersion); + return FALSE; + } + + vGetOptions(&tOptions); + bOldMacFile = bIsOldMacFile(); + vPrepareHdrFtrText(pFile); + vPrepareFootnoteText(pFile); + + vPrologue2(pDiag, iWordVersion); + + /* Initialisation */ +#if defined(__riscos) + ulCharCounter = 0; + iCurrPct = 0; + iPrevPct = -1; + ulDocumentLength = ulGetDocumentLength(); +#endif /* __riscos */ + pSection = pGetSectionInfo(NULL, 0); + pSectionNext = pSection; + lDefaultTabWidth = lGetDefaultTabWidth(); + DBG_DEC_C(lDefaultTabWidth != 36000, lDefaultTabWidth); + pRowInfo = pGetNextRowInfoListItem(); + DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetStart); + DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetEnd); + DBG_MSG_C(pRowInfo == NULL, "No rows at all"); + bStartRow = FALSE; + bEndRowNorm = FALSE; + bEndRowFast = FALSE; + bIsTableRow = FALSE; + bWasTableRow = FALSE; + vResetStyles(); + pStyleInfo = pGetNextTextStyle(NULL); + bStartStyle = FALSE; + bInList = FALSE; + bWasInList = FALSE; + iListSeqNumber = 0; + usIstdNext = ISTD_NORMAL; + pAnchor = NULL; + pFontInfo = pGetNextFontInfoListItem(NULL); + DBG_HEX_C(pFontInfo != NULL, pFontInfo->ulFileOffset); + DBG_MSG_C(pFontInfo == NULL, "No fonts at all"); + bStartFont = FALSE; + ucFontNumber = 0; + usFontStyleMinimal = FONT_REGULAR; + usFontStyle = FONT_REGULAR; + usFontSize = DEFAULT_FONT_SIZE; + ucFontColor = FONT_COLOR_DEFAULT; + pAnchor = pStartNewOutput(pAnchor, NULL); + pOutput = pAnchor; + pOutput->ucFontColor = ucFontColor; + pOutput->usFontStyle = usFontStyle; + pOutput->tFontRef = tOpenFont(ucFontNumber, usFontStyle, usFontSize); + pOutput->usFontSize = usFontSize; + bTableFontClosed = TRUE; + lBeforeIndentation = 0; + lAfterIndentation = 0; + lLeftIndentation = 0; + lLeftIndentation1 = 0; + lRightIndentation = 0; + bWasEndOfParagraph = TRUE; + bNoMarks = TRUE; + bFirstLine = TRUE; + ucNFC = LIST_BULLETS; + if (pStyleInfo != NULL) { + szListChar = pStyleInfo->szListChar; + pStyleTmp = pStyleInfo; + } else { + if (tStyleNext.szListChar[0] == '\0') { + vGetBulletValue(tOptions.eConversionType, + tOptions.eEncoding, tStyleNext.szListChar, 4); + } + szListChar = tStyleNext.szListChar; + pStyleTmp = &tStyleNext; + } + usListNumber = 0; + ucAlignment = ALIGNMENT_LEFT; + bAllCapitals = FALSE; + bHiddenText = FALSE; + bMarkDelText = FALSE; + lWidthMax = lGetWidthMax(tOptions.iParagraphBreak); + NO_DBG_DEC(lWidthMax); + + Hourglass_On(); + + uiFootnoteNumber = 0; + uiEndnoteNumber = 0; + eListID = text_list; + for(;;) { + ulChar = ulGetChar(pFile, eListID); + if (ulChar == (ULONG)EOF) { + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + RESET_LINE(); + } + switch (eListID) { + case text_list: + if (tOptions.eConversionType != + conversion_xml) { + eListID = footnote_list; + if (uiFootnoteNumber != 0) { + vPutSeparatorLine(pAnchor); + OUTPUT_LINE(); + uiFootnoteNumber = 0; + } + break; + } + /* No break or return */ + case footnote_list: + eListID = endnote_list; + if (uiEndnoteNumber != 0) { + vPutSeparatorLine(pAnchor); + OUTPUT_LINE(); + uiEndnoteNumber = 0; + } + break; + case endnote_list: + eListID = textbox_list; + if (bExistsTextBox()) { + vPutSeparatorLine(pAnchor); + OUTPUT_LINE(); + } + break; + case textbox_list: + eListID = hdrtextbox_list; + if (bExistsHdrTextBox()) { + vPutSeparatorLine(pAnchor); + OUTPUT_LINE(); + } + break; + case hdrtextbox_list: + default: + eListID = end_of_lists; + break; + } + if (eListID == end_of_lists) { + break; + } + continue; + } + + if (ulChar == UNKNOWN_NOTE_CHAR) { + switch (eListID) { + case footnote_list: + ulChar = FOOTNOTE_CHAR; + break; + case endnote_list: + ulChar = ENDNOTE_CHAR; + break; + default: + break; + } + } + + if (bStartRow) { + /* Begin of a tablerow found */ + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + RESET_LINE(); + } + fail(pAnchor != pOutput); + if (bTableFontClosed) { + /* Start special table font */ + vCloseFont(); + /* + * Compensate for the fact that Word uses + * proportional fonts for its tables and we + * only one fixed-width font + */ + uiTmp = ((UINT)usFontSize * 5 + 3) / 6; + if (uiTmp < MIN_TABLEFONT_SIZE) { + uiTmp = MIN_TABLEFONT_SIZE; + } else if (uiTmp > MAX_TABLEFONT_SIZE) { + uiTmp = MAX_TABLEFONT_SIZE; + } + pOutput->usFontSize = (USHORT)uiTmp; + pOutput->tFontRef = + tOpenTableFont(pOutput->usFontSize); + pOutput->usFontStyle = FONT_REGULAR; + pOutput->ucFontColor = FONT_COLOR_BLACK; + bTableFontClosed = FALSE; + } + bIsTableRow = TRUE; + bStartRow = FALSE; + } + + if (bWasTableRow && + !bIsTableRow && + ulChar != PAR_END && + ulChar != HARD_RETURN && + ulChar != PAGE_BREAK && + ulChar != COLUMN_FEED) { + /* + * The end of a table should be followed by an + * empty line, like the end of a paragraph + */ + OUTPUT_LINE(); + vEndOfParagraph(pDiag, + pOutput->tFontRef, + pOutput->usFontSize, + (long)pOutput->usFontSize * 600); + } + + switch (ulChar) { + case PAGE_BREAK: + case COLUMN_FEED: + if (bIsTableRow) { + /* Ignore when in a table */ + break; + } + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + RESET_LINE(); + } + if (ulChar == PAGE_BREAK) { + vEndOfPage(pDiag, lAfterIndentation, + pSection != pSectionNext); + } else { + vEndOfParagraph(pDiag, + pOutput->tFontRef, + pOutput->usFontSize, + lAfterIndentation); + } + break; + default: + break; + } + + if (bStartFont || (bStartFontNext && ulChar != PAR_END)) { + /* Begin of a font found */ + if (bStartFont) { + /* bStartFont takes priority */ + fail(pFontInfo == NULL); + pFontTmp = pFontInfo; + } else { + pFontTmp = &tFontNext; + } + bAllCapitals = bIsCapitals(pFontTmp->usFontStyle); + bHiddenText = bIsHidden(pFontTmp->usFontStyle); + bMarkDelText = bIsMarkDel(pFontTmp->usFontStyle); + usTmp = pFontTmp->usFontStyle & + (FONT_BOLD|FONT_ITALIC|FONT_UNDERLINE| + FONT_STRIKE|FONT_MARKDEL| + FONT_SUPERSCRIPT|FONT_SUBSCRIPT); + if (!bIsTableRow && + (usFontSize != pFontTmp->usFontSize || + ucFontNumber != pFontTmp->ucFontNumber || + usFontStyleMinimal != usTmp || + ucFontColor != pFontTmp->ucFontColor)) { + pOutput = pStartNextOutput(pOutput); + vCloseFont(); + pOutput->ucFontColor = pFontTmp->ucFontColor; + pOutput->usFontStyle = pFontTmp->usFontStyle; + pOutput->usFontSize = pFontTmp->usFontSize; + pOutput->tFontRef = tOpenFont( + pFontTmp->ucFontNumber, + pFontTmp->usFontStyle, + pFontTmp->usFontSize); + fail(!bCheckDoubleLinkedList(pAnchor)); + } + ucFontNumber = pFontTmp->ucFontNumber; + usFontSize = pFontTmp->usFontSize; + ucFontColor = pFontTmp->ucFontColor; + usFontStyle = pFontTmp->usFontStyle; + usFontStyleMinimal = usTmp; + if (bStartFont) { + /* Get the next font info */ + pFontInfo = pGetNextFontInfoListItem(pFontInfo); + NO_DBG_HEX_C(pFontInfo != NULL, + pFontInfo->ulFileOffset); + DBG_MSG_C(pFontInfo == NULL, "No more fonts"); + } + bStartFont = FALSE; + bStartFontNext = FALSE; + } + + if (bStartStyle || (bStartStyleNext && ulChar != PAR_END)) { + bFirstLine = TRUE; + /* Begin of a style found */ + if (bStartStyle) { + /* bStartStyle takes priority */ + fail(pStyleInfo == NULL); + pStyleTmp = pStyleInfo; + } else { + pStyleTmp = &tStyleNext; + } + if (!bIsTableRow) { + vStoreStyle(pDiag, pOutput, pStyleTmp); + } + usIstdNext = pStyleTmp->usIstdNext; + lBeforeIndentation = + lTwips2MilliPoints(pStyleTmp->usBeforeIndent); + lAfterIndentation = + lTwips2MilliPoints(pStyleTmp->usAfterIndent); + lLeftIndentation = + lTwips2MilliPoints(pStyleTmp->sLeftIndent); + lLeftIndentation1 = + lTwips2MilliPoints(pStyleTmp->sLeftIndent1); + lRightIndentation = + lTwips2MilliPoints(pStyleTmp->sRightIndent); + bInList = bStyleImpliesList(pStyleTmp, iWordVersion); + bNoMarks = !bInList || pStyleTmp->bNumPause; + ucNFC = pStyleTmp->ucNFC; + szListChar = pStyleTmp->szListChar; + ucAlignment = pStyleTmp->ucAlignment; + if (bInList && !bWasInList) { + /* Start of a list */ + iListSeqNumber++; + vStartOfList(pDiag, ucNFC, + bWasTableRow && !bIsTableRow); + } + if (!bInList && bWasInList) { + /* End of a list */ + vEndOfList(pDiag); + } + bWasInList = bInList; + if (bStartStyle) { + pStyleInfo = pGetNextTextStyle(pStyleInfo); + NO_DBG_HEX_C(pStyleInfo != NULL, + pStyleInfo->ulFileOffset); + DBG_MSG_C(pStyleInfo == NULL, + "No more styles"); + } + bStartStyle = FALSE; + bStartStyleNext = FALSE; + } + + if (bWasEndOfParagraph) { + vStartOfParagraph1(pDiag, lBeforeIndentation); + } + + if (!bIsTableRow && + lTotalStringWidth(pAnchor) == 0) { + if (!bNoMarks) { + usListNumber = usGetListValue(iListSeqNumber, + iWordVersion, + pStyleTmp); + } + if (bInList && bFirstLine) { + vStartOfListItem(pDiag, bNoMarks); + } + vPutIndentation(pDiag, pAnchor, bNoMarks, bFirstLine, + usListNumber, ucNFC, szListChar, + lLeftIndentation, lLeftIndentation1); + bFirstLine = FALSE; + /* One number or mark per paragraph will do */ + bNoMarks = TRUE; + } + + if (bWasEndOfParagraph) { + vStartOfParagraph2(pDiag); + bWasEndOfParagraph = FALSE; + } + + switch (ulChar) { + case PICTURE: + (void)memset(&tImage, 0, sizeof(tImage)); + eRes = eExamineImage(pFile, ulFileOffsetImage, &tImage); + switch (eRes) { + case image_no_information: + bSuccess = FALSE; + break; + case image_minimal_information: + case image_full_information: +#if 0 + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + RESET_LINE(); + } +#endif + bSuccess = bTranslateImage(pDiag, pFile, + eRes == image_minimal_information, + ulFileOffsetImage, &tImage); + break; + default: + DBG_DEC(eRes); + bSuccess = FALSE; + break; + } + if (!bSuccess) { + vStoreString("[pic]", 5, pOutput); + } + break; + case FOOTNOTE_CHAR: + uiFootnoteNumber++; + if (tOptions.eConversionType == conversion_xml) { + vStoreCharacter((ULONG)FOOTNOTE_OR_ENDNOTE, + pOutput); + break; + } + vStoreCharacter((ULONG)'[', pOutput); + vStoreNumberAsDecimal(uiFootnoteNumber, pOutput); + vStoreCharacter((ULONG)']', pOutput); + break; + case ENDNOTE_CHAR: + uiEndnoteNumber++; + vStoreCharacter((ULONG)'[', pOutput); + vStoreNumberAsRoman(uiEndnoteNumber, pOutput); + vStoreCharacter((ULONG)']', pOutput); + break; + case UNKNOWN_NOTE_CHAR: + vStoreString("[?]", 3, pOutput); + break; + case PAR_END: + if (bIsTableRow) { + vStoreCharacter((ULONG)'\n', pOutput); + break; + } + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + vMove2NextLine(pDiag, + pOutput->tFontRef, pOutput->usFontSize); + RESET_LINE(); + } + vEndOfParagraph(pDiag, + pOutput->tFontRef, + pOutput->usFontSize, + lAfterIndentation); + bWasEndOfParagraph = TRUE; + break; + case HARD_RETURN: + if (bIsTableRow) { + vStoreCharacter((ULONG)'\n', pOutput); + break; + } + if (bOutputContainsText(pAnchor)) { + OUTPUT_LINE(); + } else { + vMove2NextLine(pDiag, + pOutput->tFontRef, pOutput->usFontSize); + RESET_LINE(); + } + break; + case PAGE_BREAK: + case COLUMN_FEED: + pSection = pSectionNext; + break; + case TABLE_SEPARATOR: + if (bIsTableRow) { + vStoreCharacter(ulChar, pOutput); + break; + } + vStoreCharacter((ULONG)' ', pOutput); + vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR, pOutput); + break; + case TAB: + if (bIsTableRow || + tOptions.eConversionType == conversion_xml) { + vStoreCharacter((ULONG)' ', pOutput); + break; + } + if (tOptions.iParagraphBreak == 0 && + (tOptions.eConversionType == conversion_text || + tOptions.eConversionType == conversion_fmt_text)) { + /* No logical lines, so no tab expansion */ + vStoreCharacter(TAB, pOutput); + break; + } + lHalfSpaceWidth = (lComputeSpaceWidth( + pOutput->tFontRef, + pOutput->usFontSize) + 1) / 2; + lTmp = lTotalStringWidth(pAnchor); + lTmp += lDrawUnits2MilliPoints(pDiag->lXleft); + lTmp /= lDefaultTabWidth; + do { + vStoreCharacter((ULONG)FILLER_CHAR, pOutput); + lWidthCurr = lTotalStringWidth(pAnchor); + lWidthCurr += + lDrawUnits2MilliPoints(pDiag->lXleft); + } while (lTmp == lWidthCurr / lDefaultTabWidth && + lWidthCurr < lWidthMax + lRightIndentation); + break; + default: + if (bHiddenText && tOptions.bHideHiddenText) { + continue; + } + if (bMarkDelText && tOptions.bRemoveRemovedText) { + continue; + } + if (ulChar == UNICODE_ELLIPSIS && + tOptions.eEncoding != encoding_utf_8) { + vStoreString("...", 3, pOutput); + } else { + if (bAllCapitals) { + ulChar = ulToUpper(ulChar); + } + vStoreCharacter(ulChar, pOutput); + } + break; + } + + if (bWasTableRow && !bIsTableRow) { + /* End of a table */ + vEndOfTable(pDiag); + /* Resume normal font */ + NO_DBG_MSG("End of table font"); + vCloseFont(); + bTableFontClosed = TRUE; + pOutput->ucFontColor = ucFontColor; + pOutput->usFontStyle = usFontStyle; + pOutput->usFontSize = usFontSize; + pOutput->tFontRef = tOpenFont( + ucFontNumber, usFontStyle, usFontSize); + } + bWasTableRow = bIsTableRow; + + if (bIsTableRow) { + fail(pAnchor != pOutput); + if (!bEndRowNorm && !bEndRowFast) { + continue; + } + /* End of a table row */ + if (bEndRowNorm) { + fail(pRowInfo == NULL); + vTableRow2Window(pDiag, pAnchor, pRowInfo, + tOptions.eConversionType, + tOptions.iParagraphBreak); + } else { + fail(!bEndRowFast); + } + /* Reset */ + pAnchor = pStartNewOutput(pAnchor, NULL); + pOutput = pAnchor; + if (bEndRowNorm) { + pRowInfo = pGetNextRowInfoListItem(); + } + bIsTableRow = FALSE; + bEndRowNorm = FALSE; + bEndRowFast = FALSE; + NO_DBG_HEX_C(pRowInfo != NULL, + pRowInfo->ulFileOffsetStart); + NO_DBG_HEX_C(pRowInfo != NULL, + pRowInfo->ulFileOffsetEnd); + continue; + } + lWidthCurr = lTotalStringWidth(pAnchor); + lWidthCurr += lDrawUnits2MilliPoints(pDiag->lXleft); + if (lWidthCurr < lWidthMax + lRightIndentation) { + continue; + } + pLeftOver = pSplitList(pAnchor); + vJustify2Window(pDiag, pAnchor, + lWidthMax, lRightIndentation, ucAlignment); + pAnchor = pStartNewOutput(pAnchor, pLeftOver); + for (pOutput = pAnchor; + pOutput->pNext != NULL; + pOutput = pOutput->pNext) + ; /* EMPTY */ + fail(pOutput == NULL); + if (lTotalStringWidth(pAnchor) > 0) { + vSetLeftIndentation(pDiag, lLeftIndentation); + } + } + + pAnchor = pStartNewOutput(pAnchor, NULL); + pAnchor->szStorage = xfree(pAnchor->szStorage); + pAnchor = xfree(pAnchor); + vCloseFont(); + vFreeDocument(); + Hourglass_Off(); + return TRUE; +} /* end of bWordDecryptor */ + +/* + * lLastStringWidth - compute the width of the last part of the output string + */ +static long +lLastStringWidth(const output_type *pAnchor) +{ + const output_type *pCurr, *pStart; + + pStart = NULL; + for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { + if (pCurr->tNextFree == 1 && + (pCurr->szStorage[0] == PAR_END || + pCurr->szStorage[0] == HARD_RETURN)) { + /* Found a separator. Start after the separator */ + pStart = pCurr->pNext; + } + } + if (pStart == NULL) { + /* No separators. Use the whole output string */ + pStart = pAnchor; + } + return lTotalStringWidth(pStart); +} /* end of lLastStringWidth */ + +/* + * pHdrFtrDecryptor - turn a header/footer list element to something useful + */ +output_type * +pHdrFtrDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext) +{ + output_type *pAnchor, *pOutput, *pLeftOver; + ULONG ulChar, ulFileOffset, ulCharPos; + long lWidthCurr, lWidthMax; + long lRightIndentation; + USHORT usChar; + UCHAR ucAlignment; + BOOL bSkip; + + fail(iWordVersion < 0); + fail(tOptions.eConversionType == conversion_unknown); + fail(tOptions.eEncoding == 0); + + if (ulCharPosStart == ulCharPosNext) { + /* There are no bytes to decrypt */ + return NULL; + } + + lRightIndentation = 0; + ucAlignment = ALIGNMENT_LEFT; + bSkip = FALSE; + lWidthMax = lGetWidthMax(tOptions.iParagraphBreak); + pAnchor = pStartNewOutput(NULL, NULL); + pOutput = pAnchor; + pOutput->tFontRef = tOpenFont(0, FONT_REGULAR, DEFAULT_FONT_SIZE); + usChar = usToHdrFtrPosition(pFile, ulCharPosStart); + ulCharPos = ulCharPosStart; + ulFileOffset = ulCharPos2FileOffset(ulCharPos); + while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) { + /* Skip embedded characters */ + if (usChar == START_EMBEDDED) { + bSkip = TRUE; + } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) { + bSkip = FALSE; + } + /* Translate character */ + if (bSkip || usChar == END_IGNORE || usChar == END_EMBEDDED) { + ulChar = IGNORE_CHARACTER; + } else { + ulChar = ulTranslateCharacters(usChar, + ulFileOffset, + iWordVersion, + tOptions.eConversionType, + tOptions.eEncoding, + bOldMacFile); + } + /* Process character */ + if (ulChar != IGNORE_CHARACTER) { + switch (ulChar) { + case PICTURE: + vStoreString("[pic]", 5, pOutput); + break; + case PAR_END: + case HARD_RETURN: + case PAGE_BREAK: + case COLUMN_FEED: + /* To the next substring */ + pOutput = pStartNextOutput(pOutput); + vCloseFont(); + pOutput->tFontRef = tOpenFont(0, + FONT_REGULAR, DEFAULT_FONT_SIZE); + /* A substring with just one character */ + if (ulChar == HARD_RETURN) { + vStoreCharacter(HARD_RETURN, pOutput); + } else { + vStoreCharacter(PAR_END, pOutput); + } + /* To the next substring */ + pOutput = pStartNextOutput(pOutput); + vCloseFont(); + pOutput->tFontRef = tOpenFont(0, + FONT_REGULAR, DEFAULT_FONT_SIZE); + fail(!bCheckDoubleLinkedList(pAnchor)); + break; + case TABLE_SEPARATOR: + vStoreCharacter((ULONG)' ', pOutput); + vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR, + pOutput); + break; + case TAB: + vStoreCharacter((ULONG)FILLER_CHAR, pOutput); + break; + default: + vStoreCharacter(ulChar, pOutput); + break; + } + } + lWidthCurr = lLastStringWidth(pAnchor); + if (lWidthCurr >= lWidthMax + lRightIndentation) { + pLeftOver = pSplitList(pAnchor); + for (pOutput = pAnchor; + pOutput->pNext != NULL; + pOutput = pOutput->pNext) + ; /* EMPTY */ + fail(pOutput == NULL); + /* To the next substring */ + pOutput = pStartNextOutput(pOutput); + /* A substring with just one HARD_RETURN */ + vStoreCharacter(HARD_RETURN, pOutput); + /* Put the leftover piece(s) at the end */ + pOutput->pNext = pLeftOver; + if (pLeftOver != NULL) { + pLeftOver->pPrev = pOutput; + } + fail(!bCheckDoubleLinkedList(pAnchor)); + for (pOutput = pAnchor; + pOutput->pNext != NULL; + pOutput = pOutput->pNext) + ; /* EMPTY */ + fail(pOutput == NULL); + } + usChar = usNextChar(pFile, hdrftr_list, + &ulFileOffset, &ulCharPos, NULL); + } + vCloseFont(); + if (bOutputContainsText(pAnchor)) { + return pAnchor; + } + pAnchor = pStartNewOutput(pAnchor, NULL); + pAnchor->szStorage = xfree(pAnchor->szStorage); + pAnchor = xfree(pAnchor); + return NULL; +} /* end of pHdrFtrDecryptor */ + +/* + * pFootnoteDecryptor - turn a footnote text list element into text + */ +char * +szFootnoteDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext) +{ + char *szText; + ULONG ulChar, ulFileOffset, ulCharPos; + USHORT usChar; + size_t tLen, tIndex, tNextFree, tStorageSize; + char szResult[6]; + BOOL bSkip; + + fail(iWordVersion < 0); + fail(tOptions.eConversionType == conversion_unknown); + fail(tOptions.eEncoding == 0); + + if (ulCharPosStart == ulCharPosNext) { + /* There are no bytes to decrypt */ + return NULL; + } + + if (tOptions.eConversionType != conversion_xml) { + /* Only implemented for XML output */ + return NULL; + } + + bSkip = FALSE; + + /* Initialise the text buffer */ + tStorageSize = INITIAL_SIZE; + szText = xmalloc(tStorageSize); + tNextFree = 0; + szText[tNextFree] = '\0'; + + /* Goto the start */ + usChar = usToFootnotePosition(pFile, ulCharPosStart); + ulCharPos = ulCharPosStart; + ulFileOffset = ulCharPos2FileOffset(ulCharPos); + /* Skip the unwanted starting characters */ + while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext && + (usChar == FOOTNOTE_OR_ENDNOTE || + usChar == PAR_END || + usChar == TAB || + usChar == (USHORT)' ')) { + usChar = usNextChar(pFile, footnote_list, + &ulFileOffset, &ulCharPos, NULL); + } + /* Process the footnote text */ + while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) { + /* Skip embedded characters */ + if (usChar == START_EMBEDDED) { + bSkip = TRUE; + } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) { + bSkip = FALSE; + } + /* Translate character */ + if (bSkip || + usChar == END_IGNORE || + usChar == END_EMBEDDED || + usChar == FOOTNOTE_OR_ENDNOTE) { + ulChar = IGNORE_CHARACTER; + } else { + ulChar = ulTranslateCharacters(usChar, + ulFileOffset, + iWordVersion, + tOptions.eConversionType, + tOptions.eEncoding, + bOldMacFile); + } + /* Process character */ + if (ulChar == PICTURE) { + tLen = 5; + strcpy(szResult, "[pic]"); + } else if (ulChar == IGNORE_CHARACTER) { + tLen = 0; + szResult[0] = '\0'; + } else { + switch (ulChar) { + case PAR_END: + case HARD_RETURN: + case PAGE_BREAK: + case COLUMN_FEED: + ulChar = (ULONG)PAR_END; + break; + case TAB: + ulChar = (ULONG)' '; + break; + default: + break; + } + tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); + } + /* Add the results to the text */ + if (tNextFree + tLen + 1 > tStorageSize) { + tStorageSize += EXTENTION_SIZE; + szText = xrealloc(szText, tStorageSize); + } + for (tIndex = 0; tIndex < tLen; tIndex++) { + szText[tNextFree++] = szResult[tIndex]; + } + szText[tNextFree] = '\0'; + /* Next character */ + usChar = usNextChar(pFile, footnote_list, + &ulFileOffset, &ulCharPos, NULL); + } + /* Remove redundant spaces */ + while (tNextFree != 0 && szText[tNextFree - 1] == ' ') { + szText[tNextFree - 1] = '\0'; + tNextFree--; + } + if (tNextFree == 0) { + /* No text */ + szText = xfree(szText); + return NULL; + } + return szText; +} /* end of szFootnoteDecryptor */ diff --git a/wordconst.h b/wordconst.h new file mode 100644 index 0000000..739f11b --- /dev/null +++ b/wordconst.h @@ -0,0 +1,321 @@ +/* + * wordconst.h + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Constants and macros for the interpretation of MS Word files + */ + +#if !defined(__wordconst_h) +#define __wordconst_h 1 + +/* + * A bit odd definition of the type Boolean, but RISC OS insists + * on this and Linux/Unix doesn't mind. + */ +#if !defined(BOOL) +#define BOOL int +#define TRUE 1 +#define FALSE 0 +#endif /* !BOOL */ + +/* Block sizes */ +#define HEADER_SIZE 768 +#define BIG_BLOCK_SIZE 512 +#define PROPERTY_SET_STORAGE_SIZE 128 +#define SMALL_BLOCK_SIZE 64 +/* Switch size of Depot use */ +#define MIN_SIZE_FOR_BBD_USE 0x1000 +/* Table sizes */ +#define TABLE_COLUMN_MAX 31 +/* Maximum number of tabs positions in a paragraph */ +#define NUMBER_OF_TABS_MAX 64 +/* Font sizes (in half-points) */ +#define MIN_FONT_SIZE 8 +#define DEFAULT_FONT_SIZE 20 +#define MAX_FONT_SIZE 240 +#define MIN_TABLEFONT_SIZE 16 +#define MAX_TABLEFONT_SIZE 20 +/* Font styles */ +#define FONT_REGULAR 0x0000 +#define FONT_BOLD 0x0001 +#define FONT_ITALIC 0x0002 +#define FONT_UNDERLINE 0x0004 +#define FONT_CAPITALS 0x0008 +#define FONT_SMALL_CAPITALS 0x0010 +#define FONT_STRIKE 0x0020 +#define FONT_HIDDEN 0x0040 +#define FONT_MARKDEL 0x0080 +#define FONT_SUPERSCRIPT 0x0100 +#define FONT_SUBSCRIPT 0x0200 +/* Font colors */ +#define FONT_COLOR_DEFAULT 0 +#define FONT_COLOR_BLACK 1 +#define FONT_COLOR_BLUE 2 +#define FONT_COLOR_CYAN 3 +#define FONT_COLOR_GREEN 4 +#define FONT_COLOR_MAGENTA 5 +#define FONT_COLOR_RED 6 +#define FONT_COLOR_YELLOW 7 +#define FONT_COLOR_WHITE 8 +/* Special block numbers */ +#define END_OF_CHAIN 0xfffffffeUL +#define UNUSED_BLOCK 0xffffffffUL +/* Blocksize (512 bytes) and maximum filesize (4 GB) gives 0..7fffff */ +#define MAX_BLOCKNUMBER 0x007fffffUL +/* Invalid character position */ +#define CP_INVALID 0xffffffffUL +/* Invalid file offset */ +#define FC_INVALID 0xffffffffUL +/* Special istd values */ +#define ISTD_INVALID USHRT_MAX +#define ISTD_NORMAL 0 +/* Properties modifier without value */ +#define IGNORE_PROPMOD 0 +/* Types of lists */ +#define LIST_ARABIC_NUM 0x00 +#define LIST_UPPER_ROMAN 0x01 +#define LIST_LOWER_ROMAN 0x02 +#define LIST_UPPER_ALPHA 0x03 +#define LIST_LOWER_ALPHA 0x04 +#define LIST_ORDINAL_NUM 0x05 +#define LIST_NUMBER_TXT 0x06 +#define LIST_ORDINAL_TXT 0x07 +#define LIST_OUTLINE_NUM 0x16 +#define LIST_SPECIAL 0x17 +#define LIST_SPECIAL2 0x19 +#define LIST_BULLETS 0xff +/* Types of paragraph alignment */ +#define ALIGNMENT_LEFT 0x00 +#define ALIGNMENT_CENTER 0x01 +#define ALIGNMENT_RIGHT 0x02 +#define ALIGNMENT_JUSTIFY 0x03 +/* Minimum vertical space before and after a heading line */ +#define HEADING_GAP 120 /* twips */ +/* Style identifier */ +#define STI_USER 0xffe +#define STI_NIL 0xfff +/* Table border style codes */ +#define TABLE_BORDER_TOP 0x01 +#define TABLE_BORDER_LEFT 0x02 +#define TABLE_BORDER_BOTTOM 0x04 +#define TABLE_BORDER_RIGHT 0x08 + +/* Macros */ + /* Get macros */ +#define ucGetByte(i,a) ((unsigned char)(a[i])) +#define usGetWord(i,a) ((unsigned short)\ + ((unsigned int)(a[(i)+1])<<8|\ + (unsigned int)(a[i]))) +#define ulGetLong(i,a) ((unsigned long)(a[i])|\ + (unsigned long)(a[(i)+1])<<8|\ + (unsigned long)(a[(i)+2])<<16|\ + (unsigned long)(a[(i)+3])<<24) +#define usGetWordBE(i,a) ((unsigned short)\ + ((unsigned int)(a[i])<<8|\ + (unsigned int)(a[(i)+1]))) +#define ulGetLongBE(i,a) ((unsigned long)(a[(i)+3])|\ + (unsigned long)(a[(i)+2])<<8|\ + (unsigned long)(a[(i)+1])<<16|\ + (unsigned long)(a[i])<<24) + /* Font style macros */ +#define bIsBold(x) (((x) & FONT_BOLD) == FONT_BOLD) +#define bIsItalic(x) (((x) & FONT_ITALIC) == FONT_ITALIC) +#define bIsUnderline(x) (((x) & FONT_UNDERLINE) == FONT_UNDERLINE) +#define bIsCapitals(x) (((x) & FONT_CAPITALS) == FONT_CAPITALS) +#define bIsSmallCapitals(x) (((x) & FONT_SMALL_CAPITALS) == FONT_SMALL_CAPITALS) +#define bIsStrike(x) (((x) & FONT_STRIKE) == FONT_STRIKE) +#define bIsHidden(x) (((x) & FONT_HIDDEN) == FONT_HIDDEN) +#define bIsMarkDel(x) (((x) & FONT_MARKDEL) == FONT_MARKDEL) +#define bIsSuperscript(x) (((x) & FONT_SUPERSCRIPT) == FONT_SUPERSCRIPT) +#define bIsSubscript(x) (((x) & FONT_SUBSCRIPT) == FONT_SUBSCRIPT) + /* Table border style code macros */ +#define bIsTableBorderTop(x) (((x) & TABLE_BORDER_TOP) == TABLE_BORDER_TOP) +#define bIsTableBorderLeft(x) (((x) & TABLE_BORDER_LEFT) == TABLE_BORDER_LEFT) +#define bIsTableBorderBottom(x) (((x) & TABLE_BORDER_BOTTOM) == TABLE_BORDER_BOTTOM) +#define bIsTableBorderRight(x) (((x) & TABLE_BORDER_RIGHT) == TABLE_BORDER_RIGHT) + /* Computation macros */ +#if defined(__riscos) +/* From Words half-points to draw units (plus a percentage) */ +#define lWord2DrawUnits00(x) ((long)(x) * 320) +#define lWord2DrawUnits20(x) ((long)(x) * 384) +#define lToBaseLine(x) ((long)(x) * 45) +#endif /* __riscos */ +/* From twips (1/20 of a point) to millipoints */ +#define lTwips2MilliPoints(x) ((long)(x) * 50) +/* From twips (1/20 of a point) to points */ +#define dTwips2Points(x) ((double)(x) / 20.0) +/* From default characters (16 OS units wide) to millipoints */ +#define lChar2MilliPoints(x) ((long)(x) * 6400) +#define iMilliPoints2Char(x) (int)(((long)(x) + 3200) / 6400) +#define iDrawUnits2Char(x) (int)(((long)(x) + 2048) / 4096) +/* From draw units (1/180*256 inch) to millipoints (1/72*1000 inch) */ +#define lDrawUnits2MilliPoints(x) (((long)(x) * 25 + 8) / 16) +#define lMilliPoints2DrawUnits(x) (((long)(x) * 16 + 12) / 25) +#define lPoints2DrawUnits(x) ((long)(x) * 640) +#define dDrawUnits2Points(x) ((double)(x) / 640.0) + +/* Special characters */ +#define IGNORE_CHARACTER 0x00 /* ^@ */ +#define PICTURE 0x01 /* ^A */ +#define FOOTNOTE_OR_ENDNOTE 0x02 /* ^B */ +#define FOOTNOTE_SEPARATOR 0x03 /* ^C */ +#define FOOTNOTE_CONTINUATION 0x04 /* ^D */ +#define ANNOTATION 0x05 /* ^E */ +#define TABLE_SEPARATOR 0x07 /* ^G */ +#define FRAME 0x08 /* ^H */ +#define TAB 0x09 /* ^I */ +/* End of line characters */ +#define LINE_FEED 0x0a /* ^J */ +#define HARD_RETURN 0x0b /* ^K */ +#define PAGE_BREAK 0x0c /* ^L */ +#define PAR_END 0x0d /* ^M */ +#define COLUMN_FEED 0x0e /* ^N */ +/* Embedded stuff */ +#define START_EMBEDDED 0x13 /* ^S */ +#define END_IGNORE 0x14 /* ^T */ +#define END_EMBEDDED 0x15 /* ^U */ +/* Special characters */ +#if defined(DEBUG) +#define FILLER_CHAR '~' +#else +#define FILLER_CHAR ' ' +#endif /* DEBUG */ +#define TABLE_SEPARATOR_CHAR '|' +/* Pseudo characters. These must be outside the Unicode range */ +#define FOOTNOTE_CHAR ((unsigned long)0xffff + 1) +#define ENDNOTE_CHAR ((unsigned long)0xffff + 2) +#define UNKNOWN_NOTE_CHAR ((unsigned long)0xffff + 3) + +/* Charactercodes as used by Word */ +#define WORD_UNBREAKABLE_JOIN 0x1e +#define WORD_SOFT_HYPHEN 0x1f + +/* Unicode characters */ +#define UNICODE_DOUBLE_LEFT_ANGLE_QMARK 0x00ab +#define UNICODE_MIDDLE_DOT 0x00b7 +#define UNICODE_DOUBLE_RIGHT_ANGLE_QMARK 0x00bb +#define UNICODE_CAPITAL_D_WITH_STROKE 0x0110 +#define UNICODE_SMALL_D_WITH_STROKE 0x0111 +#define UNICODE_CAPITAL_LIGATURE_OE 0x0152 +#define UNICODE_SMALL_LIGATURE_OE 0x0153 +#define UNICODE_SMALL_F_HOOK 0x0192 +#define UNICODE_GREEK_CAPITAL_CHI 0x03a7 +#define UNICODE_GREEK_SMALL_UPSILON 0x03c5 +#define UNICODE_MODIFIER_CIRCUMFLEX 0x02c6 +#define UNICODE_SMALL_TILDE 0x02dc +#define UNICODE_SMALL_LETTER_OMEGA 0x03c9 +#define UNICODE_EN_QUAD 0x2000 +#define UNICODE_EM_QUAD 0x2001 +#define UNICODE_EN_SPACE 0x2002 +#define UNICODE_EM_SPACE 0x2003 +#define UNICODE_THREE_PER_EM_SPACE 0x2004 +#define UNICODE_FOUR_PER_EM_SPACE 0x2005 +#define UNICODE_SIX_PER_EM_SPACE 0x2006 +#define UNICODE_FIGURE_SPACE 0x2007 +#define UNICODE_PUNCTUATION_SPACE 0x2008 +#define UNICODE_THIN_SPACE 0x2009 +#define UNICODE_HAIR_SPACE 0x200a +#define UNICODE_ZERO_WIDTH_SPACE 0x200b +#define UNICODE_ZERO_WIDTH_NON_JOINER 0x200c +#define UNICODE_ZERO_WIDTH_JOINER 0x200d +#define UNICODE_LEFT_TO_RIGHT_MARK 0x200e +#define UNICODE_RIGHT_TO_LEFT_MARK 0x200f +#define UNICODE_HYPHEN 0x2010 +#define UNICODE_NON_BREAKING_HYPHEN 0x2011 +#define UNICODE_FIGURE_DASH 0x2012 +#define UNICODE_EN_DASH 0x2013 +#define UNICODE_EM_DASH 0x2014 +#define UNICODE_HORIZONTAL_BAR 0x2015 +#define UNICODE_DOUBLE_VERTICAL_LINE 0x2016 +#define UNICODE_DOUBLE_LOW_LINE 0x2017 +#define UNICODE_LEFT_SINGLE_QMARK 0x2018 +#define UNICODE_RIGHT_SINGLE_QMARK 0x2019 +#define UNICODE_SINGLE_LOW_9_QMARK 0x201a +#define UNICODE_SINGLE_HIGH_REV_9_QMARK 0x201b +#define UNICODE_LEFT_DOUBLE_QMARK 0x201c +#define UNICODE_RIGHT_DOUBLE_QMARK 0x201d +#define UNICODE_DOUBLE_LOW_9_QMARK 0x201e +#define UNICODE_DOUBLE_HIGH_REV_9_QMARK 0x201f +#define UNICODE_DAGGER 0x2020 +#define UNICODE_DOUBLE_DAGGER 0x2021 +#define UNICODE_BULLET 0x2022 +#define UNICODE_TRIANGULAR_BULLET 0x2023 +#define UNICODE_ONE_DOT_LEADER 0x2024 +#define UNICODE_TWO_DOT_LEADER 0x2025 +#define UNICODE_ELLIPSIS 0x2026 +#define UNICODE_HYPHENATION_POINT 0x2027 +#define UNICODE_LEFT_TO_RIGHT_EMBEDDING 0x202a +#define UNICODE_RIGHT_TO_LEFT_EMBEDDING 0x202b +#define UNICODE_POP_DIRECTIONAL_FORMATTING 0x202c +#define UNICODE_LEFT_TO_RIGHT_OVERRIDE 0x202d +#define UNICODE_RIGHT_TO_LEFT_OVERRIDE 0x202e +#define UNICODE_NARROW_NO_BREAK_SPACE 0x202f +#define UNICODE_PER_MILLE_SIGN 0x2030 +#define UNICODE_PRIME 0x2032 +#define UNICODE_DOUBLE_PRIME 0x2033 +#define UNICODE_SINGLE_LEFT_ANGLE_QMARK 0x2039 +#define UNICODE_SINGLE_RIGHT_ANGLE_QMARK 0x203a +#define UNICODE_UNDERTIE 0x203f +#define UNICODE_FRACTION_SLASH 0x2044 +#define UNICODE_EURO_SIGN 0x20ac +#define UNICODE_CIRCLE 0x20dd +#define UNICODE_SQUARE 0x20de +#define UNICODE_DIAMOND 0x20df +#define UNICODE_NUMERO_SIGN 0x2116 +#define UNICODE_TRADEMARK_SIGN 0x2122 +#define UNICODE_KELVIN_SIGN 0x212a +#define UNICODE_LEFTWARDS_ARROW 0x2190 +#define UNICODE_UPWARDS_ARROW 0x2191 +#define UNICODE_RIGHTWARDS_ARROW 0x2192 +#define UNICODE_DOWNWARDS_ARROW 0x2193 +#define UNICODE_N_ARY_SUMMATION 0x2211 +#define UNICODE_MINUS_SIGN 0x2212 +#define UNICODE_DIVISION_SLASH 0x2215 +#define UNICODE_ASTERISK_OPERATOR 0x2217 +#define UNICODE_BULLET_OPERATOR 0x2219 +#define UNICODE_RATIO 0x2236 +#define UNICODE_TILDE_OPERATOR 0x223c +#define UNICODE_BD_LIGHT_HORIZONTAL 0x2500 +#define UNICODE_BD_LIGHT_VERTICAL 0x2502 +#define UNICODE_BD_LIGHT_DOWN_RIGHT 0x250c +#define UNICODE_BD_LIGHT_DOWN_AND_LEFT 0x2510 +#define UNICODE_BD_LIGHT_UP_AND_RIGHT 0x2514 +#define UNICODE_BD_LIGHT_UP_AND_LEFT 0x2518 +#define UNICODE_BD_LIGHT_VERTICAL_AND_RIGHT 0x251c +#define UNICODE_BD_LIGHT_VERTICAL_AND_LEFT 0x2524 +#define UNICODE_BD_LIGHT_DOWN_AND_HORIZONTAL 0x252c +#define UNICODE_BD_LIGHT_UP_AND_HORIZONTAL 0x2534 +#define UNICODE_BD_LIGHT_VERTICAL_AND_HORIZONTAL 0x253c +#define UNICODE_BD_DOUBLE_HORIZONTAL 0x2550 +#define UNICODE_BD_DOUBLE_VERTICAL 0x2551 +#define UNICODE_BD_DOUBLE_DOWN_AND_RIGHT 0x2554 +#define UNICODE_BD_DOUBLE_DOWN_AND_LEFT 0x2557 +#define UNICODE_BD_DOUBLE_UP_AND_RIGHT 0x255a +#define UNICODE_BD_DOUBLE_UP_AND_LEFT 0x255d +#define UNICODE_BD_DOUBLE_VERTICAL_AND_RIGHT 0x2560 +#define UNICODE_BD_DOUBLE_VERTICAL_AND_LEFT 0x2563 +#define UNICODE_BD_DOUBLE_DOWN_AND_HORIZONTAL 0x2566 +#define UNICODE_BD_DOUBLE_UP_AND_HORIZONTAL 0x2569 +#define UNICODE_BD_DOUBLE_VERTICAL_AND_HORIZONTAL 0x256c +#define UNICODE_LIGHT_SHADE 0x2591 +#define UNICODE_MEDIUM_SHADE 0x2592 +#define UNICODE_DARK_SHADE 0x2593 +#define UNICODE_BLACK_SQUARE 0x25a0 +#define UNICODE_BLACK_CLUB_SUIT 0x2663 +#define UNICODE_SMALL_LIGATURE_FI 0xfb01 +#define UNICODE_SMALL_LIGATURE_FL 0xfb02 +#define UNICODE_ZERO_WIDTH_NO_BREAK_SPACE 0xfeff + +#if defined(__riscos) +#define OUR_ELLIPSIS 0x8c +#define OUR_EM_DASH 0x98 +#define OUR_UNBREAKABLE_JOIN 0x99 +#else +#define OUR_ELLIPSIS '.' +#define OUR_EM_DASH '-' +#define OUR_UNBREAKABLE_JOIN '-' +#endif /* __riscos */ +#define OUR_DIAMOND '-' + +#endif /* __wordconst_h */ diff --git a/worddos.c b/worddos.c new file mode 100644 index 0000000..c0e0142 --- /dev/null +++ b/worddos.c @@ -0,0 +1,110 @@ +/* + * worddos.c + * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Deal with the DOS internals of a MS Word file + */ + +#include "antiword.h" + + +/* + * bGetDocumentText - make a list of the text blocks of a Word document + * + * Return TRUE when succesful, otherwise FALSE + */ +static BOOL +bGetDocumentText(FILE *pFile, long lFilesize, const UCHAR *aucHeader) +{ + text_block_type tTextBlock; + ULONG ulTextLen; + BOOL bFastSaved; + UCHAR ucDocStatus, ucVersion; + + fail(pFile == NULL); + fail(lFilesize < 128); + fail(aucHeader == NULL); + + /* Get the status flags from the header */ + ucDocStatus = ucGetByte(0x75, aucHeader); + DBG_HEX(ucDocStatus); + bFastSaved = (ucDocStatus & BIT(1)) != 0; + DBG_MSG_C(bFastSaved, "This document is Fast Saved"); + ucVersion = ucGetByte(0x74, aucHeader); + DBG_DEC(ucVersion); + DBG_MSG_C(ucVersion == 0, "Written by Word 4.0 or earlier"); + DBG_MSG_C(ucVersion == 3, "Word 5.0 format, but not written by Word"); + DBG_MSG_C(ucVersion == 4, "Written by Word 5.x"); + if (bFastSaved) { + werr(0, "Word for DOS: autosave documents are not supported"); + return FALSE; + } + + /* Get length information */ + ulTextLen = ulGetLong(0x0e, aucHeader); + DBG_HEX(ulTextLen); + ulTextLen -= 128; + DBG_DEC(ulTextLen); + tTextBlock.ulFileOffset = 128; + tTextBlock.ulCharPos = 128; + tTextBlock.ulLength = ulTextLen; + tTextBlock.bUsesUnicode = FALSE; + tTextBlock.usPropMod = IGNORE_PROPMOD; + if (!bAdd2TextBlockList(&tTextBlock)) { + DBG_HEX(tTextBlock.ulFileOffset); + DBG_HEX(tTextBlock.ulCharPos); + DBG_DEC(tTextBlock.ulLength); + DBG_DEC(tTextBlock.bUsesUnicode); + DBG_DEC(tTextBlock.usPropMod); + return FALSE; + } + return TRUE; +} /* end of bGetDocumentText */ + +/* + * iInitDocumentDOS - initialize an DOS document + * + * Returns the version of Word that made the document or -1 + */ +int +iInitDocumentDOS(FILE *pFile, long lFilesize) +{ + int iWordVersion; + BOOL bSuccess; + USHORT usIdent; + UCHAR aucHeader[128]; + + fail(pFile == NULL); + + if (lFilesize < 128) { + return -1; + } + + /* Read the headerblock */ + if (!bReadBytes(aucHeader, 128, 0x00, pFile)) { + return -1; + } + /* Get the "magic number" from the header */ + usIdent = usGetWord(0x00, aucHeader); + DBG_HEX(usIdent); + fail(usIdent != 0xbe31); /* Word for DOS */ + iWordVersion = iGetVersionNumber(aucHeader); + if (iWordVersion != 0) { + werr(0, "This file is not from 'Word for DOS'."); + return -1; + } + bSuccess = bGetDocumentText(pFile, lFilesize, aucHeader); + if (bSuccess) { + vGetPropertyInfo(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + vSetDefaultTabWidth(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + vGetNotesInfo(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + } + return bSuccess ? iWordVersion : -1; +} /* end of iInitDocumentDOS */ diff --git a/wordlib.c b/wordlib.c new file mode 100644 index 0000000..d8471d6 --- /dev/null +++ b/wordlib.c @@ -0,0 +1,359 @@ +/* + * wordlib.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Deal with the internals of a MS Word file + */ + +#include "antiword.h" + +static BOOL bOldMacFile = FALSE; + + +/* + * Common part of the file checking functions + */ +static BOOL +bCheckBytes(FILE *pFile, const UCHAR *aucBytes, size_t tBytes) +{ + int iIndex, iChar; + + fail(pFile == NULL || aucBytes == NULL || tBytes == 0); + + rewind(pFile); + + for (iIndex = 0; iIndex < (int)tBytes; iIndex++) { + iChar = getc(pFile); + if (iChar == EOF || iChar != (int)aucBytes[iIndex]) { + NO_DBG_HEX(iChar); + NO_DBG_HEX(aucBytes[iIndex]); + return FALSE; + } + } + return TRUE; +} /* end of bCheckBytes */ + +/* + * This function checks whether the given file is or is not a "Word for DOS" + * document + */ +BOOL +bIsWordForDosFile(FILE *pFile, long lFilesize) +{ + static UCHAR aucBytes[] = + { 0x31, 0xbe, 0x00, 0x00, 0x00, 0xab }; /* Word for DOS */ + + DBG_MSG("bIsWordForDosFile"); + + if (pFile == NULL || lFilesize < 0) { + DBG_MSG("No proper file given"); + return FALSE; + } + if (lFilesize < 128) { + DBG_MSG("File too small to be a Word document"); + return FALSE; + } + return bCheckBytes(pFile, aucBytes, elementsof(aucBytes)); +} /* end of bIsWordForDosFile */ + +/* + * This function checks whether the given file is or is not a file with an + * OLE envelope (That is a document made by Word 6 or later) + */ +static BOOL +bIsWordFileWithOLE(FILE *pFile, long lFilesize) +{ + static UCHAR aucBytes[] = + { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 }; + int iTailLen; + + if (pFile == NULL || lFilesize < 0) { + DBG_MSG("No proper file given"); + return FALSE; + } + if (lFilesize < (long)BIG_BLOCK_SIZE * 3) { + DBG_MSG("This file is too small to be a Word document"); + return FALSE; + } + + iTailLen = (int)(lFilesize % BIG_BLOCK_SIZE); + switch (iTailLen) { + case 0: /* No tail, as it should be */ + break; + case 1: + case 2: /* Filesize mismatch or a buggy email program */ + if ((int)(lFilesize % 3) == iTailLen) { + DBG_DEC(lFilesize); + return FALSE; + } + /* + * Ignore extra bytes caused by buggy email programs. + * They have bugs in their base64 encoding or decoding. + * 3 bytes -> 4 ascii chars -> 3 bytes + */ + DBG_MSG("Document with extra bytes"); + break; + default: /* Wrong filesize for a Word document */ + DBG_DEC(lFilesize); + DBG_DEC(iTailLen); + return FALSE; + } + return bCheckBytes(pFile, aucBytes, elementsof(aucBytes)); +} /* end of bIsWordFileWithOLE */ + +/* + * This function checks whether the given file is or is not a RTF document + */ +BOOL +bIsRtfFile(FILE *pFile) +{ + static UCHAR aucBytes[] = + { '{', '\\', 'r', 't', 'f', '1' }; + + DBG_MSG("bIsRtfFile"); + + return bCheckBytes(pFile, aucBytes, elementsof(aucBytes)); +} /* end of bIsRtfFile */ + +/* + * This function checks whether the given file is or is not a WP document + */ +BOOL +bIsWordPerfectFile(FILE *pFile) +{ + static UCHAR aucBytes[] = + { 0xff, 'W', 'P', 'C' }; + + DBG_MSG("bIsWordPerfectFile"); + + return bCheckBytes(pFile, aucBytes, elementsof(aucBytes)); +} /* end of bIsWordPerfectFile */ + +/* + * This function checks whether the given file is or is not a "Win Word 1 or 2" + * document + */ +BOOL +bIsWinWord12File(FILE *pFile, long lFilesize) +{ + static UCHAR aucBytes[2][4] = { + { 0x9b, 0xa5, 0x21, 0x00 }, /* Win Word 1.x */ + { 0xdb, 0xa5, 0x2d, 0x00 }, /* Win Word 2.0 */ + }; + int iIndex; + + DBG_MSG("bIsWinWord12File"); + + if (pFile == NULL || lFilesize < 0) { + DBG_MSG("No proper file given"); + return FALSE; + } + if (lFilesize < 384) { + DBG_MSG("This file is too small to be a Word document"); + return FALSE; + } + + for (iIndex = 0; iIndex < (int)elementsof(aucBytes); iIndex++) { + if (bCheckBytes(pFile, + aucBytes[iIndex], + elementsof(aucBytes[iIndex]))) { + return TRUE; + } + } + return FALSE; +} /* end of bIsWinWord12File */ + +/* + * This function checks whether the given file is or is not a "Mac Word 4 or 5" + * document + */ +BOOL +bIsMacWord45File(FILE *pFile) +{ + static UCHAR aucBytes[2][6] = { + { 0xfe, 0x37, 0x00, 0x1c, 0x00, 0x00 }, /* Mac Word 4 */ + { 0xfe, 0x37, 0x00, 0x23, 0x00, 0x00 }, /* Mac Word 5 */ + }; + int iIndex; + + DBG_MSG("bIsMacWord45File"); + + for (iIndex = 0; iIndex < (int)elementsof(aucBytes); iIndex++) { + if (bCheckBytes(pFile, + aucBytes[iIndex], + elementsof(aucBytes[iIndex]))) { + return TRUE; + } + } + return FALSE; +} /* end of bIsMacWord45File */ + +/* + * iGuessVersionNumber - guess the Word version number from first few bytes + * + * Returns the guessed version number or -1 when no guess it possible + */ +int +iGuessVersionNumber(FILE *pFile, long lFilesize) +{ + if(bIsWordForDosFile(pFile, lFilesize)) { + return 0; + } + if (bIsWinWord12File(pFile, lFilesize)) { + return 2; + } + if (bIsMacWord45File(pFile)) { + return 5; + } + if (bIsWordFileWithOLE(pFile, lFilesize)) { + return 6; + } + return -1; +} /* end of iGuessVersionNumber */ + +/* + * iGetVersionNumber - get the Word version number from the header + * + * Returns the version number or -1 when unknown + */ +int +iGetVersionNumber(const UCHAR *aucHeader) +{ + USHORT usFib, usChse; + + usFib = usGetWord(0x02, aucHeader); + if (usFib >= 0x1000) { + /* To big: must be MacWord using Big Endian */ + DBG_HEX(usFib); + usFib = usGetWordBE(0x02, aucHeader); + } + DBG_DEC(usFib); + bOldMacFile = FALSE; + switch (usFib) { + case 0: + DBG_MSG("Word for DOS"); + return 0; + case 28: + DBG_MSG("Word 4 for Macintosh"); + bOldMacFile = TRUE; + return 4; + case 33: + DBG_MSG("Word 1.x for Windows"); + return 1; + case 35: + DBG_MSG("Word 5 for Macintosh"); + bOldMacFile = TRUE; + return 5; + case 45: + DBG_MSG("Word 2 for Windows"); + return 2; + case 101: + case 102: + DBG_MSG("Word 6 for Windows"); + return 6; + case 103: + case 104: + usChse = usGetWord(0x14, aucHeader); + DBG_DEC(usChse); + switch (usChse) { + case 0: + DBG_MSG("Word 7 for Win95"); + return 7; + case 256: + DBG_MSG("Word 6 for Macintosh"); + bOldMacFile = TRUE; + return 6; + default: + DBG_FIXME(); + if ((int)ucGetByte(0x05, aucHeader) == 0xe0) { + DBG_MSG("Word 7 for Win95"); + return 7; + } + DBG_MSG("Word 6 for Macintosh"); + bOldMacFile = TRUE; + return 6; + } + default: + usChse = usGetWord(0x14, aucHeader); + DBG_DEC(usChse); + if (usFib < 192) { + /* Unknown or unsupported version of Word */ + DBG_DEC(usFib); + return -1; + } + DBG_MSG_C(usChse != 256, "Word97 for Win95/98/NT"); + DBG_MSG_C(usChse == 256, "Word98 for Macintosh"); + return 8; + } +} /* end of iGetVersionNumber */ + +/* + * TRUE if the current file was made by Word version 6 or older on an + * Apple Macintosh, otherwise FALSE. + * This function hides the methode of how to find out from the rest of the + * program. + */ +BOOL +bIsOldMacFile(void) +{ + return bOldMacFile; +} /* end of bIsOldMacFile */ + +/* + * iInitDocument - initialize a document + * + * Returns the version of Word that made the document or -1 + */ +int +iInitDocument(FILE *pFile, long lFilesize) +{ + int iGuess, iWordVersion; + + iGuess = iGuessVersionNumber(pFile, lFilesize); + switch (iGuess) { + case 0: + iWordVersion = iInitDocumentDOS(pFile, lFilesize); + break; + case 2: + iWordVersion = iInitDocumentWIN(pFile, lFilesize); + break; + case 5: + iWordVersion = iInitDocumentMAC(pFile, lFilesize); + break; + case 6: + iWordVersion = iInitDocumentOLE(pFile, lFilesize); + break; + default: + DBG_DEC(iGuess); + iWordVersion = -1; + break; + } + return iWordVersion; +} /* end of iInitDocument */ + +/* + * vFreeDocument - free a document by free-ing its parts + */ +void +vFreeDocument(void) +{ + DBG_MSG("vFreeDocument"); + + /* Free the memory */ + vDestroyTextBlockList(); + vDestroyDataBlockList(); + vDestroyListInfoList(); + vDestroyRowInfoList(); + vDestroyStyleInfoList(); + vDestroyFontInfoList(); + vDestroyStylesheetList(); + vDestroyPictInfoList(); + vDestroyDocumentInfoList(); + vDestroySectionInfoList(); + vDestroyHdrFtrInfoList(); + vDestroyPropModList(); + vDestroyNotesInfoLists(); + vDestroyFontTable(); + vDestroySummaryInfo(); +} /* end of vFreeDocument */ diff --git a/wordmac.c b/wordmac.c new file mode 100644 index 0000000..c6a8f26 --- /dev/null +++ b/wordmac.c @@ -0,0 +1,108 @@ +/* + * wordmac.c + * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL + * + * Description: + * Deal with the MAC internals of a MS Word file + */ + +#include "antiword.h" + + +/* + * bGetDocumentText - make a list of the text blocks of a Word document + * + * Return TRUE when succesful, otherwise FALSE + */ +static BOOL +bGetDocumentText(FILE *pFile, const UCHAR *aucHeader) +{ + text_block_type tTextBlock; + ULONG ulBeginOfText, ulEndOfText; + ULONG ulTextLen; + UCHAR ucDocStatus; + BOOL bFastSaved; + + fail(pFile == NULL); + fail(aucHeader == NULL); + + DBG_MSG("bGetDocumentText"); + + NO_DBG_PRINT_BLOCK(aucHeader, 0x20); + + /* Get the status flags from the header */ + ucDocStatus = ucGetByte(0x0a, aucHeader); + DBG_HEX(ucDocStatus); + bFastSaved = (ucDocStatus & BIT(5)) != 0; + DBG_MSG_C(bFastSaved, "This document is Fast Saved"); + if (bFastSaved) { + werr(0, "MacWord: fast saved documents are not supported yet"); + return FALSE; + } + + /* Get length information */ + ulBeginOfText = ulGetLongBE(0x14, aucHeader); + DBG_HEX(ulBeginOfText); + ulEndOfText = ulGetLongBE(0x18, aucHeader); + DBG_HEX(ulEndOfText); + ulTextLen = ulEndOfText - ulBeginOfText; + DBG_DEC(ulTextLen); + tTextBlock.ulFileOffset = ulBeginOfText; + tTextBlock.ulCharPos = ulBeginOfText; + tTextBlock.ulLength = ulTextLen; + tTextBlock.bUsesUnicode = FALSE; + tTextBlock.usPropMod = IGNORE_PROPMOD; + if (!bAdd2TextBlockList(&tTextBlock)) { + DBG_HEX(tTextBlock.ulFileOffset); + DBG_HEX(tTextBlock.ulCharPos); + DBG_DEC(tTextBlock.ulLength); + DBG_DEC(tTextBlock.bUsesUnicode); + DBG_DEC(tTextBlock.usPropMod); + return FALSE; + } + return TRUE; +} /* end of bGetDocumentText */ + +/* + * iInitDocumentMAC - initialize an MAC document + * + * Returns the version of Word that made the document or -1 + */ +int +iInitDocumentMAC(FILE *pFile, long lFilesize) +{ + int iWordVersion; + BOOL bSuccess; + USHORT usIdent; + UCHAR aucHeader[256]; + + fail(pFile == NULL); + + if (lFilesize < 256) { + return -1; + } + + /* Read the headerblock */ + if (!bReadBytes(aucHeader, 256, 0x00, pFile)) { + return -1; + } + /* Get the "magic number" from the header */ + usIdent = usGetWord(0x00, aucHeader); + DBG_HEX(usIdent); + fail(usIdent != 0x37fe); /* MacWord 4 and 5 */ + iWordVersion = iGetVersionNumber(aucHeader); + if (iWordVersion != 4 && iWordVersion != 5) { + werr(0, "This file is not from ''Mac Word 4 or 5'."); + return -1; + } + bSuccess = bGetDocumentText(pFile, aucHeader); + if (bSuccess) { + vGetPropertyInfo(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + vSetDefaultTabWidth(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + } + return bSuccess ? iWordVersion : -1; +} /* end of iInitDocumentMAC */ diff --git a/wordole.c b/wordole.c new file mode 100644 index 0000000..8a95fb9 --- /dev/null +++ b/wordole.c @@ -0,0 +1,804 @@ +/* + * wordole.c + * Copyright (C) 1998-2004 A.J. van Os; Released under GPL + * + * Description: + * Deal with the OLE internals of a MS Word file + */ + +#include +#include "antiword.h" + +/* Private type for Property Set Storage entries */ +typedef struct pps_entry_tag { + ULONG ulNext; + ULONG ulPrevious; + ULONG ulDir; + ULONG ulSB; + ULONG ulSize; + int iLevel; + char szName[32]; + UCHAR ucType; +} pps_entry_type; + +/* Show that a PPS number or index should not be used */ +#define PPS_NUMBER_INVALID 0xffffffffUL + + +/* Macro to make sure all such statements will be identical */ +#define FREE_ALL() \ + do {\ + vDestroySmallBlockList();\ + aulRootList = xfree(aulRootList);\ + aulSbdList = xfree(aulSbdList);\ + aulBbdList = xfree(aulBbdList);\ + aulSBD = xfree(aulSBD);\ + aulBBD = xfree(aulBBD);\ + } while(0) + + +/* + * ulReadLong - read four bytes from the given file and offset + */ +static ULONG +ulReadLong(FILE *pFile, ULONG ulOffset) +{ + UCHAR aucBytes[4]; + + fail(pFile == NULL); + + if (!bReadBytes(aucBytes, 4, ulOffset, pFile)) { + werr(1, "Read long 0x%lx not possible", ulOffset); + } + return ulGetLong(0, aucBytes); +} /* end of ulReadLong */ + +/* + * vName2String - turn the name into a proper string. + */ +static void +vName2String(char *szName, const UCHAR *aucBytes, size_t tNameSize) +{ + char *pcChar; + size_t tIndex; + + fail(aucBytes == NULL || szName == NULL); + + if (tNameSize < 2) { + szName[0] = '\0'; + return; + } + for (tIndex = 0, pcChar = szName; + tIndex < 2 * tNameSize; + tIndex += 2, pcChar++) { + *pcChar = (char)aucBytes[tIndex]; + } + szName[tNameSize - 1] = '\0'; +} /* end of vName2String */ + +/* + * tReadBlockIndices - read the Big/Small Block Depot indices + * + * Returns the number of indices read + */ +static size_t +tReadBlockIndices(FILE *pFile, ULONG *aulBlockDepot, + size_t tMaxRec, ULONG ulOffset) +{ + size_t tDone; + int iIndex; + UCHAR aucBytes[BIG_BLOCK_SIZE]; + + fail(pFile == NULL || aulBlockDepot == NULL); + fail(tMaxRec == 0); + + /* Read a big block with BBD or SBD indices */ + if (!bReadBytes(aucBytes, BIG_BLOCK_SIZE, ulOffset, pFile)) { + werr(0, "Reading big block from 0x%lx is not possible", + ulOffset); + return 0; + } + /* Split the big block into indices, an index is four bytes */ + tDone = min(tMaxRec, (size_t)BIG_BLOCK_SIZE / 4); + for (iIndex = 0; iIndex < (int)tDone; iIndex++) { + aulBlockDepot[iIndex] = ulGetLong(4 * iIndex, aucBytes); + NO_DBG_DEC(aulBlockDepot[iIndex]); + } + return tDone; +} /* end of tReadBlockIndices */ + +/* + * bGetBBD - get the Big Block Depot indices from the index-blocks + */ +static BOOL +bGetBBD(FILE *pFile, const ULONG *aulDepot, size_t tDepotLen, + ULONG *aulBBD, size_t tBBDLen) +{ + ULONG ulBegin; + size_t tToGo, tDone; + int iIndex; + + fail(pFile == NULL || aulDepot == NULL || aulBBD == NULL); + + DBG_MSG("bGetBBD"); + + tToGo = tBBDLen; + for (iIndex = 0; iIndex < (int)tDepotLen && tToGo != 0; iIndex++) { + ulBegin = (aulDepot[iIndex] + 1) * BIG_BLOCK_SIZE; + NO_DBG_HEX(ulBegin); + tDone = tReadBlockIndices(pFile, aulBBD, tToGo, ulBegin); + fail(tDone > tToGo); + if (tDone == 0) { + return FALSE; + } + aulBBD += tDone; + tToGo -= tDone; + } + return tToGo == 0; +} /* end of bGetBBD */ + +/* + * bGetSBD - get the Small Block Depot indices from the index-blocks + */ +static BOOL +bGetSBD(FILE *pFile, const ULONG *aulDepot, size_t tDepotLen, + ULONG *aulSBD, size_t tSBDLen) +{ + ULONG ulBegin; + size_t tToGo, tDone; + int iIndex; + + fail(pFile == NULL || aulDepot == NULL || aulSBD == NULL); + + DBG_MSG("bGetSBD"); + + tToGo = tSBDLen; + for (iIndex = 0; iIndex < (int)tDepotLen && tToGo != 0; iIndex++) { + fail(aulDepot[iIndex] >= ULONG_MAX / BIG_BLOCK_SIZE); + ulBegin = (aulDepot[iIndex] + 1) * BIG_BLOCK_SIZE; + NO_DBG_HEX(ulBegin); + tDone = tReadBlockIndices(pFile, aulSBD, tToGo, ulBegin); + fail(tDone > tToGo); + if (tDone == 0) { + return FALSE; + } + aulSBD += tDone; + tToGo -= tDone; + } + return tToGo == 0; +} /* end of bGetSBD */ + +/* + * vComputePPSlevels - compute the levels of the Property Set Storage entries + */ +static void +vComputePPSlevels(pps_entry_type *atPPSlist, pps_entry_type *pNode, + int iLevel, int iRecursionLevel) +{ + fail(atPPSlist == NULL || pNode == NULL); + fail(iLevel < 0 || iRecursionLevel < 0); + + if (iRecursionLevel > 25) { + /* This removes the possibility of an infinite recursion */ + DBG_DEC(iRecursionLevel); + return; + } + if (pNode->iLevel <= iLevel) { + /* Avoid entering a loop */ + DBG_DEC(iLevel); + DBG_DEC(pNode->iLevel); + return; + } + + pNode->iLevel = iLevel; + + if (pNode->ulDir != PPS_NUMBER_INVALID) { + vComputePPSlevels(atPPSlist, + &atPPSlist[pNode->ulDir], + iLevel + 1, + iRecursionLevel + 1); + } + if (pNode->ulNext != PPS_NUMBER_INVALID) { + vComputePPSlevels(atPPSlist, + &atPPSlist[pNode->ulNext], + iLevel, + iRecursionLevel + 1); + } + if (pNode->ulPrevious != PPS_NUMBER_INVALID) { + vComputePPSlevels(atPPSlist, + &atPPSlist[pNode->ulPrevious], + iLevel, + iRecursionLevel + 1); + } +} /* end of vComputePPSlevels */ + +/* + * bGetPPS - search the Property Set Storage for three sets + * + * Return TRUE if the WordDocument PPS is found + */ +static BOOL +bGetPPS(FILE *pFile, + const ULONG *aulRootList, size_t tRootListLen, pps_info_type *pPPS) +{ + pps_entry_type *atPPSlist; + ULONG ulBegin, ulOffset, ulTmp; + size_t tNbrOfPPS, tNameSize; + int iIndex, iStartBlock, iRootIndex; + BOOL bWord, bExcel; + UCHAR aucBytes[PROPERTY_SET_STORAGE_SIZE]; + + fail(pFile == NULL || aulRootList == NULL || pPPS == NULL); + + DBG_MSG("bGetPPS"); + + NO_DBG_DEC(tRootListLen); + + bWord = FALSE; + bExcel = FALSE; + (void)memset(pPPS, 0, sizeof(*pPPS)); + + /* Read and store all the Property Set Storage entries */ + + tNbrOfPPS = tRootListLen * BIG_BLOCK_SIZE / PROPERTY_SET_STORAGE_SIZE; + atPPSlist = xcalloc(tNbrOfPPS, sizeof(pps_entry_type)); + iRootIndex = 0; + + for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) { + ulTmp = (ULONG)iIndex * PROPERTY_SET_STORAGE_SIZE; + iStartBlock = (int)(ulTmp / BIG_BLOCK_SIZE); + ulOffset = ulTmp % BIG_BLOCK_SIZE; + ulBegin = (aulRootList[iStartBlock] + 1) * BIG_BLOCK_SIZE + + ulOffset; + NO_DBG_HEX(ulBegin); + if (!bReadBytes(aucBytes, PROPERTY_SET_STORAGE_SIZE, + ulBegin, pFile)) { + werr(0, "Reading PPS %d is not possible", iIndex); + atPPSlist = xfree(atPPSlist); + return FALSE; + } + tNameSize = (size_t)usGetWord(0x40, aucBytes); + tNameSize = (tNameSize + 1) / 2; + vName2String(atPPSlist[iIndex].szName, aucBytes, tNameSize); + atPPSlist[iIndex].ucType = ucGetByte(0x42, aucBytes); + if (atPPSlist[iIndex].ucType == 5) { + iRootIndex = iIndex; + } + atPPSlist[iIndex].ulPrevious = ulGetLong(0x44, aucBytes); + atPPSlist[iIndex].ulNext = ulGetLong(0x48, aucBytes); + atPPSlist[iIndex].ulDir = ulGetLong(0x4c, aucBytes); + atPPSlist[iIndex].ulSB = ulGetLong(0x74, aucBytes); + atPPSlist[iIndex].ulSize = ulGetLong(0x78, aucBytes); + atPPSlist[iIndex].iLevel = INT_MAX; + if ((atPPSlist[iIndex].ulPrevious >= (ULONG)tNbrOfPPS && + atPPSlist[iIndex].ulPrevious != PPS_NUMBER_INVALID) || + (atPPSlist[iIndex].ulNext >= (ULONG)tNbrOfPPS && + atPPSlist[iIndex].ulNext != PPS_NUMBER_INVALID) || + (atPPSlist[iIndex].ulDir >= (ULONG)tNbrOfPPS && + atPPSlist[iIndex].ulDir != PPS_NUMBER_INVALID)) { + DBG_DEC(iIndex); + DBG_DEC(atPPSlist[iIndex].ulPrevious); + DBG_DEC(atPPSlist[iIndex].ulNext); + DBG_DEC(atPPSlist[iIndex].ulDir); + DBG_DEC(tNbrOfPPS); + werr(0, "The Property Set Storage is damaged"); + atPPSlist = xfree(atPPSlist); + return FALSE; + } + } + +#if 0 /* defined(DEBUG) */ + DBG_MSG("Before"); + for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) { + DBG_MSG(atPPSlist[iIndex].szName); + DBG_HEX(atPPSlist[iIndex].ulDir); + DBG_HEX(atPPSlist[iIndex].ulPrevious); + DBG_HEX(atPPSlist[iIndex].ulNext); + DBG_DEC(atPPSlist[iIndex].ulSB); + DBG_HEX(atPPSlist[iIndex].ulSize); + DBG_DEC(atPPSlist[iIndex].iLevel); + } +#endif /* DEBUG */ + + /* Add level information to each entry */ + vComputePPSlevels(atPPSlist, &atPPSlist[iRootIndex], 0, 0); + + /* Check the entries on level 1 for the required information */ + NO_DBG_MSG("After"); + for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) { +#if 0 /* defined(DEBUG) */ + DBG_MSG(atPPSlist[iIndex].szName); + DBG_HEX(atPPSlist[iIndex].ulDir); + DBG_HEX(atPPSlist[iIndex].ulPrevious); + DBG_HEX(atPPSlist[iIndex].ulNext); + DBG_DEC(atPPSlist[iIndex].ulSB); + DBG_HEX(atPPSlist[iIndex].ulSize); + DBG_DEC(atPPSlist[iIndex].iLevel); +#endif /* DEBUG */ + if (atPPSlist[iIndex].iLevel != 1 || + atPPSlist[iIndex].ucType != 2 || + atPPSlist[iIndex].szName[0] == '\0' || + atPPSlist[iIndex].ulSize == 0) { + /* This entry can be ignored */ + continue; + } + if (pPPS->tWordDocument.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, "WordDocument")) { + pPPS->tWordDocument.ulSB = atPPSlist[iIndex].ulSB; + pPPS->tWordDocument.ulSize = atPPSlist[iIndex].ulSize; + bWord = TRUE; + } else if (pPPS->tData.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, "Data")) { + pPPS->tData.ulSB = atPPSlist[iIndex].ulSB; + pPPS->tData.ulSize = atPPSlist[iIndex].ulSize; + } else if (pPPS->t0Table.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, "0Table")) { + pPPS->t0Table.ulSB = atPPSlist[iIndex].ulSB; + pPPS->t0Table.ulSize = atPPSlist[iIndex].ulSize; + } else if (pPPS->t1Table.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, "1Table")) { + pPPS->t1Table.ulSB = atPPSlist[iIndex].ulSB; + pPPS->t1Table.ulSize = atPPSlist[iIndex].ulSize; + } else if (pPPS->tSummaryInfo.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, + "\005SummaryInformation")) { + pPPS->tSummaryInfo.ulSB = atPPSlist[iIndex].ulSB; + pPPS->tSummaryInfo.ulSize = atPPSlist[iIndex].ulSize; + } else if (pPPS->tDocSummaryInfo.ulSize == 0 && + STREQ(atPPSlist[iIndex].szName, + "\005DocumentSummaryInformation")) { + pPPS->tDocSummaryInfo.ulSB = atPPSlist[iIndex].ulSB; + pPPS->tDocSummaryInfo.ulSize = atPPSlist[iIndex].ulSize; + } else if (STREQ(atPPSlist[iIndex].szName, "Book") || + STREQ(atPPSlist[iIndex].szName, "Workbook")) { + bExcel = TRUE; + } + } + + /* Free the space for the Property Set Storage entries */ + atPPSlist = xfree(atPPSlist); + + /* Draw your conclusions */ + if (bWord) { + return TRUE; + } + + if (bExcel) { + werr(0, "Sorry, but this is an Excel spreadsheet"); + } else { + werr(0, "This OLE file does not contain a Word document"); + } + return FALSE; +} /* end of bGetPPS */ + +/* + * vGetBbdList - make a list of the places to find big blocks + */ +static void +vGetBbdList(FILE *pFile, int iNbr, ULONG *aulBbdList, ULONG ulOffset) +{ + int iIndex; + + fail(pFile == NULL); + fail(iNbr > 127); + fail(aulBbdList == NULL); + + NO_DBG_DEC(iNbr); + for (iIndex = 0; iIndex < iNbr; iIndex++) { + aulBbdList[iIndex] = + ulReadLong(pFile, ulOffset + 4 * (ULONG)iIndex); + NO_DBG_DEC(iIndex); + NO_DBG_HEX(aulBbdList[iIndex]); + } +} /* end of vGetBbdList */ + +/* + * bGetDocumentText - make a list of the text blocks of a Word document + * + * Return TRUE when succesful, otherwise FALSE + */ +static BOOL +bGetDocumentText(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const ULONG *aulSBD, size_t tSBDLen, + const UCHAR *aucHeader, int iWordVersion) +{ + ULONG ulBeginOfText; + ULONG ulTextLen, ulFootnoteLen, ulEndnoteLen; + ULONG ulHdrFtrLen, ulMacroLen, ulAnnotationLen; + ULONG ulTextBoxLen, ulHdrTextBoxLen; + UINT uiQuickSaves; + BOOL bFarEastWord, bTemplate, bFastSaved, bEncrypted, bSuccess; + USHORT usIdent, usDocStatus; + + fail(pFile == NULL || pPPS == NULL); + fail(aulBBD == NULL); + fail(aulSBD == NULL); + + DBG_MSG("bGetDocumentText"); + + /* Get the "magic number" from the header */ + usIdent = usGetWord(0x00, aucHeader); + DBG_HEX(usIdent); + bFarEastWord = usIdent == 0x8098 || usIdent == 0x8099 || + usIdent == 0xa697 || usIdent == 0xa699; + /* Get the status flags from the header */ + usDocStatus = usGetWord(0x0a, aucHeader); + DBG_HEX(usDocStatus); + bTemplate = (usDocStatus & BIT(0)) != 0; + DBG_MSG_C(bTemplate, "This document is a Template"); + bFastSaved = (usDocStatus & BIT(2)) != 0; + uiQuickSaves = (UINT)(usDocStatus & 0x00f0) >> 4; + DBG_MSG_C(bFastSaved, "This document is Fast Saved"); + DBG_DEC_C(bFastSaved, uiQuickSaves); + bEncrypted = (usDocStatus & BIT(8)) != 0; + if (bEncrypted) { + werr(0, "Encrypted documents are not supported"); + return FALSE; + } + + /* Get length information */ + ulBeginOfText = ulGetLong(0x18, aucHeader); + DBG_HEX(ulBeginOfText); + switch (iWordVersion) { + case 6: + case 7: + ulTextLen = ulGetLong(0x34, aucHeader); + ulFootnoteLen = ulGetLong(0x38, aucHeader); + ulHdrFtrLen = ulGetLong(0x3c, aucHeader); + ulMacroLen = ulGetLong(0x40, aucHeader); + ulAnnotationLen = ulGetLong(0x44, aucHeader); + ulEndnoteLen = ulGetLong(0x48, aucHeader); + ulTextBoxLen = ulGetLong(0x4c, aucHeader); + ulHdrTextBoxLen = ulGetLong(0x50, aucHeader); + break; + case 8: + ulTextLen = ulGetLong(0x4c, aucHeader); + ulFootnoteLen = ulGetLong(0x50, aucHeader); + ulHdrFtrLen = ulGetLong(0x54, aucHeader); + ulMacroLen = ulGetLong(0x58, aucHeader); + ulAnnotationLen = ulGetLong(0x5c, aucHeader); + ulEndnoteLen = ulGetLong(0x60, aucHeader); + ulTextBoxLen = ulGetLong(0x64, aucHeader); + ulHdrTextBoxLen = ulGetLong(0x68, aucHeader); + break; + default: + werr(0, "This version of Word is not supported"); + return FALSE; + } + DBG_DEC(ulTextLen); + DBG_DEC(ulFootnoteLen); + DBG_DEC(ulHdrFtrLen); + DBG_DEC(ulMacroLen); + DBG_DEC(ulAnnotationLen); + DBG_DEC(ulEndnoteLen); + DBG_DEC(ulTextBoxLen); + DBG_DEC(ulHdrTextBoxLen); + + /* Make a list of the text blocks */ + switch (iWordVersion) { + case 6: + case 7: + if (bFastSaved) { + bSuccess = bGet6DocumentText(pFile, + bFarEastWord, + pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, + aucHeader); + } else { + bSuccess = bAddTextBlocks(ulBeginOfText, + ulTextLen + + ulFootnoteLen + + ulHdrFtrLen + + ulMacroLen + ulAnnotationLen + + ulEndnoteLen + + ulTextBoxLen + ulHdrTextBoxLen, + bFarEastWord, + IGNORE_PROPMOD, + pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen); + } + break; + case 8: + bSuccess = bGet8DocumentText(pFile, + pPPS, + aulBBD, tBBDLen, aulSBD, tSBDLen, + aucHeader); + break; + default: + werr(0, "This version of Word is not supported"); + bSuccess = FALSE; + break; + } + + if (bSuccess) { + vSplitBlockList(pFile, + ulTextLen, + ulFootnoteLen, + ulHdrFtrLen, + ulMacroLen, + ulAnnotationLen, + ulEndnoteLen, + ulTextBoxLen, + ulHdrTextBoxLen, + !bFastSaved && iWordVersion == 8); + } else { + vDestroyTextBlockList(); + werr(0, "I can't find the text of this document"); + } + return bSuccess; +} /* end of bGetDocumentText */ + +/* + * vGetDocumentData - make a list of the data blocks of a Word document + */ +static void +vGetDocumentData(FILE *pFile, const pps_info_type *pPPS, + const ULONG *aulBBD, size_t tBBDLen, + const UCHAR *aucHeader, int iWordVersion) +{ + options_type tOptions; + ULONG ulBeginOfText; + BOOL bFastSaved, bHasImages, bSuccess; + USHORT usDocStatus; + + fail(pFile == NULL); + fail(pPPS == NULL); + fail(aulBBD == NULL); + + /* Get the options */ + vGetOptions(&tOptions); + + /* Get the status flags from the header */ + usDocStatus = usGetWord(0x0a, aucHeader); + DBG_HEX(usDocStatus); + bFastSaved = (usDocStatus & BIT(2)) != 0; + bHasImages = (usDocStatus & BIT(3)) != 0; + + if (!bHasImages || + tOptions.eConversionType == conversion_text || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_xml || + tOptions.eImageLevel == level_no_images) { + /* + * No images in the document or text-only output or + * no images wanted, so no data blocks will be needed + */ + vDestroyDataBlockList(); + return; + } + + /* Get length information */ + ulBeginOfText = ulGetLong(0x18, aucHeader); + DBG_HEX(ulBeginOfText); + + /* Make a list of the data blocks */ + switch (iWordVersion) { + case 6: + case 7: + /* + * The data blocks are in the text stream. The text stream + * is in "fast saved" format or "normal saved" format + */ + if (bFastSaved) { + bSuccess = bGet6DocumentData(pFile, + pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen, + aucHeader); + } else { + bSuccess = bAddDataBlocks(ulBeginOfText, + (ULONG)LONG_MAX, + pPPS->tWordDocument.ulSB, + aulBBD, tBBDLen); + } + break; + case 8: + /* + * The data blocks are in the data stream. The data stream + * is always in "normal saved" format + */ + bSuccess = bAddDataBlocks(0, (ULONG)LONG_MAX, + pPPS->tData.ulSB, aulBBD, tBBDLen); + break; + default: + werr(0, "This version of Word is not supported"); + bSuccess = FALSE; + break; + } + + if (!bSuccess) { + vDestroyDataBlockList(); + werr(0, "I can't find the data of this document"); + } +} /* end of vGetDocumentData */ + +/* + * iInitDocumentOLE - initialize an OLE document + * + * Returns the version of Word that made the document or -1 + */ +int +iInitDocumentOLE(FILE *pFile, long lFilesize) +{ + pps_info_type PPS_info; + ULONG *aulBBD, *aulSBD; + ULONG *aulRootList, *aulBbdList, *aulSbdList; + ULONG ulBdbListStart, ulAdditionalBBDlist; + ULONG ulRootStartblock, ulSbdStartblock, ulSBLstartblock; + ULONG ulStart, ulTmp; + long lMaxBlock; + size_t tBBDLen, tSBDLen, tNumBbdBlocks, tRootListLen; + int iWordVersion, iIndex, iToGo; + BOOL bSuccess; + USHORT usIdent, usDocStatus; + UCHAR aucHeader[HEADER_SIZE]; + + fail(pFile == NULL); + + lMaxBlock = lFilesize / BIG_BLOCK_SIZE - 2; + DBG_DEC(lMaxBlock); + if (lMaxBlock < 1) { + return -1; + } + tBBDLen = (size_t)(lMaxBlock + 1); + tNumBbdBlocks = (size_t)ulReadLong(pFile, 0x2c); + DBG_DEC(tNumBbdBlocks); + ulRootStartblock = ulReadLong(pFile, 0x30); + DBG_DEC(ulRootStartblock); + ulSbdStartblock = ulReadLong(pFile, 0x3c); + DBG_DEC(ulSbdStartblock); + ulAdditionalBBDlist = ulReadLong(pFile, 0x44); + DBG_HEX(ulAdditionalBBDlist); + ulSBLstartblock = ulReadLong(pFile, + (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x74); + DBG_DEC(ulSBLstartblock); + tSBDLen = (size_t)(ulReadLong(pFile, + (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x78) / + SMALL_BLOCK_SIZE); + /* All to be xcalloc-ed pointers to NULL */ + aulRootList = NULL; + aulSbdList = NULL; + aulBbdList = NULL; + aulSBD = NULL; + aulBBD = NULL; +/* Big Block Depot */ + aulBbdList = xcalloc(tNumBbdBlocks, sizeof(ULONG)); + aulBBD = xcalloc(tBBDLen, sizeof(ULONG)); + iToGo = (int)tNumBbdBlocks; + vGetBbdList(pFile, min(iToGo, 109), aulBbdList, 0x4c); + ulStart = 109; + iToGo -= 109; + while (ulAdditionalBBDlist != END_OF_CHAIN && iToGo > 0) { + ulBdbListStart = (ulAdditionalBBDlist + 1) * BIG_BLOCK_SIZE; + vGetBbdList(pFile, min(iToGo, 127), + aulBbdList + ulStart, ulBdbListStart); + ulAdditionalBBDlist = ulReadLong(pFile, + ulBdbListStart + 4 * 127); + DBG_DEC(ulAdditionalBBDlist); + DBG_HEX(ulAdditionalBBDlist); + ulStart += 127; + iToGo -= 127; + } + if (!bGetBBD(pFile, aulBbdList, tNumBbdBlocks, aulBBD, tBBDLen)) { + FREE_ALL(); + return -1; + } + aulBbdList = xfree(aulBbdList); +/* Small Block Depot */ + aulSbdList = xcalloc(tBBDLen, sizeof(ULONG)); + aulSBD = xcalloc(tSBDLen, sizeof(ULONG)); + for (iIndex = 0, ulTmp = ulSbdStartblock; + iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN; + iIndex++, ulTmp = aulBBD[ulTmp]) { + if (ulTmp >= (ULONG)tBBDLen) { + DBG_DEC(ulTmp); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + aulSbdList[iIndex] = ulTmp; + NO_DBG_HEX(aulSbdList[iIndex]); + } + if (!bGetSBD(pFile, aulSbdList, tBBDLen, aulSBD, tSBDLen)) { + FREE_ALL(); + return -1; + } + aulSbdList = xfree(aulSbdList); +/* Root list */ + for (tRootListLen = 0, ulTmp = ulRootStartblock; + tRootListLen < tBBDLen && ulTmp != END_OF_CHAIN; + tRootListLen++, ulTmp = aulBBD[ulTmp]) { + if (ulTmp >= (ULONG)tBBDLen) { + DBG_DEC(ulTmp); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + } + if (tRootListLen == 0) { + werr(0, "No Rootlist found"); + FREE_ALL(); + return -1; + } + aulRootList = xcalloc(tRootListLen, sizeof(ULONG)); + for (iIndex = 0, ulTmp = ulRootStartblock; + iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN; + iIndex++, ulTmp = aulBBD[ulTmp]) { + if (ulTmp >= (ULONG)tBBDLen) { + DBG_DEC(ulTmp); + DBG_DEC(tBBDLen); + werr(1, "The Big Block Depot is damaged"); + } + aulRootList[iIndex] = ulTmp; + NO_DBG_DEC(aulRootList[iIndex]); + } + fail(tRootListLen != (size_t)iIndex); + bSuccess = bGetPPS(pFile, aulRootList, tRootListLen, &PPS_info); + aulRootList = xfree(aulRootList); + if (!bSuccess) { + FREE_ALL(); + return -1; + } +/* Small block list */ + if (!bCreateSmallBlockList(ulSBLstartblock, aulBBD, tBBDLen)) { + FREE_ALL(); + return -1; + } + + if (PPS_info.tWordDocument.ulSize < MIN_SIZE_FOR_BBD_USE) { + DBG_DEC(PPS_info.tWordDocument.ulSize); + FREE_ALL(); + werr(0, "I'm afraid the text stream of this file " + "is too small to handle."); + return -1; + } + /* Read the headerblock */ + if (!bReadBuffer(pFile, PPS_info.tWordDocument.ulSB, + aulBBD, tBBDLen, BIG_BLOCK_SIZE, + aucHeader, 0, HEADER_SIZE)) { + FREE_ALL(); + return -1; + } + usIdent = usGetWord(0x00, aucHeader); + DBG_HEX(usIdent); + fail(usIdent != 0x8098 && /* Word 7 for oriental languages */ + usIdent != 0x8099 && /* Word 7 for oriental languages */ + usIdent != 0xa5dc && /* Word 6 & 7 */ + usIdent != 0xa5ec && /* Word 7 & 97 & 98 */ + usIdent != 0xa697 && /* Word 7 for oriental languages */ + usIdent != 0xa699); /* Word 7 for oriental languages */ + iWordVersion = iGetVersionNumber(aucHeader); + if (iWordVersion < 6) { + FREE_ALL(); + werr(0, "This file is from a version of Word before Word 6."); + return -1; + } + + /* Get the status flags from the header */ + usDocStatus = usGetWord(0x0a, aucHeader); + if (usDocStatus & BIT(9)) { + PPS_info.tTable = PPS_info.t1Table; + } else { + PPS_info.tTable = PPS_info.t0Table; + } + /* Clean the entries that should not be used */ + memset(&PPS_info.t0Table, 0, sizeof(PPS_info.t0Table)); + memset(&PPS_info.t1Table, 0, sizeof(PPS_info.t1Table)); + + bSuccess = bGetDocumentText(pFile, &PPS_info, + aulBBD, tBBDLen, aulSBD, tSBDLen, + aucHeader, iWordVersion); + if (bSuccess) { + vGetDocumentData(pFile, &PPS_info, + aulBBD, tBBDLen, aucHeader, iWordVersion); + vGetPropertyInfo(pFile, &PPS_info, + aulBBD, tBBDLen, aulSBD, tSBDLen, + aucHeader, iWordVersion); + vSetDefaultTabWidth(pFile, &PPS_info, + aulBBD, tBBDLen, aulSBD, tSBDLen, + aucHeader, iWordVersion); + vGetNotesInfo(pFile, &PPS_info, + aulBBD, tBBDLen, aulSBD, tSBDLen, + aucHeader, iWordVersion); + } + FREE_ALL(); + return bSuccess ? iWordVersion : -1; +} /* end of iInitDocumentOLE */ diff --git a/wordtypes.h b/wordtypes.h new file mode 100644 index 0000000..d71dc8f --- /dev/null +++ b/wordtypes.h @@ -0,0 +1,317 @@ +/* + * wordtypes.h + * Copyright (C) 1998-2004 A.J. van Os; Released under GPL + * + * Description: + * Typedefs for the interpretation of MS Word files + */ + +#if !defined(__wordtypes_h) +#define __wordtypes_h 1 + +#include +#if defined(__riscos) +#include "DeskLib:Font.h" +#include "DeskLib:Wimp.h" +#endif /* __riscos */ + +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned int UINT; +typedef unsigned long ULONG; + +#if defined(__riscos) +typedef struct diagram_tag { + drawfile_info tInfo; + window_handle tMainWindow; + window_handle tScaleWindow; + menu_ptr pSaveMenu; + long lXleft; /* In DrawUnits */ + long lYtop; /* In DrawUnits */ + size_t tMemorySize; + int iScaleFactorCurr; /* In percentage */ + int iScaleFactorTemp; /* In percentage */ + char szFilename[19+1]; +} diagram_type; +#else +typedef struct diagram_tag { + FILE *pOutFile; + long lXleft; /* In DrawUnits */ + long lYtop; /* In DrawUnits */ +} diagram_type; +typedef UCHAR drawfile_fontref; +#endif /* __riscos */ + +typedef struct output_tag { + char *szStorage; + long lStringWidth; /* In millipoints */ + size_t tStorageSize; + size_t tNextFree; + USHORT usFontStyle; + USHORT usFontSize; + UCHAR ucFontColor; + drawfile_fontref tFontRef; + struct output_tag *pPrev; + struct output_tag *pNext; +} output_type; + +/* Types of conversion */ +typedef enum conversion_tag { + conversion_unknown = 0, + conversion_text, + conversion_draw, + conversion_ps, + conversion_xml, + conversion_pdf, + conversion_fmt_text +} conversion_type; + +/* Types of encoding */ +typedef enum encoding_tag { + encoding_neutral = 100, + encoding_latin_1 = 801, + encoding_latin_2 = 802, + encoding_cyrillic = 805, + encoding_utf_8 = 1601 +} encoding_type; + +/* Font translation table entry */ +typedef struct font_table_tag { + USHORT usFontStyle; + UCHAR ucWordFontNumber; + UCHAR ucFFN; + UCHAR ucEmphasis; + UCHAR ucInUse; + char szWordFontname[65]; + char szOurFontname[33]; +} font_table_type; + +/* Options */ +typedef enum image_level_tag { + level_gs_special = 0, + level_no_images, + level_ps_2, + level_ps_3, + level_default = level_ps_2 +} image_level_enum; + +typedef struct options_tag { + int iParagraphBreak; + conversion_type eConversionType; + BOOL bHideHiddenText; + BOOL bRemoveRemovedText; + BOOL bUseLandscape; + encoding_type eEncoding; + int iPageHeight; /* In points */ + int iPageWidth; /* In points */ + image_level_enum eImageLevel; +#if defined(__riscos) + BOOL bAutofiletypeAllowed; + int iScaleFactor; /* As a percentage */ +#endif /* __riscos */ +} options_type; + +/* Property Set Storage */ +typedef struct pps_tag { + ULONG ulSB; + ULONG ulSize; +} pps_type; +typedef struct pps_info_tag { + pps_type tWordDocument; /* Text stream */ + pps_type tData; /* Data stream */ + pps_type tTable; /* Table stream */ + pps_type tSummaryInfo; /* Summary Information */ + pps_type tDocSummaryInfo;/* Document Summary Information */ + pps_type t0Table; /* Table 0 stream */ + pps_type t1Table; /* Table 1 stream */ +} pps_info_type; + +/* Record of data block information */ +typedef struct data_block_tag { + ULONG ulFileOffset; + ULONG ulDataPos; + ULONG ulLength; +} data_block_type; + +/* Record of text block information */ +typedef struct text_block_tag { + ULONG ulFileOffset; + ULONG ulCharPos; + ULONG ulLength; + BOOL bUsesUnicode; /* This block uses 16 bits per character */ + USHORT usPropMod; +} text_block_type; + +/* Record of the document block information */ +typedef struct document_block_tag { + time_t tCreateDate; /* Unix timestamp */ + time_t tRevisedDate; /* Unix timestamp */ + USHORT usDefaultTabWidth; /* In twips */ + UCHAR ucHdrFtrSpecification; +} document_block_type; + +/* Record of table-row block information */ +typedef struct row_block_tag { + ULONG ulFileOffsetStart; + ULONG ulFileOffsetEnd; + ULONG ulCharPosStart; + ULONG ulCharPosEnd; + short asColumnWidth[TABLE_COLUMN_MAX+1]; /* In twips */ + UCHAR ucNumberOfColumns; + UCHAR ucBorderInfo; +} row_block_type; + +/* Various level types */ +typedef enum level_type_tag { + level_type_none = 0, + level_type_outline, + level_type_numbering, + level_type_sequence, + level_type_pause +} level_type_enum; + +typedef enum list_id_tag { + no_list = 0, + text_list, + footnote_list, + hdrftr_list, + macro_list, + annotation_list, + endnote_list, + textbox_list, + hdrtextbox_list, + end_of_lists +} list_id_enum; + +/* Linked list of style description information */ +typedef struct style_block_tag { + ULONG ulFileOffset; /* The style start with this character */ + list_id_enum eListID;/* The fileoffset is in this list */ + BOOL bNumPause; + BOOL bNoRestart; /* Don't restart by more significant levels */ + USHORT usIstd; /* Current style */ + USHORT usIstdNext; /* Next style unless overruled */ + USHORT usStartAt; /* Number at the start of a list */ + USHORT usBeforeIndent; /* Vertical indent before paragraph in twips */ + USHORT usAfterIndent; /* Vertical indent after paragraph in twips */ + USHORT usListIndex; /* Before Word 8 this field was not filled */ + USHORT usListChar; /* Character for an itemized list (Unicode) */ + short sLeftIndent; /* Left indentation in twips */ + short sLeftIndent1; /* First line left indentation in twips */ + short sRightIndent; /* Right indentation in twips */ + UCHAR ucAlignment; + UCHAR ucNFC; /* Number format code */ + UCHAR ucNumLevel; + UCHAR ucListLevel; /* Before Word 8 this field was not filled */ + char szListChar[4]; /* Character for an itemized list */ +} style_block_type; + +/* Font description information */ +typedef struct font_block_tag { + ULONG ulFileOffset; + USHORT usFontStyle; + USHORT usFontSize; + UCHAR ucFontNumber; + UCHAR ucFontColor; +} font_block_type; + +/* Picture description information */ +typedef struct picture_block_tag { + ULONG ulFileOffset; + ULONG ulFileOffsetPicture; + ULONG ulPictureOffset; +} picture_block_type; + +/* Section description information */ +typedef struct section_block_tag { + BOOL bNewPage; + USHORT usNeedPrevLvl; /* Print previous level numbers */ + USHORT usHangingIndent; + UCHAR aucNFC[9]; /* Number format code */ + UCHAR ucHdrFtrSpecification; /* Which headers/footers Word < 8 */ +} section_block_type; + +/* Header/footer description information */ +typedef struct hdrftr_block_tag { + output_type *pText; + long lHeight; /* In DrawUnits */ +} hdrftr_block_type; + +/* Footnote description information */ +typedef struct footnote_block_tag { + char *szText; +} footnote_block_type; + +/* List description information */ +typedef struct list_block_tag { + ULONG ulStartAt; /* Number at the start of a list */ + BOOL bNoRestart; /* Don't restart by more significant levels */ + USHORT usListChar; /* Character for an itemized list (Unicode) */ + short sLeftIndent; /* Left indentation in twips */ + UCHAR ucNFC; /* Number format code */ +} list_block_type; + +/* Types of images */ +typedef enum imagetype_tag { + imagetype_is_unknown = 0, + imagetype_is_external, + imagetype_is_emf, + imagetype_is_wmf, + imagetype_is_pict, + imagetype_is_jpeg, + imagetype_is_png, + imagetype_is_dib +} imagetype_enum; + +/* Types of compression */ +typedef enum compression_tag { + compression_unknown = 0, + compression_none, + compression_rle4, + compression_rle8, + compression_jpeg, + compression_zlib +} compression_enum; + +/* Image information */ +typedef struct imagedata_tag { + /* The type of the image */ + imagetype_enum eImageType; + /* Information from the Word document */ + size_t tPosition; + size_t tLength; + int iHorSizeScaled; /* Size in points */ + int iVerSizeScaled; /* Size in points */ + /* Information from the image */ + int iWidth; /* Size in pixels */ + int iHeight; /* Size in pixels */ + int iComponents; /* Number of color components */ + UINT uiBitsPerComponent; /* Bits per color component */ + BOOL bAdobe; /* Image includes Adobe comment marker */ + compression_enum eCompression; /* Type of compression */ + BOOL bColorImage; /* Is color image */ + int iColorsUsed; /* 0 = uses the maximum number of colors */ + UCHAR aucPalette[256][3]; /* RGB palette */ +} imagedata_type; + +typedef enum row_info_tag { + found_nothing, + found_a_cell, + found_not_a_cell, + found_end_of_row, + found_not_end_of_row +} row_info_enum; + +typedef enum notetype_tag { + notetype_is_footnote, + notetype_is_endnote, + notetype_is_unknown +} notetype_enum; + +typedef enum image_info_tag { + image_no_information, + image_minimal_information, + image_full_information +} image_info_enum; + +#endif /* __wordtypes_h */ diff --git a/wordwin.c b/wordwin.c new file mode 100644 index 0000000..d31b7be --- /dev/null +++ b/wordwin.c @@ -0,0 +1,209 @@ +/* + * wordwin.c + * Copyright (C) 2002-2005 A.J. van Os; Released under GPL + * + * Description: + * Deal with the WIN internals of a MS Word file + */ + +#include "antiword.h" + + +/* + * bGetDocumentText - make a list of the text blocks of a Word document + * + * Return TRUE when succesful, otherwise FALSE + */ +static BOOL +bGetDocumentText(FILE *pFile, const UCHAR *aucHeader) +{ + text_block_type tTextBlock; + ULONG ulBeginOfText; + ULONG ulTextLen, ulFootnoteLen; + ULONG ulHdrFtrLen, ulMacroLen, ulAnnotationLen; + UINT uiQuickSaves; + USHORT usDocStatus; + BOOL bTemplate, bFastSaved, bEncrypted, bSuccess; + + fail(pFile == NULL); + fail(aucHeader == NULL); + + DBG_MSG("bGetDocumentText"); + + /* Get the status flags from the header */ + usDocStatus = usGetWord(0x0a, aucHeader); + DBG_HEX(usDocStatus); + bTemplate = (usDocStatus & BIT(0)) != 0; + DBG_MSG_C(bTemplate, "This document is a Template"); + bFastSaved = (usDocStatus & BIT(2)) != 0; + uiQuickSaves = (UINT)(usDocStatus & 0x00f0) >> 4; + DBG_MSG_C(bFastSaved, "This document is Fast Saved"); + DBG_DEC_C(bFastSaved, uiQuickSaves); + if (bFastSaved) { + werr(0, "Word2: fast saved documents are not supported yet"); + return FALSE; + } + bEncrypted = (usDocStatus & BIT(8)) != 0; + if (bEncrypted) { + werr(0, "Encrypted documents are not supported"); + return FALSE; + } + + /* Get length information */ + ulBeginOfText = ulGetLong(0x18, aucHeader); + DBG_HEX(ulBeginOfText); + ulTextLen = ulGetLong(0x34, aucHeader); + ulFootnoteLen = ulGetLong(0x38, aucHeader); + ulHdrFtrLen = ulGetLong(0x3c, aucHeader); + ulMacroLen = ulGetLong(0x40, aucHeader); + ulAnnotationLen = ulGetLong(0x44, aucHeader); + DBG_DEC(ulTextLen); + DBG_DEC(ulFootnoteLen); + DBG_DEC(ulHdrFtrLen); + DBG_DEC(ulMacroLen); + DBG_DEC(ulAnnotationLen); + if (bFastSaved) { + bSuccess = FALSE; + } else { + tTextBlock.ulFileOffset = ulBeginOfText; + tTextBlock.ulCharPos = ulBeginOfText; + tTextBlock.ulLength = ulTextLen + + ulFootnoteLen + + ulHdrFtrLen + ulMacroLen + ulAnnotationLen; + tTextBlock.bUsesUnicode = FALSE; + tTextBlock.usPropMod = IGNORE_PROPMOD; + bSuccess = bAdd2TextBlockList(&tTextBlock); + DBG_HEX_C(!bSuccess, tTextBlock.ulFileOffset); + DBG_HEX_C(!bSuccess, tTextBlock.ulCharPos); + DBG_DEC_C(!bSuccess, tTextBlock.ulLength); + DBG_DEC_C(!bSuccess, tTextBlock.bUsesUnicode); + DBG_DEC_C(!bSuccess, tTextBlock.usPropMod); + } + + if (bSuccess) { + vSplitBlockList(pFile, + ulTextLen, + ulFootnoteLen, + ulHdrFtrLen, + ulMacroLen, + ulAnnotationLen, + 0, + 0, + 0, + FALSE); + } else { + vDestroyTextBlockList(); + werr(0, "I can't find the text of this document"); + } + return bSuccess; +} /* end of bGetDocumentText */ + +/* + * vGetDocumentData - make a list of the data blocks of a Word document + */ +static void +vGetDocumentData(FILE *pFile, const UCHAR *aucHeader) +{ + data_block_type tDataBlock; + options_type tOptions; + ULONG ulEndOfText, ulBeginCharInfo; + BOOL bFastSaved, bHasImages, bSuccess; + USHORT usDocStatus; + + /* Get the options */ + vGetOptions(&tOptions); + + /* Get the status flags from the header */ + usDocStatus = usGetWord(0x0a, aucHeader); + DBG_HEX(usDocStatus); + bFastSaved = (usDocStatus & BIT(2)) != 0; + bHasImages = (usDocStatus & BIT(3)) != 0; + + if (!bHasImages || + tOptions.eConversionType == conversion_text || + tOptions.eConversionType == conversion_fmt_text || + tOptions.eConversionType == conversion_xml || + tOptions.eImageLevel == level_no_images) { + /* + * No images in the document or text-only output or + * no images wanted, so no data blocks will be needed + */ + vDestroyDataBlockList(); + return; + } + + if (bFastSaved) { + bSuccess = FALSE; + } else { + /* This datablock is too big, but it contains all images */ + ulEndOfText = ulGetLong(0x1c, aucHeader); + DBG_HEX(ulEndOfText); + ulBeginCharInfo = ulGetLong(0xa0, aucHeader); + DBG_HEX(ulBeginCharInfo); + if (ulBeginCharInfo > ulEndOfText) { + tDataBlock.ulFileOffset = ulEndOfText; + tDataBlock.ulDataPos = ulEndOfText; + tDataBlock.ulLength = ulBeginCharInfo - ulEndOfText; + bSuccess = bAdd2DataBlockList(&tDataBlock); + DBG_HEX_C(!bSuccess, tDataBlock.ulFileOffset); + DBG_HEX_C(!bSuccess, tDataBlock.ulDataPos); + DBG_DEC_C(!bSuccess, tDataBlock.ulLength); + } else { + bSuccess = ulBeginCharInfo == ulEndOfText; + } + } + + if (!bSuccess) { + vDestroyDataBlockList(); + werr(0, "I can't find the data of this document"); + } +} /* end of vGetDocumentData */ + +/* + * iInitDocumentWIN - initialize an WIN document + * + * Returns the version of Word that made the document or -1 + */ +int +iInitDocumentWIN(FILE *pFile, long lFilesize) +{ + int iWordVersion; + BOOL bSuccess; + USHORT usIdent; + UCHAR aucHeader[384]; + + fail(pFile == NULL); + + if (lFilesize < 384) { + return -1; + } + + /* Read the headerblock */ + if (!bReadBytes(aucHeader, 384, 0x00, pFile)) { + return -1; + } + /* Get the "magic number" from the header */ + usIdent = usGetWord(0x00, aucHeader); + DBG_HEX(usIdent); + fail(usIdent != 0xa59b && /* WinWord 1.x */ + usIdent != 0xa5db); /* WinWord 2.0 */ + iWordVersion = iGetVersionNumber(aucHeader); + if (iWordVersion != 1 && iWordVersion != 2) { + werr(0, "This file is not from ''Win Word 1 or 2'."); + return -1; + } + bSuccess = bGetDocumentText(pFile, aucHeader); + if (bSuccess) { + vGetDocumentData(pFile, aucHeader); + vGetPropertyInfo(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + vSetDefaultTabWidth(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + vGetNotesInfo(pFile, NULL, + NULL, 0, NULL, 0, + aucHeader, iWordVersion); + } + return bSuccess ? iWordVersion : -1; +} /* end of iInitDocumentWIN */ diff --git a/xmalloc.c b/xmalloc.c new file mode 100644 index 0000000..b64bc44 --- /dev/null +++ b/xmalloc.c @@ -0,0 +1,136 @@ +/* + * xmalloc.c + * Copyright (C) 1998-2005 A.J. van Os + * + * Description: + * Extended malloc and friends + */ + +#include +#include +#include "antiword.h" + +static char *szMessage = + "Memory allocation failed, unable to continue"; +#if defined(__dos) && !defined(__DJGPP__) +static char *szDosMessage = + "DOS can't allocate this kind of memory, unable to continue"; +#endif /* __dos && !__DJGPP__ */ + + +/* + * xmalloc - Allocates dynamic memory + * + * See malloc(3), but unlike malloc(3) xmalloc does not return in case + * of error. + */ +void * +xmalloc(size_t tSize) +{ + void *pvTmp; + + TRACE_MSG("xmalloc"); + + if (tSize == 0) { + tSize = 1; + } + pvTmp = malloc(tSize); + if (pvTmp == NULL) { + DBG_MSG("xmalloc returned NULL"); + DBG_DEC(tSize); + werr(1, szMessage); + } + return pvTmp; +} /* end of xmalloc */ + +/* + * xcalloc - Allocates and zeros dynamic memory + * + * See calloc(3), but unlike calloc(3) xcalloc does not return in case of error + */ +void * +xcalloc(size_t tNmemb, size_t tSize) +{ + void *pvTmp; + + TRACE_MSG("xcalloc"); + +#if defined(__dos) && !defined(__DJGPP__) + if ((ULONG)tNmemb * (ULONG)tSize > 0xffffUL) { + DBG_DEC((ULONG)tNmemb * (ULONG)tSize); + werr(1, szDosMessage); + } +#endif /* __dos && !__DJGPP__ */ + + if (tNmemb == 0 || tSize == 0) { + tNmemb = 1; + tSize = 1; + } + pvTmp = calloc(tNmemb, tSize); + if (pvTmp == NULL) { + DBG_MSG("xcalloc returned NULL"); + werr(1, szMessage); + } + return pvTmp; +} /* end of xcalloc */ + +/* + * xrealloc - Changes the size of a memory object + * + * See realloc(3), but unlike realloc(3) xrealloc does not return in case + * of error. + */ +void * +xrealloc(void *pvArg, size_t tSize) +{ + void *pvTmp; + + TRACE_MSG("xrealloc"); + + pvTmp = realloc(pvArg, tSize); + if (pvTmp == NULL) { + DBG_MSG("realloc returned NULL"); + werr(1, szMessage); + } + return pvTmp; +} /* end of xrealloc */ + +/* + * xstrdup - Duplicate a string + * + * See strdup(3), but unlike strdup(3) xstrdup does not return in case + * of error. + * + * NOTE: + * Does not use strdup(3), because some systems don't have it. + */ +char * +xstrdup(const char *szArg) +{ + char *szTmp; + + TRACE_MSG("xstrdup"); + + szTmp = xmalloc(strlen(szArg) + 1); + strcpy(szTmp, szArg); + return szTmp; +} /* end of xstrdup */ + +/* + * xfree - Deallocates dynamic memory + * + * See free(3). + * + * returns NULL; + * This makes p=xfree(p) possible, free memory and overwrite the pointer to it. + */ +void * +xfree(void *pvArg) +{ + TRACE_MSG("xfree"); + + if (pvArg != NULL) { + free(pvArg); + } + return NULL; +} /* end of xfree */ diff --git a/xml.c b/xml.c new file mode 100644 index 0000000..92048ad --- /dev/null +++ b/xml.c @@ -0,0 +1,1438 @@ +/* + * xml.c + * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL + * + * Description: + * Functions to deal with the XML/DocBook format + * + */ + +#include +#include "antiword.h" + + +#define vAddEndTagsUntil1(p,t) vAddEndTagsUntil2(p,t,TAG_NOTAG) + +#if defined(DEBUG) +#define vStackTrace() __vStackTrace(__LINE__) +#else +#define vStackTrace() /* EMPTY */ +#endif /* DEBUG */ + +/* The character set */ +static encoding_type eEncoding = encoding_neutral; +/* Word version */ +static int iWordVersion = -1; +/* Special treatment for files from Word 4/5/6 on an Apple Macintosh */ +static BOOL bOldMacFile = FALSE; +/* Text is emphasised */ +static BOOL bEmphasisOpen = FALSE; +/* Text is superscript */ +static BOOL bSuperscriptOpen = FALSE; +/* Text is subscript */ +static BOOL bSubscriptOpen = FALSE; +/* Title is open */ +static BOOL bTitleOpen = FALSE; +/* Table is open */ +static BOOL bTableOpen = FALSE; +/* Footnote is open */ +static BOOL bFootnoteOpen = FALSE; +/* Current paragraph level */ +static UINT uiParagraphLevel = 0; +/* Current list level */ +static UINT uiListLevel = 0; +/* Current list level is still empty */ +static BOOL bEmptyListLevel = TRUE; +/* Current header level */ +static USHORT usHeaderLevelCurrent = 0; +/* Current header level is still empty */ +static BOOL bEmptyHeaderLevel = TRUE; +/* Number of columns in the current table */ +static int iTableColumnsCurrent = 0; +/* Footnote number */ +static UINT uiFootnoteNumber = 0; + +/* Constants for the stack */ +#define INITIAL_STACK_SIZE 10 +#if defined(DEBUG) +#define EXTENSION_STACK_SIZE 2 +#else +#define EXTENSION_STACK_SIZE 10 +#endif /* DEBUG */ + +/* Variables for the stack */ +static UCHAR *aucStack = NULL; +static size_t tStacksize = 0; +static size_t tStackNextFree = 0; + +/* Constants for the tags */ +#define TAG_NOTAG (UCHAR)0 +#define TAG_AUTHOR (UCHAR)1 +#define TAG_BEGINPAGE (UCHAR)2 +#define TAG_BOOK (UCHAR)3 +#define TAG_BOOKINFO (UCHAR)4 +#define TAG_CHAPTER (UCHAR)5 +#define TAG_COLSPEC (UCHAR)6 +#define TAG_CORPNAME (UCHAR)7 +#define TAG_DATE (UCHAR)8 +#define TAG_EMPHASIS (UCHAR)9 +#define TAG_ENTRY (UCHAR)10 +#define TAG_FILENAME (UCHAR)11 +#define TAG_FOOTNOTE (UCHAR)12 +#define TAG_INFORMALTABLE (UCHAR)13 +#define TAG_ITEMIZEDLIST (UCHAR)14 +#define TAG_LISTITEM (UCHAR)15 +#define TAG_ORDEREDLIST (UCHAR)16 +#define TAG_PARA (UCHAR)17 +#define TAG_ROW (UCHAR)18 +#define TAG_SECT1 (UCHAR)19 +#define TAG_SECT2 (UCHAR)20 +#define TAG_SECT3 (UCHAR)21 +#define TAG_SECT4 (UCHAR)22 +#define TAG_SECT5 (UCHAR)23 +#define TAG_SUBSCRIPT (UCHAR)24 +#define TAG_SUBTITLE (UCHAR)25 +#define TAG_SUPERSCRIPT (UCHAR)26 +#define TAG_SURNAME (UCHAR)27 +#define TAG_TBODY (UCHAR)28 +#define TAG_TGROUP (UCHAR)29 +#define TAG_TITLE (UCHAR)30 + +typedef struct docbooktags_tag { + UCHAR ucTagnumber; + char szTagname[15]; + BOOL bAddNewlineStart; + BOOL bAddNewlineEnd; +} docbooktags_type; + +static const docbooktags_type atDocBookTags[] = { + { TAG_NOTAG, "!ERROR!", TRUE, TRUE }, + { TAG_AUTHOR, "author", TRUE, TRUE }, + { TAG_BEGINPAGE, "beginpage", TRUE, TRUE }, + { TAG_BOOK, "book", TRUE, TRUE }, + { TAG_BOOKINFO, "bookinfo", TRUE, TRUE }, + { TAG_CHAPTER, "chapter", TRUE, TRUE }, + { TAG_COLSPEC, "colspec", TRUE, TRUE }, + { TAG_CORPNAME, "corpname", FALSE, FALSE }, + { TAG_DATE, "date", FALSE, FALSE }, + { TAG_EMPHASIS, "emphasis", FALSE, FALSE }, + { TAG_ENTRY, "entry", TRUE, TRUE }, + { TAG_FILENAME, "filename", FALSE, FALSE }, + { TAG_FOOTNOTE, "footnote", FALSE, FALSE }, + { TAG_INFORMALTABLE, "informaltable",TRUE, TRUE }, + { TAG_ITEMIZEDLIST, "itemizedlist", TRUE, TRUE }, + { TAG_LISTITEM, "listitem", TRUE, TRUE }, + { TAG_ORDEREDLIST, "orderedlist", TRUE, TRUE }, + { TAG_PARA, "para", TRUE, TRUE }, + { TAG_ROW, "row", TRUE, TRUE }, + { TAG_SECT1, "sect1", TRUE, TRUE }, + { TAG_SECT2, "sect2", TRUE, TRUE }, + { TAG_SECT3, "sect3", TRUE, TRUE }, + { TAG_SECT4, "sect4", TRUE, TRUE }, + { TAG_SECT5, "sect5", TRUE, TRUE }, + { TAG_SUBSCRIPT, "subscript", FALSE, FALSE }, + { TAG_SUBTITLE, "subtitle", FALSE, FALSE }, + { TAG_SUPERSCRIPT, "superscript", FALSE, FALSE }, + { TAG_SURNAME, "surname", FALSE, FALSE }, + { TAG_TBODY, "tbody", TRUE, TRUE }, + { TAG_TGROUP, "tgroup", TRUE, TRUE }, + { TAG_TITLE, "title", FALSE, FALSE }, +}; + +static void vAddStartTag(diagram_type *, UCHAR, const char *); +static void vAddEndTag(diagram_type *, UCHAR); +static void vAddCombinedTag(diagram_type *, UCHAR, const char *); +static void vPrintChar(diagram_type *, char); + + +#if defined(DEBUG) +/* + * vCheckTagTable - check the tag table + */ +static void +vCheckTagTable(void) +{ + size_t tIndex; + + for (tIndex = 0; tIndex < elementsof(atDocBookTags); tIndex++) { + if (tIndex != (size_t)atDocBookTags[tIndex].ucTagnumber) { + DBG_DEC(tIndex); + werr(1, "Array atDocBookTags is broken"); + } + } +} /* end of vCheckTagTable */ + +/* + * __vStackTrace - show a stack trace + */ +static void +__vStackTrace(int iLine) +{ + int iIndex; + + fprintf(stderr, "%s[%3d]:\n", __FILE__, iLine); + + if (tStackNextFree == 0) { + fprintf(stderr, "The stack is empty\n"); + return; + } + for (iIndex = (int)tStackNextFree - 1; iIndex >= 0; iIndex--) { + fprintf(stderr, "%2d: %2d: '%s'\n", + iIndex, + (int)atDocBookTags[(UINT)aucStack[iIndex]].ucTagnumber, + atDocBookTags[(UINT)aucStack[iIndex]].szTagname); + } +} /* end of __vStackTrace */ +#endif /* DEBUG */ + +/* + * vPushStack - push a tag onto the stack + */ +static void +vPushStack(UCHAR ucTag) +{ + fail(tStackNextFree > tStacksize); + + if (tStackNextFree == tStacksize) { + /* The stack is full; enlarge the stack */ + tStacksize += EXTENSION_STACK_SIZE; + aucStack = xrealloc(aucStack, tStacksize * sizeof(UCHAR)); + DBG_DEC(tStacksize); + } + + fail(tStackNextFree >= tStacksize); + + aucStack[tStackNextFree++] = ucTag; +} /* end of vPushStack */ + +/* + * vPopStack - pop a tag from the stack + */ +static UCHAR +ucPopStack(void) +{ + DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree); + DBG_DEC_C(tStackNextFree > tStacksize, tStacksize); + fail(tStackNextFree > tStacksize); + fail(tStackNextFree == 0); + + if (tStackNextFree == 0) { + werr(1, "The stack is empty, unable to continue"); + return TAG_NOTAG; + } + return aucStack[--tStackNextFree]; +} /* end of ucPopStack */ + +/* + * vReadStack - read a tag from the top of the stack + */ +static UCHAR +ucReadStack(void) +{ + DBG_DEC_C(tStackNextFree > tStacksize, tStackNextFree); + DBG_DEC_C(tStackNextFree > tStacksize, tStacksize); + fail(tStackNextFree > tStacksize); + + if (tStackNextFree == 0) { + /* The stack is empty */ + return TAG_NOTAG; + } + return aucStack[tStackNextFree - 1]; +} /* end of ucReadStack */ + +/* + * vPrintLevel - print the tag level + */ +static void +vPrintLevel(FILE *pOutFile) +{ + size_t tIndex; + + fail(pOutFile == NULL); + + for (tIndex = 0; tIndex < tStackNextFree; tIndex++) { + (void)putc(' ', pOutFile); + } +} /* end of vPrintLevel */ + +/* + * vPrintFootnote - print a footnote + */ +static void +vPrintFootnote(diagram_type *pDiag, UINT uiFootnoteIndex) +{ + const char *szText, *pcTmp; + BOOL bSuScript; + UCHAR ucTopTag; + + TRACE_MSG("vPrintFootnote"); + + szText = szGetFootnootText(uiFootnoteIndex); + + if (szText == NULL) { + szText = ""; + } + + /* Remove the subscript/superscript (if any) */ + ucTopTag = ucReadStack(); + bSuScript = ucTopTag == TAG_SUBSCRIPT || ucTopTag == TAG_SUPERSCRIPT; + if (bSuScript) { + vAddEndTag(pDiag, ucTopTag); + } + + /* Start a footnote */ + vAddStartTag(pDiag, TAG_FOOTNOTE, NULL); + vAddStartTag(pDiag, TAG_PARA, NULL); + + /* Print a footnote */ + for (pcTmp = szText; *pcTmp != '\0'; pcTmp++) { + if (*pcTmp == PAR_END) { + if (*(pcTmp + 1) != PAR_END && *(pcTmp + 1) != '\0') { + /* PAR_END is not empty and not last */ + vAddEndTag(pDiag, TAG_PARA); + vAddStartTag(pDiag, TAG_PARA, NULL); + } + } else { + vPrintChar(pDiag, *pcTmp); + } + } + + /* End a footnote */ + vAddEndTag(pDiag, TAG_PARA); + vAddEndTag(pDiag, TAG_FOOTNOTE); + + /* Repair the subscript/superscript (if any) */ + if (bSuScript) { + vAddStartTag(pDiag, ucTopTag, NULL); + } +} /* end of vPrintFootnote */ + +/* + * vPrintChar - print a character with XML encoding + */ +static void +vPrintChar(diagram_type *pDiag, char cChar) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + + switch (cChar) { + case FOOTNOTE_OR_ENDNOTE: + uiFootnoteNumber++; + vPrintFootnote(pDiag, uiFootnoteNumber - 1); + break; + case '<': + fprintf(pDiag->pOutFile, "%s", "<"); + break; + case '>': + fprintf(pDiag->pOutFile, "%s", ">"); + break; + case '&': + fprintf(pDiag->pOutFile, "%s", "&"); + break; + default: + (void)putc(cChar, pDiag->pOutFile); + break; + } +} /* end of vPrintChar */ + +/* + * vPrintSpecialChar - convert and print a character + */ +static void +vPrintSpecialChar(diagram_type *pDiag, USHORT usChar) +{ + ULONG ulChar; + size_t tLen, tIndex; + char szResult[4]; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(iWordVersion < 0); + fail(eEncoding == encoding_neutral); + + ulChar = ulTranslateCharacters(usChar, 0, iWordVersion, + conversion_xml, eEncoding, bOldMacFile); + tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); + if (tLen == 1) { + vPrintChar(pDiag, szResult[0]); + } else { + for (tIndex = 0; tIndex < tLen; tIndex++) { + (void)putc(szResult[tIndex], pDiag->pOutFile); + } + } +} /* end of vPrintSpecialChar */ + +/* + * vPrintSpecialString - convert and print a string + */ +static void +vPrintSpecialString(diagram_type *pDiag, const char *szString) +{ + int iIndex; + USHORT usChar; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(szString == NULL); + + for (iIndex = 0; szString[iIndex] != '\0'; iIndex++) { + usChar = (USHORT)(UCHAR)szString[iIndex]; + vPrintSpecialChar(pDiag, usChar); + } +} /* end of vPrintSpecialString */ + +/* + * vAddStartTag - add the specified start tag to the file + */ +static void +vAddStartTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail((size_t)ucTag >= elementsof(atDocBookTags)); + + if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) { + fprintf(pDiag->pOutFile, "\n"); + vPrintLevel(pDiag->pOutFile); + } + + if (szAttribute == NULL || szAttribute[0] == '\0') { + fprintf(pDiag->pOutFile, "<%s>", + atDocBookTags[(UINT)ucTag].szTagname); + } else { + fprintf(pDiag->pOutFile, "<%s %s>", + atDocBookTags[(UINT)ucTag].szTagname, szAttribute); + } + + if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) { + fprintf(pDiag->pOutFile, "\n"); + pDiag->lXleft = 0; + } + + vPushStack(ucTag); + + /* Set global variables */ + switch (ucTag) { + case TAG_CHAPTER: + usHeaderLevelCurrent = 1; + bEmptyHeaderLevel = TRUE; + break; + case TAG_SECT1: + usHeaderLevelCurrent = 2; + bEmptyHeaderLevel = TRUE; + break; + case TAG_SECT2: + usHeaderLevelCurrent = 3; + bEmptyHeaderLevel = TRUE; + break; + case TAG_SECT3: + usHeaderLevelCurrent = 4; + bEmptyHeaderLevel = TRUE; + break; + case TAG_SECT4: + usHeaderLevelCurrent = 5; + bEmptyHeaderLevel = TRUE; + break; + case TAG_SECT5: + usHeaderLevelCurrent = 6; + bEmptyHeaderLevel = TRUE; + break; + case TAG_TITLE: + fail(uiParagraphLevel != 0); + bTitleOpen = TRUE; + break; + case TAG_FOOTNOTE: + bFootnoteOpen = TRUE; + break; + case TAG_PARA: + fail(bTitleOpen && !bFootnoteOpen); + uiParagraphLevel++; + bEmptyHeaderLevel = FALSE; + break; + case TAG_EMPHASIS: + bEmphasisOpen = TRUE; + break; + case TAG_ITEMIZEDLIST: + case TAG_ORDEREDLIST: + uiListLevel++; + bEmptyListLevel = TRUE; + bEmptyHeaderLevel = FALSE; + break; + case TAG_LISTITEM: + bEmptyListLevel = FALSE; + break; + case TAG_SUPERSCRIPT: + bSuperscriptOpen = TRUE; + break; + case TAG_SUBSCRIPT: + bSubscriptOpen = TRUE; + break; + case TAG_INFORMALTABLE: + bTableOpen = TRUE; + bEmptyHeaderLevel = FALSE; + break; + default: + break; + } +} /* end of vAddStartTag */ + +/* + * vAddEndTag - add the specified end tag to the file + */ +static void +vAddEndTag(diagram_type *pDiag, UCHAR ucTag) +{ + UCHAR ucTopTag; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail((size_t)ucTag >= elementsof(atDocBookTags)); + +#if defined(DEBUG) + ucTopTag = ucReadStack(); + if (ucTag != ucTopTag) { + DBG_DEC(ucTag); + DBG_MSG(atDocBookTags[(UINT)ucTag].szTagname); + vStackTrace(); + } +#endif /* DEBUG */ + + ucTopTag = ucPopStack(); + fail((size_t)ucTopTag >= elementsof(atDocBookTags)); + if (ucTag != ucTopTag) { + DBG_DEC(ucTag); + DBG_DEC(ucTopTag); + DBG_FIXME(); + werr(1, "Impossible tag sequence, unable to continue"); + } + + if (atDocBookTags[(UINT)ucTag].bAddNewlineEnd) { + fprintf(pDiag->pOutFile, "\n"); + vPrintLevel(pDiag->pOutFile); + } + + fprintf(pDiag->pOutFile, "", atDocBookTags[(UINT)ucTag].szTagname); + + if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) { + fprintf(pDiag->pOutFile, "\n"); + pDiag->lXleft = 0; + } + + /* Set global variables */ + switch (ucTag) { + case TAG_CHAPTER: + usHeaderLevelCurrent = 0; + break; + case TAG_SECT1: + usHeaderLevelCurrent = 1; + break; + case TAG_SECT2: + usHeaderLevelCurrent = 2; + break; + case TAG_SECT3: + usHeaderLevelCurrent = 3; + break; + case TAG_SECT4: + usHeaderLevelCurrent = 4; + break; + case TAG_SECT5: + usHeaderLevelCurrent = 5; + break; + case TAG_TITLE: + bTitleOpen = FALSE; + break; + case TAG_FOOTNOTE: + bFootnoteOpen = FALSE; + break; + case TAG_PARA: + uiParagraphLevel--; + break; + case TAG_EMPHASIS: + bEmphasisOpen = FALSE; + break; + case TAG_SUPERSCRIPT: + bSuperscriptOpen = FALSE; + break; + case TAG_ITEMIZEDLIST: + case TAG_ORDEREDLIST: + uiListLevel--; + break; + case TAG_SUBSCRIPT: + bSubscriptOpen = FALSE; + break; + case TAG_INFORMALTABLE: + bTableOpen = FALSE; + iTableColumnsCurrent = 0; + break; + default: + break; + } +} /* end of vAddEndTag */ + +/* + * vAddEndTagOptional - add the specified end tag to the file if needed + */ +static void +vAddEndTagOptional(diagram_type *pDiag, UCHAR ucTag) +{ + UCHAR ucTopTag; + + ucTopTag = ucReadStack(); + if (ucTag == ucTopTag) { + vAddEndTag(pDiag, ucTag); + } +} /* end of vAddEndTagOptional */ + +/* + * vAddCombinedTag - add the specified start and end tag to the file + */ +static void +vAddCombinedTag(diagram_type *pDiag, UCHAR ucTag, const char *szAttribute) +{ + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail((size_t)ucTag >= elementsof(atDocBookTags)); + + if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) { + fprintf(pDiag->pOutFile, "\n"); + vPrintLevel(pDiag->pOutFile); + } + + if (szAttribute == NULL || szAttribute[0] == '\0') { + fprintf(pDiag->pOutFile, "<%s/>", + atDocBookTags[(UINT)ucTag].szTagname); + } else { + fprintf(pDiag->pOutFile, "<%s %s/>", + atDocBookTags[(UINT)ucTag].szTagname, szAttribute); + } + + if (atDocBookTags[(UINT)ucTag].bAddNewlineStart) { + fprintf(pDiag->pOutFile, "\n"); + pDiag->lXleft = 0; + } +} /* end of vAddCombinedTag */ + +/* + * vAddEndTagsUntil2 - add end tags until one the specified tags is seen + */ +static void +vAddEndTagsUntil2(diagram_type *pDiag, UCHAR ucTag1, UCHAR ucTag2) +{ + UCHAR ucTopTag; + + do { + ucTopTag = ucReadStack(); + switch (ucTopTag) { + case TAG_CHAPTER: + case TAG_SECT1: + case TAG_SECT2: + case TAG_SECT3: + case TAG_SECT4: + case TAG_SECT5: + if (bEmptyHeaderLevel) { + /* + * An empty chapter is legal in Word, + * but not in DocBook. + */ + vAddCombinedTag(pDiag, TAG_PARA, NULL); + bEmptyHeaderLevel = FALSE; + } + break; + case TAG_ITEMIZEDLIST: + case TAG_ORDEREDLIST: + if (bEmptyListLevel) { + /* + * A list without items is legal in Word, + * but not in DocBook. (Nor are empty items) + */ + vAddStartTag(pDiag, TAG_LISTITEM, NULL); + vAddCombinedTag(pDiag, TAG_PARA, NULL); + vAddEndTag(pDiag, TAG_LISTITEM); + bEmptyListLevel = FALSE; + } + break; + default: + break; + } + vAddEndTag(pDiag, ucTopTag); + } while (ucTopTag != ucTag1 && ucTopTag != ucTag2); +} /* end of vAddEndTagsUntil2 */ + +/* + * vCreateBookIntro - create title and bookinfo + */ +void +vCreateBookIntro(diagram_type *pDiag, int iVersion) +{ + const char *szTitle, *szSubject, *szAuthor; + const char *szLastSaveDtm, *szCompany; + const char *szLanguage; + char szTmp[13]; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(iVersion < 0); + fail(eEncoding == encoding_neutral); + + iWordVersion = iVersion; + bOldMacFile = bIsOldMacFile(); + szTitle = szGetTitle(); + szSubject = szGetSubject(); + szAuthor = szGetAuthor(); + szLastSaveDtm = szGetLastSaveDtm(); + szCompany = szGetCompany(); + + /* Start Book */ + szLanguage = szGetLanguage(); + if (szLanguage != NULL) { + DBG_MSG(szLanguage); + sprintf(szTmp, "lang='%.5s'", szLanguage); + szLanguage = szTmp; + } + vAddStartTag(pDiag, TAG_BOOK, szLanguage); + + /* Book title */ + if (szTitle != NULL && szTitle[0] != '\0') { + vAddStartTag(pDiag, TAG_TITLE, NULL); + vPrintSpecialString(pDiag, szTitle); + vAddEndTag(pDiag, TAG_TITLE); + } + /* Bookinfo */ + if ((szTitle != NULL && szTitle[0] != '\0') || + (szSubject != NULL && szSubject[0] != '\0') || + (szAuthor != NULL && szAuthor[0] != '\0') || + (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') || + (szCompany != NULL && szCompany[0] != '\0')) { + vAddStartTag(pDiag, TAG_BOOKINFO, NULL); + if (szTitle != NULL && szTitle[0] != '\0') { + vAddStartTag(pDiag, TAG_TITLE, NULL); + vPrintSpecialString(pDiag, szTitle); + vAddEndTag(pDiag, TAG_TITLE); + } + if (szSubject != NULL && szSubject[0] != '\0') { + vAddStartTag(pDiag, TAG_SUBTITLE, NULL); + vPrintSpecialString(pDiag, szSubject); + vAddEndTag(pDiag, TAG_SUBTITLE); + } + if (szAuthor != NULL && szAuthor[0] != '\0') { + vAddStartTag(pDiag, TAG_AUTHOR, NULL); + vAddStartTag(pDiag, TAG_SURNAME, NULL); + vPrintSpecialString(pDiag, szAuthor); + vAddEndTag(pDiag, TAG_SURNAME); + vAddEndTag(pDiag, TAG_AUTHOR); + } + if (szLastSaveDtm != NULL && szLastSaveDtm[0] != '\0') { + vAddStartTag(pDiag, TAG_DATE, NULL); + vPrintSpecialString(pDiag, szLastSaveDtm); + vAddEndTag(pDiag, TAG_DATE); + } + if (szCompany != NULL && szCompany[0] != '\0') { + vAddStartTag(pDiag, TAG_CORPNAME, NULL); + vPrintSpecialString(pDiag, szCompany); + vAddEndTag(pDiag, TAG_CORPNAME); + } + vAddEndTag(pDiag, TAG_BOOKINFO); + } +} /* end of vCreateBookIntro */ + +/* + * vPrologueXML - perform the XML initialization + */ +void +vPrologueXML(diagram_type *pDiag, const options_type *pOptions) +{ + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(pOptions == NULL); + +#if defined(DEBUG) + vCheckTagTable(); +#endif /* DEBUG */ + + /* Set global variables to their start values */ + eEncoding = pOptions->eEncoding; + bEmphasisOpen = FALSE; + bSuperscriptOpen = FALSE; + bSubscriptOpen = FALSE; + bTitleOpen = FALSE; + bTableOpen = FALSE; + bFootnoteOpen = FALSE; + uiParagraphLevel = 0; + uiListLevel = 0; + bEmptyListLevel = TRUE; + usHeaderLevelCurrent = 0; + bEmptyHeaderLevel = TRUE; + iTableColumnsCurrent = 0; + uiFootnoteNumber = 0; + + pDiag->lXleft = 0; + pDiag->lYtop = 0; + + /* Create an empty stack */ + tStacksize = INITIAL_STACK_SIZE; + aucStack = xcalloc(tStacksize, sizeof(UCHAR)); + tStackNextFree = 0; +} /* end of vPrologueXML */ + +/* + * vEpilogueXML - clean up after everything is done + */ +void +vEpilogueXML(diagram_type *pDiag) +{ + vStackTrace(); + + vAddEndTagsUntil1(pDiag, TAG_BOOK); + + vStackTrace(); + + /* Destroy the stack */ + fail(tStackNextFree != 0); + tStacksize = 0; + aucStack = xfree(aucStack); + tStackNextFree = 0; +} /* end of vEpilogueXML */ + +/* + * vPrintXML - print a XML string + */ +static void +vPrintXML(diagram_type *pDiag, const char *szString, size_t tStringLength, + USHORT usFontstyle) +{ + const char *szAttr; + int iCount; + size_t tNextFree; + BOOL bNotReady, bEmphasisNew, bSuperscriptNew, bSubscriptNew; + UCHAR ucTopTag, aucStorage[3]; + + fail(szString == NULL); + + if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { + return; + } + + if (tStringLength == 1 && szString[0] == FOOTNOTE_OR_ENDNOTE) { + /* Don't do anything special for just a single footnote */ + bEmphasisNew = FALSE; + bSuperscriptNew = FALSE; + bSubscriptNew = FALSE; + } else { + /* Situation normal */ + bEmphasisNew = bIsBold(usFontstyle) || + bIsItalic(usFontstyle) || + bIsUnderline(usFontstyle) || + bIsStrike(usFontstyle); + bSuperscriptNew = bIsSuperscript(usFontstyle); + bSubscriptNew = bIsSubscript(usFontstyle); + } + + /* End what has to be ended (or more to keep the stack happy) */ + tNextFree = 0; + bNotReady = TRUE; + do { + ucTopTag = ucReadStack(); + switch (ucTopTag) { + case TAG_EMPHASIS: + fail(!bEmphasisOpen); + if (bEmphasisNew) { + aucStorage[tNextFree++] = ucTopTag; + } + vAddEndTag(pDiag, ucTopTag); + break; + case TAG_SUPERSCRIPT: + fail(!bSuperscriptOpen); + if (bSuperscriptNew) { + aucStorage[tNextFree++] = ucTopTag; + } + vAddEndTag(pDiag, ucTopTag); + break; + case TAG_SUBSCRIPT: + fail(!bSubscriptOpen); + if (bSubscriptNew) { + aucStorage[tNextFree++] = ucTopTag; + } + vAddEndTag(pDiag, ucTopTag); + break; + default: + bNotReady = FALSE; + break; + } + fail(tNextFree > elementsof(aucStorage)); + fail(bNotReady && tNextFree == elementsof(aucStorage)); + } while (bNotReady); + + /* Just te make sure */ + vStartOfParagraphXML(pDiag, 1); + + /* Restart to keep the stack happy */ + for (iCount = (int)tNextFree - 1; iCount > 0; iCount--) { + vAddStartTag(pDiag, aucStorage[iCount], NULL); + } + + /* Start what has to be started */ + if (bEmphasisNew && !bEmphasisOpen) { + if (bIsBold(usFontstyle)) { + szAttr = "role='bold'"; + } else if (bIsItalic(usFontstyle)) { + szAttr = NULL; + } else if (bIsUnderline(usFontstyle)) { + szAttr = "role='underline'"; + } else if (bIsStrike(usFontstyle)) { + szAttr = "role='strikethrough'"; + } else { + szAttr = NULL; + } + vAddStartTag(pDiag, TAG_EMPHASIS, szAttr); + } + if (bSuperscriptNew && !bSuperscriptOpen) { + vAddStartTag(pDiag, TAG_SUPERSCRIPT, NULL); + } + if (bSubscriptNew && !bSubscriptOpen) { + vAddStartTag(pDiag, TAG_SUBSCRIPT, NULL); + } + + /* The print the string */ + for (iCount = 0; iCount < (int)tStringLength; iCount++) { + vPrintChar(pDiag, szString[iCount]); + } +} /* end of vPrintXML */ + +/* + * vMove2NextLineXML - move to the next line + */ +void +vMove2NextLineXML(diagram_type *pDiag) +{ + fail(pDiag == NULL); + + /* + if (uiParagraphLevel != 0) { + We need something like HTML's
tag + } + */ +} /* end of vMove2NextLineXML */ + +/* + * vSubstringXML - put a sub string into a diagram + */ +void +vSubstringXML(diagram_type *pDiag, + const char *szString, size_t tStringLength, long lStringWidth, + USHORT usFontstyle) +{ + fail(pDiag == NULL || szString == NULL); + fail(pDiag->pOutFile == NULL); + fail(pDiag->lXleft < 0); + fail(tStringLength != strlen(szString)); + + if (szString[0] == '\0' || tStringLength == 0) { + return; + } + + vPrintXML(pDiag, szString, tStringLength, usFontstyle); + pDiag->lXleft += lStringWidth; +} /* end of vSubstringXML */ + +/* + * Create an start of a paragraph + * Only works on paragraph level one, because Word doesn't allow paragraphs + * in paragraphs. Other paragraph levels result from DocBooks special needs. + */ +void +vStartOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel) +{ + fail(pDiag == NULL); + + if (uiParagraphLevel >= uiMaxLevel || bTitleOpen) { + /* In Word a title is just a paragraph */ + return; + } + if (uiListLevel != 0 && bEmptyListLevel) { + /* No paragraphs in a list before the first listitem */ + return; + } + if (usHeaderLevelCurrent == 0) { + /* No paragraphs without an open header */ + vAddStartTag(pDiag, TAG_CHAPTER, NULL); + /* Dummy title */ + vAddCombinedTag(pDiag, TAG_TITLE, NULL); + } + vAddStartTag(pDiag, TAG_PARA, NULL); +} /* end of vStartOfParagraphXML */ + +/* + * Create an end of a paragraph + * Only for paragraph level one and for titles + */ +void +vEndOfParagraphXML(diagram_type *pDiag, UINT uiMaxLevel) +{ + UCHAR ucTopTag; + + fail(pDiag == NULL); + + if (uiParagraphLevel > uiMaxLevel) { + DBG_DEC(uiParagraphLevel); + return; + } + + for(;;) { + ucTopTag = ucReadStack(); + switch (ucTopTag) { + case TAG_EMPHASIS: + fail(!bEmphasisOpen); + vAddEndTag(pDiag, TAG_EMPHASIS); + break; + case TAG_SUPERSCRIPT: + fail(!bSuperscriptOpen); + vAddEndTag(pDiag, TAG_SUPERSCRIPT); + break; + case TAG_SUBSCRIPT: + fail(!bSubscriptOpen); + vAddEndTag(pDiag, TAG_SUBSCRIPT); + break; + case TAG_TITLE: + fail(!bTitleOpen); + vAddEndTag(pDiag, TAG_TITLE); + return; + case TAG_PARA: + fail(uiParagraphLevel == 0); + vAddEndTag(pDiag, TAG_PARA); + return; + case TAG_TBODY: + case TAG_TGROUP: + case TAG_INFORMALTABLE: + fail(!bTableOpen); + vAddEndTag(pDiag, ucTopTag); + break; + case TAG_NOTAG: + DBG_FIXME(); + werr(1, "Impossible tag sequence, unable to continue"); + break; + default: + DBG_DEC(ucTopTag); + DBG_MSG_C((size_t)ucTopTag < elementsof(atDocBookTags), + atDocBookTags[(UINT)ucTopTag].szTagname); + return; + } + } +} /* end of vEndOfParagraphXML */ + +/* + * Create an end of a page + */ +void +vEndOfPageXML(diagram_type *pDiag) +{ + if (bTableOpen || usHeaderLevelCurrent == 0) { + /* No beginpage in a table or outside a chapter */ + return; + } + if (bTitleOpen) { + /* A beginpage is not allowed when in a title */ + /* So start a new paragraph */ + vEndOfParagraphXML(pDiag, UINT_MAX); + vStartOfParagraphXML(pDiag, UINT_MAX); + return; + } + vAddCombinedTag(pDiag, TAG_BEGINPAGE, NULL); +} /* end of vEndOfPageXML */ + +/* + * vCloseHeaderLevels - close the specified header levels + */ +static void +vCloseHeaderLevels(diagram_type *pDiag, USHORT usIstd) +{ + BOOL bNotReady; + UCHAR ucTopTag; + + DBG_MSG("vCloseHeaderLevels"); + DBG_DEC(usIstd); + DBG_DEC(usHeaderLevelCurrent); + + vStackTrace(); + + bNotReady = TRUE; + do { + ucTopTag = ucReadStack(); + switch (ucTopTag) { + case TAG_TITLE: + case TAG_PARA: + vAddEndTag(pDiag, ucTopTag); + break; + default: + bNotReady = FALSE; + break; + } + } while (bNotReady); + + vStackTrace(); + + while (usHeaderLevelCurrent >= usIstd) { + if (bEmptyHeaderLevel) { + vAddCombinedTag(pDiag, TAG_PARA, NULL); + bEmptyHeaderLevel = FALSE; + } + switch (usHeaderLevelCurrent) { + case 1: vAddEndTag(pDiag, TAG_CHAPTER); break; + case 2: vAddEndTag(pDiag, TAG_SECT1); break; + case 3: vAddEndTag(pDiag, TAG_SECT2); break; + case 4: vAddEndTag(pDiag, TAG_SECT3); break; + case 5: vAddEndTag(pDiag, TAG_SECT4); break; + case 6: vAddEndTag(pDiag, TAG_SECT5); break; + default: + DBG_DEC(usHeaderLevelCurrent); + DBG_FIXME(); + return; + } + } + + DBG_DEC(usHeaderLevelCurrent); + + vStackTrace(); +} /* end of vCloseHeaderLevels */ + +/* + * vSetHeadersXML - set the headers + */ +void +vSetHeadersXML(diagram_type *pDiag, USHORT usIstd) +{ + fail(pDiag == NULL); + + if (usIstd == 0 || usIstd > 6) { + DBG_DEC_C(usIstd != 0 && usIstd <= 9, usIstd); + return; + } + DBG_DEC(usIstd); + + if (bTableOpen || uiListLevel != 0) { + /* No headers when you're in a table or in a list */ + return; + } + + /* Close levels */ + vCloseHeaderLevels(pDiag, usIstd); + + DBG_DEC(usHeaderLevelCurrent); + + /* Open levels */ + while (usHeaderLevelCurrent < usIstd) { + switch (usHeaderLevelCurrent) { + case 0: vAddStartTag(pDiag, TAG_CHAPTER, NULL); break; + case 1: vAddStartTag(pDiag, TAG_SECT1, NULL); break; + case 2: vAddStartTag(pDiag, TAG_SECT2, NULL); break; + case 3: vAddStartTag(pDiag, TAG_SECT3, NULL); break; + case 4: vAddStartTag(pDiag, TAG_SECT4, NULL); break; + case 5: vAddStartTag(pDiag, TAG_SECT5, NULL); break; + default: + DBG_DEC(usHeaderLevelCurrent); + DBG_FIXME(); + return; + } + fail(usIstd == 0); + /* The next paragraph should be a title */ + if (usHeaderLevelCurrent < usIstd) { + /* This chapter level is not in the Word document */ + vAddCombinedTag(pDiag, TAG_TITLE, NULL); + } else { + vAddStartTag(pDiag, TAG_TITLE, NULL); + } + } +} /* end of vSetHeadersXML */ + +/* + * Create a start of a list + */ +void +vStartOfListXML(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable) +{ + const char *szAttr; + UCHAR ucTag; + + fail(pDiag == NULL); + + if (bIsEndOfTable) { + /* FIXME: until a list in a table is allowed */ + vEndOfTableXML(pDiag); + } + + if (bTableOpen) { + /* FIXME: a list in a table should be allowed */ + return; + } + + if (usHeaderLevelCurrent == 0) { + /* No list without an open header */ + vAddStartTag(pDiag, TAG_CHAPTER, NULL); + /* Dummy title */ + vAddCombinedTag(pDiag, TAG_TITLE, NULL); + } + + switch (ucNFC) { + case LIST_ARABIC_NUM: + case LIST_ORDINAL_NUM: + case LIST_NUMBER_TXT: + case LIST_ORDINAL_TXT: + case LIST_OUTLINE_NUM: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='arabic'"; + break; + case LIST_UPPER_ROMAN: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='upperroman'"; + break; + case LIST_LOWER_ROMAN: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='lowerroman'"; + break; + case LIST_UPPER_ALPHA: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='upperalpha'"; + break; + case LIST_LOWER_ALPHA: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='loweralpha'"; + break; + case LIST_SPECIAL: + case LIST_SPECIAL2: + case LIST_BULLETS: + ucTag = TAG_ITEMIZEDLIST; + szAttr = "mark='bullet'"; + break; + default: + ucTag = TAG_ORDEREDLIST; + szAttr = "numeration='arabic'"; + DBG_HEX(ucNFC); + DBG_FIXME(); + break; + } + vAddStartTag(pDiag, ucTag, szAttr); +} /* end of vStartOfListXML */ + +/* + * Create an end of a list + */ +void +vEndOfListXML(diagram_type *pDiag) +{ + fail(pDiag == NULL); + + if (bTableOpen) { + /* FIXME: a list in a table should be allowed */ + return; + } + + if (uiListLevel != 0) { + vStackTrace(); + vAddEndTagsUntil2(pDiag, TAG_ITEMIZEDLIST, TAG_ORDEREDLIST); + vStackTrace(); + } +} /* end of vEndOfListXML */ + +/* + * Create a start of a list item + */ +void +vStartOfListItemXML(diagram_type *pDiag, BOOL bNoMarks) +{ + const char *szAttr; + UCHAR ucTopTag; + + fail(pDiag == NULL); + + if (bTableOpen) { + /* FIXME: a list in a table should be allowed */ + return; + } + + ucTopTag = ucReadStack(); + if (ucTopTag != TAG_ITEMIZEDLIST && ucTopTag != TAG_ORDEREDLIST) { + /* Must end a previous list item first */ + vAddEndTagsUntil1(pDiag, TAG_LISTITEM); + } + + DBG_DEC_C(ucReadStack() != TAG_ITEMIZEDLIST && + ucReadStack() != TAG_ORDEREDLIST, ucReadStack()); + + /* Start a new list item */ + szAttr = bNoMarks ? "override='none'" : NULL; + vAddStartTag(pDiag, TAG_LISTITEM, szAttr); + /* Start a new paragraph (independant of level) */ + vAddStartTag(pDiag, TAG_PARA, NULL); +} /* end of vStartOfListItemXML */ + +/* + * Create a start of a table + */ +static void +vStartOfTable(diagram_type *pDiag, UCHAR ucBorderInfo) +{ + const char *szFrame; + BOOL bNotReady; + UCHAR ucTopTag; + char cColSep, cRowSep; + char szAttr[40]; + + fail(pDiag == NULL); + + /* Close elements that cannot contain a table */ + bNotReady = TRUE; + do { + ucTopTag = ucReadStack(); + switch (ucTopTag) { + case TAG_TITLE: + fail(!bTitleOpen); + vAddEndTag(pDiag, TAG_TITLE); + break; + case TAG_EMPHASIS: + fail(!bEmphasisOpen); + vAddEndTag(pDiag, TAG_EMPHASIS); + break; + case TAG_SUPERSCRIPT: + fail(!bSuperscriptOpen); + vAddEndTag(pDiag, TAG_SUPERSCRIPT); + break; + case TAG_SUBSCRIPT: + fail(!bSubscriptOpen); + vAddEndTag(pDiag, TAG_SUBSCRIPT); + break; + default: + bNotReady = FALSE; + break; + } + } while (bNotReady); + + /* Create table attributes */ + switch (ucBorderInfo) { + case TABLE_BORDER_TOP: + szFrame = "top"; + break; + case TABLE_BORDER_LEFT|TABLE_BORDER_RIGHT: + szFrame = "sides"; + break; + case TABLE_BORDER_TOP|TABLE_BORDER_BOTTOM: + szFrame = "topbot"; + break; + case TABLE_BORDER_BOTTOM: + szFrame = "bottom"; + break; + case TABLE_BORDER_TOP|TABLE_BORDER_LEFT| + TABLE_BORDER_BOTTOM|TABLE_BORDER_RIGHT: + szFrame = "all"; + break; + default: + szFrame = "none"; + break; + } + cColSep = bIsTableBorderLeft(ucBorderInfo) || + bIsTableBorderRight(ucBorderInfo) ? '1' : '0'; + cRowSep = bIsTableBorderTop(ucBorderInfo) || + bIsTableBorderBottom(ucBorderInfo) ? '1' : '0'; + + sprintf(szAttr, "frame='%.6s' colsep='%c' rowsep='%c'", + szFrame, cColSep, cRowSep); + + if (usHeaderLevelCurrent == 0) { + /* No table without an open header */ + vAddStartTag(pDiag, TAG_CHAPTER, NULL); + /* Dummy title */ + vAddCombinedTag(pDiag, TAG_TITLE, NULL); + } + vAddStartTag(pDiag, TAG_INFORMALTABLE, szAttr); +} /* end of vStartOfTable */ + +/* + * Create a start of a table group + */ +static void +vStartOfTableGroup(diagram_type *pDiag, + int iNbrOfColumns, const short *asColumnWidth) +{ + double dWidth; + int iIndex; + char szCols[6 + 3 * sizeof(int) + 1 + 1]; + char szColWidth[10 + 3 * sizeof(short) + 3 + 3 + 1]; + + fail(iNbrOfColumns < 1); + fail(asColumnWidth == NULL); + + sprintf(szCols, "cols='%d'", iNbrOfColumns); + vAddStartTag(pDiag, TAG_TGROUP, szCols); + + for (iIndex= 0; iIndex < iNbrOfColumns; iIndex++) { + fail(asColumnWidth[iIndex] < 0); + dWidth = dTwips2Points(asColumnWidth[iIndex]); + if (dWidth <= 1.0) { + strcpy(szColWidth, "colwidth='1.00pt'"); + } else { + sprintf(szColWidth, "colwidth='%.2fpt'", dWidth); + } + vAddCombinedTag(pDiag, TAG_COLSPEC, szColWidth); + } +} /* end of vStartOfTableGroup */ + +/* + * Create an end of a table + */ +void +vEndOfTableXML(diagram_type *pDiag) +{ + fail(pDiag == NULL); + + if (bTableOpen) { + vAddEndTag(pDiag, TAG_TBODY); + vAddEndTag(pDiag, TAG_TGROUP); + vAddEndTag(pDiag, TAG_INFORMALTABLE); + } +} /* end of vEndOfTableXML */ + +/* + * Add a table row + */ +void +vAddTableRowXML(diagram_type *pDiag, char **aszColTxt, + int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo) +{ + size_t tCount, tStringLength; + int iIndex; + + fail(pDiag == NULL); + fail(pDiag->pOutFile == NULL); + fail(aszColTxt == NULL); + fail(iNbrOfColumns < 1); + fail(asColumnWidth == NULL); + + if (iNbrOfColumns != iTableColumnsCurrent) { + /* A new number of columns */ + /* End the old table body and table group (if they exist) */ + vAddEndTagOptional(pDiag, TAG_TBODY); + vAddEndTagOptional(pDiag, TAG_TGROUP); + if (!bTableOpen) { + /* No table yet. Start a new table */ + vStartOfTable(pDiag, ucBorderInfo); + } + /* Start a new table group and a new table body */ + vStartOfTableGroup(pDiag, iNbrOfColumns, asColumnWidth); + vAddStartTag(pDiag, TAG_TBODY, NULL); + iTableColumnsCurrent = iNbrOfColumns; + } + + /* Add the table row */ + vAddStartTag(pDiag, TAG_ROW, NULL); + for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { + /* Add a table cell */ + fail(aszColTxt[iIndex] == NULL); + vAddStartTag(pDiag, TAG_ENTRY, NULL); + tStringLength = strlen(aszColTxt[iIndex]); + for (tCount = 0; tCount < tStringLength; tCount++) { + vPrintChar(pDiag, aszColTxt[iIndex][tCount]); + } + vAddEndTag(pDiag, TAG_ENTRY); + } + vAddEndTag(pDiag, TAG_ROW); +} /* end of vAddTableRowXML */