commit 71f6baaafaba8880aca9d7aeaa6ca3d28945f649 Author: simon987 <me@simon987.net> Date: Thu Nov 12 16:52:36 2020 -0500 antiword 0.37 original source 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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. + + <signature of Ty Coon>, 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 <tril@igs.net> (and others) fixed +New features: +- XML/DocBook output now contains <footnote> 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 <s.wi@gmx.net> + +Changes 0.35 to 0.36 +-------------------- +Bug fixes: +- Bug reported by Michael Minn <mail@michaelminn.com> 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 <ofir@qlusters.com> +- Improved table parsing. Based on information supplied by Bastien Legras + <bastien.legras@nectech.fr> and Alex de Kruijff <freebsd@akruijff.dds.nl> +- 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 <isle@free.kursknet.ru> +- 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 <old_coaster@yahoo.co.uk> (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 <sg@janus.freeserve.co.uk> fixed +- Bug reported by Karl-Otto Linn <linn@informatik.fh-wiesbaden.de> 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 + <sbellon@sbellon.de> (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 <yperret@bat710.univ-lyon1.fr> 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 + <arb@anand.org>. +- Antiword now turns white text into light gray text. +- Antiword is now closer to "64-bit clean". Based on information supplied by + Duncan Haldane <f.duncan.m.haldane@worldnet.att.net>. + +Changes 0.31 to 0.32 +-------------------- +Bug fixes: +- Bug reported by Forrest J. Cavalier III <mibsoft@mibsoftware.com> fixed +- Bug reported by Jan ONDREJ (SAL) <ondrejj@salstar.sk> 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 <mattdm@mattdm.org>. (Unix only) +- A white background looks much better. (RISC OS only) +- A system-wide directory for the mapping files, as suggested by Sven Geggus + <sven@geggus.net> 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 <aspinwall@timesten.com> fixed +- Bug reported by Robert Steinmetz <rob@steinmetznet.com> 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 <Greg.Robinson@dsto.defence.gov.au> +- 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 + <Jens.Schleusener@dlr.de>. +- 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 <kbamford@eurobell.co.uk> 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 <david@davidkanareck.demon.co.uk>, 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 <P.J.McCann@cfm1220.x400.icl.co.uk> fixed +- Character property "SmallCaps" works better now +- Bug reported by Richard Lambley <richard@wireless.demon.co.uk> 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 <richard@wireless.demon.co.uk> 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 <alex@emacswiki.org> +Subject: Re: MS Word mode? +Date: Fri, 08 Nov 2002 00:40:15 +0100 + +Roger Mason <rmason@sparky2.esd.mun.ca> 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 <am@ime.usp.br> +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 <alex@emacswiki.org> +Subject: Re: MS Word mode? +Date: Fri, 08 Nov 2002 18:24:07 +0100 + +Arnaldo Mandel <am@ime.usp.br> 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 <Benjamin.Riefenstahl@epost.de> +Subject: Re: emacs rmail. How to convert .doc to plain text +Date: 24 Nov 2002 18:08:22 +0100 + +Hi, + +Puff Addison <puff@theaddisons.demon.co.uk> 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 <glenn@vtecus.com> +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 <camilo@mesias.co.uk> +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 <bobzim@no.spam.org> 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" <Craig.D.Miller@jpl.nasa.gov> + +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" <Craig.D.Miller@jpl.nasa.gov> + +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 <bruno.crochet@pse.unige.ch> + +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 <azarate@saincotrafico.com> + +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 <epinter@ptcs.ch> + +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 <vitus@agropc.msk.su> creator of "catdoc" +Duncan Simpson <word2x@duncan.telstar.net> creator of "word2x" +Martin Schwartz <schwartz@cs.tu-berlin.de> creator of "laola" and "elser" +Caolan McNamara <Caolan.McNamara@ul.ie> creator of "mswordview" +Andrew Scriven <andy.scriven@research.natpower.co.uk> creator of "OLEdecode" +Craig Southeren <geoffw@extro.ucc.oz.au> creator of "nenscript" +Thomas Merz <tm@muc.de> creator of "jpeg2ps" +Ulrich von Zadow <uzadow@cs.tu-berlin.de> creator of "paintlib" + + +Contributors +------------ + +ISO-8859-2 support by: Pawel Turnau <uzturnau@cyf-kr.edu.pl> +Character set mapping by: Dmitry Chernyak + <Dmitry.Chernyak@p998.f983.n5030.z2.fidonet.org> +UTF-8 support by: Karl Koehler <koehler@or.uni-bonn.de> and + Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> +PostScript Cyrillic by: Alexander Belyaev <isle@free.kursknet.ru> + + +Ports +----- + +Antiword was ported to BeOS by Pete Goodeve <pete@jwgibbs.cchem.berkeley.edu> +Antiword was ported to OS/2 by Dave Yeo <dave_yeo@paralynx.com> +Antiword was ported to Mac OS X by Ronaldo Nascimento <ronaldo@ronaldo.com> +Antiword was ported to Amiga by Raffaele Pisapia <rafpis@libero.it> +Antiword was ported to VMS by Joseph Huber <huber@mppmu.mpg.de> +Antiword was ported to NetWare by Guenter Knauf <info@gknw.de> +Antiword was ported to EPOC by Max Tomin <tomin@samaramail.ru> +Antiword was ported to Zaurus PDA by Piotr Jachimczyk + <P.Jachimczyk@prioris.mini.pw.edu.pl> +Antiword was ported to DOS by myself ;-) +Yen-Ming Lee <leeym@freebsd.org> 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 <antiword@winfield.demon.nl> +.br +or try <comments@antiword.cjb.net> +.sp +R.F. Smith <rsmith@xs4all.nl> and +.br +Sindi Keesan <keesan@cyberspace.org> +.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 <antiword@winfield.demon.nl> + or try <comments@antiword.cjb.net> + + R.F. Smith <rsmith@xs4all.nl> and + Sindi Keesan <keesan@cyberspace.org> + 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 <pauls@etext.org> +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.php + A PHP script to convert uploaded MS Word docs to text using antiword. + This script is public domain, no copyright. + September 11, 2002 + Paul Southworth +*/ +function print_form() { +?> +<html><head><title>antiword</title></head><body> +<form method=post action=antiword.php enctype="multipart/form-data"> +<input name=upload type=file> +<input type=submit name=submit value=convert> +</form> +</body></html> +<? +} +if ($_FILES['upload']) { + header ("Content-type: text/plain"); + system("/usr/local/bin/antiword " . $_FILES['upload']['tmp_name']); +} else { + print_form(); +} +?> 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 @@ +| <?php +/* +(C) 2005 Vidar L�kken <vidarlo@vestdata.no> + +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 "<pre>"; + $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 "<pre>"; + $safe=escapeshellcmd($docfile); + $command="antiword $output /tmp/$safe"; + passthru($command); +@@ unlink("/tmp/$docfile"); + } + } +} +if (!isset($_FILES['userfile']['name'])) { + ?> +<p> + 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 <a +href=http://antiword.cjb.net>antiword.cjb.net</a> for more information +about antiword. Currently, max file size is 3MiB for the upload. This +should be enough! +</p><p>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.</p> +</p> +<form enctype="multipart/form-data" action="antiword.php" method="post"> + <input type="hidden" name="MAX_FILE_SIZE" value="30000" /> + URL:<br /><input type="text" name="url" size=50 /><br /> + Send this file:<br /> <input name="userfile" type="file"/> + <br />Output: <br /> + <SELECT name="output"> + <OPTGROUP> + <OPTION name=txt>InLine</OPTION> + <OPTION name=ps>PostScript</OPTION> + <OPTION name=PDF>PDF</OPTION> + </OPTGROUP> + </SELECT> +Papersize: <SELECT name="paper"/> +<OPTGROUP> +<OPTION>a4</OPTION> +<OPTION>a3</OPTION> +<OPTION>a5</OPTION> +<OPTION>b4</OPTION> +<OPTION>b5</OPTION> +<OPTION>10x14</OPTION> +<OPTION>executive</OPTION> +<OPTION>folio</OPTION> +<OPTION>legal</OPTION> +<OPTION>letter</OPTION> +<OPTION>note</OPTION> +<OPTION>quarto</OPTION> +<OPTION>statement</OPTION> +<OPTION>tabloid</OPTION> +</select> +<br /> + <input type="submit" value="Send File" /> + </form> +<p>This is running <a href="http://antiword.cjb.net">antiword</a> 0.36. <br> + Please drop me a note at antiword (at) bitsex.net if you have +comments for this. +<hr> +<font size=-1>(C)Vidar Løkken 2005</font> +<!-- Version: 0.2 as of 19. oct. 2005 --> +<?php +} +?> +| diff --git a/Docs/testdoc.doc b/Docs/testdoc.doc new file mode 100644 index 0000000..3f78d77 Binary files /dev/null and b/Docs/testdoc.doc differ 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<n> 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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <mkuhn@acm.org> +# Ken Whistler <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <mkuhn@acm.org> +# Ken Whistler <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <mkuhn@acm.org> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0081 # <control> +0x82 0x0082 # <control> +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0085 # <control> +0x86 0x0086 # <control> +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +0x8C 0x008C # <control> +0x8D 0x008D # <control> +0x8E 0x008E # <control> +0x8F 0x008F # <control> +0x90 0x0090 # <control> +0x91 0x0091 # <control> +0x92 0x0092 # <control> +0x93 0x0093 # <control> +0x94 0x0094 # <control> +0x95 0x0095 # <control> +0x96 0x0096 # <control> +0x97 0x0097 # <control> +0x98 0x0098 # <control> +0x99 0x0099 # <control> +0x9A 0x009A # <control> +0x9B 0x009B # <control> +0x9C 0x009C # <control> +0x9D 0x009D # <control> +0x9E 0x009E # <control> +0x9F 0x009F # <control> +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<b2>. +# 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<b2>, ufrm<b2>, and Text +# Encoding Converter version 1.5. +# n05 1998-Feb-05 Update header comments to new format; no +# mapping changes. Matches internal utom<n3>, +# ufrm<n13>, and Text Encoding Converter +# version 1.3. +# n03 1995-Apr-15 First version (after fixing some typos). +# Matches internal ufrm<n5>. +# +# 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: +# +# <http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/> +# +# 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<b5>. +# b03 1999-Sep-22 Update contact e-mail address. Matches +# internal utom<b4>, ufrm<b3>, 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<b3>, +# ufrm<b3>. +# 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<n3>, ufrm<n22>: +# 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<n9>. +# +# 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: +# +# <http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/> +# +# 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 <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0174 # CAPITAL W CIRCUMFLEX ACCENT +0x82 0x0175 # SMALL W CIRCUMFLEX ACCENT +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0176 # CAPITAL Y CIRCUMFLEX ACCENT +0x86 0x0177 # SMALL Y CIRCUMFLEX ACCENT +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +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 <mkuhn@acm.org> +# Ken Whistler <kenw@sybase.com> +# +# 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: +# <ftp://ftp.unicode.org/Public/MAPPINGS/> +# +# Any comments or problems, contact <errata@unicode.org> +# Please note that <errata@unicode.org> 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 # <control> +0x81 0x0174 # CAPITAL W CIRCUMFLEX ACCENT +0x82 0x0175 # SMALL W CIRCUMFLEX ACCENT +0x83 0x0083 # <control> +0x84 0x0084 # <control> +0x85 0x0176 # CAPITAL Y CIRCUMFLEX ACCENT +0x86 0x0177 # SMALL Y CIRCUMFLEX ACCENT +0x87 0x0087 # <control> +0x88 0x0088 # <control> +0x89 0x0089 # <control> +0x8A 0x008A # <control> +0x8B 0x008B # <control> +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 # <control> +0x9B 0x009B # <control> +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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# 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 <cdl@inkasbank.ru> +# +# 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 <richter@lrz.de> +# +# 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 <errata@unicode.org> +# Please note that <errata@unicode.org> 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 <arysin@yahoo.com> +# +# 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 <errata@unicode.org> +# Please note that <errata@unicode.org> 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<b4>, ufrm<b3>, 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<b3>, # ufrm<b3>. # 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<n3>, ufrm<n22>: # 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<n9>. # # 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: # # <ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/> # <ftp://dev.apple.com/devworld/Technical_Documentation/Misc._Standards/> # # 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 0000000..ff4f921 Binary files /dev/null and b/Unix-only/KDE3-only/hi32-app-antiword.png differ 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 0000000..c0900de Binary files /dev/null and b/Unix-only/KDE3-only/hi48-app-antiword.png differ diff --git a/Unix-only/KDE3-only/kantiword.sh b/Unix-only/KDE3-only/kantiword.sh new file mode 100644 index 0000000..40e6637 --- /dev/null +++ b/Unix-only/KDE3-only/kantiword.sh @@ -0,0 +1,71 @@ +#!/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 + +# Try to create the temp files in a secure way +if [ -x /bin/tempfile ] +then + out_file=`/bin/tempfile -d "$tmp_dir" -p antiword -s ".ps"` || exit 1 + err_file=`/bin/tempfile -d "$tmp_dir" -p antiword -s ".err"` + if [ $? -ne 0 ] + then + rm -f "$out_file" + exit 1 + fi +elif [ -x /bin/mktemp ] +then + out_file=`/bin/mktemp -q -p "$tmp_dir" antiword.ps.XXXXXXXXX` || exit 1 + err_file=`/bin/mktemp -q -p "$tmp_dir" antiword.err.XXXXXXXXX` + if [ $? -ne 0 ] + then + rm -f "$out_file" + exit 1 + fi +else + # Creating the temp files in an un-secure way + out_file=$tmp_dir"/antiword.$$.ps" + err_file=$tmp_dir"/antiword.$$.err" +fi + +# 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 + # 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 0000000..d26d00d Binary files /dev/null and b/Unix-only/KDE3-only/lo16-app-antiword.png differ diff --git a/Unix-only/KDE3-only/lo32-app-antiword.png b/Unix-only/KDE3-only/lo32-app-antiword.png new file mode 100644 index 0000000..299ce9f Binary files /dev/null and b/Unix-only/KDE3-only/lo32-app-antiword.png differ diff --git a/Unix-only/RPM-only/antiword.spec b/Unix-only/RPM-only/antiword.spec new file mode 100644 index 0000000..3f14697 --- /dev/null +++ b/Unix-only/RPM-only/antiword.spec @@ -0,0 +1,49 @@ + +%define version 0.33 +%define release 1 +%define name antiword + +Summary: an application to display Microsoft(R) Word files. +Name: %{name} +Version: %{version} +Release: %{release} +License: GPL +Group: Applications/Text +Source: http://www.winfield.demon.nl/linux/%{name}-%{version}.tar.gz +URL: http://www.winfield.demon.nl/index.html +BuildRoot: /var/tmp/%{name}-%{version} +Packager: marco antonio cabazal <nightshiphter@yahoo.com> + +%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 (<F_IN>) { + 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 <stdio.h> +#include <limits.h> +#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 <sys/types.h> +#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 <stdio.h> +#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 <stdlib.h> +#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 <stdlib.h> +#include <string.h> +#include <ctype.h> +#if defined(__STDC_ISO_10646__) +#include <wctype.h> +#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 <stdlib.h> +#include <errno.h> +#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 <stdio.h> +#include <ctype.h> + +#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 <stdio.h> +#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 <stdio.h> +#include <string.h> +#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, "<Wimp$ScrapDir>.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 <stdlib.h> +#include <ctype.h> +#include <string.h> +#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 <string.h> +#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 <stdlib.h> +#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 <stdio.h> +#include <stdlib.h> +#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 <stdio.h> +#include <stdlib.h> +#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 <ofir@qlusters.com> + * + * The credit should go to him, but all the bugs are mine. + */ + +#include <string.h> +#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 <stdlib.h> +#include <stddef.h> +#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 <ctype.h> +#include <string.h> +#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 <stdlib.h> +#include <string.h> +#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("<AntiWord$FontNamesFile>", "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("<AntiWord$Dir>.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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#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 <string.h> +#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 <string.h> +#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 <stdio.h> +#include <string.h> +#include <ctype.h> +#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 <stdio.h> +#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 <stdio.h> +#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 <stdio.h> +#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, "<Wimp$ScrapDir>.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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#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 <stdio.h> +#include <stdlib.h> +#if defined(__dos) +#include <fcntl.h> +#include <io.h> +#endif /* __dos */ +#if defined(__CYGWIN__) || defined(__CYGMING__) +# ifdef X_LOCALE +# include <X11/Xlocale.h> +# else +# include <locale.h> +# endif +#else +#include <locale.h> +#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 <paper size name> Adobe PDF output\n"); + fprintf(stderr, "\t\t-p <paper size name> PostScript output\n"); + fprintf(stderr, "\t\t paper size like: a4, letter or legal\n"); + fprintf(stderr, "\t\t-x <dtd> XML output\n"); + fprintf(stderr, "\t\t like: db (DocBook)\n"); + fprintf(stderr, "\t\t-m <mapping> character mapping file\n"); + fprintf(stderr, "\t\t-w <width> in characters of text output\n"); + fprintf(stderr, "\t\t-i <level> 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, + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<!DOCTYPE %s PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\"\n" + "\t\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n", + bMultiple ? "set" : "book"); + if (bMultiple) { + fprintf(stdout, "<set>\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, "</set>\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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#if defined(__riscos) +#include "DeskLib:SWI.h" +#else +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#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 <unixlib.h> +#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 @@ +</$objtype/mkfile + +TARG=antiword + +CFLAGS=-Bp -I/sys/include/ape -I/$objtype/include/ape -DNDEBUG -D_POSIX_SOURCE -D__Plan9__ + +TARG=antiword +OFILES= main_u.$O asc85enc.$O blocklist.$O chartrans.$O datalist.$O depot.$O\ + dib2eps.$O fail.$O finddata.$O findtext.$O fmt_text.$O fontlist.$O\ + fonts.$O fonts_u.$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 + +HFILES=antiword.h debug.h draw.h fail.h fontinfo.h version.h wordconst.h wordtypes.h + +BIN=/$objtype/bin/aux + +</sys/src/cmd/mkone + +main_u.$O: version.h +postscript.$O: version.h +pdf.$O: version.h +fonts_u.$O: fontinfo.h + +# fontinfo.h: Unix-fontinfo.pl +# fontinfo.pl > 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(__riscos) +#include "DeskLib:Error.h" +#include "DeskLib:Wimp.h" +#else +#include <stdlib.h> +#if defined(__dos) || defined(N_PLAT_NLM) +extern int getopt(int, char **, const char *); +#else +#include <unistd.h> +#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("<AntiWord$ChoicesFile>", "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 = "<AntiWord$Latin1>"; + break; + case 112: /* ISO-8859-15 aka Latin9 */ + szAlphabet = "<AntiWord$Latin9>"; + 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 <string.h> +#include <stdlib.h> +#include <ctype.h> +#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 <stdarg.h> +#include <string.h> +#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 <stdlib.h> +#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 <stdio.h> +#include <ctype.h> +#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 <stdio.h> +#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 <stdlib.h> +#include <errno.h> +#include <time.h> +#include <string.h> +#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 <string.h> +#include <time.h> +#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 <string.h> +#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 <stdlib.h> +#include <string.h> +#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 <stdlib.h> +#include <string.h> +#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 <stdlib.h> +#include <string.h> +#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 <stdio.h> +#include <string.h> +#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 <string.h> +#include <stdlib.h> +#include <stdarg.h> +#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 <stdlib.h> +#include <string.h> +#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 <stdio.h> +#include <string.h> +#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 <stddef.h> +#include <string.h> +#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 <stdlib.h> +#include <string.h> +#include <ctype.h> +#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$Dir>.!Antiword"); + if (argc > 1) { + strcat(szCommand, " "); + strcat(szCommand, argv[1]); + } +#if defined(DEBUG) + strcat(szCommand, " "); + strcat(szCommand, "2><Antiword$Dir>.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 <stdlib.h> +#include <stddef.h> +#include <ctype.h> +#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 <string.h> +#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 <time.h> +#include <string.h> +#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 <stdio.h> +#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 <string.h> +#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 <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#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" + * <http://www.UNIX-systems.org/online.html> + * Markus Kuhn -- 2001-01-12 -- public domain + *==================================================================== + * The credit should go to him, but all the bugs are mine. + */ + +#include <stdlib.h> +#include <string.h> +#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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#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 <string.h> +#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 <time.h> +#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 <stdlib.h> +#include <string.h> +#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 <string.h> +#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, "</%s>", 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 <BR> 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 */