diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-1.6')
179 files changed, 31868 insertions, 0 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/AUTHORS b/Build/source/texk/dvisvgm/dvisvgm-1.6/AUTHORS new file mode 100644 index 00000000000..d9b6468421e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/AUTHORS @@ -0,0 +1,7 @@ +Martin Gieseking <martin.gieseking@uos.de> + author of dvisvgm + +Deepak Bandyopadhyay, Lutz Kettner + authors of gzstream library + dvisvgm uses a slightly modified version + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/COPYING b/Build/source/texk/dvisvgm/dvisvgm-1.6/COPYING new file mode 100644 index 00000000000..94a9ed024d3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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) <year> <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 3 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, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-1.6/ChangeLog new file mode 100644 index 00000000000..67663e1a0d7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/ChangeLog @@ -0,0 +1,3666 @@ +2014-04-22 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + set version to 1.6 + +2014-04-21 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/DVIToSVG.cpp, src/EPSToSVG.cpp: + removed date and machine triplet from generated SVG files + +2014-04-18 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/HtmlSpecialHandler.cpp, + src/HtmlSpecialHandler.h: + added optional selection of line/box colors to option --linkmark + +2014-04-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/options.xml: + changed default argument of option --linkmark to 'box' + + * src/DVIReader.h, src/DVIToSVGActions.h, src/HtmlSpecialHandler.cpp, + src/HtmlSpecialHandler.h, src/SpecialActions.h: + only split hyperlink boxes on line breaks + + * src/CommandLine.h, src/DVIToSVG.cpp, src/EPSToSVG.cpp: + don't link GS messages unnecessarily if HAVE_LIBGS is defined + +2014-04-16 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/SVGTree.cpp, src/SVGTree.h, src/dvisvgm.cpp, src/options.xml: + added command-line option --zoom + + * src/Ghostscript.cpp, src/dvisvgm.cpp: + moved lookup of MiKTeX's GS DLL to get_libgs() + + * doc/dvisvgm.txt.in, src/Ghostscript.cpp: + if libgs is loaded during runtime, look for libgs.so.X instead of + libgs.so + + * src/DLLoader.cpp: + prevent calling dlopen() if the length of the string argument is 0 + +2014-04-11 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.5.3 + + * src/CMap.cpp, src/CmdLineParserBase.cpp, src/ColorSpecialHandler.cpp, + src/DVIReader.cpp, src/DVIToSVGActions.cpp, src/Doxyfile, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EPSFile.cpp, src/EmSpecialHandler.cpp, src/FileFinder.cpp, + src/FileSystem.cpp, src/Font.cpp, src/FontCache.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontMap.cpp, src/GraphicPath.h, + src/PSInterpreter.cpp, src/PageRanges.cpp, src/PsSpecialHandler.cpp, + src/SVGTree.cpp, src/SVGTree.h, src/SpecialManager.cpp, src/Subfont.cpp, + src/TFM.cpp, src/TpicSpecialHandler.cpp, src/XMLDocument.cpp, + src/XMLNode.cpp, src/dvisvgm.cpp: + fixed issues in the doxygen documentation + +2014-04-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.h, src/DVIActions.cpp, src/DVIActions.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/DvisvgmSpecialHandler.cpp, src/EPSToSVG.cpp, + src/EmSpecialHandler.cpp, src/Font.h, src/FontManager.cpp, + src/GFGlyphTracer.cpp, src/GFReader.cpp, src/GFTracer.cpp, + src/GFTracer.h, src/GraphicPath.h, src/HtmlSpecialHandler.h, + src/Makefile.am, src/PSPattern.cpp, src/PSPreviewFilter.cpp, + src/PSPreviewFilter.h, src/PageSize.cpp, src/PageSize.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SVGTree.cpp, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/TFM.cpp, src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h, + src/VFReader.cpp: + switched internal computations from TeX points (pt) to PS points (bp) + + * src/DVIToSVGActions.cpp: + equalize implementations of moveToX and moveToY + +2014-02-05 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/DVIReader.h: + ensure updating the SVG cursor position when executing DVI command + set_rule + +2014-01-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/Ghostscript.cpp: + check if library given by --libgs is actually a GS library + +2014-01-10 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + +2014-01-03 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + set version to 1.5.2 + + * src/FileFinder.cpp: + return 'unknown' if MiKTeX version can't be retrieved + + * src/Directory.cpp: + initialize Directory member variables (Win only) + + * src/FileFinder.cpp: + catch exceptions thrown by MiKTeXCom object + +2014-01-02 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, README, configure.ac, doc/Makefile.am, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/CMap.cpp, src/CMap.h, src/CMapManager.cpp, src/CMapManager.h, + src/CMapReader.cpp, src/CMapReader.h, src/CRC32.cpp, src/CRC32.h, + src/Calculator.cpp, src/Calculator.h, src/CharMap.cpp, src/CharMap.h, + src/CharMapID.cpp, src/CharMapID.h, src/Character.h, + src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/Color.cpp, + src/Color.h, src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/CommandLine.cpp, src/CommandLine.h, src/DLLoader.cpp, src/DLLoader.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EPSFile.cpp, src/EPSFile.h, src/EPSToSVG.cpp, src/EPSToSVG.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/EncFile.cpp, + src/EncFile.h, src/FileFinder.cpp, src/FileFinder.h, src/FilePath.cpp, + src/FilePath.h, src/FileSystem.cpp, src/FileSystem.h, src/Font.cpp, + src/Font.h, src/FontCache.cpp, src/FontCache.h, src/FontEncoding.cpp, + src/FontEncoding.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontManager.cpp, src/FontManager.h, src/FontMap.cpp, src/FontMap.h, + src/FontMetrics.cpp, src/FontMetrics.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, src/Glyph.h, + src/GlyphTracerMessages.h, src/GraphicPath.h, src/HtmlSpecialHandler.cpp, + src/HtmlSpecialHandler.h, src/InputBuffer.cpp, src/InputBuffer.h, + src/InputReader.cpp, src/InputReader.h, src/JFM.cpp, src/JFM.h, + src/Length.cpp, src/Length.h, src/Makefile.am, src/Makefile.old, + src/MapLine.cpp, src/MapLine.h, src/Matrix.cpp, src/Matrix.h, + src/Message.cpp, src/Message.h, src/MessageException.h, + src/MetafontWrapper.cpp, src/MetafontWrapper.h, src/MiKTeXCom.cpp, + src/MiKTeXCom.h, src/NoPsSpecialHandler.cpp, src/NoPsSpecialHandler.h, + src/PSFilter.h, src/PSInterpreter.cpp, src/PSInterpreter.h, + src/PSPattern.cpp, src/PSPattern.h, src/PSPreviewFilter.cpp, + src/PSPreviewFilter.h, src/PageRanges.cpp, src/PageRanges.h, + src/PageSize.cpp, src/PageSize.h, src/Pair.h, src/PdfSpecialHandler.cpp, + src/PdfSpecialHandler.h, src/Process.cpp, src/Process.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SVGOutputBase.h, + src/SVGTree.cpp, src/SVGTree.h, src/SWFWriter.cpp, src/SWFWriter.h, + src/SignalHandler.cpp, src/SignalHandler.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/StreamReader.cpp, src/StreamReader.h, src/StreamWriter.cpp, + src/StreamWriter.h, src/Subfont.cpp, src/Subfont.h, src/System.cpp, + src/System.h, src/TFM.cpp, src/TFM.h, src/Terminal.cpp, src/Terminal.h, + src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h, src/VFActions.h, + src/VFReader.cpp, src/VFReader.h, src/VectorStream.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/macros.h, + src/options.dtd, src/options.xml, src/psdefs.cpp, src/psdefs.ps, + src/types.h, tests/BoundingBoxTest.cpp, tests/CMapReaderTest.cpp, + tests/CMapTest.cpp, tests/CRC32Test.cpp, tests/CalculatorTest.cpp, + tests/ColorSpecialTest.cpp, tests/ColorTest.cpp, + tests/CommandLineTest.cpp, tests/DirectoryTest.cpp, + tests/FileFinderTest.cpp, tests/FilePathTest.cpp, + tests/FileSystemTest.cpp, tests/FontManagerTest.cpp, + tests/FontMapTest.cpp, tests/GFReaderTest.cpp, tests/GraphicPathTest.cpp, + tests/LengthTest.cpp, tests/Makefile.am, tests/MapLineTest.cpp, + tests/MatrixTest.cpp, tests/MessageExceptionTest.cpp, + tests/PSInterpreterTest.cpp, tests/PageRagesTest.cpp, + tests/PageSizeTest.cpp, tests/PairTest.cpp, + tests/SplittedCharInputBufferTest.cpp, tests/StreamInputBufferTest.cpp, + tests/StreamReaderTest.cpp, tests/StreamWriterTest.cpp, + tests/SubfontTest.cpp, tests/TypesTest.cpp, tests/VectorStreamTest.cpp, + tests/check-conv, tests/create-makefile, tests/normalize.xsl: + updated year in copyright statements to 2014 + +2013-12-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp: + catch potential StreamReaderException + + * src/Directory.cpp, src/Directory.h, src/FontMap.cpp, + tests/DirectoryTest.cpp: + changed directory entry types from char to enums + + * src/Font.cpp: + check if units per EM are not 0 to prevent divisions by zero + +2013-12-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/Directory.cpp, src/GFReader.cpp: + added missing initializations of member variables + + * src/FontCache.cpp, src/SpecialManager.cpp: + restore stream format flags + + * src/DvisvgmSpecialHandler.cpp, src/FontCache.cpp: + ensure null pointer checks before dereferencing + + * src/DVIReader.cpp: + check if denominator of DVI unit is non-zero + + * src/Matrix.cpp: + ensure return value of istream::get() is assigned to int vars + + * src/FontCache.cpp: + avoid accessing strings constructed from temporaries + + * src/BoundingBox.cpp: + explicitely initialize BoundingBox fields + +2013-11-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/SVGTree.cpp, src/SVGTree.h: + don't let global font colors interfere with color specials + +2013-10-29 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + +2013-10-28 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + set version to 1.5.1 + + * src/DVIReader.cpp: + temporarily reactivated processing of font definitions located in the + postamble + + * src/FileSystem.cpp, src/MetafontWrapper.cpp: + added explicit casts from ifstream to bool + + * src/Bitmap.cpp, src/Color.cpp, src/JFM.cpp, src/Matrix.cpp: + added missing #includes of header file <algorithm> + +2013-10-27 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + suppress output of logical page number if it equals physical page number + +2013-10-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSPreviewFilter.cpp, src/PsSpecialHandler.cpp: + ensure proper evaluation of tightpage data if multiple pages are + processed + +2013-10-12 Martin Gieseking <martin.gieseking@uos.de> + + * src/Color.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: + added 'const' to read-only methods + + * src/InputBuffer.h: + don't check unsigned variables for negative values + +2013-09-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + changed warning message that appears if PS support has been disabled + permanently + + * src/DVIToSVG.cpp, src/Ghostscript.h, src/dvisvgm.cpp: + added missing guards and functions to prevent compilation errors if + DISABLE_GS is set + + * src/FontCache.cpp, src/FontCache.h: + renamed FontCache::VERSION to FontCache::FORMAT_VERSION + +2013-09-01 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.5 + + * src/DLLoader.h, src/Directory.h: + moved #define NOMINMAX to Windows config.h + + * src/BgColorSpecialHandler.cpp, src/Bitmap.cpp, src/BoundingBox.cpp, + src/CMap.cpp, src/CMapManager.cpp, src/CMapReader.cpp, src/CRC32.cpp, + src/Calculator.cpp, src/CharMap.cpp, src/CmdLineParserBase.cpp, + src/Color.cpp, src/ColorSpecialHandler.cpp, src/CommandLine.cpp, + src/CommandLine.h, src/DLLoader.cpp, src/DVIActions.cpp, + src/DVIReader.cpp, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, + src/Directory.cpp, src/DvisvgmSpecialHandler.cpp, src/EPSFile.cpp, + src/EPSToSVG.cpp, src/EmSpecialHandler.cpp, src/EncFile.cpp, + src/FileFinder.cpp, src/FilePath.cpp, src/FileSystem.cpp, src/Font.cpp, + src/FontCache.cpp, src/FontEncoding.cpp, src/FontEngine.cpp, + src/FontManager.cpp, src/FontMap.cpp, src/FontMetrics.cpp, + src/GFGlyphTracer.cpp, src/GFReader.cpp, src/GFTracer.cpp, + src/Ghostscript.cpp, src/Ghostscript.h, src/HtmlSpecialHandler.cpp, + src/InputBuffer.cpp, src/InputReader.cpp, src/JFM.cpp, src/Length.cpp, + src/MapLine.cpp, src/Matrix.cpp, src/Message.cpp, + src/MetafontWrapper.cpp, src/MiKTeXCom.cpp, src/NoPsSpecialHandler.cpp, + src/PSInterpreter.cpp, src/PSPattern.cpp, src/PSPreviewFilter.cpp, + src/PageRanges.cpp, src/PageSize.cpp, src/PdfSpecialHandler.cpp, + src/Process.cpp, src/PsSpecialHandler.cpp, src/SVGTree.cpp, + src/SignalHandler.cpp, src/SpecialManager.cpp, src/StreamReader.cpp, + src/StreamWriter.cpp, src/Subfont.cpp, src/System.cpp, src/TFM.cpp, + src/Terminal.cpp, src/TpicSpecialHandler.cpp, src/VFReader.cpp, + src/XMLDocument.cpp, src/XMLNode.cpp, src/XMLString.cpp, src/dvisvgm.cpp: + include config.h at the top of every translation unit + +2013-08-30 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + updated manpage + + * src/Font.cpp, src/Font.h, src/XMLString.cpp: + replaced entity references by corresponding UTF-8 characters; use + correct unicode points rather than DVI charcodes + + * src/DVIReader.cpp, src/DVIReader.h, src/Font.cpp, src/Font.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontManager.h, src/FontStyle.h, src/SVGTree.cpp, src/dvisvgm.cpp: + added support for XDV (DVI format 5) files + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Font.cpp, src/Font.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontMetrics.h, src/JFM.h, + src/SVGTree.cpp, src/SVGTree.h, src/TFM.h, src/dvisvgm.cpp: + added support for DVI format 3 (pTeX, vertical mode) + + * src/FontMetrics.h, src/JFM.cpp, src/JFM.h, src/TFM.h: + added retrieval of vertical mode flag to class FontMetrics + +2013-08-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/CharMap.cpp, src/CharMap.h, src/Font.cpp, src/Font.h, + src/FontEncoding.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontManager.cpp, src/Makefile.am: + replaced local std::map tables used in Font classes with new class + CharMap + +2013-08-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/SVGTree.cpp: + appended px unit to font-size attributes in style section + +2013-08-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp: + suppress error messages from makeFOO tools + +2013-08-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h: + moved assignment of base font map to Font class + + * src/CMap.cpp, src/CMap.h, src/CMapManager.cpp, src/CMapManager.h, + src/EncFile.h, src/Font.cpp, src/Font.h, src/FontEncoding.cpp, + src/FontEncoding.h, src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h: + derive EncodingPair from FontEncoding + +2013-08-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/dvisvgm.cpp: + fix number of dashes printed by -V1 + + * configure.ac, src/FileFinder.cpp: + check if the kpathsea library is C++-safe (patch by Peter Breitenlohner) + +2013-08-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/Matrix.cpp, src/Matrix.h: + renamed Matrix skewing methods + +2013-08-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/Ghostscript.h, src/PSPreviewFilter.cpp, src/PsSpecialHandler.cpp: + added missing variable initializations + + * src/Font.cpp, src/Font.h, src/FontEngine.cpp, src/FontManager.cpp, + src/FontMap.cpp, src/FontMap.h, src/FontStyle.h, src/Makefile.am: + store pointers to font map and encoding in Font objects to speed up + looking them up + +2013-08-03 Martin Gieseking <martin.gieseking@uos.de> + + * src/CMapManager.cpp, src/CMapManager.h, src/FontManager.cpp: + avoid const_cast in CMapManager + +2013-08-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/CMap.h, src/CMapManager.cpp: + properly handle 'unicode' encoding entries set in font map + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIToSVG.cpp: + disable font processing while scanning PS header specials + +2013-08-01 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + set version to 1.4 + + * NEWS: + updated NEWS + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.h, src/EPSToSVG.h, + src/Matrix.cpp, src/Matrix.h, src/PsSpecialHandler.cpp, + src/SpecialActions.h, src/dvisvgm.cpp: + apply page transformations to width, height, and depth of preview bbox + + * src/DVIToSVG.cpp: + removed redundant #include statements + + * src/DVIToSVG.cpp, src/Makefile.am, src/SVGTree.cpp, + src/XMLDocTypeNode.h: + removed DOCTYPE declaration from generated files as suggested by the SVG + specification + + * src/XMLDocument.cpp, src/XMLString.cpp: + changed encoding of SVG files from ISO-8859-1 to UTF-8 + +2013-07-31 Martin Gieseking <martin.gieseking@uos.de> + + * src/CMap.h, src/CMapManager.cpp, src/CMapManager.h, src/CMapReader.cpp, + src/CharMapID.cpp, src/CharMapID.h, src/Font.cpp, src/Font.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontMap.cpp, src/FontMap.h, src/Makefile.am: + try to decode characters of non-CID fonts that have a CMap assigned in + the fontmap + + * src/CMap.cpp, src/CMap.h, src/CMapReader.cpp, src/CMapReader.h, + tests/CMapReaderTest.cpp, tests/CMapTest.cpp, tests/Makefile.am: + added evaluation of base font (bf) sections in CMap files + + * src/Font.cpp, src/Font.h, src/FontMetric.cpp, src/FontMetric.h, + src/FontMetrics.cpp, src/FontMetrics.h, src/Makefile.am, src/TFM.h: + renamed class FontMetric to FontMetrics + + * src/FileFinder.cpp, src/Font.cpp, src/Font.h, src/FontManager.cpp: + added support for OTF fonts + + * src/CMap.cpp, src/CMap.h, src/Character.h, src/EncFile.h, src/Font.cpp, + src/Font.h, src/FontEncoding.h, src/FontEngine.cpp, src/FontEngine.h, + src/Makefile.am, tests/CMapTest.cpp: + added Character class to handle character names, codes, and indexes + consistently + + * src/CMap.cpp, src/CMap.h, src/CMapManager.h, src/EncFile.cpp, + src/EncFile.h, src/FileFinder.cpp, src/Font.cpp, src/Font.h, + src/FontEncoding.cpp, src/FontEncoding.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontManager.cpp, src/Makefile.am, + tests/CMapTest.cpp: + derive .enc encoding vectors and CMaps from common base class + FontEncoding + + * src/CMap.cpp, src/CMap.h, src/CMapManager.cpp, src/CMapManager.h, + src/CMapReader.cpp, src/CMapReader.h, src/FontManager.cpp, + src/Makefile.am, tests/CMapTest.cpp, tests/Makefile.am: + added classes to handle CMap files + +2013-07-27 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/DVIActions.h, src/DVIReader.cpp, + src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/EPSToSVG.cpp, src/Makefile.am, src/PSFilter.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PSPreviewFilter.cpp, src/PSPreviewFilter.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h: + added evaluation of bounding box information created by preview package + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp: + added funtion to execute PS code snippets and retrieve their results + + * src/BgColorSpecialHandler.h, src/DVIToSVG.cpp, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h: + ensure that PS header code is evaluated before the page/body code; also + execute bop-hook and eop-hook + + * src/JFM.cpp: + fixed retrieval of char indexes if a JFM contains entries of chartype 0 + only + +2013-07-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontMap.cpp: + check for EOF prior to try to parse another mapline + + * src/psdefs.cpp, src/psdefs.ps: + PS handler: call newpath before executing charpath in operator show + + * src/EPSToSVG.cpp: + print warning message if height or width of EPS bbox is 0 + +2013-07-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.cpp, src/psdefs.ps: + replaced PS operator prval with =only in psdefs + +2013-07-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.cpp, src/psdefs.ps: + properly store PS operator applyscalevals in systemdict + + * src/DVIToSVG.cpp: + ensure catching PSExceptions while processing PS header specials to + prevent segfaults + +2013-07-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/FileFinder.h: + FileFinder: added lookup of cmap files + + * src/Process.cpp, src/Process.h: + extended Process::run() to grab the output written to stdout + +2013-07-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/CommandLine.cpp: + command-line parser: changed type of argument mode from char to enum + +2013-06-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp: + removed redundant 'using namespace std' + +2013-06-03 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/HtmlSpecialHandler.cpp, + src/HtmlSpecialHandler.h, src/dvisvgm.cpp: + extend option --linkmark to highlight linked areas by a given background + color + +2013-06-01 Martin Gieseking <martin.gieseking@uos.de> + + * src/Color.cpp, src/Color.h, src/ColorSpecialHandler.cpp, + src/ColorSpecialHandler.h, src/SpecialActions.h, + tests/ColorSpecialTest.cpp, tests/ColorTest.cpp, tests/Makefile.am: + use Color class in ColorSpecialHandler rather than local code; added + ColorTest + +2013-05-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/dvisvgm.cpp: + added a missing (underlining) hyphen to the output of -V1 + +2013-05-13 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.3 + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/HtmlSpecialHandler.cpp, src/dvisvgm.cpp, src/options.xml: + added option --linkmark to select the highlighing variant for hyperlinks + + * doc/dvisvgm.txt.in, src/DVIToSVG.cpp, src/HtmlSpecialHandler.cpp, + src/HtmlSpecialHandler.h, src/Makefile.am, src/SpecialManager.cpp: + added support of hyperref specials + + * src/FileFinder.cpp, src/MiKTeXCom.cpp, src/MiKTeXCom.h, src/dvisvgm.cpp: + try to load the Ghostscript library that comes with MiKTeX + + * src/Font.cpp, src/FontMetric.cpp, src/FontMetric.h, src/JFM.cpp, + src/JFM.h, src/Makefile.am, src/StreamReader.h, src/TFM.cpp, src/TFM.h: + added support for Japanese font metric (JFM) files + + * src/Font.cpp, src/Font.h, src/FontManager.h, src/FontMetric.cpp, + src/FontMetric.h, src/Makefile.am, src/TFM.cpp, src/TFM.h: + handle invalid TFM files properly + +2013-05-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/DVIToSVG.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, + src/NoPsSpecialHandler.cpp, src/NoPsSpecialHandler.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h: + added page number parameter to DVIEndPageListener::dviEndPage() + + * src/EmSpecialHandler.h, src/NoPsSpecialHandler.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h, src/TpicSpecialHandler.h: + moved DVI listener methods to dedicated listener interface classes + + * src/HtmlSpecialHandler.h: + dropped old HtmlSpecialHandler.h that should had been removed long time + ago + + * src/InputReader.cpp, src/InputReader.h: + added optional parameter 'quotechar' to InputReader::parseAttributes() + + * src/DVIToSVGActions.h, src/EPSToSVG.h, src/SpecialActions.h: + provide the context push/pop methods of class SVGTree to special + handlers + + * src/SVGTree.cpp, src/SVGTree.h: + added methods to push and pop 'context elements' to a page that wrap + parts of the page contents + + * AUTHORS, Makefile.am, README, configure.ac, potracelib/Makefile.am, + potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h: + removed bundled potrace library + +2013-05-01 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/Terminal.cpp, src/Terminal.h: + disable cursor when showing the progress indicator (Windows only) + +2013-04-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + don't link NoPsSpecialHandler if HAVE_LIBGS + +2013-04-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontEncoding.cpp: + fixed bracketing bug that prevented lookup of fontmap files + +2013-04-24 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.2.2 + + * src/BoundingBox.cpp, src/BoundingBox.h, src/Calculator.cpp, + src/Calculator.h, src/Matrix.cpp, src/Matrix.h, src/MessageException.h, + src/PageSize.cpp, src/PageSize.h, src/StreamReader.cpp, + src/StreamReader.h, src/VFReader.cpp, src/VFReader.h, src/VectorStream.h, + src/XMLDocument.cpp, src/XMLDocument.h: + added missing underscores to private member variables + +2013-04-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.cpp, src/BoundingBox.h, src/Calculator.h, + src/CmdLineParserBase.h, src/DVIToSVGActions.cpp, src/Message.cpp, + src/VFReader.cpp: + added missing member initializations to some classes + + * doc/dvisvgm.txt.in, src/CmdLineParserBase.cpp, src/CommandLine.cpp, + src/options.dtd, src/options.xml: + added information about 'dvisvgm -E' to usage line + +2013-04-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp, src/Makefile.am, src/NoPsSpecialHandler.cpp, + src/NoPsSpecialHandler.h, src/SpecialManager.cpp: + print a warning message if PS specials are found but ignored + +2013-04-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/dvisvgm.cpp: + catch MessageException if MiKTeX version can't be obtained + +2013-04-09 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.2.1 + + * tests/Makefile.am, tests/create-makefile: + updated tests/Makefile.am to honor system potracelib if present + +2013-04-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/PageRanges.h: + dropped unused variable PageRanges::_max + + * src/CmdLineParserBase.h, src/InputReader.h: + changed 'struct InputReader' to 'class InputReader' + + * doc/dvisvgm.txt.in, src/Color.cpp, src/Color.h, src/DVIToSVGActions.cpp: + allow the background color special to insert white rectancles + +2013-04-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp, src/XMLNode.h: + unhide derived method XMLDeclarationNode::append + +2013-03-10 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, configure.ac: + don't build bundled potracelib if system library is used (patch by + Alexis Ballier) + +2013-03-03 Martin Gieseking <martin.gieseking@uos.de> + + * potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h: + updated bundled potrace library to version 1.11 + +2013-03-02 Martin Gieseking <martin.gieseking@uos.de> + + * potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/decompose.h, potracelib/lists.h, potracelib/progress.h, + potracelib/trace.c, potracelib/trace.h, src/EPSFile.cpp, + src/EPSToSVG.cpp, src/EPSToSVG.h, src/PSPattern.cpp, src/PSPattern.h, + src/SVGOutputBase.h: + converted DOS line endings + +2013-02-28 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.2 + + * src/psdefs.cpp, src/psdefs.ps: + improved processing of PS operator "show" + + * tests/MapLineTest.cpp: + prevent MapLineTest from failing if file UGBK.sfd is not available + + * src/Makefile.am, src/PSInterpreter.cpp, src/psdefs.cpp, src/psdefs.ps, + src/psdefs.psc: + make psdefs a separate compilation unit + + * src/Makefile.am, src/PSInterpreter.cpp, src/PSInterpreter.h, + src/PSPattern.cpp, src/PSPattern.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/psdefs.ps, src/psdefs.psc, + tests/PSInterpreterTest.cpp: + PS handler: added support of tiling patterns + +2013-02-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp, src/XMLNode.h: + added methods to lookup attribute values and selected descendant XML + nodes + +2013-02-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/FilePath.cpp: + adapt path separators on Windows systems to get the correct output path + + * src/PSInterpreter.cpp, src/PSInterpreter.h: + added PSInterpreter::limit() to limit the number of bytes to be + processed + +2013-02-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/CommandLine.cpp, + src/CommandLine.h: + applied a few refactorings to the command-line parser + +2013-02-07 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, + src/CommandLine.cpp, src/CommandLine.h, src/dvisvgm.cpp, src/options.xml: + added optional parameter to option --help to specify output format + +2013-02-06 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/CommandLine.cpp, + src/CommandLine.h, src/EmSpecialHandler.cpp, src/GraphicPath.h, + src/Matrix.cpp, src/PsSpecialHandler.cpp, src/TpicSpecialHandler.cpp, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/options.xml: + added option --precision to set the number of decimal places applied to + attribute values + +2013-01-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/CommandLine.cpp: + fixed alignment of --help text + +2013-01-21 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, README: + updated NEWS and README + + * configure.ac, src/Doxyfile: + set version to 1.1 + + * src/CommandLine.cpp, src/Font.cpp, src/Font.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h, + src/MapLine.cpp, src/MapLine.h, tests/MapLineTest.cpp: + implemented evaluation of font style options given in a mapline + + * src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h, src/MapLine.h: + replaced FontMap entries by pointers; initialize entries with MapLine + objects + + * src/DVIReader.cpp, src/DVIToSVG.cpp, src/FileFinder.cpp, src/Font.cpp, + src/Font.h, src/FontEncoding.cpp, src/FontEngine.cpp, src/FontEngine.h, + src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h, src/Makefile.am, + src/MapLine.cpp, src/MapLine.h, src/Subfont.cpp, src/Subfont.h, + tests/FontMapTest.cpp, tests/Makefile.am, tests/MapLineTest.cpp, + tests/SubfontTest.cpp, tests/create-makefile, tests/sample.sfd: + added support for subfont definitions and multi-font (.ttc) files + +2013-01-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontEngine.cpp, src/FontEngine.h: + removed unneeded code related to font sizes from class FontEngine + +2013-01-16 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/DVIToSVG.cpp, src/FontMap.cpp, src/FontMap.h, + src/Makefile.am, src/PdfSpecialHandler.cpp, src/PdfSpecialHandler.h: + added PdfSpecialHandler to evaluate pdf:mapline and pdf:mapfile specials + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/FontMap.cpp, src/FontMap.h, src/dvisvgm.cpp, src/options.xml: + renamed option --map-file to --fontmap; allow multiple mapfiles and + modes + +2013-01-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/FontEncoding.cpp: + fixed a string exception that occurred when an encoding file or an entry + in the encoding table is unavailable + +2013-01-06 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/FileFinder.h, src/FontEncoding.cpp, + src/FontEncoding.h: + removed font encoding methods from FileFinder + +2013-01-02 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, README, configure.ac, doc/Makefile.am, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/CRC32.cpp, src/CRC32.h, src/Calculator.cpp, src/Calculator.h, + src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/Color.cpp, + src/Color.h, src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/CommandLine.cpp, src/CommandLine.h, src/DLLoader.cpp, src/DLLoader.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/FileFinder.cpp, + src/FileFinder.h, src/FilePath.cpp, src/FilePath.h, src/FileSystem.cpp, + src/FileSystem.h, src/Font.cpp, src/Font.h, src/FontCache.cpp, + src/FontCache.h, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontManager.h, src/FontMap.cpp, src/FontMap.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, src/Glyph.h, + src/GlyphTracerMessages.h, src/GraphicPath.h, src/HtmlSpecialHandler.h, + src/InputBuffer.cpp, src/InputBuffer.h, src/InputReader.cpp, + src/InputReader.h, src/Length.cpp, src/Length.h, src/Makefile.am, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/MiKTeXCom.cpp, src/MiKTeXCom.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PageRanges.cpp, src/PageRanges.h, + src/PageSize.cpp, src/PageSize.h, src/Pair.h, src/Process.cpp, + src/Process.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/SVGTree.cpp, src/SVGTree.h, src/SWFWriter.cpp, src/SWFWriter.h, + src/SignalHandler.cpp, src/SignalHandler.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/StreamReader.cpp, src/StreamReader.h, src/StreamWriter.cpp, + src/StreamWriter.h, src/System.cpp, src/System.h, src/TFM.cpp, src/TFM.h, + src/Terminal.cpp, src/Terminal.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/macros.h, + src/options.dtd, src/options.xml, src/psdefs.ps, src/psdefs.psc, + src/types.h, tests/BoundingBoxTest.cpp, tests/CRC32Test.cpp, + tests/CalculatorTest.cpp, tests/ColorSpecialTest.cpp, + tests/CommandLineTest.cpp, tests/DirectoryTest.cpp, + tests/FileFinderTest.cpp, tests/FilePathTest.cpp, + tests/FileSystemTest.cpp, tests/FontManagerTest.cpp, + tests/FontMapTest.cpp, tests/GFReaderTest.cpp, tests/GraphicPathTest.cpp, + tests/LengthTest.cpp, tests/Makefile.am, tests/MatrixTest.cpp, + tests/MessageExceptionTest.cpp, tests/PSInterpreterTest.cpp, + tests/PageRagesTest.cpp, tests/PageSizeTest.cpp, tests/PairTest.cpp, + tests/SplittedCharInputBufferTest.cpp, tests/StreamInputBufferTest.cpp, + tests/StreamReaderTest.cpp, tests/StreamWriterTest.cpp, + tests/TypesTest.cpp, tests/VectorStreamTest.cpp, tests/create-makefile: + updated year in copyright statements to 2013 + +2012-12-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/Message.cpp, src/dvisvgm.cpp: + reduced scope of some variables + + * src/CmdLineParserBase.h, src/Directory.cpp, src/GFReader.cpp, + src/PsSpecialHandler.cpp: + initialize uninitialized member variables + + * src/FileFinder.cpp, src/MiKTeXCom.cpp, src/Process.cpp: + avoid creating copies of exception objects + + * src/FontCache.cpp, src/PsSpecialHandler.cpp, src/TpicSpecialHandler.cpp: + check emptiness of containers with empty() instead of size() + +2012-12-12 Martin Gieseking <martin.gieseking@uos.de> + + * src/SpecialManager.cpp: + clear all corresponding containers when calling + SpecialHandler::unregisterHandlers() + + * src/FontCache.cpp: + replaced 'char' with 'glyph' in font cache listing + +2012-12-03 Martin Gieseking <martin.gieseking@uos.de> + + * src/Ghostscript.cpp: + added explicit cast to avoid signed/unsigned comparison warning + +2012-12-02 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/Ghostscript.cpp: + use gsdll64.dll for 64-bit builds; added info about gsdll64.dll to + manpage + + * src/FileFinder.cpp, src/FontEngine.cpp, src/Makefile.am, + src/MiKTeXCom.cpp, src/MiKTeXCom.h: + moved MiKTeX COM code to separate class + + * src/MiKTeX209-session_i.c: + add additiona files required to build dvisvgm with MinGW + + * src/macros.h: + removed SHOW() from macros.h + + * tests/FileSystemTest.cpp, tests/GFReaderTest.cpp: + ensure that tests work properly on Windows + + * src/FilePath.cpp, tests/FilePathTest.cpp: + strip drive letter if it's not set (Windows only) + +2012-11-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp, src/psdefs.ps, src/psdefs.psc: + print operand stack in case of a PS error + + * src/Ghostscript.cpp, src/Ghostscript.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/dvisvgm.cpp: + print an error message if the execution of PS code fails + +2012-11-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/Message.cpp: + handle wrapping of messages containing newlines correctly + +2012-11-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/DLLoader.cpp, src/DLLoader.h, src/Ghostscript.cpp: + renamed DLLoader::loadFunction() to DLLoader::loadSymbol() + +2012-11-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h, src/FontManager.cpp: + print warning if font checksums don't match + + * src/FontEngine.cpp, src/FontEngine.h: + renamed FontEngine::fname to FontEngine::_fontname + +2012-11-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/Directory.h: + undefine macro max() to avoid compilation problems on Windows + +2012-11-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/FontManager.cpp, src/FontMap.cpp, src/FontMap.h, + tests/FontMapTest.cpp: + adapted code to use new MapLine class; introduced support of map line + modes + + * src/Makefile.am, src/MapLine.cpp, src/MapLine.h, tests/Makefile.am, + tests/MapLineTest.cpp: + added new class MapLine to parse and evaluate a single line of a map + file + + * src/FileFinder.cpp, src/FileFinder.h, src/dvisvgm.cpp: + moved initialization of FontMap from FileFinder to dvisvgm.cpp + + * src/FileFinder.cpp, src/FileFinder.h, src/FontMap.cpp, src/FontMap.h, + tests/FontMapTest.cpp: + made class FontMap a singleton + +2012-11-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + prevent compilation error when using a C++11 compiler (patch by Peter + Breitenlohner) + + * src/FileFinder.cpp, src/FileFinder.h, src/dvisvgm.cpp, + tests/FileFinderTest.cpp, tests/FontManagerTest.cpp: + initialize second parameter of kpse_set_program_name() correctly + + * src/FileFinder.cpp: + initialize Ghostscript when compiled for TeX Live Win32 (patch by Peter + Breitenlohner) + +2012-11-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/InputBuffer.cpp, src/InputBuffer.h, src/InputReader.cpp, + src/InputReader.h, src/PsSpecialHandler.cpp, + tests/StreamInputBufferTest.cpp: + some refactorings of class InputReader; added InputReader::find() + +2012-10-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/dvisvgm.cpp: + don't show warning about disabled PS support in list of special handlers + +2012-09-27 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am: + remove manpage when calling 'make distclean' + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.0.12 + +2012-09-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: + removed Ghostscript info from ps entry in list of special handlers + + * src/DVIToSVG.cpp: + show warning if processing of PS specials is disabled + +2012-06-06 Martin Gieseking <martin.gieseking@uos.de> + + * src/gfprint.mak: + fixed bugs in gfprint, and added gfprint.mak for easier builds + +2012-04-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am: + keep manpage when calling 'make clean' or 'make distclean' + +2012-04-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/SVGTree.cpp, src/SVGTree.h, + tests/frktest-nf-cmp.svg, tests/frktest-wf-cmp.svg, + tests/sample-nf-cmp.svg, tests/sample-wf-cmp.svg: + scale point units in the SVG files to big points (bp) + +2012-04-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/Matrix.cpp, src/Matrix.h, tests/MatrixTest.cpp: + added Matrix::invert() and det() + +2012-03-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/Matrix.cpp, src/Matrix.h, tests/MatrixTest.cpp: + added start index parameter to Matrix::set(vector<>) + +2012-03-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.ps, src/psdefs.psc: + evaluate PS operators rectclip, rectfill, and rectstroke + +2012-03-09 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * src/dvisvgm.cpp: + added Ghostscript to library list printed by --version=yes + + * src/Ghostscript.cpp, src/Ghostscript.h: + added optional parameter to Ghostscript::revision() to retrieve the + revision number only + +2012-03-08 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + set version to 1.0.11 + +2012-03-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp: + correct location of a rule's bounding box (lp bug #948713) + +2012-02-24 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + fixed a couple of mistakes and formatting flaws in the manpage + +2012-02-17 Martin Gieseking <martin.gieseking@uos.de> + + * README: + updated information about bug reporting + +2012-01-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.h, src/DVIActions.h, src/DVIReader.h, + src/DVIToSVGActions.h, src/FontEngine.h, src/FontManager.h, + src/MetafontWrapper.h, src/SVGTree.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.h, src/TFM.h, src/VFReader.h: + adapt forward declarations of classes and structs to their corresponding + definition (SF bug #3480013) + +2012-01-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/TpicSpecialHandler.cpp: + added some more comments to methods of class TpicSpecialHandler + + * src/InputReader.cpp, tests/StreamInputBufferTest.cpp: + fixed parsing of negative floating point numbers starting with '-0.' (SF + bug #3471097) + +2012-01-06 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, README, configure.ac, doc/Makefile.am, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/CRC32.cpp, src/CRC32.h, src/Calculator.cpp, src/Calculator.h, + src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/Color.cpp, + src/Color.h, src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/CommandLine.cpp, src/CommandLine.h, src/DLLoader.cpp, src/DLLoader.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/FileFinder.cpp, + src/FileFinder.h, src/FilePath.cpp, src/FilePath.h, src/FileSystem.cpp, + src/FileSystem.h, src/Font.cpp, src/Font.h, src/FontCache.cpp, + src/FontCache.h, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontManager.h, src/FontMap.cpp, src/FontMap.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, src/Glyph.h, + src/GlyphTracerMessages.h, src/GraphicPath.h, src/HtmlSpecialHandler.h, + src/InputBuffer.cpp, src/InputBuffer.h, src/InputReader.cpp, + src/InputReader.h, src/Length.cpp, src/Length.h, src/Makefile.am, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PageRanges.cpp, + src/PageRanges.h, src/PageSize.cpp, src/PageSize.h, src/Pair.h, + src/Process.cpp, src/Process.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/SVGTree.cpp, src/SVGTree.h, + src/SWFWriter.cpp, src/SWFWriter.h, src/SignalHandler.cpp, + src/SignalHandler.h, src/SpecialActions.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h, src/StreamReader.cpp, + src/StreamReader.h, src/StreamWriter.cpp, src/StreamWriter.h, + src/System.cpp, src/System.h, src/TFM.cpp, src/TFM.h, src/Terminal.cpp, + src/Terminal.h, src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h, + src/VFActions.h, src/VFReader.cpp, src/VFReader.h, src/VectorStream.h, + src/XMLDocTypeNode.h, src/XMLDocument.cpp, src/XMLDocument.h, + src/XMLNode.cpp, src/XMLNode.h, src/XMLString.cpp, src/XMLString.h, + src/dvisvgm.cpp, src/macros.h, src/options.dtd, src/options.xml, + src/psdefs.ps, src/psdefs.psc, src/types.h, tests/BoundingBoxTest.cpp, + tests/CRC32Test.cpp, tests/CalculatorTest.cpp, + tests/ColorSpecialTest.cpp, tests/CommandLineTest.cpp, + tests/DirectoryTest.cpp, tests/FileFinderTest.cpp, + tests/FilePathTest.cpp, tests/FileSystemTest.cpp, + tests/FontManagerTest.cpp, tests/FontMapTest.cpp, tests/GFReaderTest.cpp, + tests/GraphicPathTest.cpp, tests/LengthTest.cpp, tests/Makefile.am, + tests/MatrixTest.cpp, tests/MessageExceptionTest.cpp, + tests/PSInterpreterTest.cpp, tests/PageRagesTest.cpp, + tests/PageSizeTest.cpp, tests/PairTest.cpp, + tests/SplittedCharInputBufferTest.cpp, tests/StreamInputBufferTest.cpp, + tests/StreamReaderTest.cpp, tests/StreamWriterTest.cpp, + tests/TypesTest.cpp, tests/VectorStreamTest.cpp, tests/check-conv, + tests/create-makefile: + updated year in copyright statements + +2011-12-18 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * configure.ac, src/Doxyfile: + set version to 1.0.10 + + * tests/Makefile.am, tests/create-makefile: + link tests with -lpthread (required by gtest on Ubuntu) + +2011-12-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + added documentation on environment variable DVISVGM_COLORS to manpage + + * src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, src/GlyphTracerMessages.h, + src/Message.cpp, src/Message.h, src/MetafontWrapper.cpp, + src/Terminal.cpp, src/Terminal.h, src/dvisvgm.cpp: + allow users to customize the message colors + +2011-11-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicPath.h: + added some more comments to the methods of GraphicPath + +2011-11-18 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac: + move linker flag -lfreetype from LDFLAGS to LIBS to avoid linking + problems + +2011-10-28 Martin Gieseking <martin.gieseking@uos.de> + + * src/SVGTree.cpp: + avoid possible collisions of glyph IDs + + * src/FontMap.cpp: + removed unused variable eval_prefix in helper function read_entry() + +2011-10-13 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + +2011-10-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h, src/FontManager.cpp, src/FontManager.h: + extended class FontManager to handle external fonts + + * src/ExternalFont.cpp, src/ExternalFont.h, src/Makefile.am: + added class ExternalFont + +2011-10-09 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/FontDB.cpp, src/FontDB.h, src/Makefile.am: + added class FontDB + + * src/DirectoryTree.cpp, src/DirectoryTree.h, src/Makefile.am, + tests/DirectoryTreeTest.cpp, tests/Makefile.am: + added class DirectoryTree + + * src/Directory.h: + dropped method Directory::getEntry() + + * src/FilePath.cpp: + added some missing comments to methods of class FilePath + +2011-10-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/Process.cpp: + exclude definition of split_paramstr() from Windows builds as it's not + used there + + * src/Process.cpp: + added missing include <signal.h> to Process.cpp + +2011-10-03 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am: + add metadata/pdfmarks to pdf version of manpage + +2011-09-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/InputReader.cpp, src/InputReader.h, tests/StreamInputBufferTest.cpp: + added InputReader::getUntil() to simplify parsing of an input stream + + * src/CommandLine.cpp, src/CommandLine.h, src/dvisvgm.cpp, + src/options.xml: + added command-line option --query + +2011-09-06 Martin Gieseking <martin.gieseking@uos.de> + + * potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h: + updated bundled potrace library to version 1.10 + +2011-06-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/MetafontWrapper.cpp: + fixed segfault occured in TeX Live Win32 caused by mf.exe being + unavailable (SF bug #3308473) + + * configure.ac, src/Doxyfile: + set version to 1.0.9dev + +2011-05-31 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp: + explicitly cast double to int in call of ClippingStack::dup()/pop() + + * NEWS, configure.ac, src/Doxyfile: + set version to 1.0.8; updated NEWS + +2011-05-27 Martin Gieseking <martin.gieseking@uos.de> + + * tests/check-conv, tests/sample-nf-cmp.svg, tests/sample-wf-cmp.svg: + updated conversion tests + +2011-05-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Makefile.am, src/MetafontWrapper.cpp, + src/MetafontWrapper.h, src/Process.cpp, src/Process.h, + src/SignalHandler.cpp: + replaced call of system() with Process::run() and kill child process if + necessary + +2011-05-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/MetafontWrapper.cpp: + dropped '--halt-on-error' in Metafont call to process buggy mf files + completely + + * src/FileFinder.cpp: + MiKTeX: maketfm and makemf have been renamed to miktex-maketfm and + miktex-makemf + +2011-05-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/DLLoader.h: + added #undef NOMINMAX before (re)defining it + +2011-05-12 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/psdefs.ps, src/psdefs.psc, + tests/PSInterpreterTest.cpp: + PS handler: implemented evaluation of save, restore, and grestoreall + +2011-05-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp: + fixed potential segfault caused by invisible zero-length paths + + * src/PsSpecialHandler.cpp: + add definitions in literal PS headers to dictionary TeXDict + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVGActions.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SpecialActions.h: + fixed interaction between PS and DVI drawing position + + * configure.ac, src/Doxyfile: + set version to 1.0.8dev + +2011-05-06 Martin Gieseking <martin.gieseking@uos.de> + + * fedora/dvisvgm-gs.patch, fedora/dvisvgm-potrace.patch, + fedora/dvisvgm.spec: + removed directories 'fedora' and 'homepage' + + * NEWS, README, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.7; updated NEWS and README + +2011-05-05 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + added info about dvips rounding issues to manpage + + * src/DVIToSVGActions.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/psdefs.ps, src/psdefs.psc: + PS handler: added missing unit conversions (pt vs. bp) + + * src/PsSpecialHandler.h: + corrected scaling formula applied to PS line properties + + * src/PSInterpreter.cpp, src/PsSpecialHandler.cpp: + separate PS snippets by newline characters to leave preceding comments + +2011-05-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/Length.h: + undefine macro IN + + * src/Ghostscript.cpp, src/Ghostscript.h, src/PSInterpreter.cpp, + src/PSInterpreter.h: + avoid 'this' pointer in initialazation list of + PSInterpreter::PSInterpreter() + + * src/PsSpecialHandler.cpp: + don't call Ghostscript::revision() in initialization of static variable + +2011-05-03 Martin Gieseking <martin.gieseking@uos.de> + + * src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h: + tpic special 'ip' must not draw the outline of the polygon but only fill + its interior + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/macros.h, src/psdefs.ps, src/psdefs.psc, + tests/PSInterpreterTest.cpp: + improved handling of pure PostScript specials + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, + src/PSInterpreter.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/SpecialActions.h, src/SpecialHandler.h, src/SpecialManager.cpp, + src/SpecialManager.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h: + replaced methods for DVI position alterations with translation semantics + +2011-05-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.ps, src/psdefs.psc: + PS handler: recognize save/restore operators + +2011-04-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.ps, src/psdefs.psc: + catch PS error /nocurrentpoint in operator 'setpos' properly + + * src/SpecialManager.cpp: + register special prefix ps:: properly + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.7dev + +2011-04-16 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, README, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.6; updated NEWS and README + +2011-04-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/Font.cpp, src/GFReader.cpp, src/Makefile.am, + src/MetafontWrapper.cpp, src/PSInterpreter.cpp, src/SignalHandler.cpp, + src/SignalHandler.h, src/TFM.cpp, src/dvisvgm.cpp: + added class SignalHandler for CTRL-C signals + + * src/DVIToSVGActions.cpp, src/MessageException.h, src/dvisvgm.cpp, + tests/Makefile.am, tests/MessageExceptionTest.cpp: + derived MessageException from std::exception and replaced getMessage() + with what() + +2011-04-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp, src/XMLNode.h: + prepended member variables of the XMLNode classes with underscore + +2011-04-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/FileFinder.h, src/dvisvgm.cpp, + tests/FileFinderTest.cpp: + dropped class FileFinder::Impl and simplified FileFinder interface + +2011-03-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp: + throw DVI exception if set_char/put_char is executed without preceding + font selection + +2011-03-12 Martin Gieseking <martin.gieseking@uos.de> + + * pull-wiki: + updated rsync parameters in 'pull-wiki' + +2011-03-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/CRC32.cpp, src/StreamWriter.cpp: + added missing 'const' to type casts (Peter Breitenlohner) + + * potracelib/potracelib.c, potracelib/potracelib.h: + changed return type of potrace_version() to 'const char *' in order to + avoid compiler warning + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.6dev + +2011-02-28 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.5, updated NEWS + + * src/Ghostscript.cpp: + fixed formatting of GS version number + + * doc/dvisvgm.txt.in, src/FontCache.cpp, src/FontCache.h, src/dvisvgm.cpp: + added code to remove outdated and corrupted cache files + +2011-02-21 Martin Gieseking <martin.gieseking@uos.de> + + * tests/frktest-nf-cmp.svg, tests/frktest-wf-cmp.svg, + tests/sample-nf-cmp.svg, tests/sample-wf-cmp.svg: + updated conversion test files + + * src/SVGTree.cpp: + added missing unit in height/width attribute of svg root element + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/GraphicPath.h, src/SVGTree.cpp, src/SVGTree.h, src/dvisvgm.cpp, + src/options.xml, tests/CommandLineTest.cpp: + added option to replace use elements with paths + +2011-02-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/InputBuffer.h: + reference to scanned string in StringInputBuffer is constant now + +2011-02-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp, src/FontCache.h: + added CRC32 checks to cache files + + * src/StreamReader.cpp, src/StreamReader.h, src/StreamWriter.cpp, + src/StreamWriter.h, tests/Makefile.am, tests/StreamReaderTest.cpp, + tests/StreamWriterTest.cpp: + added CRC32 computation methods to StreamReader and StreamWriter + + * src/CRC32.cpp, src/CRC32.h, src/Makefile.am, tests/CRC32Test.cpp, + tests/Makefile.am: + added class CRC32 and corresponding tests + + * src/FileSystem.cpp, src/FileSystem.h, src/dvisvgm.cpp, + tests/FileSystemTest.cpp: + merged FileSystem::move() into FileSystem::copy() + +2011-01-31 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.cpp: + print character instead of ascii value in message of command-line parser + +2011-01-30 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/FileFinder.cpp, src/FileFinder.h, src/FontEngine.cpp, + src/FontEngine.h, src/dvisvgm.cpp, src/options.xml: + added optional argument to --version + +2011-01-28 Martin Gieseking <martin.gieseking@uos.de> + + * potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h: + updated bundled potrace library to version 1.9 + +2011-01-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/dvisvgm.cpp: + moved cache files to subfolder ($HOME/.dvisvgm/cache) + +2011-01-04 Martin Gieseking <martin.gieseking@uos.de> + + * tests/Makefile.am, tests/PSInterpreterTest.cpp: + added basic tests for class PSInterpreter + + * Makefile.am, README, configure.ac, doc/Makefile.am, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/Calculator.cpp, src/Calculator.h, src/CmdLineParserBase.cpp, + src/CmdLineParserBase.h, src/Color.cpp, src/Color.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/CommandLine.cpp, src/CommandLine.h, src/DLLoader.cpp, src/DLLoader.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/FileFinder.cpp, + src/FileFinder.h, src/FilePath.cpp, src/FilePath.h, src/FileSystem.cpp, + src/FileSystem.h, src/Font.cpp, src/Font.h, src/FontCache.cpp, + src/FontCache.h, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontManager.h, src/FontMap.cpp, src/FontMap.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, src/Glyph.h, + src/GlyphTracerMessages.h, src/GraphicPath.h, src/HtmlSpecialHandler.h, + src/InputBuffer.cpp, src/InputBuffer.h, src/InputReader.cpp, + src/InputReader.h, src/Length.cpp, src/Length.h, src/Makefile.am, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PageRanges.cpp, + src/PageRanges.h, src/PageSize.cpp, src/PageSize.h, src/Pair.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SVGTree.cpp, + src/SVGTree.h, src/SWFWriter.cpp, src/SWFWriter.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/StreamReader.cpp, src/StreamReader.h, src/StreamWriter.cpp, + src/StreamWriter.h, src/System.cpp, src/System.h, src/TFM.cpp, src/TFM.h, + src/Terminal.cpp, src/Terminal.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/macros.h, + src/options.dtd, src/options.xml, src/psdefs.ps, src/psdefs.psc, + src/types.h, tests/BoundingBoxTest.cpp, tests/CalculatorTest.cpp, + tests/ColorSpecialTest.cpp, tests/CommandLineTest.cpp, + tests/DirectoryTest.cpp, tests/FileFinderTest.cpp, + tests/FilePathTest.cpp, tests/FontManagerTest.cpp, tests/FontMapTest.cpp, + tests/GFReaderTest.cpp, tests/GraphicPathTest.cpp, tests/LengthTest.cpp, + tests/Makefile.am, tests/MatrixTest.cpp, tests/PageRagesTest.cpp, + tests/PageSizeTest.cpp, tests/PairTest.cpp, + tests/SplittedCharInputBufferTest.cpp, tests/StreamInputBufferTest.cpp, + tests/TypesTest.cpp, tests/VectorStreamTest.cpp, tests/check-conv, + tests/create-makefile: + updated year in copyright info + +2010-12-18 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + minor update to the manpage + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.4; updated NEWS + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/psdefs.ps, src/psdefs.psc: + PS handler: added missing scaling of linewidths and dash distances + + * src/PsSpecialHandler.cpp: + fixed scaling issue in PS positioning + +2010-12-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp: + updated to MiKTeX 2.8 SDK + +2010-08-18 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.4dev + + * src/FontEngine.cpp: + fixed FreeType version check (patch by Paul Vojta) + +2010-08-11 Martin Gieseking <martin.gieseking@uos.de> + + * tests/Makefile.am, tests/PairTest.cpp: + added PairTest + +2010-08-05 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, doc/dvisvgm.txt.in: + updated manpage and NEWS + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.3 + +2010-08-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.cpp, src/BoundingBox.h, src/Matrix.cpp, src/Matrix.h, + src/PsSpecialHandler.cpp: + revamped PsSpecialHandler::psfile() to fix a transformation issue (SF + bug #3037372) + +2010-07-28 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp: + added check of DVI format version + +2010-07-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: + restore transformation matrix after execution of psfile + +2010-07-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/Directory.cpp, src/Directory.h, src/GFReader.cpp, src/GFReader.h: + added leading underscore to variables of GFReader + + * src/GraphicPath.h, src/PsSpecialHandler.h: + fixed missing initialization of GraphicPath iterator + + * src/Terminal.cpp: + replaced \e with \x1B + + * src/InputBuffer.h: + added missing namespace prefix + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.3dev + +2010-06-22 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.2 + + * src/gzstream.cpp, src/gzstream.h: + fixed class variable issue introduced by previous AIX patch + +2010-06-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/Bitmap.cpp, tests/DirectoryTest.cpp, tests/GFReaderTest.cpp, + tests/Makefile.am, tests/cmr10.600gf, tests/create-makefile: + added GFReaderTest; updated DirectoryTest + +2010-06-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/types.h, tests/Makefile.am, tests/TypesTest.cpp: + added TypesTest + + * src/Message.cpp, src/Message.h: + renamed MessageStream::putchar() to MessageStream::putChar() to avoid + name clashes + + * src/Bitmap.cpp, src/Calculator.cpp, src/CmdLineParserBase.cpp, + src/Color.cpp, src/ColorSpecialHandler.cpp, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVGActions.cpp, src/DvisvgmSpecialHandler.cpp, + src/EmSpecialHandler.cpp, src/FontCache.cpp, src/FontEncoding.cpp, + src/GFGlyphTracer.cpp, src/Pair.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/TFM.cpp, src/TFM.h: + fixed some type conversion warnings + +2010-06-16 Martin Gieseking <martin.gieseking@uos.de> + + * potracelib/curve.c, potracelib/curve.h, potracelib/decompose.c: + renamed internal potrace functions path_new() and path_free() to prevent + linker conflicts on OS X + + * configure.ac, src/CmdLineParserBase.h, src/FileFinder.h, + src/FontCache.cpp, src/FontCache.h, src/FontEncoding.cpp, + src/FontEngine.cpp, src/GFGlyphTracer.h, src/MetafontWrapper.cpp, + src/gzstream.cpp: + applied latest TL patches from Peter Breitenlohner and Karl Berry + +2010-06-14 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.2dev + +2010-06-11 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.1 + + * src/Message.cpp: + suppress ANSI color code by default + +2010-06-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.ps, src/psdefs.psc: + fixed recursion issue in PS operator charpath + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0.1dev + +2010-06-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h: + fixed PS destructor issue (SF bug #3013392) + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0 + + * doc/Makefile.am, doc/dvisvgm.txt.in: + documented option --help and --version in manpage + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/DVIActions.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/Makefile.am, src/Message.cpp, src/Message.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/SpecialActions.h, src/System.cpp, src/System.h, src/dvisvgm.cpp, + src/options.xml: + added percentage-based progress indicator + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h: + added method to compute length of DVI command + + * src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/psdefs.ps, src/psdefs.psc: + evaluate Ghostscript operator .setopacityalpha + + * src/Font.cpp: + print error message if Metafont failed + + * configure.ac, doc/Makefile.am, doc/dvisvgm.txt.in, src/CommandLine.cpp, + src/CommandLine.h, src/DVIActions.h, src/DVIToSVG.cpp, src/GFTracer.cpp, + src/GlyphTracerMessages.h, src/Makefile.am, src/Message.cpp, + src/Message.h, src/MetafontWrapper.cpp, src/Terminal.cpp, src/Terminal.h, + src/dvisvgm.cpp, src/options.xml: + improved output of messages including optional colorization + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Makefile.am, + src/PageRanges.cpp, src/PageRanges.h, src/StreamCounter.h, + src/dvisvgm.cpp, src/options.xml, tests/BoundingBoxTest.cpp, + tests/CommandLineTest.cpp, tests/Makefile.am, tests/PageRagesTest.cpp, + tests/StreamCounterTest.cpp: + added conversion of multiple pages + + * src/InputBuffer.h, tests/ColorSpecialTest.cpp, + tests/StreamInputBufferTest.cpp: + added InputBuffer::invalidate() + + * src/FilePath.cpp, src/FilePath.h, src/FileSystem.cpp, src/FileSystem.h, + src/Makefile.am, tests/FilePathTest.cpp, tests/Makefile.am: + added class FilePath + + * doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/DvisvgmSpecialHandler.cpp, + src/EmSpecialHandler.cpp, src/PsSpecialHandler.cpp, src/SpecialActions.h, + src/SpecialManager.cpp, src/TpicSpecialHandler.cpp: + added special for creating local bounding boxes + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 1.0dev + + * configure.ac, doc/Makefile.am, src/Makefile.am: + cleaned up configuration scripts + +2010-05-09 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac: + fixed whitespace issue in CPPFLAGS and LDFLAGS + +2010-05-04 Martin Gieseking <martin.gieseking@uos.de> + + * tests/FileFinderTest.cpp, tests/FontManagerTest.cpp, tests/check-conv: + fixed segfaults in tests + + * configure.ac: + fixed kpathsea check; use pkg-config to check freetype availability + +2010-04-22 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.9.1 + + * tests/check-conv, tests/frktest-wf-cmp.svg, tests/sample-wf-cmp.svg: + adapted conversion tests to new output format + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/DVIToSVG.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h: + print page count and page number of DVI page being processed + + * src/SVGTree.cpp: + fixed broken validity when using SVG fonts + + * src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/SVGTree.cpp, src/SVGTree.h, src/XMLNode.cpp, src/XMLNode.h: + ignore unused fonts in CSS styles list + + * src/CommandLine.cpp, src/options.xml: + output of option --help: replaced '(default: FOO)' by '[FOO]' + +2010-04-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontEncoding.cpp: + fixed memory bug in FontEncoding::encoding() + +2010-04-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp: + replaced wrong font pointer that could lead to segfaults + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.9.1dev + +2010-03-25 Martin Gieseking <martin.gieseking@uos.de> + + * fedora/dvisvgm.spec: + updated spec file + +2010-03-24 Martin Gieseking <martin.gieseking@uos.de> + + * transfer-cs: + added extension .patch to exported changesets + + * tests/frktest-nf-cmp.svg, tests/frktest-wf-cmp.svg, + tests/sample-nf-cmp.svg, tests/sample-wf-cmp.svg: + updated conversion tests + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.9 + + * src/FontCache.cpp, src/GFGlyphTracer.cpp, src/GFReader.cpp: + variable _fontname is now correctly set in class FontCache + + * src/CmdLineParserBase.cpp, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, + src/FontEngine.cpp, src/GlyphTracerMessages.h, src/Message.cpp, + src/Message.h, src/MetafontWrapper.cpp, src/dvisvgm.cpp: + added class MessageStream, updated message output + + * src/FontCache.cpp, src/Makefile.am, src/StreamWriter.cpp, + src/StreamWriter.h, src/TFM.cpp: + replaced local stream IO functions by StreamReader/StreamWriter methods + + * doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/BoundingBox.h, + src/CommandLine.cpp, src/CommandLine.h, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Font.cpp, src/Font.h, + src/GlyphTracerMessages.h, src/Makefile.am, src/dvisvgm.cpp, + src/options.xml: + added command-line option --exact + + * src/Font.cpp, src/Font.h, src/dvisvgm.cpp: + moved some methods from PhysicalFontImpl to PysicalFont + +2010-03-18 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/Font.cpp, src/Font.h, src/dvisvgm.cpp, src/options.xml: + added command-line option --keep + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/Font.cpp, src/Font.h, + src/dvisvgm.cpp, src/options.xml, tests/CommandLineTest.cpp: + reactivated option --trace-all, and added optional argument 'retrace' to + it + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h: + added evaluation of boolean and char arguments to the command-line + parser + + * src/DVIToSVG.cpp, src/Font.cpp, src/Font.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/SVGTree.cpp, src/SVGTree.h: + added class GFGlyphTracer::Callback providing an interface used to print + status information about the tracer + + * src/DVIToSVG.cpp, src/SVGTree.cpp: + moved creation of SVG 'use' elements from class DVIToSVG to class + SVGTree + +2010-03-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.cpp, src/Calculator.cpp, src/Matrix.cpp, + src/PSInterpreter.cpp, src/PSInterpreter.h: + fixed a couple of comments + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, src/Font.cpp, + src/Font.h, src/FontEmitter.h, src/GFGlyphTracer.h, src/Makefile.am, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/SVGTree.cpp, + src/SVGTree.h, src/dvisvgm.cpp, tests/Makefile.am, tests/check-conv, + tests/create-makefile: + removed emitter classes; incorporated their functionality into SVGTree + and PhysicalFontImpl + + * src/FontCache.cpp, src/FontCache.h: + added method FontCache::write(const char *dir) that updates the cache + file of the current font + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/FontManager.cpp, src/FontManager.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/SVGTree.cpp, + src/SVGTree.h, src/VFReader.h, tests/FontManagerTest.cpp: + made FontManager a singleton + + * src/CharmapTranslator.cpp, src/CharmapTranslator.h, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Font.cpp, src/Font.h, + src/Makefile.am, src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/SVGTree.cpp, + src/SVGTree.h: + removed class CharmapTranslator + + * src/GFReader.cpp, src/GFReader.h: + replaced GFReader messages by exceptions + +2010-02-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/FontCache.cpp, src/FontCache.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h: + refactorings of GF tracer class; removed transferGlyph() + +2010-02-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/CharmapTranslator.cpp, src/CharmapTranslator.h, src/Font.cpp, + src/Font.h, src/FontCache.cpp, src/FontCache.h, src/FontEngine.cpp, + src/FontEngine.h, src/Glyph.cpp, src/Glyph.h, src/Makefile.am, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h: + removed class Glyph and incorporated its functionality into Font class + +2010-02-05 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + added evaluation of literal PS headers to PSHeaderActions + +2010-02-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.ps, src/psdefs.psc: + removed PS error handler nocurrentpoint + +2010-02-02 Martin Gieseking <martin.gieseking@uos.de> + + * fedora/dvisvgm.spec: + updated homepage and spec file + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + version updated to 0.8.8 + +2010-02-01 Martin Gieseking <martin.gieseking@uos.de> + + * tests/check-conv: + skip conversion checks by default + +2010-01-31 Martin Gieseking <martin.gieseking@uos.de> + + * tests/normalize.xsl: + some improvements to normalize.xsl + + * tests/Makefile.am, tests/check-conv, tests/create-makefile, + tests/frktest-nf-cmp.svg, tests/frktest-wf-cmp.svg, tests/frktest.dvi, + tests/normalize.xsl, tests/sample-nf-cmp.svg, tests/sample-wf-cmp.svg, + tests/sample.dvi: + added tests to check conversion results + +2010-01-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicPath.h: + fixed scaling bug in computation of glyph paths when using -n + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/CommandLine.cpp, + src/CommandLine.h: + removed CmdLineParserBase::numOptions() + +2010-01-24 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/FontCache.h, src/dvisvgm.cpp, src/options.dtd, src/options.xml: + added command-line option --libgs + +2010-01-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/CommandLine.cpp, src/options.dtd, src/options.xml: + added DTD for options.xml + +2010-01-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/Ghostscript.cpp: + fixed typo in variable name + + * NEWS: + updated NEWS + + * doc/dvisvgm.txt.in, src/FileFinder.cpp, src/Ghostscript.cpp, + src/Ghostscript.h, src/dvisvgm.cpp: + environment variable LIBGS can now be used to set the name of the GS + shared library + + * Makefile.am, README, configure.ac, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/Calculator.cpp, src/Calculator.h, src/CharmapTranslator.cpp, + src/CharmapTranslator.h, src/CmdLineParserBase.cpp, + src/CmdLineParserBase.h, src/Color.cpp, src/Color.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/CommandLine.cpp, src/CommandLine.h, src/DLLoader.cpp, src/DLLoader.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/FileFinder.cpp, + src/FileFinder.h, src/FileSystem.cpp, src/FileSystem.h, src/Font.cpp, + src/Font.h, src/FontCache.cpp, src/FontCache.h, src/FontEmitter.h, + src/FontEncoding.cpp, src/FontEncoding.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontManager.cpp, src/FontManager.h, + src/FontMap.cpp, src/FontMap.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, src/Glyph.cpp, + src/Glyph.h, src/GraphicPath.h, src/HtmlSpecialHandler.h, + src/InputBuffer.cpp, src/InputBuffer.h, src/InputReader.cpp, + src/InputReader.h, src/Length.cpp, src/Length.h, src/Makefile.am, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PageSize.cpp, + src/PageSize.h, src/Pair.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/SVGTree.cpp, + src/SVGTree.h, src/SWFWriter.cpp, src/SWFWriter.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/StreamCounter.h, src/StreamReader.cpp, src/StreamReader.h, + src/TFM.cpp, src/TFM.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/macros.h, + src/options.xml, src/psdefs.ps, src/psdefs.psc, src/types.h, + tests/BoundingBoxTest.cpp, tests/CalculatorTest.cpp, + tests/ColorSpecialTest.cpp, tests/CommandLineTest.cpp, + tests/DirectoryTest.cpp, tests/FileFinderTest.cpp, + tests/FontManagerTest.cpp, tests/FontMapTest.cpp, + tests/GraphicPathTest.cpp, tests/LengthTest.cpp, tests/Makefile.am, + tests/MatrixTest.cpp, tests/PageSizeTest.cpp, + tests/SplittedCharInputBufferTest.cpp, tests/StreamCounterTest.cpp, + tests/StreamInputBufferTest.cpp, tests/VectorStreamTest.cpp, + tests/create-makefile: + updated boilerplates + + * doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/BoundingBox.h, + src/DVIToSVG.cpp, tests/BoundingBoxTest.cpp, tests/Makefile.am: + added support for enlarging the minimal bbox by a given amount. + + * configure.ac: + updated type of kpathsea_version_string (patch by lomov_vl) + +2009-12-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/InputReader.cpp: + fixed bug in InputReader::parseUInt() + +2009-12-15 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/dvisvgm.cpp: + appied get_time patch sent by Peter Breitenlohner + +2009-12-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.h, src/Calculator.h, src/CharmapTranslator.h, + src/DVIReader.h, src/DVIToSVG.h, src/DVIToSVGActions.h, src/Font.h, + src/FontEngine.h, src/FontManager.h, src/FontMap.h, src/GFGlyphTracer.h, + src/GFReader.h, src/MessageException.h, src/MetafontWrapper.h, + src/PageSize.h, src/SVGTree.cpp, src/SVGTree.h, src/StreamReader.h, + src/VFActions.h, src/VFReader.h, src/XMLDocTypeNode.h, src/XMLDocument.h, + src/XMLNode.h, src/XMLString.h: + removed using statements from header files + +2009-11-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp, src/FontCache.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, + src/GFGlyphTracer.cpp, src/GFGlyphTracer.h, src/GFTracer.cpp, + src/Glyph.cpp, src/Glyph.h, src/GraphicPath.h, src/Makefile.am, + src/Pair.h, src/SVGFontEmitter.cpp, src/SVGFontTraceEmitter.cpp, + tests/GraphicPathTest.cpp: + removed FEGlyphCommands and replaced separate glyph class implementation + by class GraphicPath + +2009-11-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp: + avoid scaling by 1 in use elements + +2009-11-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/DLLoader.cpp, src/DLLoader.h: + fixed line endings + + * src/Ghostscript.cpp, src/Ghostscript.h: + replaced #if HAVE_LIBGS by #if defined(HAVE_LIBGS) + + * src/DVIToSVG.cpp, src/Ghostscript.cpp, src/Ghostscript.h: + replaced #if !DISABLE_GS by #if !defined(DISABLE_GS) (Peter + Breitenlohner) + +2009-11-17 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + updated NEWS + + * src/dvisvgm.cpp: + don't use email adress PACKAGE_BUGREPORT for copyright notice + + * src/CmdLineParserBase.h, src/GraphicPath.h, src/InputReader.h, + src/Makefile.am, src/PSInterpreter.h, src/SpecialManager.h: + added missing virtual destructors to avoid warnings + + * src/InputReader.cpp: + added missing initialization value (Peter Breitenlohner) + + * src/Color.cpp, src/ColorSpecialHandler.cpp, src/FontManager.cpp, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/TpicSpecialHandler.cpp: + added explicit casts to avoid compiler warnings (Peter Breitenlohner) + + * potracelib/potracelib.c, potracelib/potracelib.h: + replaced outdated string constant type char* by const char* in + potrace_version() + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.8.8dev + +2009-11-10 Martin Gieseking <martin.gieseking@uos.de> + + * fedora/dvisvgm.spec: + updated spec file + +2009-11-09 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.8.7 + + * NEWS, src/Color.cpp, src/Color.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/SVGTree.cpp: + PS handler: colors set by color specials are now considered properly + + * src/DVIToSVG.cpp, src/dvisvgm.cpp: + added total number of pages to message text + +2009-11-06 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/PsSpecialHandler.cpp: + fixed path scaling issue in PS handler + + * NEWS, doc/dvisvgm.txt.in: + updated NEWS and manpage + + * src/GraphicPath.h, src/PsSpecialHandler.cpp: + PS handler: replace zero-length paths by dots + +2009-10-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/Font.cpp, src/Font.h: + fixed positioning of italic characters + +2009-10-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/TFM.cpp, src/TFM.h: + added italic correction values to character widths + +2009-10-16 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, src/Doxyfile: + increased version to 0.8.7dev + + * tests/Makefile.am, tests/create-makefile: + added script to create tests/Makefile.am + +2009-10-13 Martin Gieseking <martin.gieseking@uos.de> + + * README, tests/CalculatorTest.cpp, tests/CalculatorTest.h, + tests/ColorSpecialTest.cpp, tests/ColorSpecialTest.h, + tests/CommandLineTest.cpp, tests/CommandLineTest.h, + tests/DirectoryTest.cpp, tests/DirectoryTest.h, tests/FileFinderTest.cpp, + tests/FileFinderTest.h, tests/FontManagerTest.cpp, + tests/FontManagerTest.h, tests/FontMapTest.cpp, tests/FontMapTest.h, + tests/GraphicPathTest.cpp, tests/GraphicPathTest.h, tests/LengthTest.cpp, + tests/LengthTest.h, tests/Makefile.am, tests/MatrixTest.cpp, + tests/MatrixTest.h, tests/PageSizeTest.cpp, tests/PageSizeTest.h, + tests/SplittedCharInputBufferTest.cpp, + tests/SplittedCharInputBufferTest.h, tests/StreamCounterTest.cpp, + tests/StreamCounterTest.h, tests/StreamInputBufferTest.cpp, + tests/StreamInputBufferTest.h, tests/VectorStreamTest.cpp, + tests/VectorStreamTest.h: + replaced cxxtest by googletest + + * doc/Makefile.am: + added missing dvi suffix in Makefile target dvi-pdf + + * fedora/dvisvgm.spec: + updated spec file + + * doc/Makefile.am, doc/dvisvgm.txt.in: + removed outdated post-processing of manpage + +2009-10-12 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontInfo.cpp, src/FontInfo.h, src/FontTracer.h, src/PSObject.cpp, + src/PSObject.h, src/PSState.cpp, src/PSState.h, src/global.cpp, + src/global.h: + removed unused source files + + * src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/Calculator.cpp, src/Calculator.h, src/CharmapTranslator.cpp, + src/CharmapTranslator.h, src/CmdLineParserBase.cpp, + src/CmdLineParserBase.h, src/Color.cpp, src/Color.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, src/DLLoader.cpp, + src/DLLoader.h, src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Directory.cpp, src/Directory.h, + src/DvisvgmSpecialHandler.h, src/EmSpecialHandler.cpp, + src/EmSpecialHandler.h, src/FileFinder.cpp, src/FileFinder.h, + src/FileSystem.cpp, src/FileSystem.h, src/Font.cpp, src/Font.h, + src/FontCache.cpp, src/FontCache.h, src/FontEmitter.h, + src/FontEncoding.cpp, src/FontEncoding.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, + src/FontManager.cpp, src/FontManager.h, src/FontMap.cpp, src/FontMap.h, + src/GFGlyphTracer.cpp, src/GFGlyphTracer.h, src/GFReader.cpp, + src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h, src/Ghostscript.cpp, + src/Ghostscript.h, src/GraphicPath.h, src/InputBuffer.cpp, + src/InputBuffer.h, src/InputReader.cpp, src/InputReader.h, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PageSize.cpp, + src/PageSize.h, src/Pair.h, src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, + src/SpecialActions.h, src/SpecialHandler.h, src/SpecialManager.cpp, + src/SpecialManager.h, src/StreamCounter.h, src/StreamReader.cpp, + src/StreamReader.h, src/TFM.cpp, src/TFM.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/macros.h, src/types.h: + code cleanup + +2009-10-11 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS: + NEWS updated + + * src/DVIToSVG.cpp, src/DvisvgmSpecialHandler.cpp, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SVGTree.cpp, + src/SVGTree.h: + suppress empty style and transformation elements + + * transfer-cs: + improved transfer-cs + +2009-10-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp: + scale clipping paths by 72.27/72 + +2009-10-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/Makefile.am: + fixed Makefile + + * src/Length.cpp, src/Length.h, tests/LengthTest.h: + fixed unit conversion bug + + * doc/dvisvgm.txt.in: + fixed formatting of manual page + + * transfer-cs: + added script to transfer changesets to dvisvgm-pub + + * autogen.sh, prepare: + prepare script replaced by autogen.sh + + * src/Bitmap.h: + fixed bit shift overflow in Bitmap class occured on 64-bit systems + +2009-10-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/dvisvgm.cpp: + fixed uncaught PageSizeException + + * src/MetafontWrapper.cpp: + fixed file permissions + + * NEWS, src/GraphicPath.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h: + PS clipping path sequences and intersections are now handled correctly + + * NEWS, doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/CommandLine.cpp, + src/CommandLine.h, src/DVIToSVG.cpp, src/DVIToSVG.h, src/dvisvgm.cpp, + src/options.xml, tests/CommandLineTest.h, tests/Makefile.am: + cmdline parameter --bbox can now be used to set the absolute bounding + box + +2009-10-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/BoundingBox.cpp, src/BoundingBox.h, src/Length.cpp, src/Length.h, + src/Makefile.am, tests/LengthTest.h: + class Length provides length unit calculations + + * NEWS, doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/BoundingBox.h, + src/DvisvgmSpecialHandler.cpp: + added the special variant 'dvisvgm:bbox abs' and 'dvisvgm:bbox fix' + +2009-10-06 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + set version to 0.8.6 + + * src/BoundingBox.cpp, src/BoundingBox.h, src/GraphicPath.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/psdefs.ps, src/psdefs.psc: + fixed some PS bounding box and positioning issues introduced by previous + changesets + +2009-10-05 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/PsSpecialHandler.cpp: + fixed another positioning bug reported by John Bowman + + * src/PsSpecialHandler.cpp: + convert PS path coordinated to TeX point units + +2009-10-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicPath.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: + corrected positioning bug introduced with previous PS positioning fix + +2009-10-02 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am, doc/dvisvgm.txt.in: + generate pdf manpage directly with groff; adapted manpage source to work + with latest asciidoc + +2009-10-01 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am, doc/dvisvgm.txt.in: + replaced backticks in manpage by apostrophes; updated date on homepage + +2009-09-30 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + increased version number to 0.8.5 + + * LGPL-2.1.txt, NEWS, README: + updated README and NEWS, and added file with LGPL license text + + * doc/dvisvgm.txt.in: + added dvisvgm:raw example to man page + +2009-09-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in: + minor changes of the documentation + + * fedora/dvisvgm.spec: + updated spec file and fixed typo on website + + * src/PsSpecialHandler.h: + increased the default linewidth to 0.5 + + * NEWS: + added cretdit to John Bowman for sending a patch for the already fixed + clipping bug + +2009-09-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileSystem.cpp, src/MetafontWrapper.cpp: + Windows: Metafont is now called via CreateProcess() + + * NEWS, doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/SpecialManager.cpp, + src/SpecialManager.h, src/dvisvgm.cpp, src/options.xml: + added option --progress for enabling a progress indicator (feature #22) + + * NEWS, src/CmdLineParserBase.cpp, src/FontCache.cpp, + src/SVGFontTraceEmitter.cpp: + fixed memory bug in tracer module (issue #21) + +2009-09-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileSystem.cpp, src/FontCache.cpp: + fixed Windows-related bug in FileSystem::collect + + * NEWS, doc/dvisvgm.txt.in, src/FileSystem.cpp, src/FileSystem.h, + src/FontCache.cpp, src/FontCache.h, src/dvisvgm.cpp: + option --cache prints additional information about the cached fonts + (feature #7) + + * src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, src/DVIToSVG.cpp, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h: + refactored prefixes methods of the SpecialHandlers (ticket #20) + +2009-09-06 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, README: + updated NEWS and README + +2009-09-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/CommandLine.cpp, + src/InputBuffer.h, src/InputReader.h, src/psdefs.psc, + tests/CommandLineTest.h: + improved the command line parser to make it more POSIX-compliant + (feature #17) + + * src/dvisvgm.cpp: + fixed evaluation of option --help + + * src/BoundingBox.cpp, src/BoundingBox.h, src/PsSpecialHandler.cpp: + linewidths are now considered properly in computation of bounding box + (issue #13) + + * configure.ac, fedora/dvisvgm.spec, src/Doxyfile: + increased version number to 0.8.4 + +2009-09-01 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp, src/psdefs.ps, src/psdefs.psc: + fixed flattened clipping path bug (issue #11) + +2009-08-31 Martin Gieseking <martin.gieseking@uos.de> + + * src/Makefile.am: + added error checks; disallow numeric optional arguments w/o default + value + +2009-08-28 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/PSInterpreter.cpp, src/PsSpecialHandler.cpp, src/dvisvgm.cpp, + src/psdefs.ps, src/psdefs.psc: + added evaluation of PS 'show' operator in order to evaluate PSTricks + Type 3 fonts properly + +2009-08-27 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, doc/dvisvgm.txt.in, src/CmdLineParserBase.cpp, + src/CommandLine.cpp, src/Doxyfile, src/dvisvgm.cpp, src/getopt.c, + src/getopt.h, src/getopt1.c, src/options.xml: + replaced option --cache=? by --cache; increased version number to 0.8.3 + +2009-08-26 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/PsSpecialHandler.cpp, + src/SpecialManager.cpp, src/SpecialManager.h: + PS prologue files referenced in first page are now always loaded + + * configure.ac, fedora/dvisvgm.spec, src/Ghostscript.cpp, + src/Ghostscript.h, src/Makefile.am: + improved Ghostscript and potrace linking checks to simplify usage of + external devel files + + * fedora/dvisvgm-0.8.1-potrace.patch, fedora/dvisvgm-gs.patch, + fedora/dvisvgm-potrace.patch, fedora/dvisvgm.spec: + updated Fedora files + +2009-08-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/CommandLine.cpp, src/CommandLine.h: + speed up printing help by using puts() instead of C++ streams + +2009-08-21 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, + src/Doxyfile: + increased version number to 0.8.2 + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/Makefile.am, + src/dvisvgm.cpp, src/options.xml, tests/CommandLineTest.h, + tests/Makefile.am: + improved CmdLineParserBase and replaced gengetopt-based parser + + * src/FontMap.cpp: + fixed memory bug in FontMap + +2009-08-20 Martin Gieseking <martin.gieseking@uos.de> + + * COPYING: + added copy of file COPYING + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h: + finished cmdline parser + + * src/CmdLineParserBase.cpp, src/CmdLineParserBase.h, src/options.xml: + added files for replacement of gengetopt (not active yet) + + * src/InputReader.cpp, src/InputReader.h: + added method parseUInt() + +2009-08-17 Martin Gieseking <martin.gieseking@uos.de> + + * COPYING, LICENSE, Makefile.am, README, doc/dvisvgm.txt.in, + src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/Calculator.cpp, src/Calculator.h, src/CharmapTranslator.cpp, + src/CharmapTranslator.h, src/Color.cpp, src/Color.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, src/DLLoader.cpp, + src/DLLoader.h, src/DVIActions.cpp, src/DVIActions.h, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Directory.cpp, + src/Directory.h, src/DvisvgmSpecialHandler.cpp, + src/DvisvgmSpecialHandler.h, src/EmSpecialHandler.cpp, + src/EmSpecialHandler.h, src/FileFinder.cpp, src/FileFinder.h, + src/FileSystem.cpp, src/FileSystem.h, src/Font.cpp, src/Font.h, + src/FontCache.cpp, src/FontCache.h, src/FontEmitter.h, + src/FontEncoding.cpp, src/FontEncoding.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, src/FontInfo.cpp, + src/FontInfo.h, src/FontManager.cpp, src/FontManager.h, src/FontMap.cpp, + src/FontMap.h, src/FontTracer.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/Ghostscript.cpp, src/Ghostscript.h, + src/GraphicPath.h, src/HtmlSpecialHandler.h, src/InputBuffer.cpp, + src/InputBuffer.h, src/InputReader.cpp, src/InputReader.h, + src/Matrix.cpp, src/Matrix.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSInterpreter.cpp, src/PSInterpreter.h, src/PSObject.cpp, + src/PSObject.h, src/PSState.cpp, src/PSState.h, src/PageSize.cpp, + src/PageSize.h, src/Pair.h, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.h, src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/SVGTree.cpp, + src/SVGTree.h, src/SWFWriter.cpp, src/SWFWriter.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/StreamCounter.h, src/StreamReader.cpp, src/StreamReader.h, + src/TFM.cpp, src/TFM.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/global.cpp, + src/global.h, src/inttypes.h, src/macros.h, src/psdefs.ps, + src/psdefs.psc, src/types.h, tests/CalculatorTest.h, + tests/ColorSpecialTest.h, tests/DirectoryTest.h, tests/FileFinderTest.h, + tests/FontManagerTest.h, tests/FontMapTest.h, tests/GraphicPathTest.h, + tests/MatrixTest.h, tests/PageSizeTest.h, + tests/SplittedCharInputBufferTest.h, tests/StreamCounterTest.h, + tests/StreamInputBufferTest.h, tests/VectorStreamTest.h: + changed license to GPL version 3 or later + + * tests/Makefile.am: + added include path to fix broken distcheck + +2009-08-10 Martin Gieseking <martin.gieseking@uos.de> + + * tests/Makefile.am: + added generated file test-all.cpp to CLEANFILES + + * Makefile.am, configure.ac, src/Makefile.am, src/tests/CalculatorTest.h, + src/tests/ColorSpecialTest.h, src/tests/DirectoryTest.h, + src/tests/FileFinderTest.h, src/tests/FontManagerTest.h, + src/tests/FontMapTest.h, src/tests/GraphicPathTest.h, + src/tests/MatrixTest.h, src/tests/PageSizeTest.h, + src/tests/SplittedCharInputBufferTest.h, src/tests/StreamCounterTest.h, + src/tests/StreamInputBufferTest.h, src/tests/VectorStreamTest.h, + src/tests/dvipdfm_test.map, src/tests/dvips_test.map, + tests/CalculatorTest.h, tests/ColorSpecialTest.h, tests/DirectoryTest.h, + tests/FileFinderTest.h, tests/FontManagerTest.h, tests/FontMapTest.h, + tests/GraphicPathTest.h, tests/Makefile.am, tests/MatrixTest.h, + tests/PageSizeTest.h, tests/SplittedCharInputBufferTest.h, + tests/StreamCounterTest.h, tests/StreamInputBufferTest.h, + tests/VectorStreamTest.h, tests/dvipdfm_test.map, tests/dvips_test.map: + moved tests from src/tests to ./tests + + * fedora/dvisvgm-0.8.1-potrace.patch, fedora/dvisvgm.spec, + rpm/dvisvgm.spec: + added spec file and patch for Fedora builds + +2009-08-02 Martin Gieseking <martin.gieseking@uos.de> + + * LICENSE, Makefile.am, rpm/dvisvgm.spec, rpm/dvisvgm.spec.in, + src/Ghostscript.cpp: + modified package to be compatible with prerequisites of Fedora + +2009-07-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/Ghostscript.cpp, src/Ghostscript.h, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: + added Ghostscript revision info to output of dvisvgm -l + + * configure.ac, src/DVIToSVG.cpp: + added target triplet to version string in SVG output + +2009-07-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.psc: + added vim tag to psdefs.psc + +2009-07-28 Martin Gieseking <martin.gieseking@uos.de> + + * src/gencmdline.bat, src/psdefs.psc: + cleaned up VC++ build files; added batch file to generate cmdline.c; + added generated file psdefs.psc for convenience + + * NEWS, src/FileSystem.cpp, src/FontEngine.cpp, src/FontManager.cpp, + src/Ghostscript.cpp, src/PageSize.cpp, src/dvisvgm.cpp: + fixed bug related to unsigned/size_t mismatch on x64 systems + + * NEWS, configure.ac, src/Doxyfile: + updated version number to 0.8.1 + + * src/PsSpecialHandler.cpp: + added evaluation of more psfile parameters; fixed psfile bounding box + bug + +2009-07-27 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.h, src/InputBuffer.cpp, src/InputBuffer.h, + src/InputReader.cpp, src/InputReader.h, src/Matrix.cpp, src/Matrix.h, + src/PSInterpreter.h: + replaced size_t parameters by unsigned + + * NEWS, README: + fixed typos; updated homepage/manpage + + * src/DLLoader.cpp, src/InputReader.cpp, src/PSInterpreter.cpp: + changes to make VC happy; fixed potential memory bug + +2009-07-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp: + some clean-ups + +2009-07-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/TpicSpecialHandler.cpp: + fixed reintroduced bug in TPIC handler + + * NEWS, README, doc/dvisvgm.txt.in, src/BoundingBox.cpp, + src/BoundingBox.h, src/GraphicPath.h, src/PSInterpreter.cpp, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, src/psdefs.ps: + fixed clipping bug; updated homepage, README, NEWS + +2009-07-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/PsSpecialHandler.cpp, src/SVGTree.cpp: + fixed bbox bug; added missing file + + * src/DvisvgmSpecialHandler.cpp, src/InputBuffer.cpp, src/InputReader.cpp, + src/InputReader.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/psdefs.ps, src/tests/StreamInputBufferTest.h: + implemented psfile special; fixed some bugs + +2009-06-01 Martin Gieseking <martin.gieseking@uos.de> + + * src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.h, + src/EmSpecialHandler.cpp, src/EmSpecialHandler.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h: + transplanted changes to SpecialHandlers from branch 'pages' + + * src/GFTracer.cpp: + transplanted changes to GFTracer from branch 'pages' + + * src/VFReader.cpp: + transplanted changes to VFReader from branch 'pages' + + * src/FileSystem.cpp, src/FileSystem.h: + transplanted changes to FileSystem from branch 'pages' + + * src/DVIReader.cpp, src/DVIReader.h: + transplanted changes to DVIReader from branch 'pages' + + * src/Bitmap.cpp, src/Bitmap.h: + transplanted changes to Bitmap from branch 'pages' + + * src/InputBuffer.cpp, src/InputBuffer.h, src/Makefile.am: + transplanted changes to InputBuffer from branch 'pages' + +2009-04-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.h: + increased version of font cache files to ensure their recreation due to + the previously fixed shorthand path command bug + + * NEWS, configure.ac, src/Doxyfile: + increased version number to 0.7.3 + + * src/TpicSpecialHandler.cpp: + fixed TPIC handler bug that could caused unwanted color fills of + ellipses due to a missing call of reset() + +2009-04-02 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac, doc/dvisvgm.txt.in, src/MetafontWrapper.cpp, + src/dvisvgm.cpp: + prepared release 0.7.2 (removed inclusions of debug.h, adapted homepage + and manpage) + +2009-03-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/Doxyfile: + added doxygen files + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/FontGlyph.cpp, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/dvisvgm.cpp: + replaced Metafont magnification variable and its setters by a public + class variable + +2009-03-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontGlyph.cpp: + fixed memory bug in Glyph::optimizeCommands() + + * src/FontGlyph.cpp: + fixed potential bug in Glyph::optimizeCommands() + + * NEWS, src/FontCache.cpp, src/FontGlyph.cpp, src/FontGlyph.h, + src/GFGlyphTracer.cpp, src/Pair.h, src/SVGFontEmitter.cpp: + use of shorthand path commands has been implemented + +2009-03-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp: + cache files are being compressed now to reduce the file size + +2009-03-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp, src/SVGFontTraceEmitter.cpp: + don't read existing cache file if --trace-all is given (trace complete + font and then write cache file instead) + + * NEWS, doc/dvisvgm.txt.in, src/FontEmitter.h, src/GFGlyphTracer.cpp, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/dvisvgm.cpp, + src/options.ggo: + added option --trace-all that forces tracing of all glyphs of all + currently used bitmap fonts + +2009-03-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp, src/TFM.cpp, src/TFM.h: + added firstChar()/lastChar() to TFM class, removed unnecessary mag + member variable and its setter + + * src/FontCache.cpp: + fixed bug in read/write functions of FontCache + +2009-03-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp: + reduced size of cache file format by using variable integer sizes + + * doc/dvisvgm.txt.in, src/dvisvgm.cpp: + added option variant --cache=? to display the default cache directory + + * doc/dvisvgm.txt.in, src/DVIToSVG.cpp, src/FileSystem.cpp, + src/FileSystem.h, src/FontCache.cpp, src/FontCache.h, src/FontGlyph.h, + src/GFGlyphTracer.cpp, src/GFGlyphTracer.h, src/Makefile.am, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/dvisvgm.cpp: + completed font caching support + +2009-03-16 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, doc/dvisvgm.txt.in, src/DVIToSVG.cpp, + src/FileSystem.cpp, src/FileSystem.h, src/FontCache.cpp, src/FontCache.h, + src/FontGlyph.cpp, src/FontGlyph.h, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.h, src/GFTracer.cpp, src/options.ggo: + first additions to support font caching; not working yet + +2009-03-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/FontEmitter.h, src/SVGFontEmitter.cpp, + src/SVGFontEmitter.h, src/SVGFontTraceEmitter.cpp, + src/SVGFontTraceEmitter.h: + improved font embedding algorithm in case of --no-fonts (identical + glyphs in different sizes are now referenced rather than duplicated) + +2009-03-10 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, src/Font.h, + src/SVGFontEmitter.cpp, src/SVGFontTraceEmitter.cpp: + all glyph sizes are now computed correctly in conjuction with option + --no-fonts + +2009-03-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp: + fixed transformation bug (transformations are now applied properly to + the page) + + * src/types.h: + minor changes to homepage and .hgignore + + * src/BgColorSpecialHandler.cpp, src/SpecialManager.cpp, + src/TpicSpecialHandler.cpp: + adapted Code to make VC happy + +2009-03-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/BgColorSpecialHandler.cpp, src/BgColorSpecialHandler.h: + added missing background color handler + + * NEWS, README, src/Color.cpp, src/Color.h, src/ColorSpecialHandler.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/DvisvgmSpecialHandler.cpp, src/EmSpecialHandler.cpp, src/Makefile.am, + src/TpicSpecialHandler.cpp: + added bgcolor support, updated homepage, fixed color handler bug + +2009-03-06 Martin Gieseking <martin.gieseking@uos.de> + + * src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h: + implemented splines of tpic specials + + * src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.h: + implemented arc drawing of tpic special set + +2009-03-03 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/DvisvgmSpecialHandler.cpp, + src/DvisvgmSpecialHandler.h: + minor code improvements; comments added + + * doc/Makefile.am, doc/dvisvgm.txt.in, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/DvisvgmSpecialHandler.cpp, + src/DvisvgmSpecialHandler.h, src/InputBuffer.cpp, src/InputBuffer.h, + src/SpecialActions.h: + implemented the dvisvgm specials raw, image, and bbox + + * src/BoundingBox.cpp, src/BoundingBox.h, src/Color.cpp, + src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, src/DVIActions.h, + src/DVIBBoxActions.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/EmSpecialHandler.cpp, + src/Makefile.am, src/SpecialActions.h, src/SpecialHandler.h, + src/TpicSpecialHandler.cpp: + improved computation of the bounding box (works with specials now); + added dummy function for background color assignments + +2009-02-26 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am, doc/dvisvgm.txt.in: + improved manpage + + * doc/Makefile.am, doc/dvisvgm.txt, doc/dvisvgm.txt.in: + removed generated file, added dvisvgm.txt.in + +2009-02-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/DvisvgmSpecialHandler.cpp, src/EmSpecialHandler.cpp, + src/SpecialActions.h, src/TpicSpecialHandler.cpp: + renamed appendInPage() to appendToPage + +2009-02-24 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, doc/dvisvgm.1.in, src/TpicSpecialHandler.cpp: + few additions to tpic handler + + * NEWS, src/Color.cpp, src/Color.h, src/DVIToSVGActions.cpp, + src/Makefile.am, src/Pair.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h, src/TpicSpecialHandler.cpp, + src/TpicSpecialHandler.h: + first tpic implementations; not complete yet + + * src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/DVIToSVGActions.cpp, src/DvisvgmSpecialHandler.cpp, + src/DvisvgmSpecialHandler.h, src/EmSpecialHandler.cpp, + src/EmSpecialHandler.h, src/HtmlSpecialHandler.h, src/Makefile.am, + src/SpecialColorHandler.cpp, src/SpecialColorHandler.h, + src/SpecialDvisvgmHandler.cpp, src/SpecialDvisvgmHandler.h, + src/SpecialEmHandler.cpp, src/SpecialEmHandler.h, src/SpecialHandler.h, + src/SpecialHtmlHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/tests/ColorSpecialTest.h: + improved SpecialHandler is now able to handle unprefixed specials + +2009-02-23 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, doc/dvisvgm.1.in, src/DVIBBoxActions.h, + src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/FontEmitter.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, src/XMLNode.cpp, + src/XMLNode.h, src/dvisvgm.cpp, src/options.ggo, + src/tests/ColorSpecialTest.h: + added option --no-fonts wich uses path elements instead of fonts + +2009-02-20 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, doc/dvisvgm.1.in, src/Color.cpp, src/Color.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Makefile.am, + src/SpecialActions.h, src/SpecialColorHandler.cpp, + src/SpecialDvisvgmHandler.cpp, src/SpecialDvisvgmHandler.h, + src/SpecialEmHandler.cpp, src/SpecialEmHandler.h, + src/SpecialHtmlHandler.h, src/VerbSpecialHandler.cpp, + src/VerbSpecialHandler.h: + fixed bug in color handler, added skeletons of dvisvgm/hyperref special + handlers + +2009-02-18 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/SpecialActions.h, src/tests/ColorSpecialTest.h: + adapted color test to new interface, added emtex info + + * src/Color.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/Makefile.am, src/SpecialActions.h, src/SpecialColorHandler.cpp, + src/SpecialEmHandler.cpp: + added color support to emTeX specials, removed Color class + +2009-02-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp: + made DVICommand local to executeCommand, removed unnecessary if + statement + +2009-02-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Makefile.am, + src/SpecialActions.h, src/SpecialManager.cpp, src/VerbSpecialHandler.cpp, + src/VerbSpecialHandler.h, src/XMLString.cpp, src/XMLString.h: + added special handler for verbatim output + +2009-02-14 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac: + prepared release of version 0.7 + + * doc/dvisvgm.1.in, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/dvisvgm.cpp, src/options.ggo: + added option --no-style + + * NEWS, configure.ac: + increased version number to 0.6.2, updated NEWS + + * src/dvisvgm.cpp: + fixed incorrect behavior of option -V/--version + + * src/Color.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h: + finished color support + +2009-02-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/ColorSpecialHandler.cpp, src/Makefile.am, + src/tests/ColorSpecialTest.h: + added tests for ColorSpecialHandler + + * prepare: + updated administrative files + + * src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Makefile.am, + src/SpecialActions.h, src/SpecialHandler.h, src/SpecialManager.cpp, + src/SpecialManager.h: + color specials are now processed by DVIToSVGActions, but don't create + any results yet + + * src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h: + reverted to previous version, removed dependency on Color class + + * hgauthors, prepare: + added administrative files + + * Makefile.am, configure.ac, src/tests/DirectoryTest.h: + removed rpm support + + * src/types.h: + replaced static definition of sized integers by template program + +2009-02-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/Color.h, src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/Makefile.am: + replaced RGB arrays by Color class + +2009-02-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/TransformationMatrix.cpp: + made y-coordinate of cmdline-option -t optional + +2009-02-06 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp: + changed lookup order of font maps + + * doc/dvisvgm.1.in, src/ColorSpecialHandler.h, src/DVIToSVG.cpp, + src/DVIToSVG.h, src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h, + src/dvisvgm.cpp, src/options.ggo: + added option --list-specials that lists all registered special handlers + +2009-02-05 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp: + replaced special ignore list evaluation algorithm + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/dvisvgm.cpp, src/options.ggo: + added optional prefix list to commandline option --no-specials + + * src/extract-colors.php: + added php-script that extracts color definitions from color.pro + +2009-02-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontMap.cpp: + added output of font encoding in write method + + * src/FileFinder.cpp: + added option for additional loading of user maps + +2009-02-03 Martin Gieseking <martin.gieseking@uos.de> + + * map/cork-lm.map: + removed deprecated map subdirectory + + * src/FileFinder.cpp, src/FileFinder.h, src/dvisvgm.cpp: + option -m/--map-file is now evaluated properly + + * src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/SpecialHandler.h, + src/SpecialManager.cpp, src/SpecialManager.h, src/options.ggo: + more color special implementation (color constants), still not ready + +2009-02-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h: + some refactorings in color handler + + * src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.h, src/Makefile.am, + src/SpecialHandler.h, src/SpecialManager.cpp, src/SpecialManager.h: + added special support skeletons; not working yet + + * NEWS, src/FileFinder.cpp: + fixed buggy call of maketfm/makemf in Windows version + +2009-01-30 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, src/DVIReader.cpp, src/DVIReader.h: + fixed magnification bug + + * src/dvisvgm.cpp: + prevented writing zero-length svg files; simplified main code by using + auto pointers + +2009-01-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp: + adapted Windows version to new release + +2009-01-28 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, configure.ac, doc/dvisvgm.1.in: + adapted configuration and documentation to new dvips map file support + + * src/FileFinder.cpp, src/FontMap.cpp, src/FontMap.h, + src/tests/FontMapTest.h, src/tests/dvips_test.map: + FontMap now supports dvips and dvipdfm maps + + * src/Calculator.cpp, src/DVIToSVG.cpp, src/FontEncoding.cpp, + src/FontMap.cpp, src/SVGFontEmitter.cpp, src/SVGFontTraceEmitter.cpp: + replaced comparisions with "" with calls of empty() + + * src/FontMap.cpp, src/Makefile.am, src/tests/FontMapTest.h, + src/tests/dvipdfm_test.map, src/tests/dvips_test.map: + extensions to FontMap almost complete but not finished yet + + * src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h: + improved GFTracer to support unscaled results + + * src/dvisvgm.cpp: + use new initialisation of FileFinder + + * src/FileFinder.cpp, src/FileFinder.h, src/Makefile.am, + src/tests/DirectoryTest.h, src/tests/FileFinderTest.h, + src/tests/FontManagerTest.h, src/tests/KPSFileFinderTest.h: + refactored FileFinder (implementation as singleton) + +2009-01-27 Martin Gieseking <martin.gieseking@uos.de> + + * src/GFGlyphTracer.cpp, src/GFGlyphTracer.h, src/GFTracer.cpp, + src/GFTracer.h, src/Makefile.am, src/SVGFontTraceEmitter.cpp, + src/SVGFontTraceEmitter.h: + made GFTracer a generic class with template methods + +2009-01-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/InputBuffer.h: + fixed incompatible types bug + + * src/Bitmap.cpp, src/Bitmap.h, src/GFReader.cpp, src/GFReader.h, + src/GFTracer.cpp, src/Makefile.am: + improvements to GF handling, first skeletton of gf->metapost (gfprint) + +2009-01-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontMap.cpp: + basic dvips font map support, not complete yet + + * src/CharmapTranslator.cpp, src/DVIToSVG.cpp, src/FileFinder.cpp, + src/FileFinder.h, src/Font.cpp, src/FontEncoding.cpp, + src/FontManager.cpp, src/KPSFileFinder.cpp, src/KPSFileFinder.h, + src/Makefile.am, src/MetafontWrapper.cpp, src/TFM.cpp, src/dvisvgm.cpp: + renamed KPSFileFinder to FileFinder + + * src/FontMap.cpp, src/FontMap.h: + started redesign of FontMap, not complete yet + + * src/InputBuffer.cpp, src/InputBuffer.h: + added missing include + +2009-01-23 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am, doc/dvisvgm.1.in: + manpage updates + +2009-01-22 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac: + added test whether dvipdfm.map is available + + * doc/dvisvgm.1.in, rpm/dvisvgm.spec.in, src/Bitmap.cpp, src/Bitmap.h, + src/BoundingBox.cpp, src/BoundingBox.h, src/Calculator.cpp, + src/Calculator.h, src/CharmapTranslator.cpp, src/CharmapTranslator.h, + src/DVIActions.cpp, src/DVIActions.h, src/DVIBBoxActions.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Directory.cpp, + src/Directory.h, src/FileFinder.cpp, src/FileFinder.h, + src/FileSystem.cpp, src/FileSystem.h, src/Font.cpp, src/Font.h, + src/FontEmitter.h, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, + src/FontInfo.cpp, src/FontInfo.h, src/FontManager.cpp, src/FontManager.h, + src/FontMap.cpp, src/FontMap.h, src/FontTracer.h, src/GFReader.cpp, + src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h, src/InputBuffer.cpp, + src/InputBuffer.h, src/KPSFileFinder.cpp, src/KPSFileFinder.h, + src/Makefile.am, src/Makefile.orig, src/Matrix.cpp, src/Matrix.h, + src/Message.cpp, src/Message.h, src/MessageException.h, + src/MetafontWrapper.cpp, src/MetafontWrapper.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PSObject.cpp, src/PSObject.h, src/PSState.cpp, + src/PSState.h, src/PageSize.cpp, src/PageSize.h, src/Pair.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, + src/StreamCounter.h, src/StreamReader.cpp, src/StreamReader.h, + src/TFM.cpp, src/TFM.h, src/TransformationMatrix.cpp, + src/TransformationMatrix.h, src/VFActions.h, src/VFReader.cpp, + src/VFReader.h, src/VectorStream.h, src/XMLDocTypeNode.h, + src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/global.cpp, + src/global.h, src/macros.h, src/options.ggo, src/types.h: + updated file header comments + + * src/tests/CalculatorTest.h, src/tests/DirectoryTest.h, + src/tests/FontManagerTest.h, src/tests/FontMapTest.h, + src/tests/KPSFileFinderTest.h, src/tests/PageSizeTest.h, + src/tests/StreamCounterTest.h, src/tests/VectorStreamTest.h: + updated tests + + * Makefile.am, NEWS, README, configure.ac, potracelib/Makefile.am: + updated version info to 0.6 + + * src/KPSFileFinder.cpp: + fixed throwing of COM exception + + * src/DVIReader.cpp, src/FontManager.cpp, src/KPSFileFinder.cpp: + memory leak fixed + + * src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/dvisvgm.cpp: + added support for MiKTeX' new COM interface + + * src/FontMap.cpp: + forgot to remove address operator + +2009-01-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/Calculator.cpp, src/DVIReader.cpp, src/DVIToSVGActions.cpp, + src/Directory.cpp, src/FontEncoding.cpp, src/FontEngine.cpp, + src/FontManager.cpp, src/FontMap.cpp, src/KPSFileFinder.cpp, + src/MetafontWrapper.cpp, src/PageSize.cpp, src/StreamReader.cpp, + src/TFM.cpp, src/TransformationMatrix.cpp, src/VFReader.cpp, + src/XMLDocument.cpp, src/XMLNode.cpp: + added in/out attributes to parameter documentation + + * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/FontEncoding.cpp, src/FontGlyph.cpp: + fixed bugs in handling of font encodings and virtual fonts + +2009-01-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/SVGFontEmitter.cpp: + fixed memory bug + + * src/FontEngine.cpp, src/FontEngine.h, src/SVGFontEmitter.cpp: + fixed glyph positioning bug occured in conjunction with font encoding + + * src/DVIReader.cpp, src/DVIToSVG.cpp, src/Font.h, src/FontEncoding.cpp, + src/FontEncoding.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontGlyph.cpp, src/FontGlyph.h, src/FontManager.cpp, + src/FontManager.h, src/InputBuffer.cpp, src/InputBuffer.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h: + first working version with font encoding support + +2009-01-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/FontEncoding.cpp, src/FontEncoding.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontManager.cpp, + src/FontManager.h, src/FontMap.cpp: + partly working mapping support, but yet too slow + + * src/FontEncoding.cpp, src/FontEncoding.h, src/FontEngine.cpp, + src/FontEngine.h, src/FontManager.cpp, src/FontManager.h, + src/FontMap.cpp, src/FontMap.h, src/KPSFileFinder.cpp, + src/KPSFileFinder.h: + more encoding implementations, not complete yet + +2009-01-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/TransformationMatrix.cpp: + fixed bug in argument assignment of transformation command M + +2009-01-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/TransformationMatrix.cpp: + removed a dangerous loop remained from previous code + +2009-01-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/KPSFileFinder.cpp: + added enc-file support + + * src/dvisvgm.cpp: + updated copyright string + + * src/FileSystem.cpp, src/FileSystem.h: + const string parameters + + * src/FontEncoding.cpp, src/FontEncoding.h, src/InputBuffer.cpp, + src/InputBuffer.h, src/Makefile.am: + added basic skeleton for handling of font encodings + + * potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h: + updated libpotrace to version 1.8 + +2009-01-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/CharmapTranslator.cpp: + fixed crash on loading corrupt pfb-files + +2008-06-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/Makefile.am: + adapted to latest gengetopt version + +2008-04-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp: + minor change + +2007-03-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIActions.cpp, src/DVIReader.cpp, src/DVIReader.h, + src/FontManager.cpp, src/tests/FontManagerTest.h: + few minor changes + + * NEWS, src/CharmapTranslator.cpp, src/CharmapTranslator.h, + src/DVIActions.h, src/DVIReader.cpp, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Font.h, + src/FontManager.cpp, src/Makefile.am, src/SVGFontTraceEmitter.cpp, + src/SVGFontTraceEmitter.h: + redesigned DVIActions and CharmapTranslator + +2007-03-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/DVIReader.h, src/VFActions.h: + minor fixes + + * src/DVIActions.cpp, src/DVIActions.h, src/DVIBBoxActions.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/Font.cpp, src/Font.h, + src/FontManager.cpp, src/FontManager.h, src/StreamReader.cpp, + src/StreamReader.h, src/VFActions.h, src/VFReader.cpp, src/VFReader.h, + src/VectorStream.h: + first working version 0.5, release candidate 1 + +2007-03-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/FontManager.cpp, src/FontManager.h, + src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/VFReader.cpp: + more vf implementations, not complete yet + +2007-03-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/Font.cpp, src/Font.h, src/FontManager.cpp, + src/VFActions.h, src/VFReader.cpp, src/VFReader.h: + more vf implementations + + * NEWS, doc/Makefile.in, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/FileSystem.cpp, src/FileSystem.h, + src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/Makefile.am, + src/dvisvgm.cpp, src/tests/DirectoryTest.h, src/tests/FontManagerTest.h: + reintegrated font map initialization into KPSFileFinderm adapted some + tests + +2007-03-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/dvisvgm.cpp: + implemented options -n and -m + + * src/Directory.cpp, src/Directory.h, src/KPSFileFinder.cpp, + src/KPSFileFinder.h, src/dvisvgm.cpp: + completed MiKTeX font map file look-up, fixed bug in Directory class + + * src/Calculator.cpp, src/DVIReader.cpp, src/Directory.cpp, src/Font.h, + src/FontManager.cpp, src/Makefile, src/Makefile.am, src/Makefile.in, + src/MetafontWrapper.cpp, src/VFReader.cpp, src/VectorStream.h, + src/test-all.cpp, src/tests/VectorStreamTest.h: + removed redundant code and commented code fragments, added + VectorInputStream class + + * AUTHORS, Makefile.am, README, potracelib/Makefile.am, + rpm/dvisvgm.spec.in, src/Directory.cpp, src/Directory.h, + src/KPSFileFinder.cpp, src/Makefile, src/Makefile.am, src/Makefile.in, + src/SVGFontTraceEmitter.cpp, src/test-all.cpp, src/tests/DirectoryTest.h: + implemented Directory class for Linux, added DirectoryTest + +2007-03-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/Directory.cpp, src/Directory.h, src/FileSystem.cpp, src/FontMap.cpp, + src/FontMap.h, src/KPSFileFinder.cpp: + more changes for MiKTeX support + + * NEWS, doc/Makefile, doc/Makefile.in, doc/dvisvgm.1.in, + src/DVIReader.cpp, src/DVIToSVG.cpp, src/Font.cpp, src/Font.h, + src/FontManager.cpp, src/KPSFileFinder.cpp, src/Makefile, + src/Makefile.am, src/Makefile.in, src/VFReader.cpp, src/dvisvgm.cpp, + src/test-all.cpp, src/tests/KPSFileFinderTest.h: + added KPSFileFinderTest, added EmptyFont, fixed compilation error + +2007-03-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h, src/FontManager.cpp, src/FontMap.cpp, + src/FontMap.h, src/KPSFileFinder.cpp: + made sources comaptible with MikTeX + + * src/KPSFileFinder.cpp: + bug fixed, font maps work now + + * src/CharmapTranslator.cpp, src/DVIToSVG.cpp, src/FontManager.cpp, + src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/Makefile, + src/Makefile.am, src/Makefile.in, src/MetafontWrapper.cpp, src/TFM.cpp: + added mktexFOO support and font map lookups to KPSFileFinder + +2007-03-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h, src/FontManager.cpp, src/FontMap.cpp, + src/FontMap.h, src/KPSFileFinder.cpp, src/Makefile, src/Makefile.am, + src/Makefile.in, src/StreamReader.cpp, src/TFM.cpp, src/options.ggo, + src/tests/FontMapTest.h: + more coding in the font department, not finished yet + +2007-03-09 Martin Gieseking <martin.gieseking@uos.de> + + * src/CharmapTranslator.cpp, src/CharmapTranslator.h, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, src/Font.cpp, + src/FontInfo.cpp, src/FontManager.cpp, src/GFTracer.cpp, + src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/Makefile, + src/Makefile.am, src/Makefile.in, src/MetafontWrapper.cpp, + src/MetafontWrapper.h, src/SVGFontTraceEmitter.cpp, + src/SVGFontTraceEmitter.h, src/StreamReader.cpp, src/StreamReader.h, + src/TFM.cpp, src/TFM.h, src/VFReader.cpp, src/VFReader.h, + src/dvisvgm.cpp, src/options.ggo, src/test-all.cpp: + refactorings: extracted StreamReader class, replaced generic FileFinder + support by KPSFileFinder calls + +2007-03-08 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/DVIToSVGActions.cpp, src/Font.h, src/Makefile, + src/Makefile.am, src/Makefile.in, src/Makefile.orig, src/VFActions.h, + src/VFReader.cpp, src/VFReader.h, src/dvisvgm.cpp: + plugged VFReader and its actions into the code (not usable yet) + + * src/DVIBBoxReader.cpp, src/DVIBBoxReader.h, src/Font.cpp, src/Font.h, + src/Makefile.orig, src/StreamCounter.h, src/dvisvgm.cpp: + fixed memory bug + + * doc/dvisvgm.1, src/FontEngine.h, src/Makefile.orig, src/dvisvgm.cpp, + src/tests/FontManagerTest.h: + minor changes + + * COPYING, Makefile, Makefile.am, Makefile.in, Martins_svg_neu.svg, NEWS, + aclocal.m4, cmdline.c, config.guess, config.h, config.h.in, + config.status, config.sub, configure.ac, depcomp, doc/Makefile, + doc/dvisvgm.1, doc/dvisvgm.1.in, gpl.txt, install-sh, missing, + src/FontManager.cpp, src/FontManager.h, src/Makefile.am, + src/VFReader.cpp, src/tests/FontManagerTest.h, stamp-h1, table.txt: + removed some garbage from the repository, added initial FontManagerTest + + * src/DVIActions.h, src/DVIBBoxActions.h, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/Font.cpp, src/Font.h, src/FontManager.cpp, + src/FontManager.h, src/KPSFileFinder.cpp, src/KPSFileFinder.h, + src/Makefile, src/Makefile.am, src/Makefile.in, src/Message.cpp, + src/dvisvgm.cpp, src/macros.h, src/test-all.cpp: + first unstable version with redesigned font handling + +2007-03-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/Font.cpp, src/Font.h: + added Font classes (not yet error-free) + +2007-03-06 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.h, src/DVIToSVG.cpp, src/FontManager.cpp, + src/FontManager.h: + added FontManager skeleton, fixed bug in makehead + +2007-03-03 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/FontManager.cpp, src/VFReader.cpp: + added some more skeleton code + +2007-03-02 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIReader.cpp, src/Makefile, src/Makefile.in, src/VFReader.cpp, + src/VFReader.h, src/options.ggo: + added skeleton of VFReader + +2007-01-10 Martin Gieseking <martin.gieseking@uos.de> + + * INSTALL, Makefile.am, NEWS, README, configure.ac, doc/Makefile, + doc/Makefile.am, doc/Makefile.in, doc/dvisvgm.1, doc/dvisvgm.1.in, + gzstream/COPYING.LIB, gzstream/Makefile, gzstream/README, + gzstream/gzstream.cpp, gzstream/gzstream.h, gzstream/index.html, + gzstream/logo.gif, gzstream/test_gunzip.C, gzstream/test_gzip.C, + gzstream/version, map/cork-lm.map, mkwindist.pl, potracelib/Makefile.am, + potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h, + rpm/Makefile, rpm/Makefile.am, rpm/Makefile.in, rpm/dvisvgm.spec, + rpm/dvisvgm.spec.in: + moved sources + +2007-01-09 Martin Gieseking <martin.gieseking@uos.de> + + * map/cork-lm.map, rpm/Makefile, rpm/Makefile.am, rpm/Makefile.in, + rpm/dvisvgm.spec, rpm/dvisvgm.spec.in: + moved files to trunk + + * INSTALL, Makefile.am, NEWS, README, configure.ac, doc/Makefile, + doc/Makefile.am, doc/Makefile.in, doc/dvisvgm.1, doc/dvisvgm.1.in, + gzstream/COPYING.LIB, gzstream/Makefile, gzstream/README, + gzstream/gzstream.cpp, gzstream/gzstream.h, gzstream/index.html, + gzstream/logo.gif, gzstream/test_gunzip.C, gzstream/test_gzip.C, + gzstream/version, mkwindist.pl, potracelib/Makefile.am, + potracelib/auxiliary.h, potracelib/bitmap.h, potracelib/curve.c, + potracelib/curve.h, potracelib/decompose.c, potracelib/decompose.h, + potracelib/lists.h, potracelib/potracelib.c, potracelib/potracelib.h, + potracelib/progress.h, potracelib/trace.c, potracelib/trace.h, + rpm/Makefile, rpm/Makefile.am, rpm/Makefile.in, rpm/dvisvgm.spec, + rpm/dvisvgm.spec.in, src/A, src/Bitmap.cpp, src/Bitmap.h, + src/BoundingBox.cpp, src/BoundingBox.h, src/Calculator.cpp, + src/Calculator.h, src/CharmapTranslator.cpp, src/CharmapTranslator.h, + src/DVIActions.h, src/DVIBBoxActions.h, src/DVIBBoxReader.cpp, + src/DVIBBoxReader.h, src/DVIReader.cpp, src/DVIReader.h, + src/DVIToSVG.cpp, src/DVIToSVG.h, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/FileFinder.cpp, src/FileFinder.h, + src/FileSystem.cpp, src/FileSystem.h, src/FontEmitter.h, + src/FontEngine.cpp, src/FontEngine.h, src/FontGlyph.cpp, src/FontGlyph.h, + src/FontInfo.cpp, src/FontInfo.h, src/FontMap.cpp, src/FontMap.h, + src/FontTracer.h, src/GFReader.cpp, src/GFReader.h, src/GFTracer.cpp, + src/GFTracer.h, src/KPSFileFinder.cpp, src/KPSFileFinder.h, src/Makefile, + src/Makefile.am, src/Makefile.in, src/Makefile.orig, src/Matrix.cpp, + src/Matrix.h, src/Message.cpp, src/Message.h, src/MessageException.h, + src/MetafontWrapper.cpp, src/MetafontWrapper.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PSObject.cpp, src/PSObject.h, src/PSState.cpp, + src/PSState.h, src/PageSize.cpp, src/PageSize.h, src/Pair.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, + src/StreamCounter.h, src/TFM.cpp, src/TFM.h, + src/TransformationMatrix.cpp, src/TransformationMatrix.h, + src/XMLDocTypeNode.h, src/XMLDocument.cpp, src/XMLDocument.h, + src/XMLNode.cpp, src/XMLNode.h, src/XMLString.cpp, src/XMLString.h, + src/cmdline.c, src/cmdline.h, src/dvisvgm.cpp, src/getopt.c, + src/getopt.h, src/getopt1.c, src/global.cpp, src/global.h, + src/gzstream.cpp, src/gzstream.h, src/macros.h, src/miktex-core.def, + src/miktex-kps.def, src/miktex-kps.h, src/options.ggo, src/test-all.cpp, + src/tests/CalculatorTest.h, src/tests/PageSizeTest.h, + src/tests/StreamCounterTest.h, src/types.h: + moved files to trunk subfolder + +2007-01-05 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile, Makefile.am, Makefile.in, README, config.status, configure.ac, + potracelib/Makefile.am, potracelib/bitops.h, potracelib/flate.c, + potracelib/flate.h, src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, + src/BoundingBox.h, src/Calculator.cpp, src/Calculator.h, + src/CharmapTranslator.cpp, src/CharmapTranslator.h, src/DVIActions.h, + src/DVIBBoxActions.h, src/DVIBBoxReader.cpp, src/DVIBBoxReader.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/FileFinder.cpp, + src/FileFinder.h, src/FileSystem.cpp, src/FileSystem.h, + src/FontEmitter.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontGlyph.cpp, src/FontGlyph.h, src/FontInfo.cpp, src/FontInfo.h, + src/FontMap.cpp, src/FontMap.h, src/FontTracer.h, src/GFReader.cpp, + src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h, src/KPSFileFinder.cpp, + src/KPSFileFinder.h, src/Makefile.am, src/Matrix.cpp, src/Matrix.h, + src/Message.cpp, src/Message.h, src/MessageException.h, + src/MetafontWrapper.cpp, src/MetafontWrapper.h, src/PSInterpreter.cpp, + src/PSInterpreter.h, src/PSObject.cpp, src/PSObject.h, src/PSState.cpp, + src/PSState.h, src/PageSize.cpp, src/PageSize.h, src/Pair.h, + src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, + src/StreamCounter.h, src/TFM.cpp, src/TFM.h, + src/TransformationMatrix.cpp, src/TransformationMatrix.h, + src/XMLDocTypeNode.h, src/XMLDocument.cpp, src/XMLDocument.h, + src/XMLNode.cpp, src/XMLNode.h, src/XMLString.cpp, src/XMLString.h, + src/dvisvgm.cpp, src/global.cpp, src/global.h, src/macros.h, + src/test-all.cpp, src/types.h: + minor modifications + +2007-01-03 Martin Gieseking <martin.gieseking@uos.de> + + * configure: + removed configure from repository + + * Makefile, Makefile.am, Makefile.in, config.h, config.h.in, + config.status, configure, configure.ac, doc/Makefile, + potracelib/Makefile.am, potracelib/auxiliary.h, potracelib/bitmap.h, + potracelib/bitops.h, potracelib/curve.c, potracelib/curve.h, + potracelib/decompose.c, potracelib/decompose.h, potracelib/flate.c, + potracelib/flate.h, potracelib/lists.h, potracelib/potracelib.c, + potracelib/potracelib.h, potracelib/progress.h, potracelib/trace.c, + potracelib/trace.h, src/Makefile, src/Makefile.am, src/Makefile.in: + added potracelib to distribution + + * NEWS, mkwindist.pl, src/KPSFileFinder.cpp: + updated homepage + +2006-12-31 Martin Gieseking <martin.gieseking@uos.de> + + * src/KPSFileFinder.cpp: + fixed namepsace bug + + * Makefile, config.status, configure, configure.ac, doc/Makefile, + doc/dvisvgm.1, src/FileSystem.cpp, src/FontEngine.cpp, + src/KPSFileFinder.cpp, src/Makefile, src/dvisvgm.cpp, src/test-all.cpp: + some minor fixes + + * NEWS, configure.ac, src/DVIToSVG.cpp, src/FileSystem.cpp, + src/FontEngine.cpp, src/GFTracer.cpp, src/KPSFileFinder.cpp, + src/Makefile.orig, src/Matrix.h, src/Message.cpp, src/PageSize.cpp, + src/TransformationMatrix.cpp, src/dvisvgm.cpp: + updated to MikTeX 2.5 support + +2006-08-01 Martin Gieseking <martin.gieseking@uos.de> + + * configure.ac: + enabled svn keyword expansion + + * Makefile, Makefile.in, NEWS, aclocal.m4, autom4te.cache/output.0, + autom4te.cache/requests, autom4te.cache/traces.0, config.h, config.log, + config.status, configure, configure.ac, doc/Makefile, doc/Makefile.in, + doc/dvisvgm.1, src/FontEngine.cpp, src/Makefile, src/Makefile.in, + src/cmdline.c, src/cmdline.h, src/dvisvgm.cpp: + added support for freetype version >= 2.1.1 + +2006-04-12 Martin Gieseking <martin.gieseking@uos.de> + + * src/lshort-cm.dvi, src/lshort-cm.svg, src/lshort-cm.svgz, + src/lshort.dvi, src/lshort.svg, src/lshort.svgz: + removed files that need not be version controlled + + * src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, src/BoundingBox.h, + src/Calculator.cpp, src/Calculator.h, src/CharmapTranslator.cpp, + src/CharmapTranslator.h, src/DVIActions.h, src/DVIBBoxActions.h, + src/DVIBBoxReader.cpp, src/DVIBBoxReader.h, src/DVIReader.cpp, + src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/FileFinder.cpp, + src/FileFinder.h, src/FileSystem.cpp, src/FileSystem.h, + src/FontEmitter.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontGlyph.cpp, src/FontGlyph.h, src/FontInfo.cpp, src/FontInfo.h, + src/FontMap.cpp, src/FontMap.h, src/FontTracer.h, src/GFReader.cpp, + src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h, src/KPSFileFinder.cpp, + src/KPSFileFinder.h, src/Message.cpp, src/Message.h, + src/MessageException.h, src/MetafontWrapper.cpp, src/MetafontWrapper.h, + src/PSObject.cpp, src/PSObject.h, src/PageSize.cpp, src/PageSize.h, + src/Pair.h, src/SVGFontEmitter.cpp, src/SVGFontEmitter.h, + src/SVGFontTraceEmitter.cpp, src/SVGFontTraceEmitter.h, + src/StreamCounter.h, src/TFM.cpp, src/TFM.h, + src/TransformationMatrix.cpp, src/TransformationMatrix.h, + src/XMLDocTypeNode.h, src/XMLDocument.cpp, src/XMLDocument.h, + src/XMLNode.cpp, src/XMLNode.h, src/XMLString.cpp, src/XMLString.h, + src/dvisvgm.cpp, src/global.cpp, src/global.h, src/macros.h, + src/test-all.cpp, src/tests/CalculatorTest.h, src/tests/PageSizeTest.h, + src/tests/StreamCounterTest.h, src/types.h: + changed keyword tags + + * COPYING, INSTALL, Makefile, Makefile.am, Makefile.in, + Martins_svg_neu.svg, NEWS, README, aclocal.m4, autom4te.cache/output.0, + autom4te.cache/requests, autom4te.cache/traces.0, cmdline.c, + config.guess, config.h, config.h.in, config.log, config.status, + config.sub, configure, configure.ac, depcomp, doc/Makefile, + doc/Makefile.am, doc/Makefile.in, doc/dvisvgm.1, doc/dvisvgm.1.in, + gpl.txt, gzstream/COPYING.LIB, gzstream/Makefile, gzstream/README, + gzstream/gzstream.cpp, gzstream/gzstream.h, gzstream/index.html, + gzstream/logo.gif, gzstream/test_gunzip.C, gzstream/test_gzip.C, + gzstream/version, install-sh, map/cork-lm.map, missing, mkwindist.pl, + src/A, src/Bitmap.cpp, src/Bitmap.h, src/BoundingBox.cpp, + src/BoundingBox.h, src/Calculator.cpp, src/Calculator.h, + src/CharmapTranslator.cpp, src/CharmapTranslator.h, src/DVIActions.h, + src/DVIBBoxActions.h, src/DVIBBoxReader.cpp, src/DVIBBoxReader.h, + src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVG.cpp, src/DVIToSVG.h, + src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, src/FileFinder.cpp, + src/FileFinder.h, src/FileSystem.cpp, src/FileSystem.h, + src/FontEmitter.h, src/FontEngine.cpp, src/FontEngine.h, + src/FontGlyph.cpp, src/FontGlyph.h, src/FontInfo.cpp, src/FontInfo.h, + src/FontMap.cpp, src/FontMap.h, src/FontTracer.h, src/GFReader.cpp, + src/GFReader.h, src/GFTracer.cpp, src/GFTracer.h, src/KPSFileFinder.cpp, + src/KPSFileFinder.h, src/Makefile, src/Makefile.am, src/Makefile.in, + src/Makefile.orig, src/Matrix.cpp, src/Matrix.h, src/Message.cpp, + src/Message.h, src/MessageException.h, src/MetafontWrapper.cpp, + src/MetafontWrapper.h, src/PSInterpreter.cpp, src/PSInterpreter.h, + src/PSObject.cpp, src/PSObject.h, src/PSState.cpp, src/PSState.h, + src/PageSize.cpp, src/PageSize.h, src/Pair.h, src/SVGFontEmitter.cpp, + src/SVGFontEmitter.h, src/SVGFontTraceEmitter.cpp, + src/SVGFontTraceEmitter.h, src/StreamCounter.h, src/TFM.cpp, src/TFM.h, + src/TransformationMatrix.cpp, src/TransformationMatrix.h, + src/XMLDocTypeNode.h, src/XMLDocument.cpp, src/XMLDocument.h, + src/XMLNode.cpp, src/XMLNode.h, src/XMLString.cpp, src/XMLString.h, + src/cmdline.c, src/cmdline.h, src/dvisvgm.cpp, src/getopt.c, + src/getopt.h, src/getopt1.c, src/global.cpp, src/global.h, + src/gzstream.cpp, src/gzstream.h, src/lshort-cm.dvi, src/lshort-cm.svg, + src/lshort-cm.svgz, src/lshort.dvi, src/lshort.svg, src/lshort.svgz, + src/macros.h, src/miktex-core.def, src/miktex-kps.def, src/miktex-kps.h, + src/options.ggo, src/test-all.cpp, src/tests/CalculatorTest.h, + src/tests/PageSizeTest.h, src/tests/StreamCounterTest.h, src/types.h, + stamp-h1, table.txt: + initial import + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/INSTALL b/Build/source/texk/dvisvgm/dvisvgm-1.6/INSTALL new file mode 100644 index 00000000000..a4b34144dcf --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/INSTALL @@ -0,0 +1,229 @@ +Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/LGPL-2.1.txt b/Build/source/texk/dvisvgm/dvisvgm-1.6/LGPL-2.1.txt new file mode 100644 index 00000000000..602bfc94635 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/LGPL-2.1.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-1.6/Makefile.am new file mode 100644 index 00000000000..b73dbf588f8 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/Makefile.am @@ -0,0 +1,9 @@ +## This file is part of dvisvgm +## Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> +## +## Process this file with automake. + +AUTOMAKE_OPTIONS = foreign +EXTRA_DIST = COPYING LGPL-2.1.txt +SUBDIRS = src tests doc + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/NEWS b/Build/source/texk/dvisvgm/dvisvgm-1.6/NEWS new file mode 100644 index 00000000000..45104994435 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/NEWS @@ -0,0 +1,349 @@ +dvisvgm-1.6 (2014-04-22) +- added option --zoom to "visually" scale the generated SVG graphics while + preserving the original size and position values of the graphic objects +- extended argument syntax of option --linkmark to allow to select the + box/line color +- changed default link marker from 'line' to 'box' +- changed link markers to be only split on line breaks while extended in all + other cases +- if libgs is not directly linked to the binary, dvisvgm now looks for + libgs.so.X instead of libgs.so (supported GS ABIs: X = 7, 8, 9) +- removed time stamp and machine triplet from generated SVG files +- some code improvements and refactorings + +dvisvgm-1.5.3 (2014-04-11) +- improved positioning of PostScript graphics +- fixed positioning of DVI rules/rectangles +- switched internal computations from TeX points (pt) to PostScript points (bp) + +dvisvgm-1.5.2 (2014-01-10) +- fixed handling of global font colors and color specials +- several code improvements + +dvisvgm-1.5.1 (2013-10-29) +- fixed processing of bounding box data created by the preview package +- fixed processing of font definitions across DVI pages +- fixed compilation issues occurred if processing of PS specials is disabled +- don't print the logical page number if it's equal to the physical one +- some minor code improvements + +dvisvgm-1.5 (2013-09-02) +- added support for DVI format 3 as created by pTeX in vertical/tate mode +- added support for DVI format 5 (XDV) as created by XeTeX +- replaced numeric entity references by corresponding UTF-8 characters in + generated SVG files +- added px unit to font-size attributes as used in the stylesheet section + to ensure correct computation of font sizes (LP bug #1215857) +- various code refactorings + +dvisvgm-1.4 (2013-08-02) +- added basic support for CMap files and CID-based fonts +- added character mapping from CIDs to char codes based on the encoding tables of a non-CID font +- added support for OTF fonts +- added evaluation of bounding box data generated by the preview package +- extended option --linkmark to mark hyperlinked areas with an arbitrary background color +- PS handler: improved evaluation of PS header specials +- PS handler: improved evaluation of operator 'show' +- removed DOCTYPE declaration from generated SVG files +- removed encoding attribute from xml declaration (replaces ISO-8859-1 with UTF-8) +- various code improvements and refactorings + +dvisvgm-1.3 (2013-05-13) +- added support for hyperref specials +- added command-line option --linkmarker to select the way how to mark hyperlinked areas +- dvisvgm builds for MiKTeX now try to access the Ghostscript DLL provided by MiKTeX so that + it's no longer necessary to install Ghostscript separately +- improved the handling of TFM files to avoid failures in case of malformed files +- added evaluation of Japanese Font Metric (JFM) files +- the bundled potrace library has been removed from the source tarball as it's easy to build + the latest releases from the original sources available at http://potrace.sourceforge.net +- several code refactorings + +dvisvgm-1.2.2 (2013-04-26) +- fixed a bug that prevented the lookup of fontmap files +- avoid throwing an exception but print a warning message if MiKTeX is not available +- print a warning message if PostScript specials are found but ignored +- added information about "dvisvgm -E" to the --help text and to the manpage +- various code refactorings and cleanups + +dvisvgm-1.2.1 (2013-04-09) +- updated bundled potrace library to version 1.11 +- avoid building bundled potracelib if system library is present (patch by Alexis Ballier) +- allow background color specials to create white background rectangles +- code refactorings and cleanup + +dvisvgm-1.2 (2013-03-01) +- PostScript handler: added support of tiling patterns +- PostScript handler: added support for EPS files with binary headers/footers +- added option --eps to directly convert EPS files to SVG +- added option --precision to select the number of decimal places used in the generated SVG files +- added an optional argument to --help to choose a display variant +- fixed the text alignment of the --help output +- improved handling of PostScript operator "show" +- choose the correct output location if the input file argument contains path specifiers (Windows only) + +dvisvgm-1.1 (2013-01-22) +- added evaluation of pdf:mapline and pdf:mapfile specials +- added evaluation of subfont file definitions (.sfd files) +- added support for TTC (TrueType collection) fonts +- added evaluation of font style parameters given in a font map definition +- renamed option --map-file to --fontmap +- the new option --fontmap allows multiple mapfile arguments and optional mode specifiers +- if a PostScript error occurs, dvisvgm prints an error message together with the + PS operand stack, as generated by Ghostscript +- if font checksums don't match, dvisvgm prints a warning now +- avoid throwing exceptions if referenced encoding files are not available +- added support for 64bit Windows builds +- removed compilation error when using a C++11 compiler (patch by Peter Breitenlohner) +- some code refactorings and improvements + +dvisvgm-1.0.12 (2012-09-27) +- print a message if the processing of PostScript specials is disabled +- the resulting SVG is now scaled to bp ("big point" units) properly +- added the evaluation of PS operators rectclip, rectfill, and rectstroke +- ignore dvips operator bop if present in a PS special +- fixed processing of special strings that contain newline characters + +dvisvgm-1.0.11 (2012-03-09) +- added Ghostscript to library list printed by --version=yes +- fixed a bug in the number parser that could lead to displaced objects (SF bug #3471097) +- corrected the computation of bounding boxes of DVI rules (lp bug #948713) +- improved code compatibility to make dvisvgm compile with clang++ (patch by Vladimir Lomov) +- fixed formatting issues in the manual page +- updated information about bug reporting (tracker moved to Launchpad) + +dvisvgm-1.0.10 (2011-12-18) +- introduced environment variable DVISVGM_COLORS to allow user-defined message colors +- fixed linking issue concerning libfreetype +- fixed potential clashes of character IDs + +dvisvgm-1.0.9 (2011-10-13) +- fixed segfault occurred in TeX Live Win32 caused by mf.exe being unavailable + (thanks to Akira Kakuto for tracking down the issue) +- updated bundled potrace library to version 1.10 +- some minor code improvements + +dvisvgm-1.0.8 (2011-05-31) +- PS handler: added evaluation of PS operators save, restore, and grestoreall +- PS handler: fixed potential segfault caused by invisible zero-length paths +- fixed computation of current drawing position influenced by PS and DVI actions +- don't stop Metafont conversions on errors any longer in order to convert + buggy MF fonts properly + +dvisvgm-1.0.7 (2011-05-06) +- improved overall handling of PS specials +- fixed broken PS special subset 'ps::' +- fixed scaling of PS line properties (width, dash distance, etc.) +- fixed semantics of TPIC special 'ip' (doesn't draw polygon outlines any longer) + +dvisvgm-1.0.6 (2011-04-21) +- fixed segfault occurred if a (malformed) DVI file calls set_char/put_char + without preceding font definition +- added CTRL-C handler +- MiKTeX support updated to version 2.9 +- some code refactorings + +dvisvgm-1.0.5 (2011-03-01) +- added optional integer argument to option -n to disable generation of <use> elements +- added missing unit to width/height attributes of svg root element (SF bug #3185773) +- added integrity check to font cache files +- updated bundled potrace library to version 1.9 +- fixed a couple of minor issues + +dvisvgm-1.0.4 (2010-12-18) +- added missing line width/dash pattern scaling to PS handler +- fixed scaling issue in PS positioning +- fixed compilation issue related to FreeType 2.4.0 + +dvisvgm-1.0.3 (2010-08-06) +- applied some more portability patches for TeX Live +- fixed a potential memory issue +- fixed a transformation issue regarding special 'psfile' (SF bug #3037372) + +dvisvgm-1.0.2 (2010-06-22) +- applied latest TeX Live portability patches sent by Peter Breitenlohner and Karl Berry +- fixed a potrace name clash occurred on Mac OS X Tiger +- fixed putchar() name clash occurred on Solaris +- fixed a couple of conversion warnings +- updated the test suite + +dvisvgm-1.0.1 (2010-06-11) +- fixed a memory issue in the PS handler that could lead to a segfault (SF bug #3013392) +- fixed a recursion issue in the PS handler +- suppress ANSI color code when terminating + +dvisvgm-1.0 (2010-06-08) +- conversion of multiple pages (must be enabled explicitly, see option --pages) +- added transparency support to the PS handler +- improved conversion results of the PS handler +- added support for computation of local bounding boxes +- optional colorization of dvisvgm messages (option --color) +- improved progress indicator (option --progress) +- a couple of improvements of the build system + +dvisvgm-0.9.1 (2010-04-23) +- CSS style definitions omit unnecessary fonts now +- SVG validity was broken when using font elements +- fixed two memory issues that could lead to segfaults + +dvisvgm-0.9 (2010-03-25) +- added option --exact and corresponding algorithms to compute the exact + bounding boxes of characters +- added option --keep that prevents deleting temporary font files +- extended option --trace-all by an optional boolean argument controlling + the re-tracing of glyphs +- fixed bug in evaluation of embedded PS headers +- several code refactorings + +dvisvgm-0.8.8 (2010-02-02) +- added option --libgs and evaluation of environment variable LIBGS + to overwrite the expected file name of the GS shared library + (only available if dvisvgm isn't linked against libgs and GS support + isn't completely disabled) +- option --bbox can now be used to enlarge the minimal bounding box by + a given amount +- fixed bug in evaluation of option --page +- applied patches sent by Peter Breitenlohner to prepare the integration of + dvisvgm into TeX Live +- some code refactorings + +dvisvgm-0.8.7 (2009-11-09) +- fixed a bounding box issue concerning italic corrections +- PS handler: zero-length paths are now drawn as dots +- PS handler: fixed a path positioning issue +- PS handler: colors set by color specials are now considered properly +- added macro {?nl} to be used with special dvisvgm:raw + +dvisvgm-0.8.6 (2009-10-13) +- renamed command-line option --bbox-format to --bbox +- option --bbox can now be used to set an arbitrary bounding box +- added the two special variants "dvisvgm:bbox abs" and "dvisvgm:bbox fix" +- PS clipping path sequences and intersections are now handled correctly +- fixed a PS bounding box bug +- fixed a couple of PS positioning issues reported by John Bowman +- fixed a bit shift overflow in the font tracer occurred on 64-bit systems + +dvisvgm-0.8.5 (2009-10-01) +- added an optional depth parameter to special dvisvgm:raw +- updated the man page +- added LGPL license text needed for the gzstream wrapper classes + +dvisvgm-0.8.4 (2009-09-17) +- improved the command-line parser to be more POSIX-compliant +- added a simple progress indicator for time-consuming special operations +- option --cache prints more information about the cached fonts +- fixed a clipping bug in the PostScript handler + (thanks to John Bowman for also providing a patch for this issue) +- fixed a bug in computation of the PS bounding box +- fixed a memory bug in the GF tracer module + +dvisvgm-0.8.3 (2009-08-28) +- added basic evaluation of the PostScript "show" operator + (handles PSTricks Type 3 fonts properly now) +- improved checks for Ghostscript and potrace library in configure script +- external Ghostscript and potrace development files are used if available +- PostScript header/prologue files are now loaded regardless of converted page +- replaced command-line option variant --cache=? by --cache + +dvisvgm-0.8.2 (2009-08-24) +- changed license of dvisvgm to GPL version 3 or later +- replaced getopt-based command-line parser by own implementation + in order to simplify future internationalizations +- fixed memory bug in fontmap reader + +dvisvgm-0.8.1 (2009-08-02) +- added evaluation of more psfile parameters +- fixed computation of bounding box in psfile special +- fixed compilation errors and a conversion bug occurred on x64 systems + +dvisvgm-0.8 (2009-07-27) +- experimental evaluation of PostScript specials has been added (requires + a recent version of the Ghostscript shared library libgs.so or gsdll32.dll) +- several code improvements and refactorings +- fixed compilation bug occurred when using GCC 4.4.x + +dvisvgm-0.7.3 (2009-04-24) +- fixed bug in font map reader that could cause a segmentation fault +- fixed bug in creation of shorthand path drawing commands +- fixed bug in TPIC special handler + +dvisvgm-0.7.2 (2009-04-02) +- font caching has been added (speeds up embedding of bitmap fonts) +- added option --trace-all that enables tracing of all glyphs of all + bitmap fonts used in the current DVI file. Even glyphs that are currently + not needed are considered. This avoids multiple calls of Metafont for the + same fonts. In combination with the new caching functionality this can + drastically increase the speed of successive dvisvgm calls. +- if option --no-fonts is used, all glyph sizes are now computed correctly +- use shorthand path commands in SVG fonts if possible + +dvisvgm-0.7.1 (2009-03-09) +- evaluation of a subset of emTeX specials has been added +- specials for embedding of raw SVG snippets have been added +- evaluation of TPIC specials has been added +- added background color support +- added option -n, --no-fonts that replaces fonts by paths + (enables applications w/o SVG font support to render dvisvgm's output properly) +- moved defs to top of SVG file to make Firefox's SVG renderer happy +- fixed bug in color handler + +dvisvgm-0.7 (2009-02-16) +- basic support for evaluation of specials has been added +- evaluation of color specials has been added +- renamed command-line option -S to --no-specials and inverted previous behavior +- selected special sets can be disabled by optional arguments to --no-specials + (currently only color specials) +- added option --no-style (see manpage for further details) +- added optional '+' flag to option --map-file (see manpage for further details) +- fixed \magnificaton bug (dvi magnification factor is now applied properly) +- fixed buggy call of maketfm/makemf in Windows/MiKTeX version +- fixed buggy evaluation of command-line argument -m/--map-file +- several internal code improvements + +dvisvgm-0.6.1 (2009-01-29) +- added support for dvips map files +- removed dependency on dvipdfm's map file (now ps2pk.map, psfonts.map or dvipdfm.map is used by default) +- fixed compilation bug #2535497 +- some internal refactorings + +dvisvgm-0.6 (2009-01-23) +- added support for varying font encodings +- updated MiKTeX support using its COM interface +- fixed incomplete handling of nested virtual fonts +- fixed a font handling bug that could cause segmentation faults +- fixed bug in matrix transformation code +- updated bundled potrace library to version 1.8 + +dvisvgm-0.5 (2007-03-26) +- redesigned and improved font handling +- added support for virtual fonts +- evaluation of dvipdfm's map file to find font files with differing + names (e.g. cork-lmr10 => lmr10) +- automatic invocation of mktexmf etc. in case of missing font files (tfm, mf) +- command-line option -m has been renamed to -M +- added command-line options -m/--map-file and -n/--no-mktexmf +- memory bug in StreamCounter class has been fixed +- added sources of Peter Selinger's potrace library (part of potrace, http://potrace.sourceforge.net) + to simplify the build process + +dvisvgm-0.4.3 (2007-01-03) +- problem with changed freetype API (freetype version >= 2.2.1) has been fixed +- updated MiKTeX support to version 2.5 +- minor code improvements +- some unit tests based on CxxTest (http://cxxtest.sourceforge.net) have been added + +dvisvgm-0.4.2 (2005-09-22) +- added SVG transformation options +- some bugfixes in command line frontend and TFM handling +- code refactorings to improve modularity and extensibility + +dvisvgm-0.4.1 (2005-09-02) +- added option -b to specify the bounding box +- added a manual page + +dvisvgm-0.4 (2005-08-24) +- Added a glyph tracing module that vectorizes Metafont's bitmap output + if no corresponding Type 1 font file is available. + +dvisvgm-0.3 (2005-08-10) +- Initial public release with basic conversion functionality. diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/README b/Build/source/texk/dvisvgm/dvisvgm-1.6/README new file mode 100644 index 00000000000..2454a2a23f4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/README @@ -0,0 +1,110 @@ +dvisvgm -- A DVI to SVG converter + +DESCRIPTION + + dvisvgm is a utility for TeX/LaTeX users. It converts + DVI files to the XML-based scalable vector graphics format SVG. + + +DEPENDENCIES + + dvisvgm relies on the following free libraries: + * FreeType 2 (http://www.freetype.org) + This library is used to extract glyph outlines + from PFB files. + + * Ghostscript (http://pages.cs.wisc.edu/~ghost) + The PostScript special handler requires the Ghostscript + library libgs.so (Linux) or gsdll32.dll/gsdll64.dll (Windows) + to be installed. If the configure script finds the corresponding + Ghostscript development files on the system, it directly + links against libgs.so. Otherwise, the library is looked up + at runtime and PostScript support is enabled only if libgs.so + could be found. + Due to incompatible changes of the Ghostscript API, dvisvgm + requires Ghostscript 8.31 or later. + + * kpathsea + This library is part of the Web2C package and is + usually installed in conjunction with a TeX distribution. + kpathsea provides functions for searching files in the + large texmf tree. + + * potracelib (http://potrace.sourceforge.net) + Peter Selinger's bitmap tracing library is utilized to + vectorize Metafont's bitmap output. + + * zlib (http://www.zlib.org) + Compressed SVG files are produced by using functions + of this library and the Gzstream wrapper classes + (http://www.cs.unc.edu/Research/compgeom/gzstream) + which are licensed under LGPL version 2.1 (or optionally any + later version) and should be included with this package. + + If you want to build and run the testsuite located in the tests + subdirectory, you also need the googletest libraries + (http://code.google.com/p/googletest). + + +COMPILATION + + Quick installation info: + * type "./configure" + * type "make" + * type "make install" as root (or "sudo make install") + + For generic configuration instructions see the file INSTALL. + + The configure script should recognize all necessary parameters. + If a library is installed but not detected, specify its location + as commandline parameter of configure, e.g. + ./configure --with-freetype=/usr/local/freetype + (all available options can be displayed with ./configure --help) + + The tracer module calls Metafont in case of lacking TFM or PFB files + via a system call. Please ensure that Metafont is installed and + reachable through the search path. + + If you don't like compiling the sources yourself, you can + download pre-compiled executables for Windows and MiKTeX + from sourceforge.net instead (see below). + + +USAGE + Information about the command-line interface and the available options + can be found in the manual page. + + +ADDITIONAL INFORMATION + This package is available from CTAN (dviware/dvisvgm) and can + be downloaded from the project website at sourceforge.net as well: + + http://dvisvgm.sourceforge.net + + Here you can find the sources, pre-compiled binaries and further additional + information about the converter and related topics. + + If you've found a bug, please let me know. You can either send me an + email or preferably use the bug tracker at Launchpad + (see https://launchpad.net/dvisvgm). + + +COPYRIGHT + + Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> + + 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 3 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, see <http://www.gnu.org/licenses/>. + + See the file COPYING for details. + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/config.h.in b/Build/source/texk/dvisvgm/dvisvgm-1.6/config.h.in new file mode 100644 index 00000000000..fcd8cf41872 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/config.h.in @@ -0,0 +1,169 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if the `closedir' function returns void instead of `int'. */ +#undef CLOSEDIR_VOID + +/* Set to 1 if PostScript support should be disabled */ +#undef DISABLE_GS + +/* Define to 1 if `TIOCGWINSZ' requires <sys/ioctl.h>. */ +#undef GWINSZ_IN_SYS_IOCTL + +/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the `ftime' function. */ +#undef HAVE_FTIME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `gs' library (-lgs). */ +#undef HAVE_LIBGS + +/* Define to 1 if you have the <libintl.h> header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the `kpathsea' library (-lkpathsea). */ +#undef HAVE_LIBKPATHSEA + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `potrace' library (-lpotrace). */ +#undef HAVE_LIBPOTRACE + +/* Define to 1 if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/timeb.h> header file. */ +#undef HAVE_SYS_TIMEB_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if the kpathsea headers are not C++ safe. */ +#undef KPSE_CXX_UNSAFE + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* The machine triplet of the target system */ +#undef TARGET_SYSTEM + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/configure.ac b/Build/source/texk/dvisvgm/dvisvgm-1.6/configure.ac new file mode 100644 index 00000000000..934dffccbb0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/configure.ac @@ -0,0 +1,166 @@ +# This file is part of dvisvgm +# Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> +# +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([dvisvgm],[1.6],[martin.gieseking@uos.de]) +DATE="April 2014" +AC_CONFIG_SRCDIR(src) +AC_CONFIG_HEADER(config.h) +AC_CANONICAL_HOST +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE + +AH_TEMPLATE([TARGET_SYSTEM], [The machine triplet of the target system]) +AC_DEFINE_UNQUOTED([TARGET_SYSTEM], ["$target"]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +AC_PROG_RANLIB +AC_LANG(C) + +AC_CHECK_FUNCS([ftime gettimeofday]) +AC_CHECK_HEADERS([sys/time.h sys/timeb.h]) +AC_HEADER_TIOCGWINSZ + +AC_CHECK_HEADER([kpathsea/kpathsea.h], , + [AC_MSG_ERROR([please install the kpathsea development package])]) +AC_CHECK_LIB(kpathsea, kpse_find_file, , + [AC_MSG_ERROR([libkpathsea not found, please install the corresponding package first])]) + +AC_MSG_CHECKING([kpathsea version]) +AC_RUN_IFELSE([AC_LANG_SOURCE([#include <stdio.h> + #include <kpathsea/kpathsea.h> + int main() { + FILE *f; + f = fopen("kpseversion", "w"); + if(!f) exit(1); + fprintf(f, "%s\n", KPSEVERSION); + fclose(f); + exit(0); + }])], + [kpseversion=`cat kpseversion|sed 's/kpathsea version //'`], [kpseversion=], [kpseversion=unknown]) +AC_MSG_RESULT("$kpseversion") +rm -f kpseversion +if test -z "$kpseversion"; then + AC_MSG_ERROR([Could not compile a simple kpathsea program -- check your installation]) +fi + + +# Check how to link potracelib +HAVE_LIBPOTRACE=1 +AC_CHECK_HEADER([potracelib.h], + [AC_CHECK_LIB(m, sqrt) # required to pass potrace check + AC_CHECK_LIB(potrace, potrace_trace, , HAVE_LIBPOTRACE=0)], HAVE_LIBPOTRACE=0) + +if test "$HAVE_LIBPOTRACE" -eq 0; then + AC_MSG_ERROR([potrace library not found]) +fi + + +# Check how to link Ghostscript +HAVE_LIBGS=1 +AC_CHECK_HEADER([ghostscript/iapi.h], + AC_CHECK_LIB(gs, gsapi_new_instance, , HAVE_LIBGS=0), HAVE_LIBGS=0) + +if test "$HAVE_LIBGS" -eq 0; then + AC_CHECK_LIB(dl, dlopen, , + [AC_DEFINE(DISABLE_GS, 1, [Set to 1 if PostScript support is to be disabled]) + AC_MSG_WARN(PostScript support disabled)]) +else + # query Ghostscript version + AC_MSG_CHECKING([Ghostscript version]) + AC_RUN_IFELSE([AC_LANG_SOURCE([#include <stdio.h> + #include <ghostscript/iapi.h> + int main () { + gsapi_revision_t r; + if (gsapi_revision(&r, sizeof(gsapi_revision_t)) == 0) { + FILE *f; + f = fopen("gsversion", "w"); + if (!f) exit(1); + fprintf(f, "%ld\n", r.revision); + fclose(f); + exit(0); + } + }])], + [gsversion=`cat gsversion`], [gsversion=], [gsversion=unknown]) + AC_MSG_RESULT("$gsversion") + rm -f gsversion + if test "$gsversion" -lt 831; then + # current Ghostscript API was introduced in version 8.31 + # older versions are not supported + LIBS=`echo $LIBS | sed "s/-lgs //" $LIBS` + AC_DEFINE(DISABLE_GS, 1, [Set to 1 if PostScript support should be disabled]) + AC_MSG_WARN([Ghostscript version < 8.31 found; PostScript support disabled]) + fi +fi + +# Check for pkg-config +PKG_PROG_PKG_CONFIG + +# Check for libraries. +PKG_CHECK_MODULES([FREETYPE], [freetype2]) +CXXFLAGS="$CXXFLAGS ${FREETYPE_CFLAGS}" +LIBS="$LIBS ${FREETYPE_LIBS}" + +AC_CHECK_LIB(z, gzopen) + +# Check for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_CHECK_HEADERS([libintl.h stdlib.h string.h strings.h unistd.h]) + +# Check for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_STRUCT_TM + +# Check for library functions. +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_ERROR_AT_LINE +AC_FUNC_MALLOC +AC_FUNC_STAT +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([memset strcasecmp strtol]) + +# add options for selection of "optional" library locations +# currently these libraries are mandatory; the --with-foo options +# are used to specify the locations explicitely + +AC_ARG_WITH(zlib,[ --with-zlib=DIR location of the zlib library], + [if test "$withval" != no; then + if test "$withval" != yes; then + ZLIB_DIR=$withval + fi + fi]) + +if test "$withval" != no; then + if test -n "$ZLIB_DIR"; then + CPPFLAGS="$CPPFLAGS -I$ZLIB_DIR -I$ZLIB_DIR/include" + LDFLAGS="$LDFLAGS -L$ZLIB_DIR/lib" + fi +fi + +# Check if the kpathsea headers are C++ safe +AC_MSG_CHECKING([if the kpathsea headers are C++ safe]) +AC_LANG_PUSH([C++]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <kpathsea/kpathsea.h>]], + [[printf("%s\n", concat("one", "two"))]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_DEFINE([KPSE_CXX_UNSAFE], 1, + [Define to 1 if the kpathsea headers are not C++ safe.])]) +AC_LANG_POP([C++]) + +AC_SUBST(DATE) +AC_SUBST(EXTRA_LIBS) +AC_SUBST(AM_CPPFLAGS) +AC_SUBST(AM_LDFLAGS) +AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile doc/dvisvgm.txt doc/Makefile]) +AC_OUTPUT + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/Makefile.am new file mode 100644 index 00000000000..13254cb773a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/Makefile.am @@ -0,0 +1,39 @@ +## This file is part of dvisvgm +## Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> +## +## Process this file with automake. + +man_MANS = dvisvgm.1 +EXTRA_DIST = $(man_MANS) + +dvisvgm.1: dvisvgm.txt + if [ `type -p a2x` ]; then \ + a2x -dmanpage -fmanpage -L -a icons -a 'iconsdir=.' $<; \ + rm -f dvisvgm.xml; \ + fi + +dvisvgm.pdf: dvisvgm.1 + echo '[ /Author (Martin Gieseking) /Title (dvisvgm manual page) /Subject (manual page of dvisvgm @VERSION@) /DOCINFO pdfmark' >tmp.ps + man -t ./$< >>tmp.ps + ps2pdf tmp.ps $@ + rm -f tmp.ps + +dvi-pdf: dvisvgm.dvi + dvipdfm $< + rm -f $< + +dvisvgm.dvi: dvisvgm.1 + groff -Tdvi -mandoc ./$< >$@ + +dvisvgm.html: dvisvgm.txt + asciidoc -a icons -a 'iconsdir=.' -a badges -a 'revnumber=@VERSION@' --unsafe -dmanpage $< + +html: dvisvgm.html +man: dvisvgm.1 +pdf: dvisvgm.pdf + +clean: + rm -f dvisvgm.pdf dvisvgm.html dvisvgm.xml dvisvgm.txt + +distclean-local: + rm -f dvisvgm.pdf dvisvgm.html dvisvgm.xml dvisvgm.txt dvisvgm.1 diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.1 b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.1 new file mode 100644 index 00000000000..0c65adf919a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.1 @@ -0,0 +1,1103 @@ +'\" t +.\" Title: dvisvgm +.\" Author: Martin Gieseking <martin.gieseking@uos.de> +.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> +.\" Date: 04/23/2014 +.\" Manual: dvisvgm Manual +.\" Source: dvisvgm 1.6 +.\" Language: English +.\" +.TH "DVISVGM" "1" "04/23/2014" "dvisvgm 1\&.6" "dvisvgm Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +dvisvgm \- converts DVI files to the XML\-based SVG format +.SH "SYNOPSIS" +.sp +\fBdvisvgm\fR [ \fIoptions\fR ] \fIfile\fR [\&.dvi] +.sp +\fBdvisvgm\fR \-E [ \fIoptions\fR ] \fIfile\fR [\&.eps] +.SH "DESCRIPTION" +.sp +The command\-line utility \fBdvisvgm\fR converts DVI files, as generated by TeX/LaTeX, to the XML\-based scalable vector graphics format SVG\&. It supports the classic DVI format 2 as well as format 3 (created by pTeX in vertical mode), and format 5 which is also known as XDV (created by XeTeX)\&. Besides the basic DVI commands, dvisvgm also evaluates many so\-called \fIspecials\fR which heavily extend the capabilities of the DVI format\&. For a more detailed overview, see section \fBsupport of specials\fR below\&. +.sp +Since the current SVG standard 1\&.1 doesn\(cqt specify multi\-page graphics, dvisvgm creates separate SVG files for each DVI page\&. Because of compatibility reasons, only the first page is converted by default\&. In order to select a different page or arbitrary page sequences, use option \fB\-p\fR which is described below\&. +.sp +SVG is a vector\-based graphics format and therefore dvisvgm tries to convert the glyph outlines of all used fonts to scalable path descriptions\&. The fastest way to do that is to extract the path information from font files in PFB, TTF, or OTF format\&. If dvisvgm is able to find such a file, it extracts all necessary outline information about the glyphs from it\&. +.sp +However, TeX\(cqs main source for font descriptions is Metafont, which produces bitmap output (GF files)\&. That\(cqs why not all obtainable TeX fonts are available in a scalable format\&. In these cases, dvisvgm tries to vectorize Metafont\(cqs output by tracing the glyph bitmaps\&. The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are nonetheless really nice in most cases\&. +.sp +When running dvisvgm without option \fB\-\-no\-fonts\fR, \fIfont\fR elements (<font>\&...</font>) are used to embed the font data into the SVG files\&. Unfortunately, only few SVG renderes support these elements yet\&. Most web browsers and vector graphics applications don\(cqt evaluate them properly so that the text components of the resulting graphics might look strange\&. In order to create more compatible SVG files, command\-line option \fB\-\-no\-fonts\fR can be given to replace the font elements by plain graphics paths\&. +.SH "OPTIONS" +.PP +\fB\-a, \-\-trace\-all\fR=[\fIretrace\fR] +.RS 4 +This option forces dvisvgm to trace not only the actually needed glyphs but all glyphs of all bitmap fonts used in the DVI file\&. Since the tracing results are stored in the font cache, all following DVI conversions (without option +\fB\-\-trace\-all\fR) where these fonts are involved, will be much faster\&. By default, dvisvgm traces only the actually needed glyphs, and adds them to the cache\&. The boolean option +\fIretrace\fR +determines how to handle glyphs already stored in the cache\&. By default, these glyphs are skipped\&. Setting argument +\fIretrace\fR +to +\fIyes\fR +or +\fItrue\fR +forces dvisvgm to trace the corresponding bitmaps again\&. +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +This option only takes affect if font caching is active\&. Thus, +\fB\-\-trace\-all\fR +cannot be combined with option +\fB\-\-cache=none\fR\&. +.sp .5v +.RE +.RE +.PP +\fB\-b, \-\-bbox\fR=\fIfmt\fR +.RS 4 +Sets the bounding box of the generated graphic to the specified format\&. The parameter +\fIfmt\fR +takes either one of the format specifiers listed below, or a sequence of four comma\- or whitespace\-separated length values +\fIx1\fR, +\fIy1\fR, +\fIx2\fR +and +\fIy2\fR\&. The latter define two diagonal corners of the bounding box\&. Each length value consists of a floating point number and an optional length unit (pt, bp, cm, mm, in, or pc)\&. If the unit is omitted, TeX points (pt) are assumed\&. +.sp +It\(cqs also possible to give only one length value +\fIl\fR\&. In this case, the minimal bounding box is computed and enlarged by adding (\-\fIl\fR,\-\fIl\fR) to the upper left and (\fIl\fR,\fIl\fR) to the lower right corner\&. +.sp +Alternatively, the following format specifiers are supported: +.PP +\fBInternational DIN/ISO paper sizes\fR +.RS 4 +A\fIn\fR, B\fIn\fR, C\fIn\fR, D\fIn\fR, where +\fIn\fR +is a non\-negative integer, e\&.g\&. A4 or a4 for DIN/ISO A4 format (210mm \(mu 297mm)\&. +.RE +.PP +\fBNorth American paper sizes\fR +.RS 4 +invoice, executive, legal, letter, ledger +.RE +.PP +\fBSpecial bounding box sizes\fR +.RS 4 +.TS +tab(:); +lt lt +lt lt +lt lt. +T{ +\fBdvi\fR +T}:T{ +page size stored in the DVI file +T} +T{ +\fBmin\fR +T}:T{ +computes the minimal/tightest bounding box +T} +T{ +\fBnone\fR +T}:T{ +no bounding box is assigned +T} +.TE +.sp 1 +.RE +.PP +\fBPage orientation\fR +.RS 4 +The default page orientation for DIN/ISO and American paper sizes is +\fIportrait\fR, i\&.e\&. +\fIwidth\fR +< +\fIheight\fR\&. Appending +\fB\-landscape\fR +or simply +\fB\-l\fR +to the format string switches to +\fIlandscape\fR +mode (\fIwidth\fR +> +\fIheight\fR)\&. For symmetry reasons you can also explicitly add +\fB\-portrait\fR +or +\fB\-p\fR +to indicate the default portrait format\&. Note that these suffixes are part of the size string and not separate options\&. Thus, they must directly follow the size specifier without additional blanks\&. Furthermore, the orientation suffixes can\(cqt be used with +\fBdvi\fR, +\fBmin\fR, and +\fBnone\fR\&. +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +Option +\fB\-b, \-\-bbox\fR +only affects the bounding box and does not transform the page content\&. Hence, if you choose a landscape format, the page won\(cqt be rotated\&. +.sp .5v +.RE +.RE +.RE +.PP +\fB\-C, \-\-cache\fR[=\fIdir\fR] +.RS 4 +To speed up the conversion process of bitmap fonts, dvisvgm saves intermediate conversion information in cache files\&. By default, these files are stored in $HOME/\&.dvisvgm/cache\&. If you prefer a different location, use option +\fB\-\-cache\fR +to overwrite the default\&. Furthermore, it is also possible to disable the font caching mechanism completely with option +\fB\-\-cache=none\fR\&. If argument +\fIdir\fR +is omitted, dvisvgm prints the path of the default cache directory together with further information about the stored fonts\&. Additionally, outdated and corrupted cache files are removed\&. +.RE +.PP +\fB\-\-color\fR +.RS 4 +Enables colorization of messages printed during the conversion process\&. The colors can be customized via the environment variable +DVISVGM_COLORS\&. See the ENVIRONMENT section below for further information\&. +.RE +.PP +\fB\-E, \-\-eps\fR +.RS 4 +If this option is given, dvisvgm does not expect a DVI but an EPS input file, and tries to convert it to SVG\&. In order to do so, a single +\fIpsfile\fR +special command is created and forwarded to the PostScript special handler\&. This option is only available if dvisvgm was built with PostScript support enabled, and requires Ghostscript to be available\&. See option +\fB\-\-libgs\fR +for further information\&. +.RE +.PP +\fB\-e, \-\-exact\fR +.RS 4 +If this option is given, dvisvgm computes the precise bounding box of each character\&. By default, the values stored in a font\(cqs TFM file are used to determine a glyph\(cqs extent\&. As these values are intended to implement optimal character placements and are not designed to represent the exact dimensions, they don\(cqt necessarily correspond with the bounds of the visual glyphs\&. Thus, width and/or height of some glyphs may be larger (or smaller) than the respective TFM values\&. As a result, this can lead to clipped characters at the bounds of the SVG graphics\&. With option +\fB\-\-exact\fR +given, dvisvgm analyzes the actual shape of each character and derives a usually tight bounding box\&. +.RE +.PP +\fB\-m, \-\-fontmap\fR=\fIfilenames\fR +.RS 4 +Loads and evaluates a single or multiple font map files\&. These files are required to resolve font file names and encodings\&. dvisvgm does not provide its own map files but tries to read available ones coming with dvips or dvipdfm\&. If option +\fB\-\-fontmap\fR +is omitted, dvisvgm looks for the default map files +ps2pk\&.map, +dvipdfm\&.map, and +psfonts\&.map +(in this order)\&. Otherwise, the listed files are used\&. Multiple filenames must be separated by commas without leading and/or trailing whitespace\&. The map files are evaluated in the given order\&. By default, redefined mappings do not replace previous ones\&. However, each filename can be preceded by an optional mode specifier (\fB+\fR, +\fB\-\fR, or +\fB=\fR) to change this behavior: +.PP ++mapfile +.RS 4 +Only those entries in the given map file that don\(cqt redefine a font mapping are applied\&. That\(cqs also the default mode if no mode specifier is given\&. +.RE +.PP +\-mapfile +.RS 4 +Ensures that none of the font mappings defined in the given map file are used, i\&.e\&. previously defined mappings for the specified fonts are removed\&. +.RE +.PP +=mapfile +.RS 4 +All mappings defined in the map file are applied\&. Previously defined settings for the same font are replaced\&. +.sp +If the first filename in the filename sequence is preceded by a mode specifier, dvisvgm loads the default font map (see above) and applies the other map files afterwards\&. Otherwise, none of default map files will be loaded automatically\&. +.sp +Examples: +\fB\-\-fontmap=myfile1\&.map,+myfile2\&.map\fR +loads +myfile1\&.map +followed by +myfile2\&.map +where all redefinitions of +myfile2\&.map +are ignored\&. +\fB\-\-fontmap==myfile1\&.map,\-myfile2\&.map\fR +loads the default map file followed by +myfile1\&.map +and +myfile2\&.map +where all redefinitions of +myfile1\&.map +replace previous entries\&. Afterwards, all definitions for the fonts given in +myfile2\&.map +are removed from the font map tree\&. +.sp +For further information about the map file formats and the mode specifiers, see the manuals of dvips and dvipdfm\&. +.RE +.RE +.PP +\fB\-h, \-\-help\fR[=\fImode\fR] +.RS 4 +Prints a short summary of all available command\-line options\&. The optional +\fImode\fR +parameter is an integer value between 0 and 2\&. It selects the display variant of the help text\&. Mode 0 lists all options divided into categories with section headers\&. This is also the default if dvisvgm is called without parameters\&. Mode 1 lists all options ordered by the short option names, while mode 2 sorts the lines by the long option names\&. +.RE +.PP +\fB\-\-keep\fR +.RS 4 +Disables the removal of temporary files as created by Metafont (usually \&.gf, \&.tfm, and \&.log files)\&. +.RE +.PP +\fB\-\-libgs\fR=\fIfilename\fR +.RS 4 +This option is only available if the Ghostscript library is not directly linked to dvisvgm and if PostScript support was not completely disabled during compilation\&. In this case, dvisvgm tries to load the shared GS library dynamically during runtime\&. By default, it expects the library\(cqs name to be libgs\&.so\&.X (on Unix\-like systems, where X is the ABI version of the library) or gsdll32\&.dll/gsdll64\&.dll (Windows)\&. Option +\fB\-\-libgs\fR +can be used to give a different name\&. Alternatively, it\(cqs also possible to set the GS library name by the environment variable +LIBGS\&. The latter has less precedence than the command\-line option\&. +.RE +.PP +\fB\-L, \-\-linkmark\fR=\fItype\fR +.RS 4 +Selects the method how to mark hyperlinked areas\&. The +\fItype\fR +argument can take one of the values +\fInone\fR, +\fIbox\fR, and +\fIline\fR, where +\fIbox\fR +is the default, i\&.e\&. a rectangle is drawn around the linked region if option +\fB\-\-linkmark\fR +is omitted\&. Type +\fIline\fR +just draws the lower edge of the bounding rectangle, and +\fInone\fR +tells dvisvgm not to add any visible objects to hyperlinks\&. The lines and boxes get the current text color selected\&. In order to apply a different, constant color, a colon followed by a color specifier can be appended to the type string\&. A +\fIcolor specifier\fR +is either a hexadecimal RGB value of the form +\fI#RRGGBB\fR, or a dvips color name as listed here: +http://en\&.wikibooks\&.org/wiki/LaTeX/Colors#The_68_standard_colors_known_to_dvips +.sp +Moreover, argument +\fItype\fR +can take a single color specifier to highlight the linked region by a frameless box filled with that color\&. An optional second color specifier separated by colon selects the frame color\&. +.sp +Examples: +\fBbox:red\fR +or +\fBbox:#ff0000\fR +draws red boxes around the linked areas\&. +\fByellow:blue\fR +creates yellow filled rectangles with blue frames\&. +.RE +.PP +\fB\-l, \-\-list\-specials\fR +.RS 4 +Prints a list of registered special handlers and exits\&. Each handler processes a set of special statements belonging to the same category\&. In most cases, the categories are identified by the prefix of the special statements\&. It\(cqs usually a leading word separated from the rest of the statement by a colon or a blank, e\&.g\&. +\fIcolor\fR +or +\fIps\fR\&. +.RE +.PP +\fB\-M, \-\-mag\fR=\fIfactor\fR +.RS 4 +Sets the magnification factor applied in conjunction with Metafont calls prior tracing the glyphs\&. The larger this value, the better the tracing results\&. Nevertheless, large magnification values can cause Metafont arithmetic errors due to number overflows\&. So, use this option with care\&. The default setting usually produces nice results\&. +.RE +.PP +\fB\-\-no\-mktexmf\fR +.RS 4 +Suppresses the generation of missing font files\&. If dvisvgm can\(cqt find a font file through the kpathsea lookup mechanism, it calls the external tools mktextfm or mktexmf by\&. This option disables these calls\&. +.RE +.PP +\fB\-n, \-\-no\-fonts\fR[=\fIvariant\fR] +.RS 4 +If this option is given, dvisvgm doesn\(cqt create SVG +\fIfont\fR +elements but uses +\fIpaths\fR +instead\&. The resulting SVG files tend to be larger but they are concurrently more compatible with most applications that don\(cqt support SVG fonts yet\&. The optional argument +\fIvariant\fR +selects the method how to substitute fonts by paths\&. Variant 0 creates +\fIpath\fR +and +\fIuse\fR +elements\&. Variant 1 creates +\fIpath\fR +elements only\&. Option +\fB\-\-no\-fonts\fR +implies +\fB\-\-no\-styles\fR\&. +.RE +.PP +\fB\-c, \-\-scale\fR=\fIsx\fR[,\fIsy\fR] +.RS 4 +Scales the page content horizontally by +\fIsx\fR +and vertically by +\fIsy\fR\&. This option is equivalent to +\fB\-TS\fR\fIsx\fR,\fIsy\fR\&. +.RE +.PP +\fB\-S, \-\-no\-specials\fR[=\fInames\fR] +.RS 4 +Disable processing of special commands embedded in the DVI file\&. If no further parameter is given, all specials are ignored\&. To selectively disable sets of specials, an optional comma\-separated list of names can be appended to this option\&. A +\fIname\fR +is the unique identifier referencing the intended special handler\&. Option +\fB\-\-list\-specials\fR +lists all currently available handlers and their names\&. All unsupported special statements are silently ignored\&. +.RE +.PP +\fB\-\-no\-styles\fR +.RS 4 +By default, dvisvgm creates CSS styles and class attributes to reference fonts because it\(cqs more compact than repeatedly set the complete font information in each text element\&. However, if you prefer direct font references, the default behavior can be disabled with option +\fB\-\-no\-styles\fR\&. +.RE +.PP +\fB\-o, \-\-output\fR=\fIpattern\fR +.RS 4 +Sets the name pattern of the output file\&. Parameter +\fIpattern\fR +is a string that may contain the variables +\fB%f\fR +and +\fB%p\fR\&. +\fB%f\fR +stands for the base name of the DVI file, i\&.e\&. the DVI filename without suffix, and +\fB%p\fR +is the current page number\&. The default pattern is +\fB%f\-%p\&.svg\fR +if the DVI file consists of more than one page, and +\fB%f\&.svg\fR +otherwise\&. That means, a DVI file +\fIfoo\&.dvi\fR +is converted to +\fIfoo\&.svg\fR +if +\fIfoo\&.dvi\fR +is a single\-page document\&. Otherwise, multiple SVG files +\fIfoo\-01\&.svg\fR, +\fIfoo\-02\&.svg\fR, etc\&. are produced\&. In Windows environments, the percent sign indicates dereferenced environment variables, and must therefore be protected by a second percent sign, e\&.g\&. +\fB\-\-output=%%f\-%%p\fR\&. +.RE +.PP +\fB\-p, \-\-page\fR=\fIranges\fR +.RS 4 +This option sets the pages to be processed\&. Parameter +\fIranges\fR +consists of a comma\-separated list of single page numbers and/or page ranges\&. A page range is a pair of numbers separated by a hyphen, e\&.g\&. 5\-12\&. Thus, a page sequence might look like this: 2\-4,6,9\-12,15\&. It doesn\(cqt matter if a page is given more than once or if page ranges overlap\&. dvisvgm always extracts the page numbers in ascending order and converts them only once\&. In order to stay compatible with previous versions, the default page sequence is 1\&. dvisvgm therefore converts only the first page and not the whole document in case option +\fB\-\-page\fR +is omitted\&. Usually, page ranges consist of two numbers denoting the first and last page to be converted\&. If the conversion is to be started at page 1, or if it should continue up to the last DVI page, the first or second range number can be omitted, respectively\&. Example: +\fB\-\-page=\-10\fR +converts all pages up to page 10, +\fB\-\-page=10\-\fR +converts all pages starting with page 10\&. Please consider that the page values don\(cqt refer to the page numbers printed on the page\&. Instead, the physical page count is expected, where the first page always gets number 1\&. +.RE +.PP +\fB\-d, \-\-precision\fR=\fIdigits\fR +.RS 4 +Specifies the maximal number of decimal places applied to floating\-point attribute values\&. All attribute values written to the generated SVG file(s) are rounded accordingly\&. The parameter +\fIdigits\fR +allows integer values from 0 to 6, where 0 enables the automatic selection of significant decimal places\&. This is also the default value if dvisvgm is called without option +\fB\-\-precision\fR\&. +.RE +.PP +\fB\-P, \-\-progress\fR[=\fIdelay\fR] +.RS 4 +Enables a simple progress indicator shown when time\-consuming operations like PostScript specials are processed\&. The indicator doesn\(cqt appear before the given delay (in seconds) has elapsed\&. The default delay value is 0\&.5 seconds\&. +.RE +.PP +\fB\-r, \-\-rotate\fR=\fIangle\fR +.RS 4 +Rotates the page content clockwise by +\fIangle\fR +degrees around the page center\&. This option is equivalent to +\fB\-TR\fR\fIangle\fR\&. +.RE +.PP +\fB\-s, \-\-stdout\fR +.RS 4 +Don\(cqt write the SVG output to a file but redirect it to +\fBstdout\fR\&. +.RE +.PP +\fB\-T, \-\-transform\fR=\fIcommands\fR +.RS 4 +Applies a sequence of transformations to the SVG content\&. Each transformation is described by a +\fIcommand\fR +beginning with a capital letter followed by a list of comma\-separated parameters\&. Following transformation commands are supported: +.PP +\fBT\fR \fItx\fR[,\fIty\fR] +.RS 4 +Translates (moves) the page in direction of vector (\fItx\fR,\fIty\fR)\&. If +\fIty\fR +is omitted, +\fIty\fR=0 is assumed\&. The expected unit length of +\fItx\fR +and +\fIty\fR +are TeX points (1pt = 1/72\&.27in)\&. However, there are several constants defined to simplify the unit conversion (see below)\&. +.RE +.PP +\fBS\fR \fIsx\fR[,\fIsy\fR] +.RS 4 +Scales the page horizontally by +\fIsx\fR +and vertically by +\fIsy\fR\&. If +\fIsy\fR +is omitted, +\fIsy\fR=\fIsx\fR +is assumed\&. +.RE +.PP +\fBR\fR \fIangle\fR[,\fIx\fR,\fIy\fR] +.RS 4 +Rotates the page clockwise by +\fIangle\fR +degrees around point (\fIx\fR,\fIy\fR)\&. If the optional arguments +\fIx\fR +and +\fIy\fR +are omitted, the page will be rotated around its center depending on the chosen page format\&. When option +\fB\-bnone\fR +is given, the rotation center is origin (0,0)\&. +.RE +.PP +\fBKX\fR \fIangle\fR +.RS 4 +Skews the page along the +\fIx\fR\-axis by +\fIangle\fR +degrees\&. Argument +\fIangle\fR +can take any value except 90+180\fIk\fR, where +\fIk\fR +is an integer\&. +.RE +.PP +\fBKY\fR \fIangle\fR +.RS 4 +Skews the page along the +\fIy\fR\-axis by +\fIangle\fR +degrees\&. Argument +\fIangle\fR +can take any value except 90+180\fIk\fR, where +\fIk\fR +is an integer\&. +.RE +.PP +\fBFH\fR [\fIy\fR] +.RS 4 +Mirrors (flips) the page at the horizontal line through point (0,\fIy\fR)\&. Omitting the optional argument leads to +\fIy\fR=\fIh\fR/2, where +\fIh\fR +denotes the page height (see +\fIpre\-defined constants\fR +below)\&. +.RE +.PP +\fBFV\fR [\fIx\fR] +.RS 4 +Mirrors (flips) the page at the vertical line through point (\fIx\fR,0)\&. Omitting the optional argument leads to +\fIx\fR=\fIw\fR/2, where +\fIw\fR +denotes the page width (see +\fIpre\-defined constants\fR +below)\&. +.RE +.PP +\fBM\fR \fIm1\fR,\&...,\fIm6\fR +.RS 4 +Applies a transformation described by the 3\(mu3 matrix ((\fIm1\fR,\fIm2\fR,\fIm3\fR),(\fIm4\fR,\fIm5\fR,\fIm6\fR),(0,0,1)), where the inner triples denote the rows\&. +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +All transformation commands of option +\fB\-T, \-\-transform\fR +are applied in the order of their appearance\&. Multiple commands can optionally be separated by spaces\&. In this case the whole transformation string has to be enclosed in double quotes\&. All parameters are expressions of floating point type\&. You can either give plain numbers or arithmetic terms combined by the operators +\fB+\fR +(addition), +\fB\-\fR +(subtraction), +\fB*\fR +(multiplication), +\fB/\fR +(division) or +\fB%\fR +(modulo) with common associativity and precedence rules\&. Parentheses may be used as well\&. +.sp +Additionally, some pre\-defined constants are provided: +.TS +tab(:); +lt lt +lt lt +lt lt +lt lt. +T{ +\fBux\fR +T}:T{ +horizontal position of upper left page corner in TeX point units +T} +T{ +\fBuy\fR +T}:T{ +vertical position of upper left page corner in TeX point units +T} +T{ +\fBh\fR +T}:T{ +page height in TeX point units (0 in case of +\fB\-bnone\fR) +T} +T{ +\fBw\fR +T}:T{ +page width in TeX point units (0 in case of +\fB\-bnone\fR) +T} +.TE +.sp 1 +Furthermore, you can use the length constants +\fBpt\fR, +\fBmm\fR, +\fBcm\fR +and +\fBin\fR, e\&.g\&. +2cm +or +1\&.6in\&. Thus, option +\-TT1in,0R45 +moves the page content 1 inch to the right and rotates it by 45 degrees around the page center afterwards\&. +.sp +For single transformations you can also use options +\fB\-c\fR, +\fB\-t\fR +and +\fB\-r\fR\&. Note that the order in which these options are given is not significant, i\&.e\&. you can\(cqt use them to describe transformation sequences\&. They are simply independent shorthand options for common transformations\&. +.sp .5v +.RE +.RE +.RE +.PP +\fB\-t, \-\-translate\fR=\fItx\fR[,\fIty\fR] +.RS 4 +Translates (moves) the page content in direction of vector (\fItx\fR,\fIty\fR)\&. This option is equivalent to +\fB\-TT\fR\fItx\fR,\fIty\fR\&. +.RE +.PP +\fB\-v, \-\-verbosity\fR=\fIlevel\fR +.RS 4 +Controls the type of messages printed during a dvisvgm run: +.TS +tab(:); +lt lt +lt lt +lt lt +lt lt. +T{ +\fB0\fR +T}:T{ +no message output +T} +T{ +\fB1\fR +T}:T{ +error messages only +T} +T{ +\fB2\fR +T}:T{ +warning messages only +T} +T{ +\fB4\fR +T}:T{ +informational messages only +T} +.TE +.sp 1 +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +By adding these values you can combine the categories\&. The default level is 7, i\&.e\&. all messages are printed\&. +.sp .5v +.RE +.RE +.PP +\fB\-V, \-\-version\fR[=\fIextended\fR] +.RS 4 +Prints the version of dvisvgm and exits\&. If the optional argument is set to +\fIyes\fR, the version numbers of the linked libraries are printed as well\&. +.RE +.PP +\fB\-z, \-\-zip\fR[=\fIlevel\fR] +.RS 4 +Creates a compressed SVG file with suffix \&.svgz\&. The optional argument specifies the compression level\&. Valid values are in the range of 1 to 9 (default value is 9)\&. Larger values cause better compression results but take more computation time\&. +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBCaution\fR +.ps -1 +.br +This option cannot be combined with +\fB\-s, \-\-stdout\fR\&. +.sp .5v +.RE +.RE +.PP +\fB\-Z, \-\-zoom\fR[=\fIfactor\fR] +.RS 4 +Multiplies the +\fIwidth\fR +and +\fIheight\fR +attributes of the SVG root element by argument +\fIfactor\fR +while the coordinate system of the graphic is retained\&. As a result, most SVG viewers zoom the graphics accordingly\&. If a negative zoom factor is given, the +\fIwidth\fR +and +\fIheight\fR +attributes are omitted\&. +.RE +.SH "SUPPORT OF SPECIALS" +.sp +dvisvgm supports several sets of \fIspecial commands\fR that can be used to enrich DVI files with additional features, like color, graphics, and hyperlinks\&. The evaluation of special commands is delegated to various handlers\&. Each handler is responsible for all special statements of the same command set, i\&.e\&. commands beginning with the same prefix\&. To get a list of actually provided special handlers, use option \fB\-\-list\-specials\fR (see above)\&. This section gives an overview of the special commands currently supported\&. +.PP +\fBbgcolor\fR +.RS 4 +Special statement for changing the background/page color\&. Since SVG 1\&.1 doesn\(cqt support background colors, dvisvgm inserts a rectangle of the chosen color into the generated SVG document\&. This rectangle always gets the same size as the selected or computed bounding box\&. This background color command is part of the color special set but is handled separately in order to let the user turn it off\&. For an overview of the command syntax, see the documentation of dvips, for instance\&. +.RE +.PP +\fBcolor\fR +.RS 4 +Statements of this command set provide instructions to change the text/paint color\&. For an overview of the exact syntax, see the documentation of dvips, for instance\&. +.RE +.PP +\fBdvisvgm\fR +.RS 4 +dvisvgm offers its own small set of specials\&. The following list gives a brief overview\&. +.PP +\fBdvisvgm:raw\fR \fItext\fR +.RS 4 +Adds an arbitrary sequence of characters to the SVG output\&. dvisvgm does not perform any validation here, thus the user has to ensure that the resulting SVG is still valid\&. Parameter +\fItext\fR +may contain the macros +\fB{?x}\fR, +\fB{?y}\fR, and +\fB{?color}\fR +that are expanded to the current +\fIx\fR +or +\fIy\fR +coordinate and the current color, respectively\&. Also, macro +\fB{?nl}\fR +expands to a newline character\&. +.RE +.PP +\fBdvisvgm:img\fR \fIwidth\fR \fIheight\fR \fIfile\fR +.RS 4 +Creates an image element at the current graphic position referencing the given file\&. JPEG, PNG, and SVG images can be used here\&. However, dvisvgm does not check the file format or the file name suffix\&. The lengths +\fIwidth\fR +and +\fIheight\fR +must be given as plain floating point numbers in TeX point units (1in = 72\&.27pt)\&. +.RE +.PP +\fBdvisvgm:bbox\fR n[ew] \fIname\fR +.RS 4 +Defines or resets a local bounding box called +\fIname\fR\&. The name may consist of letters and digits\&. While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc\&.) Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes\&. Once defined, these boxes are updated together with the global bounding box starting with the first character that follows the definition\&. Thus, the local boxes can be used to compute the extent of parts of the page\&. This is useful for scenarios where the generated SVG file is post\-processed\&. In conjunction with special dvisvgm:raw, the macro +\fB{?bbox \fR\fB\fIname\fR\fR\fB}\fR +expands to the four values +\fIx\fR, +\fIy\fR, +\fIw\fR, and +\fIh\fR +(separated by spaces) specifying the coordinates of the upper left corner, width, and height of the local box +\fIname\fR\&. If box +\fIname\fR +wasn\(cqt previously defined, all four values equal zero\&. +.RE +.PP +\fBdvisvgm:bbox\fR \fIwidth\fR \fIheight\fR [\fIdepth\fR] +.RS 4 +Updates the bounding box of the current page by embedding a virtual rectangle (\fIx\fR, +\fIy\fR, +\fIwidth\fR, +\fIheight\fR) where the lower left corner is located at the current DVI drawing position (\fIx\fR,\fIy\fR)\&. If the optional parameter +\fIdepth\fR +is specified, dvisvgm embeds a second rectangle (\fIx\fR, +\fIy\fR, +\fIwidth\fR, \-\fIdepth\fR)\&. The lengths +\fIwidth\fR, +\fIheight\fR +and +\fIdepth\fR +must be given as plain floating point numbers in TeX point units (1in = 72\&.27pt)\&. Depending on size and position of the virtual rectangle, this command either enlarges the overall bounding box or leaves it as is\&. It\(cqs not possible to reduce its extent\&. This special should be used in conjunction with +\fBdvisvgm:raw\fR +in order to update the viewport of the page properly\&. +.RE +.PP +\fBdvisvgm:bbox\fR a[bs] \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR +.RS 4 +This variant of the bbox special updates the bounding box by embedding a virtual rectangle (\fIx1\fR,\fIy1\fR,\fIx2\fR,\fIy2\fR)\&. The points (\fIx1\fR,\fIy1\fR) and (\fIx2\fR,\fIy2\fR) denote two diagonal corners of the rectangle given in TeX point units\&. +.RE +.PP +\fBdvisvgm:bbox\fR f[ix] \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR +.RS 4 +This variant of the bbox special assigns an absolute (final) bounding box to the resulting SVG\&. After executing this command, dvisvgm doesn\(cqt further alter the bounding box coordinates, except this special is called again later\&. The points (\fIx1\fR,\fIy1\fR) and (\fIx2\fR,\fIy2\fR) denote two diagonal corners of the rectangle given in TeX point units\&. +.sp +The following TeX snippet adds two raw SVG elements to the output and updates the bounding box accordingly: +.sp +.if n \{\ +.RS 4 +.\} +.nf +\especial{dvisvgm:raw <circle cx=\*(Aq{?x}\*(Aq cy=\*(Aq{?y}\*(Aq r=\*(Aq10\*(Aq stroke=\*(Aqblack\*(Aq fill=\*(Aqred\*(Aq/>} +\especial{dvisvgm:bbox 20 10 10} + +\especial{dvisvgm:raw <path d=\*(AqM50 200 L10 250 H100 Z\*(Aq stroke=\*(Aqblack\*(Aq fill=\*(Aqblue\*(Aq/>} +\especial{dvisvgm:bbox abs 10 200 100 250} +.fi +.if n \{\ +.RE +.\} +.RE +.RE +.PP +\fBem\fR +.RS 4 +These specials were introduced with the emTeX distribution by Eberhard Mattes\&. They provide line drawing statements, instructions for embedding MSP, PCX, and BMP image files, as well as two PCL commands\&. dvisvgm supports only the line drawing statements and ignores all other em specials silently\&. A description of the command syntax can be found in the DVI driver documentation coming with emTeX (see CTAN)\&. +.RE +.PP +\fBhtml\fR +.RS 4 +The hyperref specials allow the definition of hyperlinks inside DVI files in various flavors\&. dvisvgm supports the plain HyperTeX special constructs as created with hyperref package option +\fIhypertex\fR\&. Internal links, i\&.e\&. references to other parts of the same document, are only converted if the link and the corresponding link target are located on the same page\&. Links between different pages are not supported yet\&. By default, all linked areas of the document are marked by a rectangle\&. Option +\fB\-\-linkmark\fR +allows to change this behavior\&. See above for further details\&. Information on syntax and semantics of the HyperTeX specials can be found in the hyperref manual\&. +.RE +.PP +\fBpdf\fR +.RS 4 +pdfTeX and dvipdfmx introduced several special commands related to the generation of PDF files\&. Currently, only two of them, +\fIpdf:mapfile\fR +and +\fIpdf:mapline\fR +are supported by dvisvgm\&. These specials allow modifying the font map tree during the processing of DVI files\&. They are used by CTeX, for example\&. dvisvgm supports both, the dvips and dvipdfm font map format\&. For further information on the command syntax and semantics, see the documentation of \epdfmapfile in the pdfTeX user manual\&. +.RE +.PP +\fBps\fR +.RS 4 +The famous DVI driver dvips introduced its own set of specials in order to embed PostScript code into DVI files, which greatly improves the capabilities of DVI documents\&. One aim of dvisvgm is to completely evaluate all PostScript snippets and to convert a large amount of it to SVG\&. However, in contrast to dvips, dvisvgm uses floating point arithmetics to compute the precise position of each graphic element, i\&.e\&. it doesn\(cqt round the coordinates\&. Therefore, the relative locations of the graphic elements may slightly differ from those computed by dvips\&. +.sp +Since PostScript is a rather complex language, dvisvgm does not try to implement its own PostScript interpreter but relies on Ghostscript instead\&. If the Ghostscript library was not linked to the dvisvgm binary, it is looked up and loaded dynamically during runtime\&. In this case, dvisvgm looks for +\fIlibgs\&.so\&.X\fR +on Unix\-like systems (supported ABI versions: 7,8,9), and for +\fIgsdll32\&.dll\fR +or +\fIgsdll64\&.dll\fR +on Windows\&. You can override the default file names with environment variable +LIBGS +or the command\-line option +\fB\-\-libgs\fR\&. The library must be reachable through the ld search path (*nix) or the PATH environment variable (Windows)\&. Alternatively, the absolute file path can be specified\&. If the library cannot be found, dvisvgm disables the processing of PostScript specials\&. Use option +\fB\-\-list\-specials\fR +to check whether PS support is available, i\&.e\&. entry +\fIps\fR +is present\&. +.sp +The PostScript handler also recognizes and evaluates bounding box data generated by the +\fIpreview\fR +package with option +\fItightpage\fR\&. If the data is present in a DVI file, dvisvgm adapts the bounding box of the generated SVG file accordingly, and prints a message showing the width, height, and depth of the box in TeX point units\&. Especially, the depth value can be used to vertically align the SVG graphics with the baseline of surrounding text in HTML or XSL\-FO documents, for example\&. +.RE +.PP +\fBtpic\fR +.RS 4 +The TPIC special set defines instructions for drawing simple geometric objects\&. Some LaTeX packages, like eepic and tplot, use these specials to describe graphics\&. +.RE +.SH "EXAMPLES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +dvisvgm file +.fi +.if n \{\ +.RE +.\} +.sp +Converts the first page of \fIfile\&.dvi\fR to \fIfile\&.svg\fR\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +dvisvgm \-z file +.fi +.if n \{\ +.RE +.\} +.sp +Converts the first page of \fIfile\&.dvi\fR to \fIfile\&.svgz\fR with default compression level 9\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +dvisvgm \-p5 \-z3 \-ba4\-l \-onewfile file +.fi +.if n \{\ +.RE +.\} +.sp +Converts the fifth page of \fIfile\&.dvi\fR to \fInewfile\&.svgz\fR with compression level 3\&. The bounding box is set to DIN/ISO A4 in landscape format\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +dvisvgm \-\-transform="R20,w/3,2h/5 T1cm,1cm S2,3" file +.fi +.if n \{\ +.RE +.\} +.sp +Converts the first page of \fIfile\&.dvi\fR to \fIfile\&.svg\fR where three transformations are applied\&. +.SH "ENVIRONMENT" +.sp +dvisvgm uses the \fBkpathsea\fR library for locating the files that it opens\&. Hence, the environment variables described in the library\(cqs documentation influence the converter\&. +.sp +If dvisvgm was linked without the Ghostscript library, and if PostScript support has not been disabled, the shared Ghostscript library is looked up during runtime via dlopen()\&. The environment variable LIBGS can be used to specify path and file name of the library\&. +.sp +The pre\-compiled Windows versions of dvisvgm require a working installation of MiKTeX 2\&.9 or above\&. dvisvgm does not work together with the portable edition of MiKTeX because it relies on MiKTeX\(cqs COM interface only accessible in a local installation\&. To enable the evaluation of PostScript specials, the original Ghostscript DLL \fIgsdll32\&.dll\fR must be present and reachable through the search path\&. 64\-bit Windows builds require the 64\-bit Ghostscript DLL \fIgsdll64\&.dll\fR\&. Both DLLs come with the corresponding Ghostscript installers available from www\&.ghostscript\&.com\&. +.sp +The environment variable DVISVGM_COLORS specifies the colors used to highlight various parts of dvisvgm\(cqs message output\&. It is only evaluated if option \fB\-\-color\fR is given\&. The value of DVISVGM_COLORS is a list of colon\-separated entries of the form \fIgg\fR=\fIBF\fR, where \fIgg\fR denotes one of the color group indicators listed below, and \fIBF\fR are two hexadecimal digits specifying the background (first digit) and foreground/text color (second digit)\&. The color values are defined as follows: 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan, 7=gray, 8=bright red, 9=bright green, A=bright yellow, B=bright blue, C=bright magenta, D=bright cyan, E=bright gray, F=white\&. Depending on the terminal, the colors may differ\&. Rather than changing both the text and background color, it\(cqs also possible to change only one of them: An asterisk (*) in place of a hexadecimal digit indicates the default text or background color of the terminal\&. +.sp +All malformed entries in the list are silently ignored\&. +.TS +tab(:); +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt. +T{ +.sp +\fBer\fR +T}:T{ +.sp +error messages +T} +T{ +.sp +\fBwn\fR +T}:T{ +.sp +warning messages +T} +T{ +.sp +\fBpn\fR +T}:T{ +.sp +messages about page numbers +T} +T{ +.sp +\fBps\fR +T}:T{ +.sp +page size messages +T} +T{ +.sp +\fBfw\fR +T}:T{ +.sp +information about the files written +T} +T{ +.sp +\fBsm\fR +T}:T{ +.sp +state messages +T} +T{ +.sp +\fBtr\fR +T}:T{ +.sp +messages of the glyph tracer +T} +T{ +.sp +\fBpi\fR +T}:T{ +.sp +progress indicator +T} +.TE +.sp 1 +.sp +\fBExample:\fR er=01:pi=*5 sets the colors of error messages (er) to red (1) on black (0), and those of progress indicators (pi) to cyan (5) on default background (*)\&. +.SH "FILES" +.sp +The location of the following files is determined by the kpathsea library\&. To check the actual kpathsea configuration you can use the \fBkpsewhich\fR utility\&. +.TS +tab(:); +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt +lt lt. +T{ +.sp +\fB*\&.enc\fR +T}:T{ +.sp +Font encoding files +T} +T{ +.sp +\fB*\&.fgd\fR +T}:T{ +.sp +Font glyph data files (cache files created by dvisvgm) +T} +T{ +.sp +\fB*\&.map\fR +T}:T{ +.sp +Font map files +T} +T{ +.sp +\fB*\&.mf\fR +T}:T{ +.sp +Metafont input files +T} +T{ +.sp +\fB*\&.pfb\fR +T}:T{ +.sp +PostScript Type 1 font files +T} +T{ +.sp +\fB*\&.pro\fR +T}:T{ +.sp +PostScript header/prologue files +T} +T{ +.sp +\fB*\&.tfm\fR +T}:T{ +.sp +TeX font metric files +T} +T{ +.sp +\fB*\&.ttf\fR +T}:T{ +.sp +TrueType font files +T} +T{ +.sp +\fB*\&.vf\fR +T}:T{ +.sp +Virtual font files +T} +.TE +.sp 1 +.SH "SEE ALSO" +.sp +\fBtex(1), mf(1), mktexmf(1), grodvi(1), potrace(1)\fR, and the \fBkpathsea library\fR info documentation\&. +.SH "RESOURCES" +.PP +Project home page +.RS 4 +http://dvisvgm\&.sourceforge\&.net +.RE +.PP +SourceForge project site +.RS 4 +http://sourceforge\&.net/projects/dvisvgm +.RE +.SH "BUGS" +.sp +Please report bugs using the bug tracker at Launchpad (see https://launchpad\&.net/dvisvgm)\&. +.SH "AUTHOR" +.sp +Written by Martin Gieseking <martin\&.gieseking@uos\&.de> +.SH "COPYING" +.sp +Copyright \(co 2005\-2014 Martin Gieseking\&. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version\&. +.SH "AUTHOR" +.PP +\fBMartin Gieseking\fR <\&martin\&.gieseking@uos\&.de\&> +.RS 4 +Author. +.RE diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.txt.in b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.txt.in new file mode 100644 index 00000000000..7d942066d3b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/doc/dvisvgm.txt.in @@ -0,0 +1,676 @@ +////////////////////////////////////////////////////////////////////////// +// This file is part of dvisvgm -- the DVI to SVG converter // +// Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> // +// // +// 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 3 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, see <http://www.gnu.org/licenses/>. // +////////////////////////////////////////////////////////////////////////// + +dvisvgm(1) +========== +Martin Gieseking <@PACKAGE_BUGREPORT@> +:man source: dvisvgm +:man version: @VERSION@ +:man manual: dvisvgm Manual + +NAME +---- +dvisvgm - converts DVI files to the XML-based SVG format + + +SYNOPSIS +-------- +*dvisvgm* [ 'options' ] 'file' [.dvi] + +*dvisvgm* -E [ 'options' ] 'file' [.eps] + + +DESCRIPTION +----------- +The command-line utility *dvisvgm* converts DVI files, as generated by TeX/LaTeX, to the +XML-based scalable vector graphics format SVG. It supports the classic DVI format 2 as +well as format 3 (created by pTeX in vertical mode), and format 5 which is also known as +XDV (created by XeTeX). Besides the basic DVI commands, dvisvgm also evaluates many so-called +'specials' which heavily extend the capabilities of the DVI format. For a more detailed +overview, see section *support of specials* below. + +Since the current SVG standard 1.1 doesn't specify multi-page graphics, dvisvgm creates +separate SVG files for each DVI page. Because of compatibility reasons, only the first page +is converted by default. In order to select a different page or arbitrary page sequences, +use option *-p* which is described below. + +SVG is a vector-based graphics format and therefore dvisvgm tries to convert the glyph outlines +of all used fonts to scalable path descriptions. The fastest way to do that is to extract the +path information from font files in PFB, TTF, or OTF format. If dvisvgm is able to find such +a file, it extracts all necessary outline information about the glyphs from it. + +However, TeX's main source for font descriptions is Metafont, which produces bitmap output +(GF files). That's why not all obtainable TeX fonts are available in a scalable format. +In these cases, dvisvgm tries to vectorize Metafont's output by tracing the glyph bitmaps. +The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are +nonetheless really nice in most cases. + +When running dvisvgm without option *--no-fonts*, 'font' elements (<font>...</font>) are used to +embed the font data into the SVG files. Unfortunately, only few SVG renderes support these +elements yet. Most web browsers and vector graphics applications don't evaluate them properly +so that the text components of the resulting graphics might look strange. In order to create +more compatible SVG files, command-line option *--no-fonts* can be given to replace the font +elements by plain graphics paths. + + +OPTIONS +------- +*-a, --trace-all*=['retrace']:: +This option forces dvisvgm to trace not only the actually needed glyphs but all +glyphs of all bitmap fonts used in the DVI file. Since the tracing results are stored in +the font cache, all following DVI conversions (without option *--trace-all*) where these +fonts are involved, will be much faster. By default, dvisvgm traces only the actually +needed glyphs, and adds them to the cache. +The boolean option 'retrace' determines how to handle glyphs already stored in the cache. +By default, these glyphs are skipped. Setting argument 'retrace' to 'yes' or +'true' forces dvisvgm to trace the corresponding bitmaps again. ++ +[NOTE] +This option only takes affect if font caching is active. Thus, *--trace-all* cannot be +combined with option *--cache=none*. ++ + + +*-b, --bbox*='fmt':: +Sets the bounding box of the generated graphic to the specified format. The parameter 'fmt' +takes either one of the format specifiers listed below, or a sequence of four comma- or +whitespace-separated length values 'x1', 'y1', 'x2' and 'y2'. The latter define two diagonal +corners of the bounding box. Each length value consists of a floating point number and an optional +length unit (pt, bp, cm, mm, in, or pc). If the unit is omitted, TeX points (pt) are assumed. ++ +It's also possible to give only one length value 'l'. In this case, the minimal bounding box +is computed and enlarged by adding (-'l',-'l') to the upper left and ('l','l') to the lower +right corner. ++ +Alternatively, the following format specifiers are supported: + + *International DIN/ISO paper sizes*;; + A__n__, B__n__, C__n__, D__n__, where 'n' is a non-negative integer, e.g. A4 or a4 for DIN/ISO A4 + format (210mm × 297mm). + + *North American paper sizes*;; + invoice, executive, legal, letter, ledger + + *Special bounding box sizes*;; +[horizontal] + *dvi*::: page size stored in the DVI file + *min*::: computes the minimal/tightest bounding box + *none*::: no bounding box is assigned +// + *Page orientation*;; + The default page orientation for DIN/ISO and American paper sizes is 'portrait', + i.e. 'width' < 'height'. Appending *-landscape* or simply *-l* to the format + string switches to 'landscape' mode ('width' > 'height'). For symmetry reasons you can + also explicitly add *-portrait* or *-p* to indicate the default portrait format. + Note that these suffixes are part of the size string and not separate options. Thus, + they must directly follow the size specifier without additional blanks. + Furthermore, the orientation suffixes can't be used with *dvi*, *min*, and *none*. ++ +[NOTE] +Option *-b, --bbox* only affects the bounding box and does not transform the page content. +Hence, if you choose a landscape format, the page won't be rotated. ++ +// + +// +*-C, --cache*[='dir']:: +To speed up the conversion process of bitmap fonts, dvisvgm saves intermediate conversion +information in cache files. By default, these files are stored in $HOME/.dvisvgm/cache. If you prefer +a different location, use option *--cache* to overwrite the default. Furthermore, it is also possible +to disable the font caching mechanism completely with option *--cache=none*. If argument 'dir' is omitted, +dvisvgm prints the path of the default cache directory together with further information about the stored fonts. +Additionally, outdated and corrupted cache files are removed. + + +*--color*:: +Enables colorization of messages printed during the conversion process. The colors can be customized +via the environment variable +DVISVGM_COLORS+. See the ENVIRONMENT section below for further information. + + +*-E, --eps*:: +If this option is given, dvisvgm does not expect a DVI but an EPS input file, and tries to convert +it to SVG. In order to do so, a single 'psfile' special command is created and forwarded to the +PostScript special handler. +This option is only available if dvisvgm was built with PostScript support enabled, and requires +Ghostscript to be available. See option *--libgs* for further information. + + +*-e, --exact*:: +If this option is given, dvisvgm computes the precise bounding box of each character. By default, +the values stored in a font's TFM file are used to determine a glyph's extent. As these values are +intended to implement optimal character placements and are not designed to represent the exact +dimensions, they don't necessarily correspond with the bounds of the visual glyphs. Thus, width +and/or height of some glyphs may be larger (or smaller) than the respective TFM values. As a result, +this can lead to clipped characters at the bounds of the SVG graphics. With option *--exact* given, +dvisvgm analyzes the actual shape of each character and derives a usually tight bounding box. + + +*-m, --fontmap*='filenames':: +Loads and evaluates a single or multiple font map files. These files are required to resolve +font file names and encodings. dvisvgm does not provide its own map files but tries to read +available ones coming with dvips or dvipdfm. If option *--fontmap* is omitted, dvisvgm looks for the +default map files +ps2pk.map+, +dvipdfm.map+, and +psfonts.map+ (in this order). Otherwise, the +listed files are used. Multiple filenames must be separated by commas without leading and/or trailing +whitespace. +The map files are evaluated in the given order. By default, redefined mappings do not replace previous ones. +However, each filename can be preceded by an optional mode specifier (*+*, *-*, or *=*) to change this behavior: + + +mapfile;; + Only those entries in the given map file that don't redefine a font mapping are applied. + That's also the default mode if no mode specifier is given. + + -mapfile;; + Ensures that none of the font mappings defined in the given map file are used, i.e. previously + defined mappings for the specified fonts are removed. + + =mapfile;; + All mappings defined in the map file are applied. Previously defined settings for the same font + are replaced. ++ +If the first filename in the filename sequence is preceded by a mode specifier, dvisvgm loads the +default font map (see above) and applies the other map files afterwards. Otherwise, none of default +map files will be loaded automatically. ++ +Examples: *--fontmap=myfile1.map,+myfile2.map* loads `myfile1.map` followed by `myfile2.map` where all +redefinitions of `myfile2.map` are ignored. +*--fontmap==myfile1.map,-myfile2.map* loads the default map file followed by `myfile1.map` and `myfile2.map` +where all redefinitions of `myfile1.map` replace previous entries. Afterwards, all definitions for the fonts +given in `myfile2.map` are removed from the font map tree. ++ +For further information about the map file formats and the mode specifiers, see the manuals of dvips and dvipdfm. + + +*-h, --help*[='mode']:: +Prints a short summary of all available command-line options. The optional 'mode' parameter is +an integer value between 0 and 2. It selects the display variant of the help text. Mode 0 +lists all options divided into categories with section headers. This is also the default if +dvisvgm is called without parameters. Mode 1 lists all options ordered by the short option names, +while mode 2 sorts the lines by the long option names. + + +*--keep*:: +Disables the removal of temporary files as created by Metafont (usually .gf, .tfm, and .log files). + + +*--libgs*='filename':: +This option is only available if the Ghostscript library is not directly linked to dvisvgm and if +PostScript support was not completely disabled during compilation. In this case, dvisvgm tries +to load the shared GS library dynamically during runtime. By default, it expects the library's name +to be libgs.so.X (on Unix-like systems, where X is the ABI version of the library) or +gsdll32.dll/gsdll64.dll (Windows). Option *--libgs* can be used to give a different name. +Alternatively, it's also possible to set the GS library name by the environment variable +LIBGS+. +The latter has less precedence than the command-line option. + + +*-L, --linkmark*='type':: +Selects the method how to mark hyperlinked areas. The 'type' argument can take one of the values +'none', 'box', and 'line', where 'box' is the default, i.e. a rectangle is drawn around +the linked region if option *--linkmark* is omitted. Type 'line' just draws the lower edge of +the bounding rectangle, and 'none' tells dvisvgm not to add any visible objects to hyperlinks. +The lines and boxes get the current text color selected. In order to apply a different, constant color, +a colon followed by a color specifier can be appended to the type string. A 'color specifier' is either +a hexadecimal RGB value of the form '#RRGGBB', or a dvips color name as listed here: +http://en.wikibooks.org/wiki/LaTeX/Colors#The_68_standard_colors_known_to_dvips ++ +Moreover, argument 'type' can take a single color specifier to highlight the linked region by +a frameless box filled with that color. An optional second color specifier separated by colon +selects the frame color. ++ +Examples: *box:red* or *box:#ff0000* draws red boxes around the linked areas. *yellow:blue* creates +yellow filled rectangles with blue frames. + + +*-l, --list-specials*:: +Prints a list of registered special handlers and exits. Each handler processes a set of special +statements belonging to the same category. In most cases, the categories are identified by the +prefix of the special statements. It's usually a leading word separated from the rest of the +statement by a colon or a blank, e.g. 'color' or 'ps'. + + +*-M, --mag*='factor':: +Sets the magnification factor applied in conjunction with Metafont calls prior tracing the glyphs. +The larger this value, the better the tracing results. Nevertheless, large magnification values +can cause Metafont arithmetic errors due to number overflows. So, use this option with care. +The default setting usually produces nice results. + + +*--no-mktexmf*:: +Suppresses the generation of missing font files. If dvisvgm can't find a font file +through the kpathsea lookup mechanism, it calls the external tools mktextfm or mktexmf by. +This option disables these calls. + + +*-n, --no-fonts*[='variant']:: +If this option is given, dvisvgm doesn't create SVG 'font' elements but uses 'paths' instead. The +resulting SVG files tend to be larger but they are concurrently more compatible with most applications that +don't support SVG fonts yet. The optional argument 'variant' selects the method how to substitute fonts +by paths. Variant 0 creates 'path' and 'use' elements. Variant 1 creates 'path' elements only. +Option *--no-fonts* implies *--no-styles*. + + +*-c, --scale*='sx'[,'sy']:: +Scales the page content horizontally by 'sx' and vertically by 'sy'. This option is equivalent +to *-TS*'sx','sy'. + + +*-S, --no-specials*[='names']:: +Disable processing of special commands embedded in the DVI file. If no further +parameter is given, all specials are ignored. To selectively disable sets of specials, +an optional comma-separated list of names can be appended to this option. A 'name' is the unique +identifier referencing the intended special handler. Option *--list-specials* lists all currently +available handlers and their names. +All unsupported special statements are silently ignored. + + +*--no-styles*:: +By default, dvisvgm creates CSS styles and class attributes to reference fonts because it's more +compact than repeatedly set the complete font information in each text element. However, if you +prefer direct font references, the default behavior can be disabled with option *--no-styles*. + + +*-o, --output*='pattern':: +Sets the name pattern of the output file. Parameter 'pattern' is a string that may +contain the variables *%f* and *%p*. *%f* stands for the base name of the DVI file, i.e. +the DVI filename without suffix, and *%p* is the current page number. +The default pattern is *%f-%p.svg* if the DVI file consists of more than one page, and +*%f.svg* otherwise. That means, a DVI file 'foo.dvi' is converted to 'foo.svg' if 'foo.dvi' +is a single-page document. Otherwise, multiple SVG files 'foo-01.svg', 'foo-02.svg', etc. are +produced. In Windows environments, the percent sign indicates dereferenced environment +variables, and must therefore be protected by a second percent sign, e.g. *--output=%%f-%%p*. + + +*-p, --page*='ranges':: +This option sets the pages to be processed. Parameter 'ranges' consists of a comma-separated list +of single page numbers and/or page ranges. A page range is a pair of numbers separated by a hyphen, +e.g. 5-12. Thus, a page sequence might look like this: 2-4,6,9-12,15. It doesn't matter if a page +is given more than once or if page ranges overlap. dvisvgm always extracts the page numbers in +ascending order and converts them only once. +In order to stay compatible with previous versions, the default page sequence is 1. dvisvgm +therefore converts only the first page and not the whole document in case option *--page* is omitted. +Usually, page ranges consist of two numbers denoting the first and last page to be converted. +If the conversion is to be started at page 1, or if it should continue up to the last DVI page, the +first or second range number can be omitted, respectively. Example: *--page=-10* converts all +pages up to page 10, *--page=10-* converts all pages starting with page 10. +Please consider that the page values don't refer to the page numbers printed on the page. +Instead, the physical page count is expected, where the first page always gets number 1. + + +*-d, --precision*='digits':: +Specifies the maximal number of decimal places applied to floating-point attribute values. +All attribute values written to the generated SVG file(s) are rounded accordingly. The +parameter 'digits' allows integer values from 0 to 6, where 0 enables the automatic selection +of significant decimal places. This is also the default value if dvisvgm is called without +option *--precision*. + + +*-P, --progress*[='delay']:: +Enables a simple progress indicator shown when time-consuming operations like +PostScript specials are processed. The indicator doesn't appear before the given +delay (in seconds) has elapsed. The default delay value is 0.5 seconds. + + +*-r, --rotate*='angle':: +Rotates the page content clockwise by 'angle' degrees around the page center. +This option is equivalent to *-TR*'angle'. + + +*-s, --stdout*:: +Don't write the SVG output to a file but redirect it to *stdout*. + + +*-T, --transform*='commands':: +Applies a sequence of transformations to the SVG content. Each transformation is described +by a 'command' beginning with a capital letter followed by a list of comma-separated +parameters. Following transformation commands are supported: + + *T* 'tx'[,'ty'];; + Translates (moves) the page in direction of vector ('tx','ty'). If 'ty' is omitted, + 'ty'=0 is assumed. + The expected unit length of 'tx' and 'ty' are TeX points (1pt = 1/72.27in). However, there + are several constants defined to simplify the unit conversion (see below). + + *S* 'sx'[,'sy'];; + Scales the page horizontally by 'sx' and vertically by 'sy'. If 'sy' is omitted, + 'sy'='sx' is assumed. + + *R* 'angle'[,'x','y'];; + Rotates the page clockwise by 'angle' degrees around point ('x','y'). If the optional + arguments 'x' and 'y' are omitted, the page will be rotated around its center depending on + the chosen page format. When option *-bnone* is given, the rotation center is origin (0,0). + + *KX* 'angle';; + Skews the page along the 'x'-axis by 'angle' degrees. Argument 'angle' can take any value + except 90+180__k__, where 'k' is an integer. + + *KY* 'angle';; + Skews the page along the 'y'-axis by 'angle' degrees. Argument 'angle' can take any value + except 90+180__k__, where 'k' is an integer. + + *FH* ['y'];; + Mirrors (flips) the page at the horizontal line through point (0,'y'). Omitting the optional argument + leads to 'y'='h'/2, where 'h' denotes the page height (see 'pre-defined constants' below). + + *FV* ['x'];; + Mirrors (flips) the page at the vertical line through point ('x',0). Omitting the optional argument + leads to 'x'='w'/2, where 'w' denotes the page width (see 'pre-defined constants' below). + + *M* 'm1',...,'m6';; + Applies a transformation described by the 3×3 matrix + \(('m1','m2','m3'),('m4','m5','m6'),(0,0,1)), where the inner triples denote + the rows. ++ +[NOTE] +================================================================================================= +All transformation commands of option *-T, --transform* are applied in the order of their appearance. +Multiple commands can optionally be separated by spaces. In this case the whole transformation string +has to be enclosed in double quotes. All parameters are expressions of floating point type. You can either +give plain numbers or arithmetic terms combined by the operators *+* (addition), *-* (subtraction), +*** (multiplication), */* (division) or *%* (modulo) with common associativity and +precedence rules. Parentheses may be used as well. + +Additionally, some pre-defined constants are provided: + +[horizontal] +*ux*:: horizontal position of upper left page corner in TeX point units +*uy*:: vertical position of upper left page corner in TeX point units +*h*:: page height in TeX point units (0 in case of *-bnone*) +*w*:: page width in TeX point units (0 in case of *-bnone*) + +Furthermore, you can use the length constants *pt*, *mm*, *cm* and *in*, e.g. ++2cm+ or +1.6in+. Thus, option +-TT1in,0R45+ moves the page content 1 inch to the right and rotates it +by 45 degrees around the page center afterwards. + +For single transformations you can also use options *-c*, *-t* and *-r*. Note that +the order in which these options are given is not significant, i.e. you can't use them to describe +transformation sequences. They are simply independent shorthand options for common transformations. + +================================================================================================= ++ +// + +// +*-t, --translate*='tx'[,'ty']:: +Translates (moves) the page content in direction of vector ('tx','ty'). This option is +equivalent to *-TT*'tx','ty'. + + +*-v, --verbosity*='level':: +Controls the type of messages printed during a dvisvgm run: +[horizontal] + *0*;; no message output + *1*;; error messages only + *2*;; warning messages only + *4*;; informational messages only + ++ +[NOTE] +By adding these values you can combine the categories. The default level is 7, i.e. all +messages are printed. ++ + + +*-V, --version*[='extended']:: +Prints the version of dvisvgm and exits. If the optional argument is set to 'yes', the +version numbers of the linked libraries are printed as well. + + +*-z, --zip*[='level']:: +Creates a compressed SVG file with suffix .svgz. The optional argument specifies the compression +level. Valid values are in the range of 1 to 9 (default value is 9). Larger values cause better +compression results but take more computation time. ++ +CAUTION: This option cannot be combined with *-s, --stdout*. + + +*-Z, --zoom*[='factor']:: +Multiplies the 'width' and 'height' attributes of the SVG root element by argument 'factor' while +the coordinate system of the graphic is retained. As a result, most SVG viewers zoom the graphics +accordingly. If a negative zoom factor is given, the 'width' and 'height' attributes are omitted. + + +SUPPORT OF SPECIALS +------------------- +dvisvgm supports several sets of 'special commands' that can be used to enrich DVI files with additional +features, like color, graphics, and hyperlinks. The evaluation of special commands is delegated to various +handlers. Each handler is responsible for all special statements of the same command set, i.e. commands +beginning with the same prefix. To get a list of actually provided special handlers, use option +*--list-specials* (see above). This section gives an overview of the special commands currently supported. + +*bgcolor*:: +Special statement for changing the background/page color. Since SVG 1.1 doesn't support background colors, +dvisvgm inserts a rectangle of the chosen color into the generated SVG document. This rectangle always gets +the same size as the selected or computed bounding box. This background color command is part of the color +special set but is handled separately in order to let the user turn it off. For an overview of the command +syntax, see the documentation of dvips, for instance. + +*color*:: +Statements of this command set provide instructions to change the text/paint color. For an overview of the +exact syntax, see the documentation of dvips, for instance. + +*dvisvgm*:: +dvisvgm offers its own small set of specials. The following list gives a brief overview. + *dvisvgm:raw* 'text';; + Adds an arbitrary sequence of characters to the SVG output. dvisvgm does not perform any validation here, + thus the user has to ensure that the resulting SVG is still valid. Parameter 'text' may + contain the macros *{?x}*, *{?y}*, and *{?color}* that are expanded to the current 'x' or 'y' coordinate + and the current color, respectively. Also, macro *{?nl}* expands to a newline character. + + *dvisvgm:img* 'width' 'height' 'file';; + Creates an image element at the current graphic position referencing the given file. JPEG, PNG, and SVG images + can be used here. However, dvisvgm does not check the file format or the file name suffix. The lengths 'width' + and 'height' must be given as plain floating point numbers in TeX point units (1in = 72.27pt). + + *dvisvgm:bbox* n[ew] 'name';; + Defines or resets a local bounding box called 'name'. The name may consist of letters and digits. + While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to + determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc.) + Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes. + Once defined, these boxes are updated together with the global bounding box starting with the first character that + follows the definition. Thus, the local boxes can be used to compute the extent of parts of the page. This is useful + for scenarios where the generated SVG file is post-processed. + In conjunction with special dvisvgm:raw, the macro *{?bbox 'name'}* expands to the four values 'x', 'y', 'w', and 'h' + (separated by spaces) specifying the coordinates of the upper left corner, width, and height of the local box 'name'. + If box 'name' wasn't previously defined, all four values equal zero. + + *dvisvgm:bbox* 'width' 'height' ['depth'];; + Updates the bounding box of the current page by embedding a virtual rectangle ('x', 'y', 'width', 'height') + where the lower left corner is located at the current DVI drawing position ('x','y'). If the optional parameter 'depth' + is specified, dvisvgm embeds a second rectangle ('x', 'y', 'width', -__depth__). The lengths 'width', 'height' and + 'depth' must be given as plain floating point numbers in TeX point units (1in = 72.27pt). Depending on size and position + of the virtual rectangle, this command either enlarges the overall bounding box or leaves it as is. It's not possible + to reduce its extent. This special should be used in conjunction with *dvisvgm:raw* in order to update the viewport + of the page properly. + + *dvisvgm:bbox* a[bs] 'x1' 'y1' 'x2' 'y2';; + This variant of the bbox special updates the bounding box by embedding a virtual rectangle ('x1','y1','x2','y2'). + The points ('x1','y1') and ('x2','y2') denote two diagonal corners of the rectangle given in TeX point units. + + *dvisvgm:bbox* f[ix] 'x1' 'y1' 'x2' 'y2';; + This variant of the bbox special assigns an absolute (final) bounding box to the resulting SVG. After executing + this command, dvisvgm doesn't further alter the bounding box coordinates, except this special is called again later. + The points ('x1','y1') and ('x2','y2') denote two diagonal corners of the rectangle given in TeX point units. ++ +The following TeX snippet adds two raw SVG elements to the output and updates the bounding box accordingly: ++ +------------------------------------------------------------------------------------ +\special{dvisvgm:raw <circle cx='{?x}' cy='{?y}' r='10' stroke='black' fill='red'/>} +\special{dvisvgm:bbox 20 10 10} + +\special{dvisvgm:raw <path d='M50 200 L10 250 H100 Z' stroke='black' fill='blue'/>} +\special{dvisvgm:bbox abs 10 200 100 250} +------------------------------------------------------------------------------------ ++ + +*em*:: +These specials were introduced with the emTeX distribution by Eberhard Mattes. They provide line drawing +statements, instructions for embedding MSP, PCX, and BMP image files, as well as two PCL commands. +dvisvgm supports only the line drawing statements and ignores all other em specials silently. +A description of the command syntax can be found in the DVI driver documentation coming with emTeX (see CTAN). + +*html*:: +The hyperref specials allow the definition of hyperlinks inside DVI files in various flavors. dvisvgm supports +the plain HyperTeX special constructs as created with hyperref package option 'hypertex'. Internal links, i.e. +references to other parts of the same document, are only converted if the link and the corresponding link target +are located on the same page. Links between different pages are not supported yet. +By default, all linked areas of the document are marked by a rectangle. Option *--linkmark* allows to change +this behavior. See above for further details. Information on syntax and semantics of the HyperTeX specials can be +found in the hyperref manual. + +*pdf*:: +pdfTeX and dvipdfmx introduced several special commands related to the generation of PDF files. Currently, only +two of them, 'pdf:mapfile' and 'pdf:mapline' are supported by dvisvgm. These specials allow modifying the font map +tree during the processing of DVI files. They are used by CTeX, for example. dvisvgm supports both, the dvips and +dvipdfm font map format. For further information on the command syntax and semantics, see the documentation of +\pdfmapfile in the pdfTeX user manual. + +*ps*:: +The famous DVI driver dvips introduced its own set of specials in order to embed PostScript code into DVI files, +which greatly improves the capabilities of DVI documents. One aim of dvisvgm is to completely evaluate all +PostScript snippets and to convert a large amount of it to SVG. However, in contrast to dvips, dvisvgm uses floating point +arithmetics to compute the precise position of each graphic element, i.e. it doesn't round the coordinates. Therefore, +the relative locations of the graphic elements may slightly differ from those computed by dvips. ++ +Since PostScript is a rather complex language, dvisvgm does not try to implement its own PostScript interpreter but relies on +Ghostscript instead. If the Ghostscript library was not linked to the dvisvgm binary, it is looked up and loaded dynamically +during runtime. In this case, dvisvgm looks for 'libgs.so.X' on Unix-like systems (supported ABI versions: 7,8,9), +and for 'gsdll32.dll' or 'gsdll64.dll' on Windows. +You can override the default file names with environment variable +LIBGS+ or the command-line option *--libgs*. +The library must be reachable through the ld search path (\*nix) or the PATH environment variable (Windows). Alternatively, +the absolute file path can be specified. If the library cannot be found, dvisvgm disables the processing of PostScript specials. +Use option *--list-specials* to check whether PS support is available, i.e. entry 'ps' is present. ++ +The PostScript handler also recognizes and evaluates bounding box data generated by the 'preview' package with +option 'tightpage'. If the data is present in a DVI file, dvisvgm adapts the bounding box of the generated SVG file +accordingly, and prints a message showing the width, height, and depth of the box in TeX point units. Especially, +the depth value can be used to vertically align the SVG graphics with the baseline of surrounding text in HTML or XSL-FO +documents, for example. + +*tpic*:: +The TPIC special set defines instructions for drawing simple geometric objects. Some LaTeX packages, like +eepic and tplot, use these specials to describe graphics. + + +EXAMPLES +-------- +-------------- +dvisvgm file +-------------- +Converts the first page of 'file.dvi' to 'file.svg'. + +--------------- +dvisvgm -z file +--------------- +Converts the first page of 'file.dvi' to 'file.svgz' with default compression level 9. + +------------------------------------- +dvisvgm -p5 -z3 -ba4-l -onewfile file +------------------------------------- +Converts the fifth page of 'file.dvi' to 'newfile.svgz' with compression level 3. +The bounding box is set to DIN/ISO A4 in landscape format. + +----------------------------------------------------- +dvisvgm --transform="R20,w/3,2h/5 T1cm,1cm S2,3" file +----------------------------------------------------- +Converts the first page of 'file.dvi' to 'file.svg' where three transformations are applied. + + +ENVIRONMENT +----------- +dvisvgm uses the *kpathsea* library for locating the files that it opens. +Hence, the environment variables described in the library's documentation influence the converter. + +If dvisvgm was linked without the Ghostscript library, and if PostScript support has not been disabled, +the shared Ghostscript library is looked up during runtime via dlopen(). The environment variable +LIBGS+ +can be used to specify path and file name of the library. + +The pre-compiled Windows versions of dvisvgm require a working installation of MiKTeX 2.9 or above. +dvisvgm does not work together with the portable edition of MiKTeX because it relies on MiKTeX's COM +interface only accessible in a local installation. +To enable the evaluation of PostScript specials, the original Ghostscript DLL 'gsdll32.dll' must be present +and reachable through the search path. 64-bit Windows builds require the 64-bit Ghostscript DLL 'gsdll64.dll'. +Both DLLs come with the corresponding Ghostscript installers available from www.ghostscript.com. + +The environment variable +DVISVGM_COLORS+ specifies the colors used to highlight various parts of dvisvgm's +message output. It is only evaluated if option *--color* is given. The value of +DVISVGM_COLORS+ is a list of +colon-separated entries of the form 'gg'='BF', where 'gg' denotes one of the color group indicators listed +below, and 'BF' are two hexadecimal digits specifying the background (first digit) and foreground/text color +(second digit). The color values are defined as follows: 0=black, 1=red, 2=green, 3=yellow, 4=blue, +5=magenta, 6=cyan, 7=gray, 8=bright red, 9=bright green, A=bright yellow, B=bright blue, C=bright magenta, +D=bright cyan, E=bright gray, F=white. Depending on the terminal, the colors may differ. Rather than changing +both the text and background color, it's also possible to change only one of them: An asterisk (*) in +place of a hexadecimal digit indicates the default text or background color of the terminal. + +All malformed entries in the list are silently ignored. + +[horizontal] +*er*:: error messages +*wn*:: warning messages +*pn*:: messages about page numbers +*ps*:: page size messages +*fw*:: information about the files written +*sm*:: state messages +*tr*:: messages of the glyph tracer +*pi*:: progress indicator + +*Example:* +er=01:pi=\*5+ sets the colors of error messages (+er+) to red (+1+) on black (+0+), and those +of progress indicators (+pi+) to cyan (+5+) on default background (+*+). + +FILES +----- +The location of the following files is determined by the kpathsea library. +To check the actual kpathsea configuration you can use the *kpsewhich* utility. + +[horizontal] +**.enc*:: Font encoding files +**.fgd*:: Font glyph data files (cache files created by dvisvgm) +**.map*:: Font map files +**.mf*:: Metafont input files +**.pfb*:: PostScript Type 1 font files +**.pro*:: PostScript header/prologue files +**.tfm*:: TeX font metric files +**.ttf*:: TrueType font files +**.vf*:: Virtual font files + +SEE ALSO +-------- +*tex(1), mf(1), mktexmf(1), grodvi(1), potrace(1)*, and the *kpathsea library* info documentation. + + +RESOURCES +--------- +Project home page::: http://dvisvgm.sourceforge.net +SourceForge project site::: http://sourceforge.net/projects/dvisvgm + + +BUGS +---- +Please report bugs using the bug tracker at Launchpad (see https://launchpad.net/dvisvgm). + + +AUTHOR +------ +Written by {author} <{email}> + + +COPYING +------- +Copyright (C) 2005-2014 Martin Gieseking. Free use of this software is +granted under the terms of the GNU General Public License (GPL) version 3 +or, (at your option) any later version. + +// vim: set syntax=asciidoc: diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.cpp new file mode 100644 index 00000000000..dd19e4b5f53 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.cpp @@ -0,0 +1,38 @@ +/************************************************************************* +** BgColorSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "BgColorSpecialHandler.h" +#include "ColorSpecialHandler.h" +#include "SpecialActions.h" + +using namespace std; + + +bool BgColorSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + ColorSpecialHandler csh; + return csh.process(prefix, is, actions); +} + + +const char** BgColorSpecialHandler::prefixes () const { + static const char *pfx[] = {"background", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.h new file mode 100644 index 00000000000..edd764e86b2 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BgColorSpecialHandler.h @@ -0,0 +1,34 @@ +/************************************************************************* +** BgColorSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_BGCOLORSPECIALHANDLER_H +#define DVISVGM_BGCOLORSPECIALHANDLER_H + +#include "SpecialHandler.h" + +struct BgColorSpecialHandler : SpecialHandler +{ + const char* info () const {return "background color special";} + const char* name () const {return "bgcolor";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.cpp new file mode 100644 index 00000000000..265533b1ef5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.cpp @@ -0,0 +1,126 @@ +/************************************************************************* +** Bitmap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cstdlib> +#include <iostream> +#include "Bitmap.h" +#include "macros.h" + +using namespace std; + +Bitmap::Bitmap () : _rows(0), _cols(0), _xshift(0), _yshift(0), _bpr(0), _bytes(0) +{ +} + + +/** Constructs a Bitmap */ +Bitmap::Bitmap (int minx, int maxx, int miny , int maxy) { + resize(minx, maxx, miny, maxy); +} + + +/** Resizes the bitmap and clears all pixels. + * @param[in] minx index of leftmost pixel column + * @param[in] maxx index of rightmost pixel column + * @param[in] miny index of bottom row + * @param[in] maxy index of top row */ +void Bitmap::resize (int minx, int maxx, int miny , int maxy) { + _rows = abs(maxy-miny)+1; + _cols = abs(maxx-minx)+1; + _xshift = minx; + _yshift = miny; + _bpr = _cols/8 + (_cols % 8 ? 1 : 0); // bytes per row + _bytes.resize(_rows*_bpr); + FORALL(_bytes, vector<UInt8>::iterator, it) + *it = 0; +} + + +/** Sets n pixels of row r to 1 starting at pixel c. + * @param[in] r number of row + * @param[in] c number of column (pixel) + * @param[in] n number of bits to be set */ +void Bitmap::setBits (int r, int c, int n) { + r -= _yshift; + c -= _xshift; + UInt8 *byte = &_bytes[r*_bpr + c/8];// + (c%8 ? 1 : 0); + while (n > 0) { + int b = 7 - c%8; // number of leftmost bit in current byte to be set + int m = min(n, b+1); // number of bits to be set in current byte + int bitseq = (1 << m)-1; // sequence of n set bits (bits 0..n-1 are set) + bitseq <<= b-m+1; // move bit sequence so that bit b is the leftmost set bit + *byte |= UInt8(bitseq); // apply bit sequence to current byte + byte++; + n -= m; + c += m; + } +} + + +void Bitmap::forAllPixels (ForAllData &data) const { + for (int y=_rows-1; y >= 0 ; y--) { + for (int c=0; c < _bpr; c++) { + UInt8 byte = _bytes[y*_bpr+c]; + int x; + for (int b=7; (b >= 0) && ((x = 8*c+(7-b)) < _cols); b--) { + data.pixel(x, y, byte & (1 << b), *this); + } + } + } +} + + +struct BBoxData : public Bitmap::ForAllData +{ + BBoxData () : maxx(0), maxy(0) {} + void pixel (int x, int y, bool set, const Bitmap &bm) { + if (set) { + maxx = max(maxx, x); + maxy = max(maxy, y); + } + } + int maxx, maxy; +}; + + +void Bitmap::bbox (int &w, int &h) const { + BBoxData data; + forAllPixels(data); + w = data.maxx+1; + h = data.maxy+1; +} + + +ostream& Bitmap::write (ostream &os) const { +#if 0 + for (int r=_rows-1; r >= 0 ; r--) { + for (int c=0; c < _bpr; c++) { + UInt8 byte = _bytes[r*_bpr+c]; + for (int b=128; b; b>>=1) + os << (byte & b ? '*' : '-'); + os << ' '; + } + os << endl; + } +#endif + return os; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.h new file mode 100644 index 00000000000..af03597be33 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Bitmap.h @@ -0,0 +1,109 @@ +/************************************************************************* +** Bitmap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_BITMAP_H +#define DVISVGM_BITMAP_H + +#include <ostream> +#include <vector> +#include "types.h" + + +class Bitmap +{ + public: + struct ForAllData { + virtual ~ForAllData() {} + virtual void pixel (int x, int y, bool set, Bitmap &bm) {} + virtual void pixel (int x, int y, bool set, const Bitmap &bm) {} + }; + + public: + Bitmap (); + Bitmap (int minx, int maxx, int miny , int maxy); + void resize (int minx, int maxx, int miny , int maxy); + void setBits(int r, int c, int n); + const UInt8* operator[] (int r) const {return &_bytes[r*_bpr];} + int height () const {return _rows;} + int width () const {return _cols;} + int xshift () const {return _xshift;} + int yshift () const {return _yshift;} + int bytesPerRow () const {return _bpr;} + bool empty () const {return (!_rows && !_cols) || _bytes.empty();} + void bbox (int &w, int &h) const; + void forAllPixels (ForAllData &data) const; + + template <typename T> + int copy (std::vector<T> &target, bool vflip=false) const; + +// template <typename T> +// void write (std::ostream &os, const std::vector<T> &v) const; + + std::ostream& write (std::ostream &os) const; + + private: + int _rows, _cols; ///< number of rows, columns + int _xshift, _yshift; ///< horizontal/vertical shift + int _bpr; ///< number of bytes per row + std::vector<UInt8> _bytes; +}; + + +/** Copies the bitmap to a new target area and reorganize the bits. + * @param[out] target points to first T of new bitmap (must be deleted after usage) + * @param[in] vflip true if the new bitmap should be flipped vertically + * @return number of Ts per row */ +template <typename T> +int Bitmap::copy (std::vector<T> &target, bool vflip) const { + const int s = sizeof(T); + const int tpr = _bpr/s + (_bpr%s ? 1 : 0); // number of Ts per row + target.resize(_rows*tpr); + for (int r=0; r < _rows; r++) { + int targetrow = vflip ? _rows-r-1 : r; + for (int b=0; b < _bpr; b++) { + T &t = target[targetrow*tpr + b/s]; + T chunk = (T)_bytes[r*_bpr+b] << (8*(s-1-b%s)); + if (b % s == 0) + t = chunk; + else + t |= chunk; + } + } + return tpr; +} + + +/* +template <typename T> +void Bitmap::write (std::ostream &os, const std::vector<T> &v) const { + const int s = sizeof(T); + const int tpr = _bpr/s + (_bpr%s ? 1 : 0); // number of Ts per row + for (int r=_rows-1; r >= 0; r--) { + for (int t=0; t < tpr; t++) { + for (T b=(T)1<<(8*s-1); b; b>>=1) + os << ((v[r*tpr+t] & b) ? '*' : '-'); + os << ' '; + } + os << std::endl; + } +}*/ + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.cpp new file mode 100644 index 00000000000..f6c5d0b3b9b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.cpp @@ -0,0 +1,263 @@ +/************************************************************************* +** BoundingBox.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <sstream> +#include <string> +#include "BoundingBox.h" +#include "Matrix.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +BoundingBox::BoundingBox () + : _ulx(0), _uly(0), _lrx(0), _lry(0), _valid(false), _locked(false) +{ +} + + +BoundingBox::BoundingBox (double ulxx, double ulyy, double lrxx, double lryy) + : _ulx(min(ulxx,lrxx)), _uly(min(ulyy,lryy)), + _lrx(max(ulxx,lrxx)), _lry(max(ulyy,lryy)), + _valid(true), _locked(false) +{ +} + + +BoundingBox::BoundingBox (const DPair &p1, const DPair &p2) + : _ulx(min(p1.x(), p2.x())), _uly(min(p1.y(), p2.y())), + _lrx(max(p1.x(), p2.x())), _lry(max(p1.y(), p2.y())), + _valid(true), _locked(false) +{ +} + + +BoundingBox::BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy) + : _ulx(min(ulxx.pt(),lrxx.pt())), _uly(min(ulyy.pt(),lryy.pt())), + _lrx(max(ulxx.pt(),lrxx.pt())), _lry(max(ulyy.pt(),lryy.pt())), + _valid(true), _locked(false) +{ +} + + +BoundingBox::BoundingBox (const string &boxstr) + : _ulx(0), _uly(0), _lrx(0), _lry(0), _valid(false), _locked(false) +{ + set(boxstr); +} + + +/** Removes leading and trailing whitespace from the given string. */ +static string& strip (string &str) { + size_t n=0; + while (n < str.length() && isspace(str[n])) + ++n; + str.erase(0, n); + n=str.length()-1; + while (n > 0 && isspace(str[n])) + --n; + str.erase(n+1); + return str; +} + + +/** Sets or modifies the bounding box. If 'boxstr' consists of 4 length values, + * they denote the absolute position of two diagonal corners of the box. In case + * of a single length value l the current box is enlarged by adding (-l,-l) the upper + * left and (l,l) to the lower right corner. + * @param[in] boxstr whitespace and/or comma separated string of lengths. */ +void BoundingBox::set (string boxstr) { + vector<Length> coord; + const size_t len = boxstr.length(); + size_t l=0; + strip(boxstr); + string lenstr; + do { + while (l < len && isspace(boxstr[l])) + l++; + size_t r=l; + while (r < len && !isspace(boxstr[r]) && boxstr[r] != ',') + r++; + lenstr = boxstr.substr(l, r-l); + if (!lenstr.empty()) { + coord.push_back(Length(lenstr)); + if (boxstr[r] == ',') + r++; + l = r; + } + } while (!lenstr.empty() && coord.size() < 4); + + switch (coord.size()) { + case 1: + _ulx -= coord[0].pt(); + _uly -= coord[0].pt(); + _lrx += coord[0].pt(); + _lry += coord[0].pt(); + break; + case 2: + _ulx -= coord[0].pt(); + _uly -= coord[1].pt(); + _lrx += coord[0].pt(); + _lry += coord[1].pt(); + break; + case 4: + _ulx = min(coord[0].pt(), coord[2].pt()); + _uly = min(coord[1].pt(), coord[3].pt()); + _lrx = max(coord[0].pt(), coord[2].pt()); + _lry = max(coord[1].pt(), coord[3].pt()); + break; + default: + throw BoundingBoxException("1, 2 or 4 length parameters expected"); + } + _valid = true; +} + + +/** Enlarges the box so that point (x,y) is enclosed. */ +void BoundingBox::embed (double x, double y) { + if (!_locked) { + if (_valid) { + if (x < _ulx) + _ulx = x; + else if (x > _lrx) + _lrx = x; + if (y < _uly) + _uly = y; + else if (y > _lry) + _lry = y; + } + else { + _ulx = _lrx = x; + _uly = _lry = y; + _valid = true; + } + } +} + + +/** Enlarges the box so that box bb is enclosed. */ +void BoundingBox::embed (const BoundingBox &bb) { + if (!_locked && bb._valid) { + if (_valid) { + embed(bb._ulx, bb._uly); + embed(bb._lrx, bb._lry); + } + else { + _ulx = bb._ulx; + _uly = bb._uly; + _lrx = bb._lrx; + _lry = bb._lry; + _valid = true; + } + } +} + + +void BoundingBox::embed (const DPair &c, double r) { + embed(BoundingBox(c.x()-r, c.y()-r, c.x()+r, c.y()+r)); +} + + +void BoundingBox::expand (double m) { + if (!_locked) { + _ulx -= m; + _uly -= m; + _lrx += m; + _lry += m; + } +} + + +/** Intersects the current box with bbox and applies the result to *this. + * If both boxes are disjoint, *this is not altered. + * @param[in] bbox box to intersect with + * @return false if *this is locked or both boxes are disjoint */ +bool BoundingBox::intersect (const BoundingBox &bbox) { + if (_locked || _lrx < bbox._ulx || _lry < bbox._uly || _ulx > bbox._lrx || _uly > bbox._lry) + return false; + _ulx = max(_ulx, bbox._ulx); + _uly = max(_uly, bbox._uly); + _lrx = min(_lrx, bbox._lrx); + _lry = min(_lry, bbox._lry); + return true; +} + + +void BoundingBox::operator += (const BoundingBox &bb) { + if (!_locked) { + _ulx += bb._ulx; + _uly += bb._uly; + _lrx += bb._lrx; + _lry += bb._lry; + } +} + + +void BoundingBox::scale (double sx, double sy) { + if (!_locked) { + _ulx *= sx; + _lrx *= sx; + if (sx < 0) swap(_ulx, _lrx); + _uly *= sy; + _lry *= sy; + if (sy < 0) swap(_uly, _lry); + } +} + + +void BoundingBox::transform (const Matrix &tm) { + if (!_locked) { + DPair ul = tm * DPair(_lrx, _lry); + DPair lr = tm * DPair(_ulx, _uly); + DPair ll = tm * DPair(_ulx, _lry); + DPair ur = tm * DPair(_lrx, _uly); + _ulx = min(min(ul.x(), lr.x()), min(ur.x(), ll.x())); + _uly = min(min(ul.y(), lr.y()), min(ur.y(), ll.y())); + _lrx = max(max(ul.x(), lr.x()), max(ur.x(), ll.x())); + _lry = max(max(ul.y(), lr.y()), max(ur.y(), ll.y())); + } +} + + +string BoundingBox::toSVGViewBox () const { + ostringstream oss; + oss << XMLString(_ulx) << ' ' << XMLString(_uly) << ' ' << XMLString(width()) << ' ' << XMLString(height()); + return oss.str(); +} + + +ostream& BoundingBox::write (ostream &os) const { + return os << '(' << _ulx << ", " << _uly + << ", " << _lrx << ", " << _lry << ')'; +} + + +XMLElementNode* BoundingBox::toSVGRect () const { + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", minX()); + rect->addAttribute("y", minY()); + rect->addAttribute("width", width()); + rect->addAttribute("height", height()); + rect->addAttribute("fill", "none"); + return rect; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.h new file mode 100644 index 00000000000..1996973d42d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/BoundingBox.h @@ -0,0 +1,86 @@ +/************************************************************************* +** BoundingBox.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_BOUNDINGBOX_H +#define DVISVGM_BOUNDINGBOX_H + +#include <ostream> +#include <string> +#include "Length.h" +#include "MessageException.h" +#include "Pair.h" +#include "macros.h" +#include "types.h" + + +class Matrix; +class XMLElementNode; + + +struct BoundingBoxException : MessageException +{ + BoundingBoxException (const std::string &msg) : MessageException(msg) {} +}; + + +class BoundingBox +{ + public: + BoundingBox (); + BoundingBox (double ulxx, double ulyy, double lrxx, double lryy); + BoundingBox (const DPair &p1, const DPair &p2); + BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy); + BoundingBox (const std::string &boxstr); + void set (std::string boxstr); + void embed (double x, double y); + void embed (const BoundingBox &bb); + void embed (const DPair &p) {embed(p.x(), p.y());} + void embed (const DPair &c, double r); + + template <typename T> + void embed (const Pair<T> &p) {embed(p.x(), p.y());} + + void expand (double m); + bool intersect (const BoundingBox &bbox); + double minX () const {return _ulx;} + double minY () const {return _uly;} + double maxX () const {return _lrx;} + double maxY () const {return _lry;} + double width () const {return _lrx-_ulx;} + double height () const {return _lry-_uly;} + void lock () {_locked = true;} + void unlock () {_locked = false;} + void operator += (const BoundingBox &bb); + void scale (double sx, double sy); + void transform (const Matrix &tm); + std::string toSVGViewBox () const; + std::ostream& write (std::ostream &os) const; + XMLElementNode* toSVGRect () const; + + private: + double _ulx, _uly; ///< coordinates of upper left vertex (in PS point units) + double _lrx, _lry; ///< coordinates of lower right vertex (in PS point units) + bool _valid : 1; ///< true if the box coordinates are properly set + bool _locked : 1; ///< if true, the box data is read-only +}; + +IMPLEMENT_OUTPUT_OPERATOR(BoundingBox) + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.cpp new file mode 100644 index 00000000000..f6a46a31a86 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.cpp @@ -0,0 +1,230 @@ +/************************************************************************* +** CMap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <sstream> +#include <set> +#include <vector> +#include "CMap.h" +#include "CMapManager.h" +#include "FileFinder.h" +#include "InputReader.h" + +using namespace std; + + +const char* CMap::path () const { + return FileFinder::lookup(name(), "cmap", false); +} + + +const FontEncoding* CMap::findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const { + return CMapManager::instance().findCompatibleBaseFontMap(font, this, charmapID); +} + +////////////////////////////////////////////////////////////////////// + +/** Returns the RO (Registry-Ordering) string of the CMap. */ +string SegmentedCMap::getROString() const { + if (_registry.empty() || _ordering.empty()) + return ""; + return _registry + "-" + _ordering; +} + + +/** Tries to merge range r into this one. This is only possible if the ranges + * touch or overlap and if the assigned CIDs match at the junction points. + * @param[in] r range to join + * @return true if join was successful */ +bool SegmentedCMap::Range::join (const Range &r) { + // check most common cases first + if (_max+1 < r._min || _min-1 > r._max) // disjoint ranges? + return false; + if (r._min-1 == _max) { // does r touch *this on the right? + if (decode(r._min) == r._cid) { + _max = r._max; + return true; + } + return false; + } + if (r._max+1 == _min) { // does r touch *this on the left + if (r.decode(_min) == _cid) { + setMinAndAdaptCID(r._min); + return true; + } + return false; + } + // the following cases should be pretty rare + if (r._min <= _min && r._max >= _max) { // does r overlap *this on both sides? + *this = r; + return true; + } + if (r._min < _min) { // left overlap only? + if (r.decode(_min) == _cid) { + _min = r._min; + _cid = r._cid; + return true; + } + return false; + } + if (r._max > _max) { // right overlap only? + if (decode(r._min) == r._cid) { + _max = r._max; + return true; + } + return false; + } + // r completely inside *this + return decode(r._min) == r._cid; +} + + +/** Adapts the left and right neighbor elements of a newly inserted range. + * The new range could overlap ranges in the neighborhood so that those must be + * adapted or removed. All ranges in the range vector are ordered ascendingly, i.e. + * [min_1, max_1],...,[min_n, max_n] where min_i < min_j for all i < j. + * @param[in,out] ranges range collection to be adapted + * @param[in] it pointer to the newly inserted range */ +void SegmentedCMap::adaptNeighbors (Ranges &ranges, Ranges::iterator it) { + if (it != ranges.end()) { + // adapt left neighbor + SegmentedCMap::Ranges::iterator lit = it-1; // points to left neighbor + if (it != ranges.begin() && it->min() <= lit->max()) { + bool left_neighbor_valid = (it->min() > 0 && it->min()-1 >= lit->min()); + if (left_neighbor_valid) // is adapted left neighbor valid? + lit->_max = it->min()-1; // => assign new max value + if (!left_neighbor_valid || it->join(*lit)) + it = ranges.erase(lit); + } + // remove right neighbors completely overlapped by *it + SegmentedCMap::Ranges::iterator rit = it+1; // points to right neighbor + while (rit != ranges.end() && it->max() >= rit->max()) { // complete overlap? + ranges.erase(rit); + rit = it+1; + } + // adapt rightmost range partially overlapped by *it + if (rit != ranges.end()) { + if (it->max() >= rit->min()) + rit->setMinAndAdaptCID(it->max()+1); + // try to merge right neighbor into *this + if (it->join(*rit)) + ranges.erase(rit); // remove merged neighbor + } + } +} + + +/** Adds a new code range. The range describes a mapping from character codes c to CIDs, where + * \f$c \in [cmin,cmax]\f$ and \f$CID(c):=cid+c-cmin\f$. + * @param[in,out] ranges collection the new range is added to + * @param[in] cmin smallest character code in the range + * @param[in] cmax largest character code in the range + * @param[in] cid CID of the smallest character code (cmin) */ +void SegmentedCMap::addRange (Ranges &ranges, UInt32 cmin, UInt32 cmax, UInt32 cid) { + if (cmin > cmax) + swap(cmin, cmax); + + Range range(cmin, cmax, cid); + if (ranges.empty()) + ranges.push_back(range); + else { + // check for simple cases that can be handled pretty fast + Range &lrange = *ranges.begin(); + Range &rrange = *ranges.rbegin(); + if (cmin > rrange.max()) { // non-overlapping range at end of vector? + if (!rrange.join(range)) + ranges.push_back(range); + } + else if (cmax < lrange.min()) { // non-overlapping range at begin of vector? + if (!lrange.join(range)) + ranges.insert(ranges.begin(), range); + } + else { + // ranges overlap and/or must be inserted somewhere inside the vector + Ranges::iterator it = lower_bound(ranges.begin(), ranges.end(), range); + const bool at_end = (it == ranges.end()); + if (at_end) + --it; + if (!it->join(range)) { + if (it->min() < cmin && it->max() > cmax) { // new range completely inside an existing range? + //split existing range + UInt32 itmax = it->max(); + it->_max = cmin-1; + it = ranges.insert(it+1, Range(cmax+1, itmax, it->decode(cmax+1))); + } + else if (at_end) // does new range overlap right side of last range in vector? + it = ranges.end(); // => append new range at end of vector + it = ranges.insert(it, range); + } + adaptNeighbors(ranges, it); // resolve overlaps + } + } +} + + +/** Returns the CID for a given character code. */ +UInt32 SegmentedCMap::cid (UInt32 c) const { + int pos = lookup(_cidranges, c); + if (pos >= 0) + return _cidranges[pos].decode(c); + if (_basemap) + return _basemap->cid(c); + return 0; +} + + +/** Returns the character code of a base font for a given CID. */ +UInt32 SegmentedCMap::bfcode (UInt32 cid) const { + int pos = lookup(_bfranges, cid); + if (pos >= 0) + return _bfranges[pos].decode(cid); + if (_basemap) + return _basemap->bfcode(cid); + return 0; +} + + +/** Finds the index of the range that contains a given value c. + * @param[in] ranges lookup value in these set of ranges + * @param[in] c find range that contains this value + * @return index of the range found, or -1 if range was not found */ +int SegmentedCMap::lookup (const Ranges &ranges, UInt32 c) const { + // simple binary search + int left=0, right=ranges.size()-1; + while (left <= right) { + int mid = (left+right)/2; + if (c < ranges[mid].min()) + right = mid-1; + else if (c > ranges[mid].max()) + left = mid+1; + else + return mid; + } + return -1; +} + + +void SegmentedCMap::write (ostream &os) const { + for (size_t i=0; i < _cidranges.size(); i++) { + const Range &r = _cidranges[i]; + os << '[' << r.min() << ',' << r.max() << "] => " << r.cid() << '\n'; + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.h new file mode 100644 index 00000000000..2a3e9c7dbbb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMap.h @@ -0,0 +1,148 @@ +/************************************************************************* +** CMap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CMAP_H +#define DVISVGM_CMAP_H + +#include <algorithm> +#include <ostream> +#include <vector> +#include "FontEncoding.h" +#include "types.h" + + +struct CMap : public NamedFontEncoding +{ + virtual ~CMap () {} + virtual bool vertical () const =0; + virtual bool mapsToCID () const =0; + virtual const char* path () const; + virtual UInt32 cid (UInt32 c) const =0; + virtual UInt32 bfcode (UInt32 cid) const =0; + virtual std::string getROString () const =0; + virtual const FontEncoding* findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const; + virtual bool mapsToCharIndex () const {return mapsToCID();} + + Character decode (UInt32 c) const { + if (mapsToCID()) + return Character(Character::INDEX, cid(c)); + return Character(Character::CHRCODE, bfcode(c)); + } +}; + + +struct IdentityCMap : public CMap +{ + UInt32 cid (UInt32 c) const {return c;} + UInt32 bfcode (UInt32 cid) const {return 0;} + std::string getROString () const {return "Adobe-Identity";} + bool mapsToCID() const {return true;} +}; + + +struct IdentityHCMap : public IdentityCMap +{ + bool vertical () const {return false;} + const char* name () const {return "Identity-H";} +}; + + +struct IdentityVCMap : public IdentityCMap +{ + bool vertical () const {return true;} + const char* name () const {return "Identity-V";} +}; + + +struct UnicodeCMap : public CMap +{ + bool vertical () const {return false;} + const char* name () const {return "unicode";} + bool mapsToCID () const {return false;} + const char* path () const {return 0;} + UInt32 cid (UInt32 c) const {return c;} + UInt32 bfcode (UInt32 cid) const {return cid;} + std::string getROString () const {return "";} +}; + + +class SegmentedCMap : public CMap +{ + friend class CMapReader; + + class Range { + friend class SegmentedCMap; + + public: + Range () : _min(0), _max(0), _cid(0) {} + + Range (UInt32 min, UInt32 max, UInt32 cid) : _min(min), _max(max), _cid(cid) { + if (_min > _max) + std::swap(_min, _max); + } + + UInt32 min () const {return _min;} + UInt32 max () const {return _max;} + UInt32 cid () const {return _cid;} + UInt32 decode (UInt32 c) const {return c-_min+_cid;} + bool operator < (const Range &r) const {return _min < r._min;} + + protected: + bool join (const Range &r); + void setMinAndAdaptCID (UInt32 c) {_cid = decode(c); _min = c;} + + private: + UInt32 _min, _max; + UInt32 _cid; + }; + + typedef std::vector<Range> Ranges; + + public: + SegmentedCMap (const std::string &name) : _name(name), _basemap(0), _vertical(false), _mapsToCID(true) {} + const char* name () const {return _name.c_str();} + UInt32 cid (UInt32 c) const; + UInt32 bfcode (UInt32 cid) const; + void addCIDRange (UInt32 first, UInt32 last, UInt32 cid) {addRange(_cidranges, first, last, cid);} + void addBFRange (UInt32 first, UInt32 last, UInt32 chrcode) {addRange(_bfranges, first, last, chrcode);} + void write (std::ostream &os) const; + bool vertical () const {return _vertical;} + bool mapsToCID () const {return _mapsToCID;} + size_t numCIDRanges () const {return _cidranges.size();} + size_t numBFRanges () const {return _bfranges.size();} + std::string getROString () const; + + protected: + void addRange (Ranges &ranges, UInt32 first, UInt32 last, UInt32 cid); + void adaptNeighbors (Ranges &ranges, Ranges::iterator it); + int lookup (const Ranges &ranges, UInt32 c) const; + + private: + std::string _name; + std::string _registry; + std::string _ordering; + CMap *_basemap; + bool _vertical; + bool _mapsToCID; // true: chrcode->CID, false: CID->charcode + Ranges _cidranges; + Ranges _bfranges; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.cpp new file mode 100644 index 00000000000..cbad12746c9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.cpp @@ -0,0 +1,142 @@ +/************************************************************************* +** CMapManager.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "CMap.h" +#include "CMapManager.h" +#include "CMapReader.h" +#include "Font.h" +#include "FileFinder.h" +#include "Message.h" + +using namespace std; + + +CMapManager::~CMapManager () { + for (CMaps::iterator it=_cmaps.begin(); it != _cmaps.end(); ++it) + delete it->second; +} + + +CMapManager& CMapManager::instance () { + static CMapManager cmm; + return cmm; +} + + +/** Loads a cmap and returns the corresponding object. */ +CMap* CMapManager::lookup (const string &name) { + CMaps::iterator it = _cmaps.find(name); + if (it != _cmaps.end()) + return it->second; + + if (_includedCMaps.find(name) != _includedCMaps.end()) { + _level = 0; + ostringstream oss; + oss << "circular reference of CMap " << name; + throw CMapReaderException(oss.str()); + } + + CMap *cmap=0; + if (name == "Identity-H") + cmap = new IdentityHCMap; + else if (name == "Identity-V") + cmap = new IdentityVCMap; + else if (name == "unicode") + cmap = new UnicodeCMap; + if (cmap) { + _cmaps[name] = cmap; + return cmap; + } + // Load cmap data of file <name> and also process all cmaps referenced by operator "usecmap". + // This can lead to a sequence of further calls of lookup(). In order to prevent infinite loops + // due to (disallowed) circular cmap inclusions, we keep track of all cmaps processed during + // a sequence of inclusions. + _includedCMaps.insert(name); // save name of current cmap being processed + _level++; // increase nesting level + try { + CMapReader reader; + if (!(cmap = reader.read(name))) { + _level = 1; + Message::wstream(true) << "CMap file '" << name << "' not found\n"; + } + _cmaps[name] = cmap; + } + catch (const CMapReaderException &e) { + Message::estream(true) << "CMap file " << name << ": " << e.what() << "\n"; + } + if (--_level == 0) // back again at initial nesting level? + _includedCMaps.clear(); // => names of included cmaps are no longer needed + return cmap; +} + + +/** Looks for a base font CMap and a compatible encoding table in a given font. The CMap describe + * the mapping from CIDs to character codes where the latter are relative to the encoding table + * identified by charmapID. + * cmap:X->CID, bfmap:CID->Y, enctable:Y->CharCode + * @param[in] font look for available encoding tables in this font + * @param[in] cmap take the source registry-ordering pair from this CMap + * @param[out] charmapID ID of the compatible character map found in the given font + * @return base font CMap that maps from CIDs to character codes */ +const CMap* CMapManager::findCompatibleBaseFontMap (const PhysicalFont *font, const CMap *cmap, CharMapID &charmapID) { + if (!font || !cmap) + return 0; + + static const struct CharMapIDToEncName { + CharMapID id; + const char *encname; + } encodings[] = { + {CharMapID::WIN_UCS4, "UCS4"}, + {CharMapID::WIN_UCS2, "UCS2"}, + {CharMapID::WIN_SHIFTJIS, "90ms-RKSJ"}, + {CharMapID::WIN_PRC, "GBK-EUC"}, + {CharMapID::WIN_BIG5, "ETen-B5"}, + {CharMapID::WIN_WANSUNG, "KSCms-UHC"}, + {CharMapID::MAC_JAPANESE, "90pv-RKSJ"}, + {CharMapID::MAC_TRADCHINESE, "B5pc"}, + {CharMapID::MAC_SIMPLCHINESE, "GBpc-EUC"}, + {CharMapID::MAC_KOREAN, "KSCpc-EUC"} + }; + + // get IDs of all available charmaps in font + vector<CharMapID> charmapIDs; + font->collectCharMapIDs(charmapIDs); + + const bool is_unicode_map = dynamic_cast<const UnicodeCMap*>(cmap); + const size_t num_encodings = is_unicode_map ? 2 : sizeof(encodings)/sizeof(CharMapIDToEncName); + + // try to find a compatible encoding CMap + const string ro = cmap->getROString(); + for (const CharMapIDToEncName *enc=encodings; enc < enc+num_encodings; enc++) { + for (size_t i=0; i < charmapIDs.size(); i++) { + if (enc->id == charmapIDs[i]) { + string cmapname = ro+"-"+enc->encname; + if (is_unicode_map || FileFinder::lookup(cmapname, "cmap", false)) { + charmapID = enc->id; + return is_unicode_map ? cmap : lookup(cmapname); + } + } + } + } + return 0; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.h new file mode 100644 index 00000000000..fb71886753c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapManager.h @@ -0,0 +1,52 @@ +/************************************************************************* +** CMapManager.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CMAPMANAGER_H +#define DVISVGM_CMAPMANAGER_H + +#include <map> +#include <set> +#include <string> +#include "CharMapID.h" +#include "Font.h" + +struct CMap; +struct FontEncoding; +class FontEncodingPair; + +class CMapManager +{ + typedef std::map<std::string, CMap*> CMaps; + public: + ~CMapManager (); + CMap* lookup (const std::string &name); + const CMap* findCompatibleBaseFontMap (const PhysicalFont *font, const CMap *cmap, CharMapID &charmapID); + static CMapManager& instance (); + + protected: + CMapManager () : _level(0) {} + + private: + CMaps _cmaps; ///< loaded cmaps + int _level; ///< current inclusion depth; >0 if a cmap loaded by "usecmap" is being processed + std::set<std::string> _includedCMaps; ///< names of cmaps loaded by "usecmap" +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.cpp new file mode 100644 index 00000000000..502e42ef2e0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.cpp @@ -0,0 +1,265 @@ +/************************************************************************* +** CMapReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <fstream> +#include <sstream> +#include "CMap.h" +#include "CMapManager.h" +#include "CMapReader.h" +#include "FileFinder.h" +#include "InputReader.h" + +using namespace std; + + +CMapReader::CMapReader () : _cmap(0), _inCMap(false) +{ +} + + +/** Reads a cmap file and returns the corresponding CMap object. + * @param fname[in] name/path of cmap file + * @return CMap object representing the read data, or 0 if file could not be read */ +CMap* CMapReader::read (const string &fname) { + if (const char *path = FileFinder::lookup(fname.c_str(), "cmap", false)) { + ifstream ifs(path); + if (ifs) + return read(ifs, fname); + } + _tokens.clear(); + return 0; +} + + +/** Reads cmap data from a given stream and returns the corresponding CMap object. + * @param is[in] cmap data input stream + * @param is[in] name name of CMap to be read + * @return CMap object representing the read data, or 0 if file could not be read */ +CMap* CMapReader::read (std::istream& is, const string &name) { + _tokens.clear(); + _cmap = new SegmentedCMap(name); + StreamInputReader ir(is); + try { + while (ir) { + Token token(ir); + if (token.type() == Token::TT_EOF) + break; + if (_inCMap) { + if (token.type() == Token::TT_OPERATOR) + executeOperator(token.strvalue(), ir); + else + _tokens.push_back(token); + } + else if (token.type() == Token::TT_OPERATOR && token.strvalue() == "begincmap") + _inCMap = true; + } + } + catch (CMapReaderException &e) { + delete _cmap; + _cmap = 0; + throw; + } + return _cmap; +} + + +void CMapReader::executeOperator (const string &op, InputReader &ir) { + const struct Operator { + const char *name; + void (CMapReader::*handler)(InputReader&); + } operators[] = { + {"beginbfchar", &CMapReader::op_beginbfchar}, + {"beginbfrange", &CMapReader::op_beginbfrange}, + {"begincidrange", &CMapReader::op_begincidrange}, + {"def", &CMapReader::op_def}, + {"endcmap", &CMapReader::op_endcmap}, + {"usecmap", &CMapReader::op_usecmap}, + }; + + for (size_t i=0; i < sizeof(operators)/sizeof(Operator); i++) { + if (operators[i].name == op) { + (this->*operators[i].handler)(ir); + break; + } + } + _tokens.clear(); +} + + +void CMapReader::op_def (InputReader&) { + size_t size = _tokens.size(); + if (size >= 2) { + const string val = popToken().strvalue(); + const string name = popToken().strvalue(); + if (name == "CMapName") { + if (val != _cmap->_name) + throw CMapReaderException("CMapName doesn't match filename"); + } + else if (name == "WMode") { + if (val == "0" || val == "1") + _cmap->_vertical = (val == "1"); + else + throw CMapReaderException("invalid WMode (0 or 1 expected)"); + } + else if (name == "Registry") + _cmap->_registry = val; + else if (name == "Ordering") + _cmap->_ordering = val; + } +} + + +void CMapReader::op_endcmap (InputReader &) { + _inCMap = false; +} + + +void CMapReader::op_usecmap (InputReader &) { + if (_tokens.empty()) + throw CMapReaderException("stack underflow while processing usecmap"); + else { + const string name = popToken().strvalue(); + if ((_cmap->_basemap = CMapManager::instance().lookup(name)) == 0) + throw CMapReaderException("CMap file '"+name+"' not found"); + } +} + + +static UInt32 parse_hexentry (InputReader &ir) { + ir.skipSpace(); + if (ir.get() != '<') + throw CMapReaderException("invalid range entry ('<' expected)"); + int val; + if (!ir.parseInt(16, val)) + throw CMapReaderException("invalid range entry (hexadecimal value expected)"); + if (ir.get() != '>') + throw CMapReaderException("invalid range entry ('>' expected)"); + return UInt32(val); +} + + +void CMapReader::op_begincidrange (InputReader &ir) { + if (!_tokens.empty() && _tokens.back().type() == Token::TT_NUMBER) { + ir.skipSpace(); + int num_entries = static_cast<int>(popToken().numvalue()); + while (num_entries > 0 && ir.peek() == '<') { + UInt32 first = parse_hexentry(ir); + UInt32 last = parse_hexentry(ir); + UInt32 cid; + ir.skipSpace(); + if (!ir.parseUInt(cid)) + throw CMapReaderException("invalid range entry (decimal value expected)"); + _cmap->addCIDRange(first, last, cid); + ir.skipSpace(); + } + } +} + + +void CMapReader::op_beginbfrange (InputReader &ir) { + if (!_tokens.empty() && _tokens.back().type() == Token::TT_NUMBER) { + ir.skipSpace(); + int num_entries = static_cast<int>(popToken().numvalue()); + while (num_entries > 0 && ir.peek() == '<') { + UInt32 first = parse_hexentry(ir); + UInt32 last = parse_hexentry(ir); + UInt32 chrcode = parse_hexentry(ir); + _cmap->addBFRange(first, last, chrcode); + ir.skipSpace(); + } + _cmap->_mapsToCID = false; + } +} + + +void CMapReader::op_beginbfchar (InputReader &ir) { + if (!_tokens.empty() && _tokens.back().type() == Token::TT_NUMBER) { + ir.skipSpace(); + int num_entries = static_cast<int>(popToken().numvalue()); + while (num_entries > 0 && ir.peek() == '<') { + UInt32 cid = parse_hexentry(ir); + ir.skipSpace(); + if (ir.peek() == '/') + throw CMapReaderException("mapping of named characters is not supported"); + UInt32 chrcode = parse_hexentry(ir); + _cmap->addBFRange(cid, cid, chrcode); + ir.skipSpace(); + } + _cmap->_mapsToCID = false; + } +} + +//////////////////////////////////////////////////////////////////////////////////// + +CMapReader::Token::Token (InputReader &ir) { + scan(ir); +} + + +/** Reads the next characters from the input stream to create a token. */ +void CMapReader::Token::scan (InputReader &ir) { + ir.skipSpace(); + while (ir.peek() == '%') { // comment? + while (ir.peek() != '\n') // => skip until end of line + ir.get(); + ir.skipSpace(); + } + ir.skipSpace(); + if (ir.eof()) + _type = TT_EOF; + else if (ir.peek() == '/') { // PS name? + ir.get(); + while (!strchr("[]{}<>", ir.peek()) && !isspace(ir.peek())) + _value += ir.get(); + _type = TT_NAME; + } + else if (ir.peek() == '(') { // string? + ir.get(); + int level=0; + while (ir.peek() != ')' || level > 0) { + if (ir.peek() == '(') + level++; + else if (ir.peek() == ')' && level > 0) + level--; + _value += ir.get(); + } + ir.get(); // skip ')' + _type = TT_STRING; + } + else if (strchr("[]{}<>", ir.peek())) { // PS delimiter + _value = ir.get(); + _type = TT_DELIM; + } + else if (isdigit(ir.peek())) { // number? + double val; + if (ir.parseDouble(val)) { + ostringstream oss; + oss << val; + _value = oss.str(); + _type = TT_NUMBER; + } + } + else { + while (!strchr("[]{}<>", ir.peek()) && !isspace(ir.peek())) + _value += ir.get(); + _type = TT_OPERATOR; + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.h new file mode 100644 index 00000000000..5986e92b13d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CMapReader.h @@ -0,0 +1,81 @@ +/************************************************************************* +** CMapReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CMAPREADER_H +#define DVISVGM_CMAPREADER_H + +#include <cstdlib> +#include <istream> +#include <string> +#include <vector> +#include "MessageException.h" + + +struct CMap; +class InputReader; + +class CMapReader +{ + class Token + { + public: + enum Type {TT_UNKNOWN, TT_EOF, TT_DELIM, TT_NUMBER, TT_STRING, TT_NAME, TT_OPERATOR}; + + public: + Token (InputReader &ir); + void scan (InputReader &ir); + Type type () const {return _type;} + const std::string& strvalue () const {return _value;} + double numvalue () const {return std::atof(_value.c_str());} + + private: + Type _type; + std::string _value; + }; + + public: + CMapReader (); + CMap* read (const std::string &fname); + CMap* read (std::istream &is, const std::string &name); + + protected: + Token popToken () {Token t=_tokens.back(); _tokens.pop_back(); return t;} + void executeOperator (const std::string &op, InputReader &ir); + void op_beginbfchar (InputReader &ir); + void op_beginbfrange (InputReader &ir); + void op_begincidrange (InputReader &ir); + void op_def (InputReader &ir); + void op_endcmap (InputReader &ir); + void op_usecmap (InputReader &ir); + + private: + SegmentedCMap *_cmap; ///< CMap being read + std::vector<Token> _tokens; ///< stack of tokens to be processed + bool _inCMap; ///< operator begincmap has been executed +}; + + + +struct CMapReaderException : public MessageException +{ + CMapReaderException (const std::string &msg) : MessageException(msg) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.cpp new file mode 100644 index 00000000000..3f85710c6b7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.cpp @@ -0,0 +1,113 @@ +/************************************************************************* +** CRC32.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include "CRC32.h" + +using namespace std; + + +CRC32::CRC32 () : _crc32(0xFFFFFFFF) +{ + const UInt32 poly = 0xEDB88320; + for (int i = 0; i < 256; i++) { + UInt32 crc=i; + for (int j=8; j > 0; j--) { + if (crc & 1) + crc = (crc >> 1) ^ poly; + else + crc >>= 1; + } + _tab[i] = crc; + } +} + + +/** Resets CRC32 sum to 0. */ +void CRC32::reset () { + _crc32 = 0xFFFFFFFF; +} + + +/** Appends string bytes to the previous data and computes the resulting checksum. + * @param[in] data string to update the checksum with */ +void CRC32::update (const char *data) { + update((const UInt8*)data, strlen(data)); +} + + +/** Appends a single value to the previous data and computes the resulting checksum. + * @param[in] n value to update the checksum with + * @param[in] bytes number of bytes to consider (0-4) */ +void CRC32::update (UInt32 n, int bytes) { + for (int i=bytes-1; i >= 0; --i) { + UInt8 byte = UInt8((n >> (8*i)) & 0xff); + update(&byte, 1); + } +} + + +/** Appends a sequence of bytes to the previous data and computes the resulting checksum. + * @param[in] bytes pointer to array of bytes + * @param[in] len number of bytes in array */ +void CRC32::update (const UInt8 *bytes, size_t len) { + for (size_t i=0; i < len; ++i) + _crc32 = ((_crc32 >> 8) & 0x00FFFFFF) ^ _tab[(_crc32 ^ *bytes++) & 0xFF]; +} + + +void CRC32::update (istream &is) { + char buf [4096]; + while (is) { + is.read(buf, 4096); + update((UInt8*)buf, is.gcount()); + } +} + + +/** Returns the checksum computed from values added with the update functions. */ +UInt32 CRC32::get () const { + return _crc32 ^ 0xFFFFFFFF; +} + + +/** Computes the CRC32 checksum of a sequence of bytes. + * @param[in] bytes pointer to array of bytes + * @param[in] len number of bytes in array + * @return CRC32 checksum */ +UInt32 CRC32::compute (const UInt8 *bytes, size_t len) { + CRC32 crc32; + crc32.update(bytes, len); + return crc32.get(); +} + + +/** Computes the CRC32 checksum of a string. */ +UInt32 CRC32::compute (const char *str) { + return compute((const UInt8*)str, strlen(str)); +} + + +UInt32 CRC32::compute (istream &is) { + CRC32 crc32; + crc32.update(is); + return crc32.get(); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.h new file mode 100644 index 00000000000..4376b192077 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CRC32.h @@ -0,0 +1,51 @@ +/************************************************************************* +** CRC32.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef CRC32_H +#define CRC32_H + +#include <cstdlib> +#include <istream> +#include "types.h" + +class CRC32 +{ + public: + CRC32 (); + void update (const UInt8 *bytes, size_t len); + void update (UInt32 n, int bytes=4); + void update (const char *str); + void update (std::istream &is); + UInt32 get () const; + void reset (); + static UInt32 compute (const UInt8 *bytes, size_t len); + static UInt32 compute (const char *str); + static UInt32 compute (std::istream &is); + + protected: + CRC32 (const CRC32 &crc32) {} + + private: + UInt32 _crc32; + UInt32 _tab[256]; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.cpp new file mode 100644 index 00000000000..2e0bb06a361 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.cpp @@ -0,0 +1,179 @@ +/************************************************************************* +** Calculator.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <sstream> +#include "Calculator.h" + +using namespace std; + +// token types +const char END = 0; +const char NUMBER = 1; +const char NAME = 2; + + +#include <iostream> + + +/** Evaluates a given arithmetic expression and returns its value. + * The evaluator is implemented as a recursive descendent parser. + * @param[in] is reads expression from this stream + * @return expression value */ +double Calculator::eval (istream &is) { + double ret = expr(is, false); + if (lookAhead(is) > 0) + throw CalculatorException("expression syntax error"); + return ret; +} + + +/** Evaluates a given arithmetic expression and returns its value. + * @param[in] expr expression to evaluate + * @return expression value */ +double Calculator::eval (const string &expr) { + istringstream iss; + iss.str(expr); + return eval(iss); +} + + +/** Evaluates the root rule of the expression grammar. */ +double Calculator::expr (istream &is, bool skip) { // expr: + double left = term(is, skip); + while (1) + switch (lookAhead(is)) { + case '+': left += term(is, true); break; // term '+' term => $1 + $3 + case '-': left -= term(is, true); break; // term '-' term => $1 - $3 + default : return left; // term => $1 + } +} + + +double Calculator::term (istream &is, bool skip) { // term: + double left = prim(is, skip); + while (1) + switch (lookAhead(is)) { + case '*': left *= prim(is, true); break; // prim '*' prim => $1 * $3 + case '/': { // prim '/' prim => $1 / $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left /= denom; + break; + } + case '%': { // prim '%' prim => $1 mod $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left -= denom*floor(left/denom); + break; + } + default: // prim => $1 + return left; + } +} + + +double Calculator::prim (istream &is, bool skip) { // prim: + if (skip) + lex(is); + switch (lookAhead(is)) { + case NUMBER: { // NUMBER => $1 + lex(is); + double ret = _numValue; + if (lookAhead(is) == NAME) { // NUMBER NAME => $1 * $2 + lex(is); + ret *= getVariable(_strValue); + } + return ret; + } + case NAME: { // NAME => getVariable($1) + lex(is); + return getVariable(_strValue); + } + case '-': // '-' prim => -$2 + return -prim(is, true); + case '(': { // '(' expr ')' => $2 + double e = expr(is, true); + if (lookAhead(is) != ')') + throw CalculatorException("')' expected"); + lex(is); + return e; + } + default: + throw CalculatorException("primary expression expected"); + } +} + + +/** Determines type of next token without swallowing it. That means + * the same token will be read again next time. */ +char Calculator::lookAhead (istream &is) { + while (isspace(is.peek())) // skip whitespace + is.get(); + if (is.eof()) + return END; + int c = is.peek(); + if (isdigit(c) || c == '.') + return NUMBER; + if (isalpha(c)) + return NAME; + return char(c); +} + + +/** Reads next token and returns its type. The token value is either assigned + * to the object members numValue or strValue depending on the type. The token + * type is represented by a unique integer. In contrast to method 'lookAhead' + * lex consumes the read token. + * @param[in] is next token is read from this stream + * @return token type */ +char Calculator::lex (istream &is) { + int tokenType = lookAhead(is); + switch (tokenType) { + case NUMBER: + is >> _numValue; + break; + case NAME: { + _strValue.clear(); + while (isalpha(is.peek())) + _strValue += char(is.get()); + break; + } + default: + tokenType = is.get(); + } + return char(tokenType); +} + + +/** Returns the value of a previously defined variable. If there + * is no variable of the given name, a CalculatorException is thrown. + * @param[in] name name of variable + * @return assigned value */ +double Calculator::getVariable (const string &name) const { + map<string,double>::const_iterator it = _variables.find(name); + if (it == _variables.end()) + throw CalculatorException("undefined variable '" + name + "'"); + return it->second; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.h new file mode 100644 index 00000000000..89d2c08560d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Calculator.h @@ -0,0 +1,57 @@ +/************************************************************************* +** Calculator.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CALCULATOR_H +#define DVISVGM_CALCULATOR_H + +#include <istream> +#include <map> +#include <string> +#include "MessageException.h" + + +struct CalculatorException : public MessageException +{ + CalculatorException (const std::string &msg) : MessageException(msg) {} +}; + +class Calculator +{ + public: + Calculator () : _numValue(0) {} + double eval (std::istream &is); + double eval (const std::string &expr); + void setVariable (const std::string &name, double value) {_variables[name] = value;} + double getVariable (const std::string &name) const; + + protected: + double expr (std::istream &is, bool skip); + double term (std::istream &is, bool skip); + double prim (std::istream &is, bool skip); + char lex (std::istream &is); + char lookAhead (std::istream &is); + + private: + std::map<std::string,double> _variables; + double _numValue; + std::string _strValue; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.cpp new file mode 100644 index 00000000000..3e749add96b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.cpp @@ -0,0 +1,57 @@ +/************************************************************************* +** CharMap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include "CharMap.h" + +using namespace std; + +static bool is_less (const pair<UInt32,UInt32> &p1, const pair<UInt32,UInt32> &p2) { + return p1.first < p2.first; +} + + +UInt32 CharMap::operator [] (UInt32 c) const { + vector<UInt32Pair>::const_iterator it = lower_bound(_pairs.begin(), _pairs.end(), UInt32Pair(c, 0), &is_less); + return (it != _pairs.end() && it->first == c) ? it->second : 0; +} + + +/** Returns true if the charmap contains an entry that maps to the given charcode */ +bool CharMap::valueExists (UInt32 c) const { + for (std::vector<UInt32Pair>::const_iterator it=_pairs.begin(); it != _pairs.end(); ++it) + if (it->second == c) + return true; + return false; +} + + +/** Swaps key and value of all entries. */ +void CharMap::invert () { + for (std::vector<UInt32Pair>::iterator it=_pairs.begin(); it != _pairs.end(); ++it) + swap(it->first, it->second); + sort(); +} + + +void CharMap::sort () { + std::sort(_pairs.begin(), _pairs.end(), &is_less); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.h new file mode 100644 index 00000000000..8faeffa21c1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMap.h @@ -0,0 +1,51 @@ +/************************************************************************* +** CharMap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CHARMAP_H +#define DVISVGM_CHARMAP_H + +#include <utility> +#include <vector> +#include "types.h" + +class FontEngine; + +class CharMap +{ + friend class FontEngine; + typedef std::pair<UInt32, UInt32> UInt32Pair; + public: + CharMap () {} + bool valueExists (UInt32 c) const; + UInt32 operator [] (UInt32 c) const; + UInt32 size () const {return _pairs.size();} + bool empty () const {return _pairs.empty();} + void clear () {return _pairs.clear();} + void invert (); + + protected: + void append (UInt32 from, UInt32 to) {_pairs.push_back(UInt32Pair(from, to));} + void sort (); + + private: + std::vector<UInt32Pair> _pairs; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.cpp new file mode 100644 index 00000000000..2c6e1cd8a59 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.cpp @@ -0,0 +1,35 @@ +/************************************************************************* +** CharMapID.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include "CharMapID.h" + +const CharMapID CharMapID::WIN_SYMBOL(3, 0); +const CharMapID CharMapID::WIN_UCS2(3, 1); +const CharMapID CharMapID::WIN_SHIFTJIS(3, 2); +const CharMapID CharMapID::WIN_PRC(3, 3); +const CharMapID CharMapID::WIN_BIG5(3, 4); +const CharMapID CharMapID::WIN_WANSUNG(3, 5); +const CharMapID CharMapID::WIN_JOHAB(3, 6); +const CharMapID CharMapID::WIN_UCS4(3, 10); + +const CharMapID CharMapID::MAC_JAPANESE(1, 1); +const CharMapID CharMapID::MAC_TRADCHINESE(1, 2); +const CharMapID CharMapID::MAC_KOREAN(1, 3); +const CharMapID CharMapID::MAC_SIMPLCHINESE(1, 25); diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.h new file mode 100644 index 00000000000..ea30d50d266 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CharMapID.h @@ -0,0 +1,58 @@ +/************************************************************************* +** CharMapID.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CHARMAPID_H +#define DVISVGM_CHARMAPID_H + +#include "types.h" + +/** Represents a character map of a font. */ +struct CharMapID { + CharMapID () : platform_id(0), encoding_id(0) {} + CharMapID (UInt8 plf_id, UInt8 enc_id) : platform_id(plf_id), encoding_id(enc_id) {} + + bool operator == (const CharMapID &ids) const { + return platform_id == ids.platform_id && encoding_id == ids.encoding_id; + } + + bool operator != (const CharMapID &ids) const { + return platform_id != ids.platform_id || encoding_id != ids.encoding_id; + } + + bool valid () const {return platform_id != 0 && encoding_id != 0;} + + static const CharMapID WIN_SYMBOL; + static const CharMapID WIN_UCS2; + static const CharMapID WIN_SHIFTJIS; + static const CharMapID WIN_PRC; + static const CharMapID WIN_BIG5; + static const CharMapID WIN_WANSUNG; + static const CharMapID WIN_JOHAB; + static const CharMapID WIN_UCS4; + static const CharMapID MAC_JAPANESE; + static const CharMapID MAC_TRADCHINESE; + static const CharMapID MAC_SIMPLCHINESE; + static const CharMapID MAC_KOREAN; + + UInt8 platform_id; + UInt8 encoding_id; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Character.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Character.h new file mode 100644 index 00000000000..a9d0f6a2d6d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Character.h @@ -0,0 +1,46 @@ +/************************************************************************* +** Character.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CHARACTER_H +#define DVISVGM_CHARACTER_H + +#include "types.h" + +class Character +{ + public: + enum Type {CHRCODE, INDEX, NAME}; + Character (const char *name) : _type(NAME), _name(name) {} + Character (Type type, UInt32 val) : _type(type), _number(val) {} + Character (Type type, const Character &c) : _type(type), _number(c.type() != NAME ? c._number : 0) {} + Type type () const {return _type;} + const char* name () const {return _name;} + UInt32 number () const {return _number;} + + private: + Type _type; + union { + UInt32 _number; + const char *_name; + }; +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.cpp new file mode 100644 index 00000000000..2c8d133cc97 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.cpp @@ -0,0 +1,372 @@ +/************************************************************************* +** CmdLineParserBase.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cstdio> +#include <cstring> +#include "CmdLineParserBase.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "Message.h" + +using namespace std; + +void CmdLineParserBase::init () { + _error = false; + _files.clear(); +} + + +/** Parses all options given on the command line. + * @param[in] argc number of command-line arguments + * @param[in] argv array providing the command-line arguments + * @param[in] printErrors enable/disable printing of error messages */ +void CmdLineParserBase::parse (int argc, char **argv, bool printErrors) { + init(); + _printErrors = printErrors; + bool filesOnly = false; // + for (int i=1; i < argc; i++) { + CharInputBuffer ib(argv[i], strlen(argv[i])); + BufferInputReader ir(ib); + if (filesOnly || ir.peek() != '-') + _files.push_back(argv[i]); + else { + ir.get(); + if (ir.peek() == '-') { + // scan long option + ir.get(); + if (ir.eof()) // "--" only + filesOnly = true; // treat all following options as filenames + else { + string longname; + while (isalnum(ir.peek()) || ir.peek() == '-') + longname += char(ir.get()); + if (const Option *opt = option(longname)) + (*opt->handler)(this, ir, *opt, true); + else if (!_error) { + if (printErrors) + Message::estream(false) << "unknown option --" << longname << '\n'; + _error = true; + } + } + } + else { + // scan short option(s) + bool combined = false; // multiple short options combined, e.g -abc + do { + int shortname = ir.get(); + if (const Option *opt = option(shortname)) { + if (!combined || opt->argmode == ARG_NONE) { + if (opt->argmode == ARG_REQUIRED && strlen(argv[i]) == 2) { // required argument separated by whitespace? + if (i+1 < argc && argv[i+1][0] != '-') + ib.assign(argv[++i]); + } + (*opt->handler)(this, ir, *opt, false); + if (opt->argmode == ARG_NONE) + combined = true; + } + else { + if (printErrors) + Message::estream(false) << "option -" << char(shortname) << " must be given separately\n"; + _error = true; + } + } + else if (shortname > 0) { + if (printErrors) + Message::estream(false) << "unknown option -" << char(shortname) << '\n'; + _error = true; + } + } + while (!_error && combined && !ir.eof()); + } + } + } +} + + +/** Prints an error message to stdout. + * @param[in] opt error occurred in this option + * @param[in] longopt the long option name was scanned + * @param[in] msg message to be printed */ +void CmdLineParserBase::error (const Option &opt, bool longopt, const char *msg) const { + if (_printErrors) { + Message::estream(false) << "option "; + if (longopt) + Message::estream(false) << "--" << opt.longname; + else + Message::estream(false) << '-' << opt.shortname; + Message::estream(false) << ": " << msg << '\n'; + } + _error = true; +} + + +#if 0 +#include <iostream> + +/** Lists the scanned filenames. Just for debugging purposes. */ +void CmdLineParserBase::status () const { + cout << "file names:\n"; + for (size_t i=0; i < _files.size(); i++) + cout << " " << _files[i] << endl; + cout << endl; +} +#endif + + +/** Returns the option information of a given short option name. + * If the option name can't be found 0 is returned. + * @param[in] shortname short version of the option without leading hyphen (e.g. p, not -p) */ +const CmdLineParserBase::Option* CmdLineParserBase::option (char shortname) const { + size_t numopts; // number of available options + for (const Option *opts = options(&numopts); numopts > 0; ++opts) { + if (opts->shortname == shortname) + return opts; + numopts--; + } + return 0; +} + + +/** Returns the option information of a given long option name. + * Parameter 'longname' hasn't to be the complete long option name. The function looks up + * all options that start with 'longname'. If a unique or an exact match was found, it's returned. + * Otherwise, the return value is 0. + * @param[in] longname long version of the option without leading hyphens (e.g. param, not --param) */ +const CmdLineParserBase::Option* CmdLineParserBase::option (const string &longname) const { + vector<const Option*> matches; // all matching options + size_t len = longname.length(); + size_t numopts; // number of available options + for (const Option *opts = options(&numopts); numopts > 0; ++opts) { + if (string(opts->longname, len) == longname) { + if (len == strlen(opts->longname)) // exact match? + return opts; + matches.push_back(opts); + } + numopts--; + } + switch (matches.size()) { + default: + if (_printErrors) { + Message::estream(false) << "option --" << longname << " is ambiguous ("; + for (size_t i=0; i < matches.size(); i++) { + if (i > 0) + Message::estream(false) << ", "; + Message::estream(false) << matches[i]->longname; + } + Message::estream(false) << ")\n"; + } + _error = true; + + case 0 : return 0; + case 1 : return matches[0]; + } +} + + +/** Returns true if a valid separator between option and argument was found. + * Arguments of long options are preceded by a '='. The argument of a short option + * directly follows the option without a separation character. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given */ +bool CmdLineParserBase::checkArgPrefix (InputReader &ir, const Option &opt, bool longopt) const { + if (longopt) { + if (ir.peek() == '=') + ir.get(); + else { + error(opt, longopt, "'=' expected"); + return false; + } + } + return true; +} + + +/** Returns true if a given option has no argument, .e.g. -p or --param. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given */ +bool CmdLineParserBase::checkNoArg (InputReader &ir, const Option &opt, bool longopt) const { + if (ir.eof()) + return true; + error(opt, longopt, "no argument expected"); + return false; +} + + +/** Gets an integer argument of a given option, e.g. -p5 or --param=5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getIntArg (InputReader &ir, const Option &opt, bool longopt, int &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseInt(arg) && ir.eof()) + return true; + error(opt, longopt, "integer value expected"); + } + return false; +} + + +/** Gets an unsigned integer argument of a given option, e.g. -p5 or --param=5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getUIntArg (InputReader &ir, const Option &opt, bool longopt, unsigned &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseUInt(arg) && ir.eof()) + return true; + error(opt, longopt, "unsigned integer value expected"); + } + return false; +} + + +/** Gets a double (floating point) argument of a given option, e.g. -p2.5 or --param=2.5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getDoubleArg (InputReader &ir, const Option &opt, bool longopt, double &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseDouble(arg) != 0 && ir.eof()) + return true; + error(opt, longopt, "floating point value expected"); + } + return false; +} + + +/** Gets a string argument of a given option, e.g. -pstr or --param=str. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getStringArg (InputReader &ir, const Option &opt, bool longopt, string &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + arg.clear(); + while (!ir.eof()) + arg += char(ir.get()); + if (!arg.empty()) + return true; + error(opt, longopt, "string argument expected"); + } + return false; +} + + +/** Gets a boolean argument of a given option, e.g. -pyes or --param=yes. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getBoolArg (InputReader &ir, const Option &opt, bool longopt, bool &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + string str; + while (!ir.eof()) + str += char(ir.get()); + if (str == "yes" || str == "y" || str == "true" || str == "1") { + arg = true; + return true; + } + else if (str == "no" || str == "n" || str == "false" || str == "0") { + arg = false; + return true; + } + error(opt, longopt, "boolean argument expected (yes, no, true, false, 0, 1)"); + } + return false; +} + + +/** Gets a (single) character argument of a given option, e.g. -pc or --param=c. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getCharArg (InputReader &ir, const Option &opt, bool longopt, char &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + arg = char(ir.get()); + if (arg >= 0 && ir.eof()) + return true; + error(opt, longopt, "character argument expected"); + } + return false; +} + + +/** Compares the short option characters of two help lines. + * @return true if line1 should appear before line2 */ +static bool cmp_short (const char *line1, const char *line2) { + if (*line1 != 'o' || *line2 != 'o' || (line1[1] == ' ' && line2[1] == ' ')) + return strcmp(line1, line2) < 0; + char lopt1 = tolower(line1[2]); + char lopt2 = tolower(line2[2]); + if (lopt1 == lopt2) // same character but different case? + return line1[2] > line2[2]; // line with lower-case letter first + return lopt1 < lopt2; +} + + +/** Compares the long option names of two help lines. + * @return true if line1 should appear before line2 */ +static bool cmp_long (const char *line1, const char *line2) { + if (*line1 != 'o' || *line2 != 'o') + return strcmp(line1, line2) < 0; + return strcmp(line1+6, line2+6) < 0; +} + + +/** Prints the help text to stdout. + * @param[in] mode format of help text */ +void CmdLineParserBase::help (int mode) const { + size_t numlines; + const char **lines = helplines(&numlines); + if (mode == 0) { // list options with section headers + for (size_t i=0; i < numlines; i++) { + switch (*lines[i]) { + case 's': fputc('\n', stdout); break; // section header + case 'o': fputs(" ", stdout); break; // option info + } + puts(lines[i]+1); + } + } + else { + vector<const char*> linevec(lines, lines+numlines); + sort(linevec.begin(), linevec.end(), mode == 1 ? cmp_short : cmp_long); + for (vector<const char*>::iterator it=linevec.begin(); it != linevec.end(); ++it) { + if (**it != 's') { // skip section headers + puts(*it+1); + if (**it == 'd') + puts("\nOptions:"); + } + } + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.h new file mode 100644 index 00000000000..87e740feaf3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CmdLineParserBase.h @@ -0,0 +1,99 @@ +/************************************************************************* +** CmdLineParserBase.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_CMDLINEPARSERBASE_H +#define DVISVGM_CMDLINEPARSERBASE_H + +#include <string> +#include <vector> + +class InputReader; + +class CmdLineParserBase +{ + protected: + struct Option; + + struct OptionHandler { + virtual ~OptionHandler () {} + virtual void operator () (CmdLineParserBase *obj, InputReader &ir, const Option &opt, bool longopt) const=0; + }; + + template <typename T> + class OptionHandlerImpl : public OptionHandler { + protected: + typedef void (T::*LocalHandler)(InputReader &ir, const Option &opt, bool longopt); + + public: + OptionHandlerImpl (LocalHandler handler) : _handler(handler) {} + + void operator () (CmdLineParserBase *obj, InputReader &ir, const Option &opt, bool longopt) const { + if (T *tobj = dynamic_cast<T*>(obj)) + (tobj->*_handler)(ir, opt, longopt); + } + + private: + LocalHandler _handler; + }; + + enum ArgMode {ARG_NONE, ARG_OPTIONAL, ARG_REQUIRED}; + + struct Option { + ~Option () {delete handler;} + char shortname; + const char *longname; + ArgMode argmode; // mode of option argument + const OptionHandler *handler; + }; + + public: + virtual void parse (int argc, char **argv, bool printErrors=true); + virtual void help (int mode=0) const; + virtual int numFiles () const {return _files.size();} + virtual const char* file (size_t n) {return n < _files.size() ? _files[n].c_str() : 0;} +// virtual void status () const; + virtual bool error () const {return _error;} + + protected: + CmdLineParserBase () : _printErrors(true), _error(false) {} + CmdLineParserBase (const CmdLineParserBase &cmd) : _printErrors(true), _error(false) {} + virtual ~CmdLineParserBase () {} + virtual void init (); + virtual void error (const Option &opt, bool longopt, const char *msg) const; + virtual const Option* options (size_t *numopts) const =0; + virtual const char** helplines (size_t *numlines) const =0; + bool checkArgPrefix (InputReader &ir, const Option &opt, bool longopt) const; + bool checkNoArg (InputReader &ir, const Option &opt, bool longopt) const; + bool getIntArg (InputReader &ir, const Option &opt, bool longopt, int &arg) const; + bool getUIntArg (InputReader &ir, const Option &opt, bool longopt, unsigned &arg) const; + bool getDoubleArg (InputReader &ir, const Option &opt, bool longopt, double &arg) const; + bool getStringArg (InputReader &ir, const Option &opt, bool longopt, std::string &arg) const; + bool getBoolArg (InputReader &ir, const Option &opt, bool longopt, bool &arg) const; + bool getCharArg (InputReader &ir, const Option &opt, bool longopt, char &arg) const; + const Option* option (char shortname) const; + const Option* option (const std::string &longname) const; + + private: + bool _printErrors; ///< if true, print error messages + mutable bool _error; ///< error occured while parsing options + std::vector<std::string> _files; ///< filename parameters +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.cpp new file mode 100644 index 00000000000..7e8d9d56069 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.cpp @@ -0,0 +1,264 @@ +/************************************************************************* +** Color.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cctype> +#include <cmath> +#include <cstdlib> +#include <cstring> +#include <iomanip> +#include <sstream> +#include "Color.h" + +using namespace std; + + +const Color Color::BLACK(UInt32(0)); +const Color Color::WHITE(UInt8(255), UInt8(255), UInt8(255)); +const Color Color::TRANSPARENT(UInt32(0xff000000)); + + +static inline UInt8 float_to_byte (float v) { + v = max(0.0f, min(1.0f, v)); + return UInt8(floor(255*v+0.5)); +} + + +static void tolower (string &str) { + for (size_t i=0; i < str.length(); i++) + str[i] = tolower(str[i]); +} + + +Color::Color (const char *name) { + if (!set(name, false)) + setGray(UInt8(0)); +} + + +Color::Color (const string &name) { + if (!set(name, false)) + setGray(UInt8(0)); +} + + +void Color::set (float r, float g, float b) { + set(float_to_byte(r), float_to_byte(g), float_to_byte(b)); +} + + +bool Color::set (string name, bool case_sensitive) { + if (name[0] == '#') { + char *p=0; + _rgb = UInt32(strtol(name.c_str()+1, &p, 16)); + while (isspace(*p)) + p++; + return (*p == 0 && _rgb <= 0xFFFFFF); + } + // converted color constants from color.pro + static const struct ColorConstant { + const char *name; + const UInt32 rgb; + } + constants[] = { + {"Apricot", 0xFFAD7A}, + {"Aquamarine", 0x2DFFB2}, + {"Bittersweet", 0xC10200}, + {"Black", 0x000000}, + {"Blue", 0x0000FF}, + {"BlueGreen", 0x26FFAA}, + {"BlueViolet", 0x190CF4}, + {"BrickRed", 0xB70000}, + {"Brown", 0x660000}, + {"BurntOrange", 0xFF7C00}, + {"CadetBlue", 0x606DC4}, + {"CarnationPink", 0xFF5EFF}, + {"Cerulean", 0x0FE2FF}, + {"CornflowerBlue", 0x59DDFF}, + {"Cyan", 0x00FFFF}, + {"Dandelion", 0xFFB528}, + {"DarkOrchid", 0x9932CC}, + {"Emerald", 0x00FF7F}, + {"ForestGreen", 0x00E000}, + {"Fuchsia", 0x7202EA}, + {"Goldenrod", 0xFFE528}, + {"Gray", 0x7F7F7F}, + {"Green", 0x00FF00}, + {"GreenYellow", 0xD8FF4F}, + {"JungleGreen", 0x02FF7A}, + {"Lavender", 0xFF84FF}, + {"LimeGreen", 0x7FFF00}, + {"Magenta", 0xFF00FF}, + {"Mahogany", 0xA50000}, + {"Maroon", 0xAD0000}, + {"Melon", 0xFF897F}, + {"MidnightBlue", 0x007091}, + {"Mulberry", 0xA314F9}, + {"NavyBlue", 0x0F75FF}, + {"OliveGreen", 0x009900}, + {"Orange", 0xFF6321}, + {"OrangeRed", 0xFF007F}, + {"Orchid", 0xAD5BFF}, + {"Peach", 0xFF7F4C}, + {"Periwinkle", 0x6D72FF}, + {"PineGreen", 0x00BF28}, + {"Plum", 0x7F00FF}, + {"ProcessBlue", 0x0AFFFF}, + {"Purple", 0x8C23FF}, + {"RawSienna", 0x8C0000}, + {"Red", 0xFF0000}, + {"RedOrange", 0xFF3A21}, + {"RedViolet", 0x9600A8}, + {"Rhodamine", 0xFF2DFF}, + {"RoyalBlue", 0x007FFF}, + {"RoyalPurple", 0x3F19FF}, + {"RubineRed", 0xFF00DD}, + {"Salmon", 0xFF779E}, + {"SeaGreen", 0x4FFF7F}, + {"Sepia", 0x4C0000}, + {"SkyBlue", 0x60FFE0}, + {"SpringGreen", 0xBCFF3D}, + {"Tan", 0xDB9370}, + {"TealBlue", 0x1EF9A3}, + {"Thistle", 0xE068FF}, + {"Turquoise", 0x26FFCC}, + {"Violet", 0x351EFF}, + {"VioletRed", 0xFF30FF}, + {"White", 0xFFFFFF}, + {"WildStrawberry", 0xFF0A9B}, + {"Yellow", 0xFFFF00}, + {"YellowGreen", 0x8EFF42}, + {"YellowOrange", 0xFF9300}, + }; + if (!case_sensitive) { + tolower(name); + for (size_t i=0; i < sizeof(constants)/sizeof(ColorConstant); i++) { + string cmpname = constants[i].name; + tolower(cmpname); + if (name == cmpname) { + _rgb = constants[i].rgb; + return true; + } + } + return false; + } + + // binary search + int first=0, last=sizeof(constants)/sizeof(ColorConstant)-1; + while (first <= last) { + int mid = first+(last-first)/2; + int cmp = strcmp(constants[mid].name, name.c_str()); + if (cmp > 0) + last = mid-1; + else if (cmp < 0) + first = mid+1; + else { + _rgb = constants[mid].rgb; + return true; + } + } + return false; +} + + +void Color::setHSB (float h, float s, float b) { + vector<float> hsb(3), rgb(3); + hsb[0] = h; + hsb[1] = s; + hsb[2] = b; + HSB2RGB(hsb, rgb); + set(rgb[0], rgb[1], rgb[2]); +} + + +void Color::setCMYK (float c, float m, float y, float k) { + vector<float> cmyk(4), rgb(3); + cmyk[0] = c; + cmyk[1] = m; + cmyk[2] = y; + cmyk[3] = k; + CMYK2RGB(cmyk, rgb); + set(rgb[0], rgb[1], rgb[2]); +} + + +void Color::operator *= (double c) { + UInt32 rgb=0; + for (int i=0; i < 3; i++) { + rgb |= UInt32(floor((_rgb & 0xff)*c+0.5)) << (8*i); + _rgb >>= 8; + } + _rgb = rgb; +} + + +string Color::rgbString () const { + ostringstream oss; + oss << '#'; + for (int i=2; i >= 0; i--) { + oss << setbase(16) << setfill('0') << setw(2) + << (((_rgb >> (8*i)) & 0xff)); + } + return oss.str(); +} + + +/** Approximates a CMYK color by an RGB triple. The component values + * are expected to be normalized, i.e. 0 <= cmyk[i],rgb[j] <= 1. + * @param[in] cmyk color in CMYK space + * @param[out] rgb RGB approximation */ +void Color::CMYK2RGB (const vector<float> &cmyk, vector<float> &rgb) { + for (int i=0; i < 3; i++) + rgb[i] = 1.0f-max(0.0f, min(1.0f, cmyk[i]+cmyk[3])); +} + + +/** Converts a color given in HSB coordinates to RGB. + * @param[in] hsb color in HSB space + * @param[out] rgb color in RGB space */ +void Color::HSB2RGB (const vector<float> &hsb, vector<float> &rgb) { + if (hsb[1] == 0) + rgb[0] = rgb[1] = rgb[2] = hsb[2]; + else { + float h = hsb[0]-floor(hsb[0]); + int i = int(6*h); + float f = float(6.0*h-i); + float p = hsb[2]*(1-hsb[1]); + float q = hsb[2]*(1-hsb[1]*f); + float t = hsb[2]*(1-hsb[1]*(1-f)); + switch (i) { + case 0 : rgb[0]=hsb[2]; rgb[1]=t; rgb[2]=p; break; + case 1 : rgb[0]=q; rgb[1]=hsb[2]; rgb[2]=p; break; + case 2 : rgb[0]=p; rgb[1]=hsb[2]; rgb[2]=t; break; + case 3 : rgb[0]=p; rgb[1]=q; rgb[2]=hsb[2]; break; + case 4 : rgb[0]=t; rgb[1]=p; rgb[2]=hsb[2]; break; + case 5 : rgb[0]=hsb[2]; rgb[1]=p; rgb[2]=q; break; + default: ; // prevent compiler warning + } + } +} + + +void Color::getRGB (float &r, float &g, float &b) const { + r = float(((_rgb >> 16) & 255) / 255.0); + g = float(((_rgb >> 8) & 255) / 255.0); + b = float((_rgb & 255) / 255.0); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.h new file mode 100644 index 00000000000..99d847560e0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Color.h @@ -0,0 +1,67 @@ +/************************************************************************* +** Color.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_COLOR_H +#define DVISVGM_COLOR_H + +#include <string> +#include <vector> +#include "types.h" + +#ifdef TRANSPARENT +#undef TRANSPARENT +#endif + +class Color +{ + public: + static const Color BLACK; + static const Color WHITE; + static const Color TRANSPARENT; + + public: + Color () : _rgb(0) {} + Color (UInt32 rgb) : _rgb(rgb) {} + Color (UInt8 r, UInt8 g, UInt8 b) {set(r,g,b);} + Color (float r, float g, float b) {set(r,g,b);} + Color (const std::vector<float> &rgb) {set(rgb[0], rgb[1], rgb[2]);} + Color (const char *name); + Color (const std::string &name); + operator UInt32 () const {return _rgb;} + bool operator == (const Color &c) const {return _rgb == c._rgb;} + bool operator != (const Color &c) const {return _rgb != c._rgb;} + void set (UInt8 r, UInt8 g, UInt8 b) {_rgb = (r << 16) | (g << 8) | b;} + void set (float r, float g, float b); + bool set (std::string name, bool case_sensitive=true); + void setGray (UInt8 g) {set(g,g,g);} + void setGray (float g) {set(g,g,g);} + void setHSB (float h, float s, float b); + void setCMYK (float c, float m, float y, float k); + void getRGB (float &r, float &g, float &b) const; + void operator *= (double c); + std::string rgbString () const; + static void CMYK2RGB (const std::vector<float> &cmyk, std::vector<float> &rgb); + static void HSB2RGB (const std::vector<float> &hsb, std::vector<float> &rgb); + + private: + UInt32 _rgb; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.cpp new file mode 100644 index 00000000000..31b9de68c01 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.cpp @@ -0,0 +1,126 @@ +/************************************************************************* +** ColorSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cmath> +#include <cstring> +#include <iomanip> +#include <sstream> +#include <vector> +#include "ColorSpecialHandler.h" +#include "SpecialActions.h" + +using namespace std; + + +static float read_float (istream &is) { + is.clear(); + float v; + is >> v; + if (is.fail()) + throw SpecialException("number expected"); + return v; +} + + +/** Reads multiple float values from a given stream. The number of + * values read is determined by the size of the result vector. + * @param[in] is stream to be read from + * @param[out] v the resulting floats */ +static void read_floats (istream &is, vector<float> &v) { + for (size_t i=0; i < v.size(); i++) + v[i] = read_float(is); +} + + +/** Reads a color statement from an input stream and converts it to RGB. + * A color statement has the following syntax: + * _color model_ _component values_ + * Currently, the following color models are supported: rgb, cmyk, hsb and gray. + * Examples: rgb 1 0.5 0, gray 0.5 + * @param[in] model if model != "" this value specifies the model, otherwise it's read from the stream + * @param[in] is stream to be read from + * @param[out] color italicresulting RGB triple + * @return true if statement has successfully been read */ +static void read_color (string model, istream &is, Color &color) { + if (model.empty()) + is >> model; + if (model == "rgb") { + vector<float> rgb(3); + read_floats(is, rgb); + color.set(rgb[0], rgb[1], rgb[2]); + } + else if (model == "cmyk") { + vector<float> cmyk(4); + read_floats(is, cmyk); + color.setCMYK(cmyk[0], cmyk[1], cmyk[2], cmyk[3]); + } + else if (model == "hsb") { + vector<float> hsb(3); + read_floats(is, hsb); + color.setHSB(hsb[0], hsb[1], hsb[2]); + } + else if (model == "gray") + color.setGray(read_float(is)); + else if (!color.set(model, true)) + throw SpecialException("unknown color statement"); +} + + +bool ColorSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + Color color; + if (prefix && strcmp(prefix, "background") == 0) { + read_color("", is, color); + actions->setBgColor(color); + } + else { + string cmd; + is >> cmd; + if (cmd == "push") { // color push <model> <params> + read_color("", is, color); + _colorStack.push(color); + } + else if (cmd == "pop") { + if (!_colorStack.empty()) // color pop + _colorStack.pop(); + } + else { // color <model> <params> + read_color(cmd, is, color); + while (!_colorStack.empty()) + _colorStack.pop(); + _colorStack.push(color); + } + if (actions) { + if (_colorStack.empty()) + actions->setColor(Color::BLACK); + else + actions->setColor(_colorStack.top()); + } + } + return true; +} + + +const char** ColorSpecialHandler::prefixes () const { + static const char *pfx[] = {"color", 0}; + return pfx; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.h new file mode 100644 index 00000000000..27dfe984a00 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ColorSpecialHandler.h @@ -0,0 +1,42 @@ +/************************************************************************* +** ColorSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_COLORSPECIALHANDLER_H +#define DVISVGM_COLORSPECIALHANDLER_H + +#include <stack> +#include <vector> +#include "Color.h" +#include "SpecialHandler.h" + + +class ColorSpecialHandler : public SpecialHandler +{ + public: + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + const char* name () const {return "color";} + const char* info () const {return "complete support of color specials";} + const char** prefixes () const; + + private: + std::stack<Color> _colorStack; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.cpp new file mode 100644 index 00000000000..7a50191229f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.cpp @@ -0,0 +1,316 @@ +// This file was automatically generated by opt2cpp. +// It is part of the dvisvgm package and published under the terms +// of the GNU General Public License version 3, or (at your option) any later version. +// See file COPYING for further details. +// (C) 2009-2014 Martin Gieseking <martin.gieseking@uos.de> + +#include <config.h> +#include <cstdio> +#include <iostream> +#include <iomanip> +#include "InputReader.h" +#include "CommandLine.h" + +using namespace std; + +const CmdLineParserBase::Option CommandLine::_options[] = { + {'b', "bbox", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_bbox)}, + {'C', "cache", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_cache)}, + {'\0', "color", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_color)}, +#if !defined(DISABLE_GS) + {'E', "eps", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_eps)}, +#endif + {'e', "exact", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_exact)}, + {'m', "fontmap", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_fontmap)}, + {'h', "help", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_help)}, + {'\0', "keep", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_keep)}, +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + {'\0', "libgs", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_libgs)}, +#endif + {'L', "linkmark", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_linkmark)}, + {'l', "list-specials", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_list_specials)}, + {'M', "mag", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_mag)}, + {'n', "no-fonts", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_fonts)}, + {'\0', "no-mktexmf", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_mktexmf)}, + {'S', "no-specials", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_specials)}, + {'\0', "no-styles", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_styles)}, + {'o', "output", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_output)}, + {'p', "page", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_page)}, + {'d', "precision", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_precision)}, + {'P', "progress", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_progress)}, + {'r', "rotate", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_rotate)}, + {'c', "scale", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_scale)}, + {'s', "stdout", ARG_NONE, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_stdout)}, + {'a', "trace-all", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_trace_all)}, + {'T', "transform", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_transform)}, + {'t', "translate", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_translate)}, + {'v', "verbosity", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_verbosity)}, + {'V', "version", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_version)}, + {'z', "zip", ARG_OPTIONAL, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_zip)}, + {'Z', "zoom", ARG_REQUIRED, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_zoom)}, +}; + +const CmdLineParserBase::Option* CommandLine::options (size_t *numopts) const { + *numopts = sizeof(_options)/sizeof(CmdLineParserBase::Option); + return _options; +} + +void CommandLine::init () { + CmdLineParserBase::init(); + + // disable all options by default + _bbox_given = false; + _cache_given = false; + _color_given = false; +#if !defined(DISABLE_GS) + _eps_given = false; +#endif + _exact_given = false; + _fontmap_given = false; + _help_given = false; + _keep_given = false; +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + _libgs_given = false; +#endif + _linkmark_given = false; + _list_specials_given = false; + _mag_given = false; + _no_fonts_given = false; + _no_mktexmf_given = false; + _no_specials_given = false; + _no_styles_given = false; + _output_given = false; + _page_given = false; + _precision_given = false; + _progress_given = false; + _rotate_given = false; + _scale_given = false; + _stdout_given = false; + _trace_all_given = false; + _transform_given = false; + _translate_given = false; + _verbosity_given = false; + _version_given = false; + _zip_given = false; + _zoom_given = false; + + // set default option values + _bbox_arg = "min"; + _cache_arg.clear(); + _fontmap_arg.clear(); + _help_arg = 0; +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + _libgs_arg.clear(); +#endif + _linkmark_arg = "box"; + _mag_arg = 4; + _no_fonts_arg = 0; + _no_specials_arg.clear(); + _output_arg.clear(); + _page_arg = "1"; + _precision_arg = 0; + _progress_arg = 0.5; + _rotate_arg = 0; + _scale_arg.clear(); + _trace_all_arg = false; + _transform_arg.clear(); + _translate_arg.clear(); + _verbosity_arg = 7; + _version_arg = false; + _zip_arg = 9; + _zoom_arg = 1.0; +} + +const char** CommandLine::helplines (size_t *numlines) const { + static const char *lines[] = { + "dThis program converts DVI files, as created by TeX/LaTeX, to\nthe XML-based scalable vector graphics format SVG.\n\nUsage: dvisvgm [options] dvifile\n dvisvgm -E [options] epsfile", + "sInput options:", + "o-p, --page=ranges choose pages to convert [1]", + "o-m, --fontmap=filenames evaluate (additional) font map files", +#if !defined(DISABLE_GS) + "o-E, --eps convert an EPS file to SVG", +#endif + "sSVG output options:", + "o-b, --bbox=size set size of bounding box [min]", + "o-L, --linkmark=type select how to mark hyperlinked areas [box]", + "o-o, --output=pattern set name pattern of output files", + "o-d, --precision=number set number of decimal points (0-6) [0]", + "o-s, --stdout write SVG output to stdout", + "o-n, --no-fonts[=variant] draw glyphs by using path elements [0]", + "o --no-styles don't use styles to reference fonts", + "o-z, --zip[=level] create compressed .svgz file [9]", + "sSVG transformations:", + "o-r, --rotate=angle rotate page content clockwise", + "o-c, --scale=sx[,sy] scale page content", + "o-t, --translate=tx[,ty] shift page content", + "o-T, --transform=commands transform page content", + "o-Z, --zoom=factor zoom page content [1.0]", + "sProcessing options:", + "o-C, --cache[=dir] set/print path of cache directory", + "o-e, --exact compute exact glyph boxes", + "o --keep keep temporary files", +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + "o --libgs=filename set name of Ghostscript shared library", +#endif + "o-M, --mag=factor magnification of Metafont output [4]", + "o --no-mktexmf don't try to create missing fonts", + "o-S, --no-specials[=prefixes] don't process [selected] specials", + "o-a, --trace-all[=retrace] trace all glyphs of bitmap fonts [no]", + "sMessage options:", + "o --color colorize messages", + "o-h, --help[=mode] print this summary of options and exit [0]", + "o-l, --list-specials print supported special sets and exit", + "o-P, --progress[=delay] enable progess indicator [0.5]", + "o-v, --verbosity=level set verbosity level (0-7) [7]", + "o-V, --version[=extended] print version and exit [no]", + }; + *numlines = sizeof(lines)/sizeof(char*); + return lines; +} + +void CommandLine::handle_bbox (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _bbox_arg)) + _bbox_given = true; +} + +void CommandLine::handle_cache (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getStringArg(ir, opt, longopt, _cache_arg)) + _cache_given = true; +} + +void CommandLine::handle_color (InputReader &ir, const Option &opt, bool longopt) { + _color_given = true; +} + +#if !defined(DISABLE_GS) +void CommandLine::handle_eps (InputReader &ir, const Option &opt, bool longopt) { + _eps_given = true; +} +#endif + +void CommandLine::handle_exact (InputReader &ir, const Option &opt, bool longopt) { + _exact_given = true; +} + +void CommandLine::handle_fontmap (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _fontmap_arg)) + _fontmap_given = true; +} + +void CommandLine::handle_help (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getIntArg(ir, opt, longopt, _help_arg)) + _help_given = true; +} + +void CommandLine::handle_keep (InputReader &ir, const Option &opt, bool longopt) { + _keep_given = true; +} + +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) +void CommandLine::handle_libgs (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _libgs_arg)) + _libgs_given = true; +} +#endif + +void CommandLine::handle_linkmark (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _linkmark_arg)) + _linkmark_given = true; +} + +void CommandLine::handle_list_specials (InputReader &ir, const Option &opt, bool longopt) { + _list_specials_given = true; +} + +void CommandLine::handle_mag (InputReader &ir, const Option &opt, bool longopt) { + if (getDoubleArg(ir, opt, longopt, _mag_arg)) + _mag_given = true; +} + +void CommandLine::handle_no_fonts (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getIntArg(ir, opt, longopt, _no_fonts_arg)) + _no_fonts_given = true; +} + +void CommandLine::handle_no_mktexmf (InputReader &ir, const Option &opt, bool longopt) { + _no_mktexmf_given = true; +} + +void CommandLine::handle_no_specials (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getStringArg(ir, opt, longopt, _no_specials_arg)) + _no_specials_given = true; +} + +void CommandLine::handle_no_styles (InputReader &ir, const Option &opt, bool longopt) { + _no_styles_given = true; +} + +void CommandLine::handle_output (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _output_arg)) + _output_given = true; +} + +void CommandLine::handle_page (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _page_arg)) + _page_given = true; +} + +void CommandLine::handle_precision (InputReader &ir, const Option &opt, bool longopt) { + if (getIntArg(ir, opt, longopt, _precision_arg)) + _precision_given = true; +} + +void CommandLine::handle_progress (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getDoubleArg(ir, opt, longopt, _progress_arg)) + _progress_given = true; +} + +void CommandLine::handle_rotate (InputReader &ir, const Option &opt, bool longopt) { + if (getDoubleArg(ir, opt, longopt, _rotate_arg)) + _rotate_given = true; +} + +void CommandLine::handle_scale (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _scale_arg)) + _scale_given = true; +} + +void CommandLine::handle_stdout (InputReader &ir, const Option &opt, bool longopt) { + _stdout_given = true; +} + +void CommandLine::handle_trace_all (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getBoolArg(ir, opt, longopt, _trace_all_arg)) + _trace_all_given = true; +} + +void CommandLine::handle_transform (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _transform_arg)) + _transform_given = true; +} + +void CommandLine::handle_translate (InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _translate_arg)) + _translate_given = true; +} + +void CommandLine::handle_verbosity (InputReader &ir, const Option &opt, bool longopt) { + if (getUIntArg(ir, opt, longopt, _verbosity_arg)) + _verbosity_given = true; +} + +void CommandLine::handle_version (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getBoolArg(ir, opt, longopt, _version_arg)) + _version_given = true; +} + +void CommandLine::handle_zip (InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getIntArg(ir, opt, longopt, _zip_arg)) + _zip_given = true; +} + +void CommandLine::handle_zoom (InputReader &ir, const Option &opt, bool longopt) { + if (getDoubleArg(ir, opt, longopt, _zoom_arg)) + _zoom_given = true; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.h new file mode 100644 index 00000000000..20a991b0e1e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/CommandLine.h @@ -0,0 +1,174 @@ +// This file was automatically generated by opt2cpp. +// It is part of the dvisvgm package and published under the terms +// of the GNU General Public License version 3, or (at your option) any later version. +// See file COPYING for further details. +// (C) 2009-2014 Martin Gieseking <martin.gieseking@uos.de> + +#ifndef COMMANDLINE_H +#define COMMANDLINE_H + +#include <config.h> +#include "CmdLineParserBase.h" + +class CommandLine : public CmdLineParserBase +{ + public: + CommandLine () {init();} + CommandLine (int argc, char **argv, bool printErrors) {parse(argc, argv, printErrors);} + bool bbox_given () const {return _bbox_given;} + const std::string& bbox_arg () const {return _bbox_arg;} + bool cache_given () const {return _cache_given;} + const std::string& cache_arg () const {return _cache_arg;} + bool color_given () const {return _color_given;} +#if !defined(DISABLE_GS) + bool eps_given () const {return _eps_given;} +#endif + bool exact_given () const {return _exact_given;} + bool fontmap_given () const {return _fontmap_given;} + const std::string& fontmap_arg () const {return _fontmap_arg;} + bool help_given () const {return _help_given;} + int help_arg () const {return _help_arg;} + bool keep_given () const {return _keep_given;} +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + bool libgs_given () const {return _libgs_given;} + const std::string& libgs_arg () const {return _libgs_arg;} +#endif + bool linkmark_given () const {return _linkmark_given;} + const std::string& linkmark_arg () const {return _linkmark_arg;} + bool list_specials_given () const {return _list_specials_given;} + bool mag_given () const {return _mag_given;} + double mag_arg () const {return _mag_arg;} + bool no_fonts_given () const {return _no_fonts_given;} + int no_fonts_arg () const {return _no_fonts_arg;} + bool no_mktexmf_given () const {return _no_mktexmf_given;} + bool no_specials_given () const {return _no_specials_given;} + const std::string& no_specials_arg () const {return _no_specials_arg;} + bool no_styles_given () const {return _no_styles_given;} + bool output_given () const {return _output_given;} + const std::string& output_arg () const {return _output_arg;} + bool page_given () const {return _page_given;} + const std::string& page_arg () const {return _page_arg;} + bool precision_given () const {return _precision_given;} + int precision_arg () const {return _precision_arg;} + bool progress_given () const {return _progress_given;} + double progress_arg () const {return _progress_arg;} + bool rotate_given () const {return _rotate_given;} + double rotate_arg () const {return _rotate_arg;} + bool scale_given () const {return _scale_given;} + const std::string& scale_arg () const {return _scale_arg;} + bool stdout_given () const {return _stdout_given;} + bool trace_all_given () const {return _trace_all_given;} + bool trace_all_arg () const {return _trace_all_arg;} + bool transform_given () const {return _transform_given;} + const std::string& transform_arg () const {return _transform_arg;} + bool translate_given () const {return _translate_given;} + const std::string& translate_arg () const {return _translate_arg;} + bool verbosity_given () const {return _verbosity_given;} + unsigned verbosity_arg () const {return _verbosity_arg;} + bool version_given () const {return _version_given;} + bool version_arg () const {return _version_arg;} + bool zip_given () const {return _zip_given;} + int zip_arg () const {return _zip_arg;} + bool zoom_given () const {return _zoom_given;} + double zoom_arg () const {return _zoom_arg;} + + protected: + void init (); + const CmdLineParserBase::Option* options (size_t *numopts) const; + const char** helplines (size_t *numlines) const; + void handle_bbox (InputReader &ir, const Option &opt, bool longopt); + void handle_cache (InputReader &ir, const Option &opt, bool longopt); + void handle_color (InputReader &ir, const Option &opt, bool longopt); +#if !defined(DISABLE_GS) + void handle_eps (InputReader &ir, const Option &opt, bool longopt); +#endif + void handle_exact (InputReader &ir, const Option &opt, bool longopt); + void handle_fontmap (InputReader &ir, const Option &opt, bool longopt); + void handle_help (InputReader &ir, const Option &opt, bool longopt); + void handle_keep (InputReader &ir, const Option &opt, bool longopt); +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + void handle_libgs (InputReader &ir, const Option &opt, bool longopt); +#endif + void handle_linkmark (InputReader &ir, const Option &opt, bool longopt); + void handle_list_specials (InputReader &ir, const Option &opt, bool longopt); + void handle_mag (InputReader &ir, const Option &opt, bool longopt); + void handle_no_fonts (InputReader &ir, const Option &opt, bool longopt); + void handle_no_mktexmf (InputReader &ir, const Option &opt, bool longopt); + void handle_no_specials (InputReader &ir, const Option &opt, bool longopt); + void handle_no_styles (InputReader &ir, const Option &opt, bool longopt); + void handle_output (InputReader &ir, const Option &opt, bool longopt); + void handle_page (InputReader &ir, const Option &opt, bool longopt); + void handle_precision (InputReader &ir, const Option &opt, bool longopt); + void handle_progress (InputReader &ir, const Option &opt, bool longopt); + void handle_rotate (InputReader &ir, const Option &opt, bool longopt); + void handle_scale (InputReader &ir, const Option &opt, bool longopt); + void handle_stdout (InputReader &ir, const Option &opt, bool longopt); + void handle_trace_all (InputReader &ir, const Option &opt, bool longopt); + void handle_transform (InputReader &ir, const Option &opt, bool longopt); + void handle_translate (InputReader &ir, const Option &opt, bool longopt); + void handle_verbosity (InputReader &ir, const Option &opt, bool longopt); + void handle_version (InputReader &ir, const Option &opt, bool longopt); + void handle_zip (InputReader &ir, const Option &opt, bool longopt); + void handle_zoom (InputReader &ir, const Option &opt, bool longopt); + + private: + static const CmdLineParserBase::Option _options[]; + bool _bbox_given; + std::string _bbox_arg; + bool _cache_given; + std::string _cache_arg; + bool _color_given; +#if !defined(DISABLE_GS) + bool _eps_given; +#endif + bool _exact_given; + bool _fontmap_given; + std::string _fontmap_arg; + bool _help_given; + int _help_arg; + bool _keep_given; +#if !defined(HAVE_LIBGS) && !defined(DISABLE_GS) + bool _libgs_given; + std::string _libgs_arg; +#endif + bool _linkmark_given; + std::string _linkmark_arg; + bool _list_specials_given; + bool _mag_given; + double _mag_arg; + bool _no_fonts_given; + int _no_fonts_arg; + bool _no_mktexmf_given; + bool _no_specials_given; + std::string _no_specials_arg; + bool _no_styles_given; + bool _output_given; + std::string _output_arg; + bool _page_given; + std::string _page_arg; + bool _precision_given; + int _precision_arg; + bool _progress_given; + double _progress_arg; + bool _rotate_given; + double _rotate_arg; + bool _scale_given; + std::string _scale_arg; + bool _stdout_given; + bool _trace_all_given; + bool _trace_all_arg; + bool _transform_given; + std::string _transform_arg; + bool _translate_given; + std::string _translate_arg; + bool _verbosity_given; + unsigned _verbosity_arg; + bool _version_given; + bool _version_arg; + bool _zip_given; + int _zip_arg; + bool _zoom_given; + double _zoom_arg; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.cpp new file mode 100644 index 00000000000..8f03d1a0b83 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.cpp @@ -0,0 +1,60 @@ +/************************************************************************* +** DLLoader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "DLLoader.h" + + +DLLoader::DLLoader (const char *dlname) : _handle(0) +{ + if (dlname && *dlname) { +#ifdef __WIN32__ + _handle = LoadLibrary(dlname); +#else + _handle = dlopen(dlname, RTLD_LAZY); +#endif + } +} + + +DLLoader::~DLLoader () { + if (_handle) { +#ifdef __WIN32__ + FreeLibrary(_handle); +#else + dlclose(_handle); +#endif + } +} + + +/** Loads a function or variable from the dynamic/shared library. + * @param[in] name name of function/variable to load + * @return pointer to loaded symbol, or 0 if the symbol could not be loaded */ +void* DLLoader::loadSymbol (const char *name) { + if (_handle) { +#ifdef __WIN32__ + return (void*)GetProcAddress(_handle, name); +#else + return dlsym(_handle, name); +#endif + } + return 0; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.h new file mode 100644 index 00000000000..e699fa219db --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DLLoader.h @@ -0,0 +1,50 @@ +/************************************************************************* +** DLLoader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DLLOADER_H +#define DVISVGM_DLLOADER_H + +#ifdef __WIN32__ + #include <windows.h> +#else + #include <dlfcn.h> +#endif + + +class DLLoader +{ + public: + DLLoader (const char *dlname); + virtual ~DLLoader (); + bool loaded () const {return _handle != 0;} + + protected: + DLLoader () : _handle(0) {} + void* loadSymbol (const char *name); + + private: +#ifdef __WIN32__ + HINSTANCE _handle; +#else + void *_handle; +#endif +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIActions.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIActions.h new file mode 100644 index 00000000000..613be5365d6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIActions.h @@ -0,0 +1,54 @@ +/************************************************************************* +** DVIActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DVIACTIONS_H +#define DVISVGM_DVIACTIONS_H + +#include <string> +#include "Message.h" +#include "types.h" + +class BoundingBox; +struct Font; +class SpecialManager; + + +struct DVIActions +{ + virtual ~DVIActions () {} + virtual void setChar (double x, double y, unsigned c, bool vertical, const Font *f) {} + virtual void setRule (double x, double y, double height, double width) {} + virtual void setTextOrientation (bool vertical) {} + virtual void moveToX (double x) {} + virtual void moveToY (double y) {} + virtual bool fontProcessingEnabled () const {return true;} + virtual void defineFont (int num, const Font *font) {} + virtual void setFont (int num, const Font *font) {} + virtual void special (const std::string &s, double dvi2bp) {} + virtual void preamble (const std::string &cmt) {} + virtual void postamble () {} + virtual void beginPage (unsigned pageno, Int32 *c) {} + virtual void endPage (unsigned pageno) {} + virtual BoundingBox& bbox () =0; + virtual const SpecialManager* setProcessSpecials (const char *ignorelist) {return 0;} + virtual void progress (size_t current, size_t total, const char *id=0) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.cpp new file mode 100644 index 00000000000..f9edfd0536d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.cpp @@ -0,0 +1,840 @@ +/************************************************************************* +** DVIReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdarg> +#include <fstream> +#include <iostream> +#include <sstream> +#include "Color.h" +#include "DVIActions.h" +#include "DVIReader.h" +#include "Font.h" +#include "FontManager.h" +#include "Message.h" +#include "SignalHandler.h" +#include "VectorStream.h" +#include "macros.h" +#include "types.h" + + +using namespace std; + +bool DVIReader::COMPUTE_PAGE_LENGTH = false; + + +DVIReader::DVIReader (istream &is, DVIActions *a) : StreamReader(is), _dviFormat(DVI_NONE), _actions(a) +{ + _inPage = false; + _pageHeight = _pageWidth = 0; + _dvi2bp = 0.0; + _tx = _ty = 0; // no cursor translation + _prevYPos = numeric_limits<double>::min(); + _inPostamble = false; + _totalPages = 0; // we don't know the correct value yet + _currFontNum = 0; + _currPageNum = 0; + _pageLength = 0; + _pagePos = 0; + _prevBop = 0; + _mag = 1; +} + + +DVIActions* DVIReader::replaceActions (DVIActions *a) { + DVIActions *prev_actions = _actions; + _actions = a; + return prev_actions; +} + + +/** Evaluates the next DVI command, and computes the corresponding handler. + * @param[in] compute_size if true, the size of variable-length parameters is computed + * @param[out] handler handler for current DVI command + * @param[out] length number of parameter bytes + * @param[out] param the handler must be called with this parameter + * @return opcode of current DVI command */ +int DVIReader::evalCommand (bool compute_size, CommandHandler &handler, int &length, int ¶m) { + struct DVICommand { + CommandHandler handler; + int length; // number of parameter bytes + }; + + /* Each cmdFOO command reads the necessary number of bytes from the stream, so executeCommand + doesn't need to know the exact DVI command format. Some cmdFOO methods are used for multiple + DVI commands because they only differ in length of their parameters. */ + static const DVICommand commands[] = { + {&DVIReader::cmdSetChar, 1}, {&DVIReader::cmdSetChar, 2}, {&DVIReader::cmdSetChar, 3}, {&DVIReader::cmdSetChar, 4}, // 128-131 + {&DVIReader::cmdSetRule, 8}, // 132 + {&DVIReader::cmdPutChar, 1}, {&DVIReader::cmdPutChar, 2}, {&DVIReader::cmdPutChar, 3}, {&DVIReader::cmdPutChar, 4}, // 133-136 + {&DVIReader::cmdPutRule, 8}, // 137 + {&DVIReader::cmdNop, 0}, // 138 + {&DVIReader::cmdBop, 44}, {&DVIReader::cmdEop, 0}, // 139-140 + {&DVIReader::cmdPush, 0}, {&DVIReader::cmdPop, 0}, // 141-142 + {&DVIReader::cmdRight, 1}, {&DVIReader::cmdRight, 2}, {&DVIReader::cmdRight, 3}, {&DVIReader::cmdRight, 4}, // 143-146 + {&DVIReader::cmdW0, 0}, // 147 + {&DVIReader::cmdW, 1}, {&DVIReader::cmdW, 2}, {&DVIReader::cmdW, 3}, {&DVIReader::cmdW, 4}, // 148-151 + {&DVIReader::cmdX0, 0}, // 152 + {&DVIReader::cmdX, 1}, {&DVIReader::cmdX, 2}, {&DVIReader::cmdX, 3}, {&DVIReader::cmdX, 4}, // 153-156 + {&DVIReader::cmdDown, 1}, {&DVIReader::cmdDown, 2}, {&DVIReader::cmdDown, 3}, {&DVIReader::cmdDown, 4}, // 157-160 + {&DVIReader::cmdY0, 0}, // 161 + {&DVIReader::cmdY, 1}, {&DVIReader::cmdY, 2}, {&DVIReader::cmdY, 3}, {&DVIReader::cmdY, 4}, // 162-165 + {&DVIReader::cmdZ0, 0}, // 166 + {&DVIReader::cmdZ, 1}, {&DVIReader::cmdZ, 2}, {&DVIReader::cmdZ, 3}, {&DVIReader::cmdZ, 4}, // 167-170 + {&DVIReader::cmdFontNum, 1}, {&DVIReader::cmdFontNum, 2}, {&DVIReader::cmdFontNum, 3}, {&DVIReader::cmdFontNum, 4}, // 235-238 + {&DVIReader::cmdXXX, 1}, {&DVIReader::cmdXXX, 2}, {&DVIReader::cmdXXX, 3}, {&DVIReader::cmdXXX, 4}, // 239-242 + {&DVIReader::cmdFontDef, 1}, {&DVIReader::cmdFontDef, 2}, {&DVIReader::cmdFontDef, 3}, {&DVIReader::cmdFontDef, 4}, // 243-246 + {&DVIReader::cmdPre, 0}, {&DVIReader::cmdPost, 0}, {&DVIReader::cmdPostPost, 0}, // 247-249 + {&DVIReader::cmdXPic, 0}, {&DVIReader::cmdXFontDef, 0},{&DVIReader::cmdXGlyphA, 0}, {&DVIReader::cmdXGlyphS, 0} // 251-254 + }; + + const int opcode = in().get(); + if (!in() || opcode < 0) // at end of file + throw InvalidDVIFileException("invalid file"); + + param = -1; + if (opcode >= 0 && opcode <= 127) { + handler = &DVIReader::cmdSetChar0; + length = 0; + param = opcode; + } + else if (opcode >= 171 && opcode <= 234) { + handler = &DVIReader::cmdFontNum0; + length = 0; + param = opcode-171; + } + else if (opcode >= 251 && opcode <= 254 && _dviFormat == DVI_XDV) { // XDV command? + static const CommandHandler handlers[] = { + &DVIReader::cmdXPic, + &DVIReader::cmdXFontDef, + &DVIReader::cmdXGlyphA, + &DVIReader::cmdXGlyphS + }; + handler = handlers[opcode-251]; + param = 0; + } + else if (opcode == 255 && _dviFormat == DVI_PTEX) { // direction command set by pTeX? + handler = &DVIReader::cmdDir; + length = 1; + } + else if (opcode >= 250) { + ostringstream oss; + oss << "undefined DVI command (opcode " << opcode << ')'; + throw DVIException(oss.str()); + } + else { + const int offset = opcode <= 170 ? 128 : 235-(170-128+1); + handler = commands[opcode-offset].handler; + if (!compute_size) + length = commands[opcode-offset].length; + else { + if (opcode >= 239 && opcode <= 242) { // specials + int len = opcode-238; + UInt32 bytes = readUnsigned(len); + in().seekg(-len, ios_base::cur); + length = len+bytes; + } + else if (opcode >= 243 && opcode <= 246) { // fontdefs + int len = opcode-242; + len += 12; + in().seekg(len, ios_base::cur); // skip fontnum, checksum, ssize, dsize + UInt32 bytes = readUnsigned(1); // length of font path + bytes += readUnsigned(1); // length of font name + in().seekg(-len-2, ios_base::cur); + length = len+bytes; + } + else + length = commands[opcode-offset].length; + } + } + if (param < 0) + param = length; + return opcode; +} + + +/** Reads a single DVI command from the current position of the input stream and calls the + * corresponding cmdFOO method. + * @return opcode of the executed command */ +int DVIReader::executeCommand () { + SignalHandler::instance().check(); + CommandHandler handler; + int len; // number of parameter bytes + int param; // parameter of handler + streampos pos = in().tellg(); + int opcode = evalCommand(false, handler, len, param); + (this->*handler)(param); + if (_dviState.v+_ty != _prevYPos) { + _tx = _ty = 0; + _prevYPos = _dviState.v; + } + if (COMPUTE_PAGE_LENGTH && _inPage && _actions) { + // ensure progress() is called at 0% + if (opcode == 139) // bop? + _actions->progress(0, _pageLength); + // ensure progress() is called at 100% + if (in().peek() == 140) // eop reached? + _pagePos = _pageLength; + else + _pagePos += in().tellg()-pos; + _actions->progress(_pagePos, _pageLength); + } + return opcode; +} + + +/** Executes all DVI commands read from the input stream. */ +void DVIReader::executeAll () { + int opcode = 0; + while (!in().eof() && opcode >= 0) { + try { + opcode = executeCommand(); + } + catch (const InvalidDVIFileException &e) { + // end of stream reached + opcode = -1; + } + } +} + + +/** Reads and executes the commands of a single page. + * This methods stops reading after the page's eop command has been executed. + * @param[in] n number of page to be executed + * @returns true if page was read successfully */ +bool DVIReader::executePage (unsigned n) { + in().clear(); // reset all status bits + if (!in()) + throw DVIException("invalid DVI file"); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + if (executeCommand() != 248) // execute postamble command but not the fontdefs + return false; + if (n < 1 || n > _totalPages) + return false; + in().seekg(_prevBop, ios_base::beg); // now on last bop + _inPostamble = false; // we jumped out of the postamble + unsigned pageCount = _totalPages; + for (; pageCount > n && _prevBop > 0; pageCount--) { + in().seekg(41, ios_base::cur); // skip bop and 10*4 \count bytes => now on pointer to prev bop + _prevBop = readSigned(4); + in().seekg(_prevBop, ios_base::beg); + } + _currPageNum = n; + while (pageCount == n && executeCommand() != 140); // 140 == eop + return true; +} + + +bool DVIReader::executePages (unsigned first, unsigned last) { + in().clear(); + if (!in()) + throw DVIException("invalid DVI file"); + if (first > last) + swap(first, last); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + if (executeCommand() != 248) // execute postamble command but not the fontdefs + return false; + first = max(1u, min(first, _totalPages)); + last = max(1u, min(last, _totalPages)); + in().seekg(_prevBop, ios_base::beg); // now on last bop + _inPostamble = false; // we jumped out of the postamble + unsigned count = _totalPages; + for (; count > first && _prevBop > 0; count--) { + in().seekg(41, ios_base::cur); // skip bop and 10*4 \count bytes => now on pointer to prev bop + _prevBop = readSigned(4); + in().seekg(_prevBop, ios_base::beg); + } + while (first <= last) { + _currPageNum = first++; + while (executeCommand () != 140); // 140 == eop + } + return true; +} + + +void DVIReader::executePreamble () { + in().clear(); + if (!in()) + throw DVIException("invalid DVI file"); + in().seekg(0, ios_base::beg); + if (in().get() != 247) + throw DVIException("invalid DVI file"); + cmdPre(0); +} + + +/** Reads and executes the commands of the postamble. */ +void DVIReader::executePostamble () { + in().clear(); // reset all status bits + if (!in()) + throw DVIException("invalid DVI file"); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + while (executeCommand() != 249); // read all commands until postpost (= 249) is reached +} + + +/** Returns the current x coordinate in PS point units. + * This is the horizontal position where the next output would be placed. */ +double DVIReader::getXPos () const { + return _dviState.h+_tx; +} + + +/** Returns the current y coordinate in PS point units. + * This is the vertical position where the next output would be placed. */ +double DVIReader::getYPos () const { + return _dviState.v+_ty; +} + + +double DVIReader::getPageHeight () const { + return _pageHeight; +} + + +double DVIReader::getPageWidth () const { + return _pageWidth; +} + + +void DVIReader::verifyDVIFormat (int id) const { + switch (id) { + case DVI_STANDARD: + case DVI_PTEX: + case DVI_XDV: + break; + default: + ostringstream oss; + oss << "DVI format version " << id << " not supported"; + throw DVIException(oss.str()); + } +} + +///////////////////////////////////// + +/** Reads and executes DVI preamble command. */ +void DVIReader::cmdPre (int) { + _dviFormat = max(_dviFormat, (DVIFormat)readUnsigned(1)); // identification number + verifyDVIFormat(_dviFormat); + UInt32 num = readUnsigned(4); // numerator units of measurement + UInt32 den = readUnsigned(4); // denominator units of measurement + if (den == 0) + throw DVIException("denominator of measurement unit is zero"); + _mag = readUnsigned(4); // magnification + UInt32 k = readUnsigned(1); // length of following comment + string cmt = readString(k); // comment + // 1 dviunit * num/den == multiples of 0.0000001m + // 1 dviunit * _dvibp: length of 1 dviunit in PS points * _mag/1000 + _dvi2bp = num/254000.0*72.0/den*_mag/1000.0; + if (_actions) + _actions->preamble(cmt); +} + + +/** Reads and executes DVI postamble command. */ +void DVIReader::cmdPost (int) { + _prevBop = readUnsigned(4); // pointer to previous bop + UInt32 num = readUnsigned(4); + UInt32 den = readUnsigned(4); + if (den == 0) + throw DVIException("denominator of measurement unit is zero"); + _mag = readUnsigned(4); + _pageHeight = readUnsigned(4); // height of tallest page in dvi units + _pageWidth = readUnsigned(4); // width of widest page in dvi units + readUnsigned(2); // max. stack depth + _totalPages = readUnsigned(2); // total number of pages + // 1 dviunit * num/den == multiples of 0.0000001m + // 1 dviunit * _dvi2bp: length of 1 dviunit in PS points * _mag/1000 + _dvi2bp = num/254000.0*72.0/den*_mag/1000.0; + _pageHeight *= _dvi2bp; // to pt units + _pageWidth *= _dvi2bp; + _inPostamble = true; + if (_actions) + _actions->postamble(); +} + + +/** Reads and executes DVI postpost command. */ +void DVIReader::cmdPostPost (int) { + _inPostamble = false; + readUnsigned(4); // pointer to begin of postamble + _dviFormat = max(_dviFormat, (DVIFormat)readUnsigned(1)); // identification byte + verifyDVIFormat(_dviFormat); + while (readUnsigned(1) == 223); // skip fill bytes (223), eof bit should be set now +} + + +/** Reads and executes Begin-Of-Page command. */ +void DVIReader::cmdBop (int) { + Int32 c[10]; + for (int i=0; i < 10; i++) + c[i] = readSigned(4); + readSigned(4); // pointer to peceeding bop (-1 in case of first page) + _dviState.reset(); // set all DVI registers to 0 + while (!_stateStack.empty()) + _stateStack.pop(); + _currFontNum = 0; + _inPage = true; + _pageLength = 0; + _pagePos = 0; + if (COMPUTE_PAGE_LENGTH) { + // compute number of bytes in current page + int length, param; + CommandHandler handler; + // read all commands until eop is found + while (evalCommand(true, handler, length, param) != 140) { + in().seekg(length, ios_base::cur); + _pageLength += length+1; // parameter length + opcode length (1 byte) + } + ++_pageLength; // add length of eop command (1 byte) + in().seekg(-int(_pageLength), ios_base::cur); // go back to first command following bop + _pageLength += 45; // add length of bop command + } + beginPage(_currPageNum, c); + if (_actions) + _actions->beginPage(_currPageNum, c); +} + + +/** Reads and executes End-Of-Page command. */ +void DVIReader::cmdEop (int) { + if (!_stateStack.empty()) + throw DVIException("stack not empty at end of page"); + _inPage = false; + endPage(_currPageNum); + if (_actions) + _actions->endPage(_currPageNum); +} + + +/** Reads and executes push command. */ +void DVIReader::cmdPush (int) { + _stateStack.push(_dviState); +} + + +/** Reads and executes pop command (restores pushed position information). */ +void DVIReader::cmdPop (int) { + if (_stateStack.empty()) + throw DVIException("stack empty at pop command"); + else { + DVIState prevState = _dviState; + _dviState = _stateStack.top(); + _stateStack.pop(); + if (_actions) { + if (prevState.h != _dviState.h) + _actions->moveToX(_dviState.h + _tx); + if (prevState.v != _dviState.v) + _actions->moveToY(_dviState.v + _ty); + if (prevState.d != _dviState.d) + _actions->setTextOrientation(_dviState.d != WMODE_LR); + } + } +} + + +/** Helper function that actually sets/puts a charater. It is called by the + * cmdSetChar and cmdPutChar methods. + * @param[in] c character to typeset + * @param[in] moveCursor if true, register h is increased by the character width + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::putChar (UInt32 c, bool moveCursor) { + if (!_inPage) + throw DVIException("set_char or put_char outside of page"); + + if (_actions && !_actions->fontProcessingEnabled()) + return; + + FontManager &fm = FontManager::instance(); + Font *font = fm.getFont(_currFontNum); + if (!font) + throw DVIException("no font selected"); + + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { // is current font a virtual font? + vector<UInt8> *dvi = const_cast<vector<UInt8>*>(vf->getDVI(c)); // get DVI snippet that describes character c + if (dvi) { + DVIState pos = _dviState; // save current cursor position + _dviState.x = _dviState.y = _dviState.w = _dviState.z = 0; + int save_fontnum = _currFontNum; // save current font number + fm.enterVF(vf); // new font number context + cmdFontNum0(fm.vfFirstFontNum(vf)); + double save_scale = _dvi2bp; + // DVI units in virtual fonts are multiples of 1^(-20) times the scaled size of the VF + _dvi2bp = vf->scaledSize()/(1 << 20); + + VectorInputStream<UInt8> vis(*dvi); + istream &is = replaceStream(vis); + try { + executeAll(); // execute DVI fragment + } + catch (const DVIException &e) { + // Message::estream(true) << "invalid dvi in vf: " << e.getMessage() << endl; // @@ + } + replaceStream(is); // restore previous input stream + _dvi2bp = save_scale; // restore previous scale factor + fm.leaveVF(); // restore previous font number context + cmdFontNum0(save_fontnum); // restore previous font number + _dviState = pos; // restore previous cursor position + } + } + else if (_actions) + _actions->setChar(_dviState.h+_tx, _dviState.v+_ty, c, _dviState.d != WMODE_LR, font); + + if (moveCursor) { + double dist = font->charWidth(c) * font->scaleFactor() * _mag/1000.0; + switch (_dviState.d) { + case WMODE_LR: _dviState.h += dist; break; + case WMODE_TB: _dviState.v += dist; break; + case WMODE_BT: _dviState.v -= dist; break; + } + } +} + + +/** Reads and executes set_char_x command. Puts a character at the current + * position and advances the cursor. + * @param[in] c character to set + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetChar0 (int c) { + putChar(c, true); +} + + +/** Reads and executes setx command. Puts a character at the current + * position and advances the cursor. + * @param[in] len number of parameter bytes (possible values: 1-4) + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetChar (int len) { + // According to the dvi specification all character codes are unsigned + // except len == 4. At the moment all char codes are treated as unsigned... + UInt32 c = readUnsigned(len); // if len == 4 c may be signed + putChar(c, true); +} + + +/** Reads and executes putx command. Puts a character at the current + * position but doesn't change the cursor position. + * @param[in] len number of parameter bytes (possible values: 1-4) + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdPutChar (int len) { + // According to the dvi specification all character codes are unsigned + // except len == 4. At the moment all char codes are treated as unsigned... + Int32 c = readUnsigned(len); + putChar(c, false); +} + + +/** Reads and executes set_rule command. Puts a solid rectangle at the current + * position and updates the cursor position. + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetRule (int) { + if (_inPage) { + double height = _dvi2bp*readSigned(4); + double width = _dvi2bp*readSigned(4); + if (_actions && height > 0 && width > 0) + _actions->setRule(_dviState.h+_tx, _dviState.v+_ty, height, width); + moveRight(width); + } + else + throw DVIException("set_rule outside of page"); +} + + +/** Reads and executes set_rule command. Puts a solid rectangle at the current + * position but leaves the cursor position unchanged. + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdPutRule (int) { + if (_inPage) { + double height = _dvi2bp*readSigned(4); + double width = _dvi2bp*readSigned(4); + if (_actions && height > 0 && width > 0) + _actions->setRule(_dviState.h+_tx, _dviState.v+_ty, height, width); + } + else + throw DVIException("put_rule outside of page"); +} + + +void DVIReader::moveRight (double dx) { + switch (_dviState.d) { + case WMODE_LR: _dviState.h += dx; break; + case WMODE_TB: _dviState.v += dx; break; + case WMODE_BT: _dviState.v -= dx; break; + } + if (_actions) { + if (_dviState.d == WMODE_LR) + _actions->moveToX(_dviState.h+_tx); + else + _actions->moveToY(_dviState.v+_ty); + } +} + + +void DVIReader::moveDown (double dy) { + switch (_dviState.d) { + case WMODE_LR: _dviState.v += dy; break; + case WMODE_TB: _dviState.h -= dy; break; + case WMODE_BT: _dviState.h += dy; break; + } + if (_actions) { + if (_dviState.d == WMODE_LR) + _actions->moveToY(_dviState.v+_ty); + else + _actions->moveToX(_dviState.h+_tx); + } +} + + +void DVIReader::cmdRight (int len) {moveRight(_dvi2bp*readSigned(len));} +void DVIReader::cmdDown (int len) {moveDown(_dvi2bp*readSigned(len));} +void DVIReader::cmdX0 (int) {moveRight(_dviState.x);} +void DVIReader::cmdY0 (int) {moveDown(_dviState.y);} +void DVIReader::cmdW0 (int) {moveRight(_dviState.w);} +void DVIReader::cmdZ0 (int) {moveDown(_dviState.z);} +void DVIReader::cmdX (int len) {_dviState.x = _dvi2bp*readSigned(len); cmdX0(0);} +void DVIReader::cmdY (int len) {_dviState.y = _dvi2bp*readSigned(len); cmdY0(0);} +void DVIReader::cmdW (int len) {_dviState.w = _dvi2bp*readSigned(len); cmdW0(0);} +void DVIReader::cmdZ (int len) {_dviState.z = _dvi2bp*readSigned(len); cmdZ0(0);} +void DVIReader::cmdNop (int) {} + + +/** Sets the text orientation (horizontal, vertical). + * This command is only available in DVI files of format 3 (created by pTeX) */ +void DVIReader::cmdDir (int) { + UInt8 wmode = readUnsigned(1); + if (wmode == 4) // yoko mode (4) equals default LR mode (0) + wmode = 0; + if (wmode == 2 || wmode > 3) { + ostringstream oss; + oss << "invalid writing mode value " << wmode << " (0, 1, or 3 expected)"; + throw DVIException(oss.str()); + } + _dviState.d = (WritingMode)wmode; + if (_actions) + _actions->setTextOrientation(_dviState.d != WMODE_LR); +} + + +void DVIReader::cmdXXX (int len) { + if (_inPage) { + UInt32 numBytes = readUnsigned(len); + string s = readString(numBytes); + if (_actions) + _actions->special(s, _dvi2bp); + } + else + throw DVIException("special outside of page"); +} + + +/** Selects a previously defined font by its number. + * @param[in] num font number + * @throw DVIException if font number is undefined */ +void DVIReader::cmdFontNum0 (int num) { + if (_actions && !_actions->fontProcessingEnabled()) + return; + + if (Font *font = FontManager::instance().getFont(num)) { + _currFontNum = num; + if (_actions && !dynamic_cast<VirtualFont*>(font)) + _actions->setFont(FontManager::instance().fontID(num), font); // all fonts get a recomputed ID + } + else { + ostringstream oss; + oss << "undefined font number " << num; + throw DVIException(oss.str()); + } +} + + +/** Selects a previously defined font. + * @param[in] len size of font number variable (in bytes) + * @throw DVIException if font number is undefined */ +void DVIReader::cmdFontNum (int len) { + UInt32 num = readUnsigned(len); + cmdFontNum0(num); +} + + +/** Helper function to handle a font definition. + * @param[in] fontnum local font number + * @param[in] name font name + * @param[in] cs checksum to be compared with TFM checksum + * @param[in] ds design size in PS point units + * @param[in] ss scaled size in PS point units */ +void DVIReader::defineFont (UInt32 fontnum, const string &name, UInt32 cs, double ds, double ss) { + if (_actions && !_actions->fontProcessingEnabled()) + return; + FontManager &fm = FontManager::instance(); + int id = fm.registerFont(fontnum, name, cs, ds, ss); + Font *font = fm.getFontById(id); + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { + // read vf file, register its font and character definitions + fm.enterVF(vf); + ifstream ifs(vf->path(), ios::binary); + VFReader vfReader(ifs); + vfReader.replaceActions(this); + vfReader.executeAll(); + fm.leaveVF(); + } + if (_actions) + _actions->defineFont(id, font); +} + + +/** Defines a new font. + * @param[in] len size of font number variable (in bytes) */ +void DVIReader::cmdFontDef (int len) { + UInt32 fontnum = readUnsigned(len); // font number + UInt32 checksum = readUnsigned(4); // font checksum (to be compared with corresponding TFM checksum) + UInt32 ssize = readUnsigned(4); // scaled size of font in DVI units + UInt32 dsize = readUnsigned(4); // design size of font in DVI units + UInt32 pathlen = readUnsigned(1); // length of font path + UInt32 namelen = readUnsigned(1); // length of font name + string fontpath = readString(pathlen); + string fontname = readString(namelen); + + // @@ TODO: avoid processing the font definitions in the postamble + defineFont(fontnum, fontname, checksum, dsize*_dvi2bp, ssize*_dvi2bp); +} + + +/** This template method is called by the VFReader after reading a font definition from a VF file. + * @param[in] fontnum local font number + * @param[in] path path to font file + * @param[in] name font name + * @param[in] checksum checksum to be compared with TFM checksum + * @param[in] dsize design size in PS point units + * @param[in] ssize scaled size in PS point units */ +void DVIReader::defineVFFont (UInt32 fontnum, string path, string name, UInt32 checksum, double dsize, double ssize) { + if (VirtualFont *vf = FontManager::instance().getVF()) + defineFont(fontnum, name, checksum, dsize, ssize * vf->scaleFactor()); +} + + +/** This template method is called by the VFReader after reading a character definition from a VF file. + * @param[in] c character number + * @param[in] dvi DVI fragment describing the character */ +void DVIReader::defineVFChar (UInt32 c, vector<UInt8> *dvi) { + FontManager::instance().assignVfChar(c, dvi); +} + + +/** XDV extension: include image or pdf file. + * parameters: box[1] matrix[4][6] p[2] len[2] path[l] */ +void DVIReader::cmdXPic (int) { + // just skip the parameters + readUnsigned(1); // box + for (int i=0; i < 6; i++) // matrix + readSigned(4); + readSigned(2); // page number + UInt16 len = readUnsigned(2); + readString(len); // path to image/pdf file +} + + +void DVIReader::cmdXFontDef (int) { + Int32 fontnum = readSigned(4); + double ptsize = _dvi2bp*readUnsigned(4); + UInt16 flags = readUnsigned(2); + UInt8 psname_len = readUnsigned(1); + UInt8 fmname_len = readUnsigned(1); + UInt8 stname_len = readUnsigned(1); + string fontname = readString(psname_len); + readString(fmname_len); + readString(stname_len); + FontStyle style; + Color color; + if (flags & 0x0100) { // vertical? + } + if (flags & 0x0200) { // colored? + // The font color must not interfere with color specials. If the font color is not black, + // all color specials should be ignored, i.e. glyphs of a non-black font have a fixed color + // that can't be changed by colors specials. + UInt32 rgba = readUnsigned(4); + color.set(UInt8(rgba >> 24), UInt8((rgba >> 16) & 0xff), UInt8((rgba >> 8) & 0xff)); + } + if (flags & 0x1000) // extend? + style.extend = _dvi2bp*readSigned(4); + if (flags & 0x2000) // slant? + style.slant = _dvi2bp*readSigned(4); + if (flags & 0x4000) // embolden? + style.bold = _dvi2bp*readSigned(4); + if (flags & 0x0800) { // variations? + UInt16 num_variations = readSigned(2); + for (int i=0; i < num_variations; i++) + readUnsigned(4); + } + if (_inPage && _actions && _actions->fontProcessingEnabled()) + FontManager::instance().registerFont(fontnum, fontname, ptsize, style, color); +} + + +void DVIReader::cmdXGlyphA (int) { + putGlyphArray(false); +} + + +void DVIReader::cmdXGlyphS (int) { + putGlyphArray(true); +} + + +void DVIReader::putGlyphArray (bool xonly) { + double strwidth = _dvi2bp*readSigned(4); + UInt16 num_glyphs = readUnsigned(2); + vector<Int32> x(num_glyphs); + vector<Int32> y(num_glyphs); + for (int i=0; i < num_glyphs; i++) { + x[i] = readSigned(4); + y[i] = xonly ? 0 : readSigned(4); + } + if (_actions && _actions->fontProcessingEnabled()) { + if (Font *font = FontManager::instance().getFont(_currFontNum)) { + for (int i=0; i < num_glyphs; i++) { + UInt16 glyph_index = readUnsigned(2); + double xx = _dviState.h + x[i]*_dvi2bp + _tx; + double yy = _dviState.v + y[i]*_dvi2bp + _ty; + _actions->setChar(xx, yy, glyph_index, false, font); + } + } + } + else { + for (int i=0; i < num_glyphs; i++) + readUnsigned(2); + } + moveRight(strwidth); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.h new file mode 100644 index 00000000000..d57250295b8 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIReader.h @@ -0,0 +1,161 @@ +/************************************************************************* +** DVIReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DVIREADER_H +#define DVISVGM_DVIREADER_H + +#include <limits> +#include <map> +#include <stack> +#include <string> +#include "MessageException.h" +#include "StreamReader.h" +#include "VFActions.h" +#include "types.h" + + +struct DVIException : public MessageException +{ + DVIException (const std::string &msg) : MessageException(msg) {} +}; + +struct InvalidDVIFileException : public DVIException +{ + InvalidDVIFileException(const std::string &msg) : DVIException(msg) {} +}; + +struct DVIActions; +struct FileFinder; + +class DVIReader : public StreamReader, protected VFActions +{ + typedef void (DVIReader::*CommandHandler)(int); + enum DVIFormat {DVI_NONE=0, DVI_STANDARD=2, DVI_PTEX=3, DVI_XDV=5}; + enum WritingMode {WMODE_LR=0, WMODE_TB=1, WMODE_BT=3}; + + struct DVIState + { + double h, v; ///< horizontal and vertical cursor position + double x, w, y, z; ///< additional registers to store horizontal (x, w) and vertical (y, z) positions + WritingMode d; ///< direction: 0: horizontal, 1: vertical(top->bottom), 3: vertical (bottom->top) + DVIState () {reset();} + void reset () {h = v = x = w = y = z = 0.0; d=WMODE_LR;} + }; + + public: + DVIReader (std::istream &is, DVIActions *a=0); + + bool executeDocument (); + void executeAll (); + bool executeAllPages (); + void executePreamble (); + void executePostamble (); + bool executePage (unsigned n); + bool executePages (unsigned first, unsigned last); + bool inPostamble () const {return _inPostamble;} + double getXPos () const; + double getYPos () const; + void finishLine () {_prevYPos = std::numeric_limits<double>::min();} + void translateToX (double x) {_tx=x-_dviState.h-_tx;} + void translateToY (double y) {_ty=y-_dviState.v-_ty;} + double getPageWidth () const; + double getPageHeight () const; + int getStackDepth () const {return _stateStack.size();} + int getCurrentFontNumber () const {return _currFontNum;} + unsigned getCurrentPageNumber () const {return _currPageNum;} + unsigned getTotalPages () const {return _totalPages;} + DVIActions* getActions () const {return _actions;} + DVIActions* replaceActions (DVIActions *a); + + protected: + void verifyDVIFormat (int id) const; + int executeCommand (); + int evalCommand (bool compute_size, CommandHandler &handler, int &length, int ¶m); + void moveRight (double dx); + void moveDown (double dy); + void putChar (UInt32 c, bool moveCursor); + void putGlyphArray (bool xonly); + void defineFont (UInt32 fontnum, const std::string &name, UInt32 cs, double ds, double ss); + virtual void beginPage (unsigned pageno, Int32 *c) {} + virtual void endPage (unsigned pageno) {} + + // VFAction methods + void defineVFFont (UInt32 fontnum, std::string path, std::string name, UInt32 checksum, double dsize, double ssize); + void defineVFChar (UInt32 c, std::vector<UInt8> *dvi); + + // the following methods represent the DVI commands + // they are called by executeCommand and should not be used directly + void cmdSetChar0 (int c); + void cmdSetChar (int len); + void cmdPutChar (int len); + void cmdSetRule (int len); + void cmdPutRule (int len); + void cmdNop (int len); + void cmdBop (int len); + void cmdEop (int len); + void cmdPush (int len); + void cmdPop (int len); + void cmdDir (int len); + void cmdRight (int len); + void cmdDown (int len); + void cmdX0 (int len); + void cmdY0 (int len); + void cmdW0 (int len); + void cmdZ0 (int len); + void cmdX (int len); + void cmdY (int len); + void cmdW (int len); + void cmdZ (int len); + void cmdFontDef (int len); + void cmdFontNum0 (int n); + void cmdFontNum (int len); + void cmdXXX (int len); + void cmdPre (int len); + void cmdPost (int len); + void cmdPostPost (int len); + void cmdXPic (int len); + void cmdXFontDef (int len); + void cmdXGlyphA (int len); + void cmdXGlyphS (int len); + + private: + DVIFormat _dviFormat; ///< format of DVI file currently processed + DVIActions *_actions; ///< actions to be performed on various DVI events + bool _inPage; ///< true if between bop and eop + unsigned _totalPages; ///< total number of pages in dvi file + unsigned _currPageNum; ///< current page number + int _currFontNum; ///< current font number + double _dvi2bp; ///< factor to convert dvi units to PS points + UInt32 _mag; ///< magnification factor * 1000 + bool _inPostamble; ///< true if stream pointer is inside the postamble + Int32 _prevBop; ///< pointer to previous bop + double _pageHeight, _pageWidth; ///< page height and width in PS points + DVIState _dviState; ///< current cursor position + std::stack<DVIState> _stateStack; + double _prevYPos; ///< previous vertical cursor position + double _tx, _ty; ///< tranlation of cursor position + size_t _pageLength; ///< number of bytes between current bop end eop + std::streampos _pagePos; ///< distance of current DVI command from bop (in bytes) + + public: + static bool COMPUTE_PAGE_LENGTH; ///< if true, the bop handler computes the number of bytes of the current page +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.cpp new file mode 100644 index 00000000000..8f9bb1f63a3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.cpp @@ -0,0 +1,370 @@ +/************************************************************************* +** DVIToSVG.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdlib> +#include <ctime> +#include <fstream> +#include <sstream> +#include "Calculator.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "Font.h" +#include "FontManager.h" +#include "FileFinder.h" +#include "GlyphTracerMessages.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "Matrix.h" +#include "Message.h" +#include "PageRanges.h" +#include "PageSize.h" +#include "SVGOutputBase.h" +// +/////////////////////////////////// +// special handlers + +#include "BgColorSpecialHandler.h" +#include "ColorSpecialHandler.h" +#include "DvisvgmSpecialHandler.h" +#include "EmSpecialHandler.h" +#include "PdfSpecialHandler.h" +#include "HtmlSpecialHandler.h" +#ifndef HAVE_LIBGS + #include "NoPsSpecialHandler.h" +#endif +#ifndef DISABLE_GS + #include "PsSpecialHandler.h" +#endif +#include "TpicSpecialHandler.h" + +/////////////////////////////////// + + +using namespace std; + + +class PSHeaderActions : public DVIActions +{ + public : + PSHeaderActions (DVIToSVG &dvisvg) : _dvisvg(dvisvg) {} + + void special (const std::string &str, double dvi2bp) { + // execute PS headers only + if (!str.empty() && (str[0] == '!' || str.substr(0, 7) == "header=")) + _dvisvg.specialManager().process(str, dvi2bp, 0); + } + + bool fontProcessingEnabled () const { + return false; + } + + void endPage (unsigned) { + _dvisvg.specialManager().leavePSHeaderSection(); + } + + BoundingBox& bbox () {return _bbox;} + + private: + DVIToSVG &_dvisvg; + BoundingBox _bbox; +}; + + +/** 'a': trace all glyphs even if some of them are already cached + * 'm': trace missing glyphs, i.e. glyphs not yet cached + * 0 : only trace actually required glyphs */ +char DVIToSVG::TRACE_MODE = 0; + + +DVIToSVG::DVIToSVG (istream &is, SVGOutputBase &out) : DVIReader(is), _out(out) +{ + replaceActions(new DVIToSVGActions(*this, _svg)); +} + + +DVIToSVG::~DVIToSVG () { + delete replaceActions(0); +} + + +/** Starts the conversion process. + * @param[in] first number of first page to convert + * @param[in] last number of last page to convert + * @param[out] pageinfo (number of converted pages, number of total pages) */ +void DVIToSVG::convert (unsigned first, unsigned last, pair<int,int> *pageinfo) { + if (getTotalPages() == 0) { + executePreamble(); + executePostamble(); // collect scaling information + } + if (first > last) + swap(first, last); + if (first > getTotalPages()) { + ostringstream oss; + oss << "file contains only " << getTotalPages() << " page"; + if (getTotalPages() > 1) + oss << 's'; + throw DVIException(oss.str()); + } + last = min(last, getTotalPages()); + +#ifndef DISABLE_GS + // ensure loading of PostScript prologues given at the beginning of the first page + // (prologue files are always referenced in first page) + PSHeaderActions headerActions(*this); + DVIActions *save = replaceActions(&headerActions); + try { + executePage(1); + replaceActions(save); + } + catch (PSException &e) { + replaceActions(save); + throw; + } +#endif + + for (unsigned i=first; i <= last; ++i) { + executePage(i); + embedFonts(_svg.rootNode()); + _svg.write(_out.getPageStream(getCurrentPageNumber(), getTotalPages())); + string fname = _out.filename(i, getTotalPages()); + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\npage written to " << (fname.empty() ? "<stdout>" : fname) << '\n'; + _svg.reset(); + static_cast<DVIToSVGActions*>(getActions())->reset(); + } + if (pageinfo) { + pageinfo->first = last-first+1; + pageinfo->second = getTotalPages(); + } +} + + +/** Convert DVI pages specified by a page range string. + * @param[in] rangestr string describing the pages to convert + * @param[out] pageinfo (number of converted pages, number of total pages) */ +void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { + if (getTotalPages() == 0) { + executePreamble(); + executePostamble(); // collect scaling information + } + PageRanges ranges; + if (!ranges.parse(rangestr, getTotalPages())) + throw MessageException("invalid page range format"); + FORALL(ranges, PageRanges::ConstIterator, it) + convert(it->first, it->second); + if (pageinfo) { + pageinfo->first = ranges.pages(); + pageinfo->second = getTotalPages(); + } +} + + +/** This template method is called by parent class DVIReader before + * executing the BOP actions. + * @param[in] pageno physical page number (1 = first page) + * @param[in] c contains information about the page (page number etc.) */ +void DVIToSVG::beginPage (unsigned pageno, Int32 *c) { + if (dynamic_cast<DVIToSVGActions*>(getActions())) { + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing page " << pageno; + if (pageno != (unsigned)c[0]) // Does page number shown on page differ from physical page number? + Message::mstream(false) << " [" << c[0] << ']'; + Message::mstream().indent(1); + _svg.appendToDoc(new XMLCommentNode(" This file was generated by dvisvgm " VERSION " ")); + } +} + + +/** This template method is called by parent class DVIReader before + * executing the EOP actions. */ +void DVIToSVG::endPage (unsigned pageno) { + if (!dynamic_cast<DVIToSVGActions*>(getActions())) + return; + + _specialManager.notifyEndPage(pageno); + // set bounding box and apply page transformations + BoundingBox &bbox = getActions()->bbox(); + bbox.unlock(); + Matrix matrix; + getPageTransformation(matrix); + static_cast<DVIToSVGActions*>(getActions())->setPageMatrix(matrix); + if (_bboxString == "min") + bbox.transform(matrix); + if (string("dvi none min").find(_bboxString) == string::npos) { + istringstream iss(_bboxString); + StreamInputReader ir(iss); + ir.skipSpace(); + if (isalpha(ir.peek())) { + // set explicitly given page format + PageSize size(_bboxString); + if (size.valid()) { + // convention: DVI position (0,0) equals (1in, 1in) relative + // to the upper left vertex of the page (see DVI specification) + const double border = -72; + bbox = BoundingBox(border, border, size.widthInBP()+border, size.heightInBP()+border); + } + } + else { // set/modify bounding box by explicitly given values + try { + bbox.set(_bboxString); + } + catch (const MessageException &e) { + } + } + } + else if (_bboxString == "dvi") { + // center page content + double dx = (getPageWidth()-bbox.width())/2; + double dy = (getPageHeight()-bbox.height())/2; + bbox += BoundingBox(-dx, -dy, dx, dy); + } + if (_bboxString != "none") { + if (bbox.width() == 0) + Message::wstream(false) << "\npage is empty\n"; + else { + _svg.setBBox(bbox); + + const double bp2pt = 72.27/72; + const double bp2mm = 25.4/72; + Message::mstream(false) << '\n'; + Message::mstream(false, Message::MC_PAGE_SIZE) << "page size: " << XMLString(bbox.width()*bp2pt) << "pt" + " x " << XMLString(bbox.height()*bp2pt) << "pt" + " (" << XMLString(bbox.width()*bp2mm) << "mm" + " x " << XMLString(bbox.height()*bp2mm) << "mm)"; + Message::mstream(false) << '\n'; + } + } +} + + +void DVIToSVG::getPageTransformation(Matrix &matrix) const { + if (_transCmds.empty()) + matrix.set(1); // unity matrix + else { + Calculator calc; + if (getActions()) { + const double bp2pt = 72.27/72; + BoundingBox &bbox = getActions()->bbox(); + calc.setVariable("ux", bbox.minX()*bp2pt); + calc.setVariable("uy", bbox.minY()*bp2pt); + calc.setVariable("w", bbox.width()*bp2pt); + calc.setVariable("h", bbox.height()*bp2pt); + } + calc.setVariable("pt", 1); + calc.setVariable("in", 72.27); + calc.setVariable("cm", 72.27/2.54); + calc.setVariable("mm", 72.27/25.4); + matrix.set(_transCmds, calc); + } +} + + +static void collect_chars (map<const Font*, set<int> > &fm) { + typedef const map<const Font*, set<int> > UsedCharsMap; + FORALL(fm, UsedCharsMap::const_iterator, it) { + if (it->first->uniqueFont() != it->first) { + FORALL(it->second, set<int>::const_iterator, cit) + fm[it->first->uniqueFont()].insert(*cit); + } + } +} + + +/** Adds the font information to the SVG tree. + * @param[in] svgElement the font nodes are added to this node */ +void DVIToSVG::embedFonts (XMLElementNode *svgElement) { + if (!svgElement) + return; + if (!getActions()) // no dvi actions => no chars written => no fonts to embed + return; + + typedef map<const Font*, set<int> > UsedCharsMap; + const DVIToSVGActions *svgActions = static_cast<DVIToSVGActions*>(getActions()); + UsedCharsMap &usedChars = svgActions->getUsedChars(); + + collect_chars(usedChars); + + GlyphTracerMessages messages; + FORALL(usedChars, UsedCharsMap::const_iterator, it) { + const Font *font = it->first; + if (const PhysicalFont *ph_font = dynamic_cast<const PhysicalFont*>(font)) { + if (TRACE_MODE) + ph_font->traceAllGlyphs(TRACE_MODE == 'a', &messages); + + if (font->path()) // does font file exist? + _svg.append(*ph_font, it->second, &messages); + else + Message::wstream(true) << "can't embed font '" << font->name() << "'\n"; + } + else + Message::wstream(true) << "can't embed font '" << font->name() << "'\n"; + } + _svg.appendFontStyles(svgActions->getUsedFonts()); +} + + +/** Enables or disables processing of specials. If ignorelist == 0, all + * supported special handlers are loaded. To disable selected sets of specials, + * the corresponding prefixes can be given separated by non alpha-numeric characters, + * e.g. "color, ps, em" or "color: ps em" etc. + * A single "*" in the ignore list disables all specials. + * @param[in] ignorelist list of special prefixes to ignore + * @param[in] pswarning if true, shows warning about disabled PS support + * @return the SpecialManager that handles special statements */ +const SpecialManager* DVIToSVG::setProcessSpecials (const char *ignorelist, bool pswarning) { + if (ignorelist && strcmp(ignorelist, "*") == 0) { // ignore all specials? + _specialManager.unregisterHandlers(); + } + else { + // add special handlers + SpecialHandler *handlers[] = { + 0, // placeholder for PsSpecialHandler + new BgColorSpecialHandler, // handles background color special + new ColorSpecialHandler, // handles color specials + new DvisvgmSpecialHandler, // handles raw SVG embeddings + new EmSpecialHandler, // handles emTeX specials + new HtmlSpecialHandler, // handles hyperref specials + new PdfSpecialHandler, // handles pdf specials + new TpicSpecialHandler, // handles tpic specials + 0 + }; + SpecialHandler **p = handlers; +#ifndef DISABLE_GS + if (Ghostscript().available()) + *p = new PsSpecialHandler; + else +#endif + { +#ifndef HAVE_LIBGS + *p = new NoPsSpecialHandler; // dummy PS special handler that only prints warning messages + if (pswarning) { +#ifdef DISABLE_GS + Message::wstream() << "processing of PostScript specials has been disabled permanently\n"; +#else + Message::wstream() << "processing of PostScript specials is disabled (Ghostscript not found)\n"; +#endif + } +#endif + } + _specialManager.unregisterHandlers(); + _specialManager.registerHandlers(p, ignorelist); + } + return &_specialManager; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.h new file mode 100644 index 00000000000..626e27c568a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVG.h @@ -0,0 +1,65 @@ +/************************************************************************* +** DVIToSVG.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DVITOSVG_H +#define DVISVGM_DVITOSVG_H + +#include <iostream> +#include <string> +#include <utility> +#include "DVIReader.h" +#include "SpecialManager.h" +#include "SVGTree.h" + +class Matrix; +struct SVGOutputBase; + +class DVIToSVG : public DVIReader +{ + public: + DVIToSVG (std::istream &is, SVGOutputBase &out); + ~DVIToSVG (); + void convert (unsigned firstPage, unsigned lastPage, std::pair<int,int> *pageinfo=0); + void convert (const std::string &range, std::pair<int,int> *pageinfo=0); + const SpecialManager* setProcessSpecials (const char *ignorelist=0, bool pswarning=false); + const SpecialManager& specialManager () const {return _specialManager;} + void setPageSize (const std::string &name) {_bboxString = name;} + void setPageTransformation (const std::string &cmds) {_transCmds = cmds;} + void getPageTransformation (Matrix &matrix) const; + + public: + static char TRACE_MODE; + + protected: + DVIToSVG (const DVIToSVG &); + DVIToSVG operator = (const DVIToSVG &); + void beginPage (unsigned pageno, Int32 *c); + void endPage (unsigned pageno); + void embedFonts (XMLElementNode *svgElement); + + private: + SVGTree _svg; + SVGOutputBase &_out; + std::string _bboxString; + std::string _transCmds; + SpecialManager _specialManager; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.cpp new file mode 100644 index 00000000000..7d25678d227 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.cpp @@ -0,0 +1,368 @@ +/************************************************************************* +** DVIToSVGActions.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <ctime> +#include "BoundingBox.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "Font.h" +#include "FontManager.h" +#include "GlyphTracerMessages.h" +#include "SpecialManager.h" +#include "System.h" +#include "XMLNode.h" +#include "XMLString.h" + + +using namespace std; + + +double DVIToSVGActions::PROGRESSBAR_DELAY=1000; // initial delay in seconds (values >= 1000 disable the progressbar) + + +DVIToSVGActions::DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg) + : _svg(svg), _dvisvg(dvisvg), _pageMatrix(0), _bgcolor(Color::TRANSPARENT), _boxes(0) +{ + _currentFontNum = -1; + _pageCount = 0; +} + + +DVIToSVGActions::~DVIToSVGActions () { + delete _pageMatrix; + delete _boxes; +} + + +void DVIToSVGActions::reset() { + _usedChars.clear(); + _usedFonts.clear(); + _bbox = BoundingBox(); + _currentFontNum = -1; + _bgcolor = Color::TRANSPARENT; +} + + +void DVIToSVGActions::setPageMatrix (const Matrix &matrix) { + delete _pageMatrix; + _pageMatrix = new Matrix(matrix); +} + + +void DVIToSVGActions::moveToX (double x) { + _dvisvg.specialManager().notifyPositionChange(getX(), getY()); + _svg.setX(x); +} + + +void DVIToSVGActions::moveToY (double y) { + _dvisvg.specialManager().notifyPositionChange(getX(), getY()); + _svg.setY(y); +} + + +/** This method is called when a "set char" command was found in the DVI file. + * It draws a character of the current font. + * @param[in] x horizontal position of left bounding box edge + * @param[in] y vertical position of the character's baseline + * @param[in] c character code relative to the current font + * @param[in] vertical true if we're in vertical mode + * @param[in] font font to be used */ +void DVIToSVGActions::setChar (double x, double y, unsigned c, bool vertical, const Font *font) { + // If we use SVG fonts there is no need to record all font name/char/size combinations + // because the SVG font mechanism handles this automatically. It's sufficient to + // record font names and chars. The various font sizes can be ignored here. + // For a given font object, Font::uniqueFont() returns the same unique font object for + // all fonts with the same name. + _usedChars[SVGTree::USE_FONTS ? font->uniqueFont() : font].insert(c); + + // However, we record all required fonts + _usedFonts.insert(font); + _svg.appendChar(c, x, y, *font); + + static string fontname; + GlyphTracerMessages callback(fontname != font->name(), false); + fontname = font->name(); + + BoundingBox charbox; + GlyphMetrics metrics; + font->getGlyphMetrics(c, vertical, metrics); + const PhysicalFont* pf = dynamic_cast<const PhysicalFont*>(font); + if (PhysicalFont::EXACT_BBOX && pf) { + GlyphMetrics exact_metrics; + pf->getExactGlyphBox(c, exact_metrics, vertical, &callback); + if (vertical) { + // move top of bbox to upper margin of glyph (just an approximation yet) + y += (metrics.d-exact_metrics.h-exact_metrics.d)/2; + } + metrics = exact_metrics; + } + BoundingBox bbox(x-metrics.wl, y-metrics.h, x+metrics.wr, y+metrics.d); + + // update bounding box + if (!getMatrix().isIdentity()) + bbox.transform(getMatrix()); + embed(bbox); +#if 0 + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", x-metrics.wl); + rect->addAttribute("y", y-metrics.h); + rect->addAttribute("width", metrics.wl+metrics.wr); + rect->addAttribute("height", metrics.h+metrics.d); + rect->addAttribute("fill", "none"); + rect->addAttribute("stroke", "red"); + rect->addAttribute("stroke-width", "0.5"); + _svg.appendToPage(rect); + if (metrics.d > 0) { + XMLElementNode *line = new XMLElementNode("line"); + line->addAttribute("x1", x-metrics.wl); + line->addAttribute("y1", y); + line->addAttribute("x2", x+metrics.wr); + line->addAttribute("y2", y); + line->addAttribute("stroke", "blue"); + line->addAttribute("stroke-width", "0.5"); + _svg.appendToPage(line); + } + if (metrics.wl > 0) { + XMLElementNode *line = new XMLElementNode("line"); + line->addAttribute("x1", x); + line->addAttribute("y1", y-metrics.h); + line->addAttribute("x2", x); + line->addAttribute("y2", y+metrics.d); + line->addAttribute("stroke", "blue"); + line->addAttribute("stroke-width", "0.5"); + _svg.appendToPage(line); + } +#endif +} + + +/** This method is called when a "set rule" or "put rule" command was found in the + * DVI file. It draws a solid unrotated rectangle. + * @param[in] x horizontal position of left edge + * @param[in] y vertical position of bottom(!) edge + * @param[in] height length of the vertical edges + * @param[in] width length of the horizontal edges */ +void DVIToSVGActions::setRule (double x, double y, double height, double width) { + // (x,y) is the lower left corner of the rectangle + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", x); + rect->addAttribute("y", y-height); + rect->addAttribute("height", height); + rect->addAttribute("width", width); + if (!getMatrix().isIdentity()) + rect->addAttribute("transform", getMatrix().getSVG()); + if (getColor() != Color::BLACK) + rect->addAttribute("fill", _svg.getColor().rgbString()); + _svg.appendToPage(rect); + + // update bounding box + BoundingBox bb(x, y-height, x+width, y); + if (!getMatrix().isIdentity()) + bb.transform(getMatrix()); + embed(bb); +} + + +/** This method is called when a "set font" command was found in the DVI file. The + * font must be previously defined. + * @param[in] num unique number of the font in the DVI file (not necessarily equal to the DVI font number) + * @param[in] font pointer to the font object (always represents a physical font and never a virtual font) */ +void DVIToSVGActions::setFont (int num, const Font *font) { + _currentFontNum = num; + _svg.setFont(num, font); +} + + +/** This method is called when a "special" command was found in the DVI file. + * @param[in] s the special expression + * @param[in] dvi2bp factor to scale DVI units to PS points */ +void DVIToSVGActions::special (const string &s, double dvi2bp) { + try { + _dvisvg.specialManager().process(s, dvi2bp, this, this); + // @@ output message in case of unsupported specials? + } + catch (const SpecialException &e) { + Message::estream(true) << "error in special '" << s << "': " << e.what() << '\n'; + } +} + + +void DVIToSVGActions::beginSpecial (const char *prefix) { +} + + +void DVIToSVGActions::endSpecial (const char *) { +} + + +/** This method is called when the DVI preamble was read + * @param[in] cmt preamble comment text. */ +void DVIToSVGActions::preamble (const string &cmt) { +} + + +void DVIToSVGActions::postamble () { +} + + +/** This method is called when a "begin of page (bop)" command was found in the DVI file. + * @param[in] pageno physical page number + * @param[in] c array with 10 components representing \\count0 ... \\count9. c[0] contains the + * current (printed) page number (may differ from page count) */ +void DVIToSVGActions::beginPage (unsigned pageno, Int32 *c) { + _svg.newPage(++_pageCount); + _bbox = BoundingBox(); // clear bounding box + if (_boxes) + _boxes->clear(); +} + + +/** This method is called when an "end of page (eop)" command was found in the DVI file. */ +void DVIToSVGActions::endPage (unsigned pageno) { + _svg.transformPage(_pageMatrix); + if (_bgcolor != Color::TRANSPARENT) { + // create a rectangle filled with the background color + XMLElementNode *r = new XMLElementNode("rect"); + r->addAttribute("x", _bbox.minX()); + r->addAttribute("y", _bbox.minY()); + r->addAttribute("width", _bbox.width()); + r->addAttribute("height", _bbox.height()); + r->addAttribute("fill", _bgcolor.rgbString()); + _svg.prependToPage(r); + } +} + + +void DVIToSVGActions::setBgColor (const Color &color) { + _bgcolor = color; +} + + +void DVIToSVGActions::embed(const BoundingBox& bbox) { + _bbox.embed(bbox); + if (_boxes) { + FORALL(*_boxes, BoxMap::iterator, it) + it->second.embed(bbox); + } +} + + +void DVIToSVGActions::embed(const DPair& p, double r) { + if (r == 0) + _bbox.embed(p); + else + _bbox.embed(p, r); + if (_boxes) + FORALL(*_boxes, BoxMap::iterator, it) + it->second.embed(p, r); +} + + +BoundingBox& DVIToSVGActions::bbox(const string& name, bool reset) { + if (!_boxes) + _boxes = new BoxMap; + BoundingBox &box = (*_boxes)[name]; + if (reset) + box = BoundingBox(); + return box; +} + + +/** This method is called by subprocesses like the PS handler when + * a computation step has finished. Since the total number of steps + * can't be determined in advance, we don't show a percent value but + * a rotating dash. */ +void DVIToSVGActions::progress (const char *id) { + if (PROGRESSBAR_DELAY < 1000) { + static double time=0; + // slow down updating of the progress indicator to prevent flickering + if (System::time() - time > 0.1) { + progress(0, 0, id); + time = System::time(); + } + } +} + + +/** Returns the number of digits of a given integer. */ +static int digits (int n) { + if (n == 0) + return 1; + if (n > 0) + return int(log10(double(n))+1); + return int(log10(double(-n))+2); +} + + +/** Draws a simple progress indicator. + * @param[in] current current iteration step (of 'total' steps) + * @param[in] total total number of iteration steps + * @param[in] id ID of the subprocess providing the information */ +void DVIToSVGActions::progress (size_t current, size_t total, const char *id) { + static double time=0; + static bool draw=false; // show progress indicator? + static const char *prev_id=0; + if (current == 0 && total > 0) { + time = System::time(); + draw = false; + Message::mstream() << '\n'; + } + // don't show the progress indicator before the given time has elapsed + if (!draw && System::time()-time > PROGRESSBAR_DELAY) { + draw = true; + Terminal::cursor(false); + } + if (draw && (System::time() - time > 0.1 || (total > 0 && current == total) || prev_id != id)) { + static int step = -1; // >=0: rotating dash + static size_t prev_current=0, prev_total=1; + const char *tips = "-\\|/"; + if (total == 0) { + current = prev_current; + total = prev_total; + step = (step+1) % 4; + } + else { + prev_current = current; + prev_total = total; + step = -1; + } + // adapt length of progress indicator to terminal width + int cols = Terminal::columns(); + int width = (cols == 0 || cols > 60) ? 50 : 49-60+cols; + double factor = double(current)/double(total); + int length = int(width*factor); + Message::mstream(false, Message::MC_PROGRESS) + << '[' << string(length, '=') + << (factor < 1.0 ? (step < 0 ? ' ' : tips[step]) : '=') + << string(width-length, ' ') + << "] " << string(3-digits(int(100*factor)), ' ') << int(100*factor) + << "%\r"; + // overprint indicator when finished + if (factor == 1.0) { + Message::estream().clearline(); + Terminal::cursor(true); + } + time = System::time(); + prev_id = id; + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.h new file mode 100644 index 00000000000..9b18209904b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DVIToSVGActions.h @@ -0,0 +1,107 @@ +/************************************************************************* +** DVIToSVGActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DVITOSVGACTIONS_H +#define DVISVGM_DVITOSVGACTIONS_H + +#include <map> +#include <set> +#include "BoundingBox.h" +#include "DVIActions.h" +#include "Matrix.h" +#include "SpecialActions.h" +#include "SpecialManager.h" +#include "SVGTree.h" +#include "DVIReader.h" + + +class DVIToSVG; +struct FileFinder; +struct Font; +struct XMLNode; + +class DVIToSVGActions : public DVIActions, public SpecialActions, public SpecialManager::Listener +{ + typedef std::map<const Font*, std::set<int> > CharMap; + typedef std::set<const Font*> FontSet; + typedef std::map<std::string,BoundingBox> BoxMap; + + public: + DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg); + ~DVIToSVGActions (); + void reset (); + void setChar (double x, double y, unsigned c, bool vertical, const Font *f); + void setRule (double x, double y, double height, double width); + void setBgColor (const Color &color); + void setColor (const Color &color) {_svg.setColor(color);} + void setMatrix (const Matrix &m) {_svg.setMatrix(m);} + const Matrix& getMatrix () const {return _svg.getMatrix();} + void getPageTransform (Matrix &matrix) const {_dvisvg.getPageTransformation(matrix);} + Color getColor () const {return _svg.getColor();} + int getDVIStackDepth() const {return _dvisvg.getStackDepth();} + void appendToPage (XMLNode *node) {_svg.appendToPage(node);} + void appendToDefs (XMLNode *node) {_svg.appendToDefs(node);} + void prependToPage (XMLNode *node) {_svg.prependToPage(node);} + void pushContextElement (XMLElementNode *node) {_svg.pushContextElement(node);} + void popContextElement () {_svg.popContextElement();} + void setTextOrientation(bool vertical) {_svg.setVertical(vertical);} + void moveToX (double x); + void moveToY (double y); + void setFont (int num, const Font *font); + void special (const std::string &s, double dvi2bp); + void preamble (const std::string &cmt); + void postamble (); + void beginPage (unsigned pageno, Int32 *c); + void endPage (unsigned pageno); + void beginSpecial (const char *prefix); + void endSpecial (const char *prefix); + void progress (size_t current, size_t total, const char *id=0); + void progress (const char *id); + CharMap& getUsedChars () const {return _usedChars;} + const FontSet& getUsedFonts () const {return _usedFonts;} + void setPageMatrix (const Matrix &tm); + double getX() const {return _dvisvg.getXPos();} + double getY() const {return _dvisvg.getYPos();} + void setX (double x) {_dvisvg.translateToX(x); _svg.setX(x);} + void setY (double y) {_dvisvg.translateToY(y); _svg.setY(y);} + void finishLine () {_dvisvg.finishLine();} + BoundingBox& bbox () {return _bbox;} + BoundingBox& bbox (const std::string &name, bool reset=false); + void embed (const BoundingBox &bbox); + void embed (const DPair &p, double r=0); + + public: + static double PROGRESSBAR_DELAY; ///< progress bar doesn't appear before this time has elapsed (in sec) + + private: + SVGTree &_svg; + DVIToSVG &_dvisvg; + BoundingBox _bbox; + int _pageCount; + int _currentFontNum; + mutable CharMap _usedChars; + FontSet _usedFonts; + Matrix *_pageMatrix; // transformation of whole page + Color _bgcolor; + BoxMap *_boxes; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.cpp new file mode 100644 index 00000000000..925b3065c8d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.cpp @@ -0,0 +1,129 @@ +/************************************************************************* +** Directory.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "Directory.h" + +using namespace std; + +#ifdef __WIN32__ + #include <windows.h> +#else + #include <errno.h> + #include <sys/stat.h> +#endif + + +Directory::Directory () { +#if __WIN32__ + handle = INVALID_HANDLE_VALUE; + firstread = true; + memset(&fileData, 0, sizeof(WIN32_FIND_DATA)); +#else + dir = 0; + dirent = 0; +#endif +} + + +Directory::Directory (string dirname) { +#if __WIN32__ + handle = INVALID_HANDLE_VALUE; + firstread = true; + memset(&fileData, 0, sizeof(WIN32_FIND_DATA)); +#else + dir = 0; + dirent = 0; +#endif + open(dirname); +} + + +Directory::~Directory () { + close(); +} + + +bool Directory::open (string dname) { + _dirname = dname; +#ifdef __WIN32__ + firstread = true; + if (dname[dname.length()-1] == '/' || dname[dname.length()-1] == '\\') + dname = dname.substr(0, dname.length()-1); + dname += "\\*"; + handle = FindFirstFile(dname.c_str(), &fileData); + return handle != INVALID_HANDLE_VALUE; +#else + dir = opendir(_dirname.c_str()); + return dir; +#endif +} + + +void Directory::close () { +#ifdef __WIN32__ + FindClose(handle); +#else + closedir(dir); +#endif +} + + +/** Reads first/next directory entry. + * @param[in] type type of entry to return (a: file or dir, f: file, d: dir) + * @return name of entry */ +const char* Directory::read (EntryType type) { +#ifdef __WIN32__ + if (handle == INVALID_HANDLE_VALUE) + return 0; + while (firstread || FindNextFile(handle, &fileData)) { + firstread = false; + if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (type == ET_FILE_OR_DIR || type == ET_DIR) + return fileData.cFileName; + } + else if (type == ET_FILE_OR_DIR || type == ET_FILE) + return fileData.cFileName; + } + FindClose(handle); + handle = INVALID_HANDLE_VALUE; + return 0; +#else + if (!dir) + return 0; + while ((dirent = readdir(dir))) { + string path = string(_dirname) + "/" + dirent->d_name; + struct stat stats; + if (stat(path.c_str(), &stats) == 0) { + if (S_ISDIR(stats.st_mode)) { + if (type == ET_FILE_OR_DIR || type == ET_DIR) + return dirent->d_name; + } + else if (type == ET_FILE_OR_DIR || type == ET_FILE) + return dirent->d_name; + } + } + closedir(dir); + dir = 0; + return 0; +#endif +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.h new file mode 100644 index 00000000000..0d1e9406b4e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Directory.h @@ -0,0 +1,56 @@ +/************************************************************************* +** Directory.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DIRECTORY_H +#define DVISVGM_DIRECTORY_H + +#include <string> +#ifdef __WIN32__ + #include <windows.h> +#else + #include <dirent.h> +#endif + +class Directory +{ + public: + enum EntryType {ET_FILE, ET_DIR, ET_FILE_OR_DIR}; + + public: + Directory (); + Directory (std::string path); + ~Directory (); + bool open (std::string path); + void close (); + const char* read (EntryType type=ET_FILE_OR_DIR); + + private: + std::string _dirname; +#ifdef __WIN32__ + bool firstread; + HANDLE handle; + WIN32_FIND_DATA fileData; +#else + DIR *dir; + struct dirent *dirent; +#endif +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.cpp new file mode 100644 index 00000000000..58f6a6e7ca1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.cpp @@ -0,0 +1,208 @@ +/************************************************************************* +** DvisvgmSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include "DvisvgmSpecialHandler.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +/** Replaces constants of the form {?name} by their corresponding value. + * @param[in,out] str text to expand + * @param[in] actions interfcae to the world outside the special handler */ +static void expand_constants (string &str, SpecialActions *actions) { + struct Constant { + const char *name; + string val; + } + constants[] = { + {"x", XMLString(actions->getX())}, + {"y", XMLString(actions->getY())}, + {"color", actions->getColor().rgbString()}, + {"nl", "\n"}, + {0, ""} + }; + bool repl_bbox = true; + while (repl_bbox) { + size_t pos = str.find(string("{?bbox ")); + if (pos == string::npos) + repl_bbox = false; + else { + size_t endpos = pos+7; + while (endpos < str.length() && isalnum(str[endpos])) + ++endpos; + if (str[endpos] == '}') { + BoundingBox &box=actions->bbox(str.substr(pos+7, endpos-pos-7)); + str.replace(pos, endpos-pos+1, box.toSVGViewBox()); + } + else + repl_bbox = false; + } + } + for (const Constant *p=constants; p->name; p++) { + const string pattern = string("{?")+p->name+"}"; + size_t pos = str.find(pattern); + while (pos != string::npos) { + str.replace(pos, strlen(p->name)+3, p->val); + pos = str.find(pattern, pos+p->val.length()); // look for further matches + } + } +} + + +/** Embeds the virtual rectangle (x, y ,w , h) into the current bounding box, + * where (x,y) is the lower left vertex composed of the current DVI position. + * @param[in] w width of the rectangle in PS point units + * @param[in] h height of the rectangle in PS point units + * @param[in] d depth of the rectangle in PS point units + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +static void update_bbox (double w, double h, double d, SpecialActions *actions) { + double x = actions->getX(); + double y = actions->getY(); + actions->embed(BoundingBox(x, y, x+w, y-h)); + actions->embed(BoundingBox(x, y, x+w, y+d)); +} + + +/** Inserts raw text into the SVG tree. + * @param[in,out] in the raw text is read from this input buffer + * @param[in] actions interfcae to the world outside the special handler + * @param[in] group true if the text should be wrapped by a group element */ +static void raw (InputReader &in, SpecialActions *actions, bool group=false) { + string str; + while (!in.eof()) { + int c = in.get(); + if (isprint(c)) + str += char(c); + } + expand_constants(str, actions); + if (!str.empty()) { + XMLNode *node = new XMLTextNode(str); + if (group) { + XMLElementNode *g = new XMLElementNode("g"); + g->addAttribute("x", actions->getX()); + g->addAttribute("y", actions->getY()); + if (actions->getColor() != Color::BLACK) + g->addAttribute("fill", actions->getColor().rgbString()); + g->append(node); + node = g; + } + actions->appendToPage(node); + } +} + + +/** Evaluates the special dvisvgm:bbox. + * variant 1: dvisvgm:bbox [r[el]] <width> <height> [<depth>] + * variant 2: dvisvgm:bbox a[bs] <x1> <y1> <x2> <y2> + * variant 3: dvisvgm:bbox f[ix] <x1> <y1> <x2> <y2> + * variant 4: dvisvgm:bbox n[ew] <name> */ +static void bbox (InputReader &in, SpecialActions *actions) { + const double pt2bp = 72/72.27; + in.skipSpace(); + int c = in.peek(); + if (isalpha(c)) { + while (!isspace(in.peek())) // skip trailing characters + in.get(); + if (c == 'n') { + in.skipSpace(); + string name; + while (isalnum(in.peek())) + name += char(in.get()); + in.skipSpace(); + if (!name.empty() && in.eof()) + actions->bbox(name, true); // create new user box + } + else if (c == 'a' || c == 'f') { + double p[4]; + for (int i=0; i < 4; i++) + p[i] = in.getDouble()*pt2bp; + BoundingBox b(p[0], p[1], p[2], p[3]); + if (c == 'a') + actions->embed(b); + else { + actions->bbox() = b; + actions->bbox().lock(); + } + } + } + else + c = 'r'; // no mode specifier => relative box parameters + + if (c == 'r') { + double w = in.getDouble()*pt2bp; + double h = in.getDouble()*pt2bp; + double d = in.getDouble()*pt2bp; + update_bbox(w, h, d, actions); + } +} + + +static void img (InputReader &in, SpecialActions *actions) { + if (actions) { + const double pt2bp = 72/72.27; + double w = in.getDouble()*pt2bp; + double h = in.getDouble()*pt2bp; + string f = in.getString(); + update_bbox(w, h, 0, actions); + XMLElementNode *img = new XMLElementNode("image"); + img->addAttribute("x", actions->getX()); + img->addAttribute("y", actions->getY()); + img->addAttribute("width", w); + img->addAttribute("height", h); + img->addAttribute("xlink:href", f); + if (!actions->getMatrix().isIdentity()) + img->addAttribute("transform", actions->getMatrix().getSVG()); + actions->appendToPage(img); + } +} + + +/** Evaluates and executes a dvisvgm special statement. + * @param[in] prefix special prefix read by the SpecialManager + * @param[in] is the special statement is read from this stream + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (actions) { + StreamInputBuffer ib(is); + BufferInputReader in(ib); + string cmd = in.getWord(); + if (cmd == "raw") // raw <text> + raw(in, actions); + else if (cmd == "bbox") // bbox [r] <width> <height> <depth> or bbox a <x1> <y1> <x2> <y2> + bbox(in, actions); + else if (cmd == "img") { // img <width> <height> <file> + img(in, actions); + } + } + return true; +} + + +const char** DvisvgmSpecialHandler::prefixes () const { + static const char *pfx[] = {"dvisvgm:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.h new file mode 100644 index 00000000000..1c6424c6fb8 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/DvisvgmSpecialHandler.h @@ -0,0 +1,35 @@ +/************************************************************************* +** DvisvgmSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_DVISVGMSPECIALHANDLER_H +#define DVISVGM_DVISVGMSPECIALHANDLER_H + +#include "SpecialHandler.h" + +class DvisvgmSpecialHandler : public SpecialHandler +{ + public: + const char* name () const {return "dvisvgm";} + const char* info () const {return "special set for embedding raw SVG snippets";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.cpp new file mode 100644 index 00000000000..d3def37dc68 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.cpp @@ -0,0 +1,115 @@ +/************************************************************************* +** EPSFile.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <istream> +#include <limits> +#include "EPSFile.h" +#include "InputBuffer.h" +#include "InputReader.h" + +using namespace std; + + +/** Reads a little-endian 32-bit integer from the given input stream. */ +static UInt32 getUInt32 (istream &is) { + UInt32 value=0; + char buf[4]; + is.read(buf, 4); + for (int i=0; i < 4; i++) + value |= ((buf[i] & 255) << (8*i)); + return value; +} + + +static size_t getline (istream &is, char *line, size_t n) { + char buf[512]; + is.get(buf, min(n, (size_t)512)-1); + n = is.gcount(); + size_t linelen=0; + for (size_t i=0; i < n; i++) + if (isprint(buf[i])) + line[linelen++] = buf[i]; + line[linelen] = 0; + if (is.peek() == '\n') + is.get(); + else + is.ignore(numeric_limits<size_t>::max(), '\n'); + return linelen; +} + + +EPSFile::EPSFile (const std::string& fname) : _ifs(fname.c_str(), ios::binary), _headerValid(false), _offset(0), _pslength(0) +{ + if (_ifs) { + if (getUInt32(_ifs) != 0xC6D3D0C5) // no binary header present? + _ifs.seekg(0, ios_base::beg); // go back to the first byte + else { + _offset = getUInt32(_ifs); // stream offset where PS part of the file begins + _pslength = getUInt32(_ifs); // length of PS section in bytes + _ifs.seekg(_offset, ios_base::beg); // continue reading at the beginning of the PS section + } + string str; + str += _ifs.get(); + str += _ifs.get(); + _headerValid = (str == "%!"); + _ifs.seekg(0, ios_base::beg); + } +} + + +/** Returns an input stream for the EPS file. The stream pointer is automatically moved + * to the beginning of the ASCII (PostScript) part of the file. */ +istream& EPSFile::istream () const { + _ifs.clear(); + _ifs.seekg(_offset, ios_base::beg); + return _ifs; +} + + +/** Extracts the bounding box information from the DSC header/footer (if present) + * @param[out] box the extracted bounding box + * @return true if %%BoundingBox data could be read successfully */ +bool EPSFile::bbox (BoundingBox &box) const { + std::istream &is = EPSFile::istream(); + if (is) { + char buf[64]; + while (is) { + size_t linelen = getline(is, buf, 64); + if (strncmp(buf, "%%BoundingBox:", 14) == 0) { + CharInputBuffer ib(buf, linelen); + BufferInputReader ir(ib); + ir.skip(14); + ir.skipSpace(); + if (!ir.check("(atend)", true)) { + int val[4]; + for (int i=0; i < 4; i++) { + ir.skipSpace(); + ir.parseInt(val[i]); + } + box = BoundingBox(val[0], val[1], val[2], val[3]); + return true; + } + } + } + } + return false; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.h new file mode 100644 index 00000000000..19b60a42797 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSFile.h @@ -0,0 +1,46 @@ +/************************************************************************* +** EPSFile.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_EPSFILE_H +#define DVISVGM_EPSFILE_H + +#include <fstream> +#include <string> +#include "BoundingBox.h" +#include "types.h" + +class EPSFile +{ + public: + EPSFile (const std::string &fname); + std::istream& istream () const; + bool hasValidHeader () const {return _headerValid;} + bool bbox (BoundingBox &box) const; + UInt32 pslength () const {return _pslength;} + + private: + mutable std::ifstream _ifs; + bool _headerValid; ///< true if file has a valid header + UInt32 _offset; ///< stream offset where ASCII part of the file begins + UInt32 _pslength; ///< length of PS section (in bytes) +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.cpp new file mode 100644 index 00000000000..417dde90f48 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.cpp @@ -0,0 +1,74 @@ +/************************************************************************* +** EPSToSVG.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <fstream> +#include <istream> +#include <sstream> +#include "EPSFile.h" +#include "EPSToSVG.h" +#include "Message.h" +#include "MessageException.h" +#include "PsSpecialHandler.h" +#include "SVGOutputBase.h" + + +using namespace std; + + +void EPSToSVG::convert () { +#ifndef HAVE_LIBGS + if (!Ghostscript().available()) + throw MessageException("Ghostscript is required to process the EPS file"); +#endif + EPSFile epsfile(_fname); + if (!epsfile.hasValidHeader()) + throw PSException("invalid EPS file"); + + BoundingBox bbox; + epsfile.bbox(bbox); + if (bbox.width() == 0 || bbox.height() == 0) + Message::wstream(true) << "bounding box of file " << _fname << " is empty\n"; + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing file " << _fname << '\n'; + Message::mstream().indent(1); + _svg.newPage(1); + // create a psfile special and forward it to the PsSpecialHandler + stringstream ss; + ss << "\"" << _fname << "\" " + "llx=" << bbox.minX() << " " + "lly=" << bbox.minY() << " " + "urx=" << bbox.maxX() << " " + "ury=" << bbox.maxY(); + PsSpecialHandler pshandler; + pshandler.process("psfile=", ss, this); + // output SVG file + _svg.setBBox(_bbox); + _svg.appendToDoc(new XMLCommentNode(" This file was generated by dvisvgm " VERSION " ")); + _svg.write(_out.getPageStream(1, 1)); + string svgfname = _out.filename(1, 1); + const double bp2pt = 72.27/72; + const double bp2mm = 25.4/72; + Message::mstream(false, Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(bbox.width()*bp2pt) << "pt" + " x " << XMLString(bbox.height()*bp2pt) << "pt" + " (" << XMLString(bbox.width()*bp2mm) << "mm" + " x " << XMLString(bbox.height()*bp2mm) << "mm)\n"; + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "graphic written to " << (svgfname.empty() ? "<stdout>" : svgfname) << '\n'; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.h new file mode 100644 index 00000000000..e3ea67ca87d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EPSToSVG.h @@ -0,0 +1,69 @@ +/************************************************************************* +** EPSToSVG.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_EPSTOSVG_H +#define DVISVGM_EPSTOSVG_H + +#include <string> +#include "SpecialActions.h" +#include "SVGTree.h" + +struct SVGOutputBase; + +class EPSToSVG : protected SpecialActions +{ + public: + EPSToSVG (const std::string &fname, SVGOutputBase &out) : _fname(fname), _out(out), _x(0), _y(0) {} + void convert (); + void setTransformation (const Matrix &m); + void setPageSize (const std::string &name); + + protected: + // implement abstract base class SpecialActions + double getX () const {return _x;} + double getY () const {return _y;} + void setX (double x) {_x = x; _svg.setX(x);} + void setY (double y) {_y = y; _svg.setY(y);} + void finishLine () {} + void setColor (const Color &color) {_svg.setColor(color);} + Color getColor () const {return _svg.getColor();} + void setMatrix (const Matrix &m) {_svg.setMatrix(m);} + const Matrix& getMatrix () const {return _svg.getMatrix();} + void getPageTransform (Matrix &matrix) const {} + void setBgColor (const Color &color) {} + void appendToPage (XMLNode *node) {_svg.appendToPage(node);} + void appendToDefs (XMLNode *node) {_svg.appendToDefs(node);} + void prependToPage (XMLNode *node) {_svg.prependToPage(node);} + void pushContextElement (XMLElementNode *node) {_svg.pushContextElement(node);} + void popContextElement () {_svg.popContextElement();} + void embed (const BoundingBox &bbox) {_bbox.embed(bbox);} + void embed (const DPair &p, double r=0) {if (r==0) _bbox.embed(p); else _bbox.embed(p, r);} + BoundingBox& bbox () {return _bbox;} + BoundingBox& bbox (const std::string &name, bool reset=false) {return _bbox;} + + private: + std::string _fname; ///< name of EPS file + SVGTree _svg; + SVGOutputBase &_out; + double _x, _y; + BoundingBox _bbox; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.cpp new file mode 100644 index 00000000000..cc06289464c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.cpp @@ -0,0 +1,233 @@ +/************************************************************************* +** EmSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "EmSpecialHandler.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +EmSpecialHandler::EmSpecialHandler () : _linewidth(0.4*72/72.27), _actions(0) { +} + + +/** Computes the "cut vector" that is used to compute the line shape. + * Because each line has a width > 0 the actual shape of the line is a tetragon. + * The 4 vertices can be influenced by the cut parameter c that specifies + * a horizontal, vertical or orthogonal cut of a line end. Depending on c and the + * line's slope a cut vector v can be computed that, relatively to endpoint p, denotes + * the 2 vertices of that line end: v1=p+v and v2=p-v. + * @param[in] c cut direction ('h', 'v' or 'p') + * @param[in] v direction vector of line to be drawn + * @param[in] lw width of line to be drawn + * @return the "cut vector" */ +static DPair cut_vector (char c, const DPair &v, double lw) { + if (c == 'p') + return v.ortho()/v.length() * (lw/2); + DPair cut; + if (c == 'v' && v.x() != 0) { + double slope = v.y()/v.x(); + double h = sqrt(lw*lw*(1+slope*slope)); + cut.y(0.5*h); + } + else if (v.y() != 0) { // c == 'h' + double slope = v.x()/v.y(); + double h = sqrt(lw*lw*(1+slope*slope)); + double sgn = slope < 0 ? 1.0 : -1.0; + cut.x(0.5*h*sgn); + } + return cut; +} + + +/** Creates the SVG element that will a the line. + * @param[in] p1 first endpoint in PS point units + * @param[in] p2 second endpoint in PS point units + * @param[in] c1 cut method of first endpoint ('h', 'v' or 'p') + * @param[in] c2 cut method of second endpoint ('h', 'v' or 'p') + * @param[in] lw line width in PS point units + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions *actions) { + XMLElementNode *node=0; + DPair dir = p2-p1; + if (dir.x() == 0 || dir.y() == 0 || (c1 == 'p' && c2 == 'p')) { + // draw regular line + node = new XMLElementNode("line"); + node->addAttribute("x1", p1.x()); + node->addAttribute("y1", p1.y()); + node->addAttribute("x2", p2.x()); + node->addAttribute("y2", p2.y()); + node->addAttribute("stroke-width", lw); + node->addAttribute("stroke", actions->getColor().rgbString()); + // update bounding box + actions->embed(p1); + actions->embed(p2); + } + else { + // draw polygon + DPair cv1 = cut_vector(c1, dir, lw); + DPair cv2 = cut_vector(c2, dir, lw); + DPair q11 = p1+cv1, q12 = p1-cv1; + DPair q21 = p2+cv2, q22 = p2-cv2; + node = new XMLElementNode("polygon"); + ostringstream oss; + oss << XMLString(q11.x()) << ',' << XMLString(q11.y()) << ' ' + << XMLString(q12.x()) << ',' << XMLString(q12.y()) << ' ' + << XMLString(q22.x()) << ',' << XMLString(q22.y()) << ' ' + << XMLString(q21.x()) << ',' << XMLString(q21.y()); + node->addAttribute("points", oss.str()); + if (actions->getColor() != Color::BLACK) + node->addAttribute("fill", actions->getColor().rgbString()); + // update bounding box + actions->embed(q11); + actions->embed(q12); + actions->embed(q21); + actions->embed(q22); + } + actions->appendToPage(node); +} + + +static double read_length (InputReader &in) { + struct Unit { + const char *name; + double factor; + } + units[] = { + {"pt", 1.0}, + {"pc", 12.0}, + {"in", 72.27}, + {"bp", 72.27/72}, + {"cm", 72.27/2.54}, + {"mm", 72.27/25.4}, + {"dd", 1238.0/1157}, + {"cc", 1238.0/1157*12}, + {"sp", 1.0/65536}, + {0, 0} + }; + double len = in.getDouble(); + in.skipSpace(); + for (Unit *p=units; p->name; p++) + if (in.check(p->name)) { + len *= p->factor; + break; + } + return len*72/72.27; +} + + +bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + // em:moveto => move graphic cursor to dvi cursor + // em:lineto => draw line from graphic cursor to dvi cursor, move graphic cursor to dvi cursor + // em:linewidth <w> => set line width to <w> + // em:point <n>[,<x>[,<y>]] => defines point <n> as (<x>,<y>); if <x> and/or <y> is missing, + // the corresponding dvi cursor coordinate is inserted + // <x> and <y> are lengths + // em:line <n>[h|v|p], <m>[h|v|p] [,<w>] => draws line of width <w> from point #<n> to point #<m> + // point number suffixes: + // h: cut line horizontally + // v: cut line vertically + // p: cut line orthogonally to line direction (default) + // if <w> is omitted, the global line width is used + // + // supported length units: pt, pc, in, bp, cm, mm, dd, cc, sp + // default line width: 0.4pt + + if (actions) { + _actions = actions; // save pointer to SpecialActions for later use in endPage + StreamInputBuffer ib(is, 128); + BufferInputReader in(ib); + string cmd = in.getWord(); + if (cmd == "moveto") + _pos = DPair(actions->getX(), actions->getY()); + else if (cmd == "lineto") { + DPair p(actions->getX(), actions->getY()); + create_line(_pos, p, 'p', 'p', _linewidth, actions); + _pos = p; + } + else if (cmd == "linewidth") + _linewidth = read_length(in); + else if (cmd == "point") { + DPair p(actions->getX(), actions->getY()); + int n = in.getInt(); + if (in.getPunct() == ',') { + p.x(in.getDouble()); + if (in.getPunct() == ',') + p.y(in.getDouble()); + } + _points[n] = p; + } + else if (cmd == "line") { + int n1 = in.getInt(); + int c1 = 'p'; + if (isalpha(in.peek())) + c1 = in.get(); + in.getPunct(); + int n2 = in.getInt(); + int c2 = 'p'; + if (isalpha(in.peek())) + c2 = in.get(); + double lw = _linewidth; + if (in.getPunct() == ',') + lw = read_length(in); + map<int,DPair>::iterator it1=_points.find(n1); + map<int,DPair>::iterator it2=_points.find(n2); + if (it1 != _points.end() && it2 != _points.end()) + create_line(it1->second, it2->second, char(c1), char(c2), lw, actions); + else { + // Line endpoints havn't necessarily to be defined before + // a line definition. If a point wasn't defined yet we push the line + // in a wait list and process the lines at the end of the page. + _lines.push_back(Line(n1, n2, char(c1), char(c2), lw)); + } + } + } + return true; +} + + +/** This method is called at the end of a DVI page. Here we have to draw all pending + * lines that are still in the line list. All line endpoints must be defined until here. */ +void EmSpecialHandler::dviEndPage (unsigned pageno) { + if (_actions) { + FORALL(_lines, list<Line>::iterator, it) { + map<int,DPair>::iterator pit1=_points.find(it->p1); + map<int,DPair>::iterator pit2=_points.find(it->p2); + if (pit1 != _points.end() && pit2 != _points.end()) + create_line(pit1->second, pit2->second, it->c1, it->c2, it->width, _actions); + // all lines with still undefined points are ignored + } + } + // line and point definitions are local to a page + _lines.clear(); + _points.clear(); +} + + +const char** EmSpecialHandler::prefixes () const { + static const char *pfx[] = {"em:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.h new file mode 100644 index 00000000000..17e84a3e6e2 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EmSpecialHandler.h @@ -0,0 +1,57 @@ +/************************************************************************* +** EmSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_EMSPECIALHANDLER_H +#define DVISVGM_EMSPECIALHANDLER_H + +#include <list> +#include <map> +#include "Pair.h" +#include "SpecialHandler.h" + + +class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener +{ + struct Line { + Line (int pp1, int pp2, char cc1, char cc2, double w) : p1(pp1), p2(pp2), c1(cc1), c2(cc2), width(w) {} + int p1, p2; ///< point numbers of line ends + char c1, c2; ///< cut type of line ends (h, v or p) + double width; ///< line width + }; + + public: + EmSpecialHandler (); + const char* name () const {return "em";} + const char* info () const {return "line drawing statements of the emTeX special set";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &in, SpecialActions *actions); + + protected: + void dviEndPage (unsigned pageno); + + private: + std::map<int, DPair> _points; ///< points defined by special em:point + std::list<Line> _lines; ///< list of lines with undefined end points + double _linewidth; ///< global line width + DPair _pos; ///< current position of "graphic cursor" + SpecialActions *_actions; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.cpp new file mode 100644 index 00000000000..103090bc3e3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.cpp @@ -0,0 +1,134 @@ +/************************************************************************* +** EncFile.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <fstream> +#include "Font.h" +#include "EncFile.h" +#include "FontMap.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "FileFinder.h" +#include "Message.h" + +using namespace std; + +static string read_entry (InputReader &in); +static bool valid_name_char (int c); + + +EncFile::EncFile (const string &encname) : _encname(encname) +{ + read(); +} + + +const char* EncFile::path () const { + return FileFinder::lookup(_encname+".enc", false); +} + + +/** Search for suitable enc-file and read its encoding information. + * The file contents must be a valid PostScript vector with 256 entries. */ +void EncFile::read () { + if (const char *p = path()) { + ifstream ifs(p); + read(ifs); + } + else + Message::wstream(true) << "encoding file '" << _encname << ".enc' not found\n"; +} + + +/** Read encoding information from stream. */ +void EncFile::read (istream &is) { + StreamInputBuffer ib(is, 256); + BufferInputReader in(ib); + _table.resize(256); + + // find beginning of vector + while (!in.eof()) { + in.skipSpace(); + if (in.peek() == '%') + in.skipUntil("\n"); + else + if (in.get() == '[') + break; + } + + // read vector entries + int n=0; + while (!in.eof()) { + in.skipSpace(); + if (in.peek() == '%') + in.skipUntil("\n"); + else if (in.peek() == ']') { + in.get(); + break; + } + else { + string entry = read_entry(in); + if (entry == ".notdef") + entry.clear(); + if (n < 256) + _table[n++] = entry; + } + } + // remove trailing .notdef names + for (n--; n > 0 && _table[n].empty(); n--); + _table.resize(n+1); +} + + +static string read_entry (InputReader &in) { + string entry; + bool accept_slashes=true; + while (!in.eof() && ((in.peek() == '/' && accept_slashes) || valid_name_char(in.peek()))) { + if (in.peek() != '/') + accept_slashes = false; + entry += in.get(); + } + if (entry.length() > 1) { + // strip leading slashes + // According to the PostScript specification, a single slash without further + // following characters is a valid name. + size_t n=0; + while (n < entry.length() && entry[n] == '/') + n++; + entry = entry.substr(n); + } + return entry; +} + + +static bool valid_name_char (int c) { + const char *delimiters = "<>(){}[]/~%"; + return isprint(c) && !isspace(c) && !strchr(delimiters, c); +} + + +/** Returns an entry of the encoding table. + * @param[in] c character code + * @return character name assigned to character code c*/ +const char* EncFile::charName (UInt32 c) const { + if (c < _table.size()) + return !_table[c].empty() ? _table[c].c_str() : 0; + return 0; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.h new file mode 100644 index 00000000000..10b21c15547 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/EncFile.h @@ -0,0 +1,50 @@ +/************************************************************************* +** EncFile.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_ENCFILE_H +#define DVISVGM_ENCFILE_H + +#include <istream> +#include <map> +#include <string> +#include <vector> +#include "FontEncoding.h" +#include "types.h" + + +class EncFile : public NamedFontEncoding +{ + public: + EncFile (const std::string &name); + void read (); + void read (std::istream &is); + int size () const {return _table.size();} + const char* name () const {return _encname.c_str();} + const char* charName (UInt32 c) const; + Character decode (UInt32 c) const {return Character(charName(c));} + bool mapsToCharIndex () const {return false;} + const char* path () const; + + private: + std::string _encname; + std::vector<std::string> _table; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.cpp new file mode 100644 index 00000000000..e8269991053 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.cpp @@ -0,0 +1,278 @@ +/************************************************************************* +** FileFinder.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> + +#ifdef MIKTEX + #include "MessageException.h" + #include "MiKTeXCom.h" + static MiKTeXCom *miktex=0; +#else + #ifdef KPSE_CXX_UNSAFE + extern "C" { + #endif + #include <kpathsea/kpathsea.h> + #ifdef KPSE_CXX_UNSAFE + } + #endif +#endif + +#include <cstdlib> +#include <fstream> +#include <map> +#include <string> +#include "FileFinder.h" +#include "FileSystem.h" +#include "FontMap.h" +#include "Message.h" +#include "Process.h" + +// --------------------------------------------------- + +static bool _initialized = false; +static bool _mktex_enabled = false; + +// --------------------------------------------------- + +static const char* find_file (const std::string &fname, const char *ftype); +static const char* find_mapped_file (std::string fname); +static const char* mktex (const std::string &fname); + + +/** Initializes the file finder. This function must be called before any other + * FileFinder function. + * @param[in] argv0 argv[0] of main() function + * @param[in] progname name of application using the FileFinder + * @param[in] enable_mktexmf if true, tfm and mf file generation is activated */ +void FileFinder::init (const char *argv0, const char *progname, bool enable_mktexmf) { + if (_initialized) + return; + + _mktex_enabled = enable_mktexmf; +#ifdef MIKTEX + miktex = new MiKTeXCom; +#else + kpse_set_program_name(argv0, progname); + // enable tfm and mf generation (actually invoked by calls of kpse_make_tex) + kpse_set_program_enabled(kpse_tfm_format, 1, kpse_src_env); + kpse_set_program_enabled(kpse_mf_format, 1, kpse_src_env); + kpse_make_tex_discard_errors = true; // suppress messages from mktexFOO tools +#ifdef TEXLIVEWIN32 + texlive_gs_init(); +#endif +#endif + _initialized = true; +} + + +/** Cleans up the FileFinder. This function must be called before leaving the + * application's main() function. */ +void FileFinder::finish () { +#ifdef MIKTEX + if (miktex) { + delete miktex; + miktex = 0; + } +#endif + _initialized = false; +} + + +/** Returns the version string of the underlying file searching library (kpathsea, MiKTeX) */ +std::string FileFinder::version () { +#ifdef MIKTEX + bool autoinit=false; + try { + if (!_initialized) { + init("", "", false); + autoinit = true; + } + std::string ret = miktex->getVersion(); + if (autoinit) + finish(); + return ret; + } + catch (MessageException &e) { + if (autoinit) + finish(); + } +#else + if (const char *v = strrchr(KPSEVERSION, ' ')) + return v+1; +#endif + return "unknown"; +} + + +/** Determines filetype by the filename extension and calls kpse_find_file + * to actually look up the file. + * @param[in] fname name of file to look up + * @param[in] ftype expected file format of file fname; if 0, it's derived from the filename suffix + * @return file path on success, 0 otherwise */ +static const char* find_file (const std::string &fname, const char *ftype) { + if (!_initialized || fname.empty()) + return 0; + + std::string ext; + if (ftype) + ext = ftype; + else { + size_t pos = fname.rfind('.'); + if (pos == std::string::npos) + return 0; // no extension and no file type => no search + ext = fname.substr(pos+1); + } + + static std::string buf; +#ifdef MIKTEX + if (ext == "dll" || ext == "exe") { + // lookup dll and exe files in the MiKTeX bin directory first + buf = miktex->getBinDir() + "/" + fname; + if (FileSystem::exists(buf.c_str())) + return buf.c_str(); + } + else if (ext == "cmap") { + // The MiKTeX SDK doesn't support the lookup of files without suffix (yet), thus + // it's not possible to find cmap files which usually don't have a suffix. In order + // to work around this, we try to lookup the files by calling kpsewhich. + Process process("kpsewhich", std::string("-format=cmap ")+fname); + process.run(&buf); + return buf.empty() ? 0 : buf.c_str(); + } + try { + return miktex->findFile(fname.c_str()); + } + catch (const MessageException &e) { + return 0; + } +#else +#ifdef TEXLIVEWIN32 + if (ext == "exe") { + // lookup exe files in directory where dvisvgm is located + if (const char *path = kpse_var_value("SELFAUTOLOC")) { + buf = std::string(path) + "/" + fname; + return FileSystem::exists(buf.c_str()) ? buf.c_str() : 0; + } + return 0; + } +#endif + static std::map<std::string, kpse_file_format_type> types; + if (types.empty()) { + types["tfm"] = kpse_tfm_format; + types["pfb"] = kpse_type1_format; + types["vf"] = kpse_vf_format; + types["mf"] = kpse_mf_format; + types["ttc"] = kpse_truetype_format; + types["ttf"] = kpse_truetype_format; + types["otf"] = kpse_opentype_format; + types["map"] = kpse_fontmap_format; + types["cmap"] = kpse_cmap_format; + types["sty"] = kpse_tex_format; + types["enc"] = kpse_enc_format; + types["pro"] = kpse_tex_ps_header_format; + types["sfd"] = kpse_sfd_format; + } + std::map<std::string, kpse_file_format_type>::iterator it = types.find(ext.c_str()); + if (it == types.end()) + return 0; + + if (char *path = kpse_find_file(fname.c_str(), it->second, 0)) { + // In the current version of libkpathsea, each call of kpse_find_file produces + // a memory leak since the path buffer is not freed. I don't think we can do + // anything against it here... + buf = path; + std::free(path); + return buf.c_str(); + } + return 0; +#endif +} + + +/** Checks whether the given file is mapped to a different name and if the + * file can be found under this name. + * @param[in] fname name of file to look up + * @return file path on success, 0 otherwise */ +static const char* find_mapped_file (std::string fname) { + size_t pos = fname.rfind('.'); + if (pos == std::string::npos) + return 0; + const std::string ext = fname.substr(pos+1); // file extension + const std::string base = fname.substr(0, pos); + if (const FontMap::Entry *entry = FontMap::instance().lookup(base)) { + const char *path=0; + if (entry->fontname.find('.') != std::string::npos) // does the mapped filename has an extension? + path = find_file(entry->fontname, 0); // look for that file + else { // otherwise, use extension of unmapped file + fname = entry->fontname + "." + ext; + (path = find_file(fname, 0)) || (path = mktex(fname)); + } + return path; + } + return 0; +} + + +/** Runs external mktexFOO tool to create missing tfm or mf file. + * @param[in] fname name of file to build + * @return file path on success, 0 otherwise */ +static const char* mktex (const std::string &fname) { + if (!_initialized) + return 0; + + size_t pos = fname.rfind('.'); + if (!_mktex_enabled || pos == std::string::npos) + return 0; + + std::string ext = fname.substr(pos+1); // file extension + if (ext != "tfm" && ext != "mf") + return 0; + + const char *path = 0; +#ifdef MIKTEX + // maketfm and makemf are located in miktex/bin which is in the search PATH + std::string toolname = (ext == "tfm" ? "miktex-maketfm" : "miktex-makemf"); + system((toolname+".exe "+fname).c_str()); + path = find_file(fname, 0); +#else + kpse_file_format_type type = (ext == "tfm" ? kpse_tfm_format : kpse_mf_format); + path = kpse_make_tex(type, fname.c_str()); +#endif + return path; +} + + +/** Searches a file in the TeX directory tree. + * If the file doesn't exist, maximal two further steps are applied + * (if "extended" is true): + * - checks whether the filename is mapped to a different name and returns + * the path to that name + * - in case of tfm or mf files: invokes the external mktextfm/mktexmf tool + * to create the missing file + * @param[in] fname name of file to look up + * @param[in] ftype type/format of file to look up + * @param[in] extended if true, use fontmap lookup and mktexFOO calls + * @return path to file on success, 0 otherwise */ +const char* FileFinder::lookup (const std::string &fname, const char *ftype, bool extended) { + const char *path; + if ((path = find_file(fname, ftype)) || (extended && ((path = find_mapped_file(fname)) || (path = mktex(fname))))) + return path; + return 0; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.h new file mode 100644 index 00000000000..5057e9b2593 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileFinder.h @@ -0,0 +1,35 @@ +/************************************************************************* +** FileFinder.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_KPSFILEFINDER_H +#define DVISVGM_KPSFILEFINDER_H + +#include <string> + +struct FileFinder +{ + static void init (const char *argv0, const char *progname, bool enable_mktexmf); + static void finish (); + static std::string version (); + static const char* lookup (const std::string &fname, const char *ftype, bool extended=true); + static const char* lookup (const std::string &fname, bool extended=true) {return lookup(fname, 0, extended);} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.cpp new file mode 100644 index 00000000000..92922d99354 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.cpp @@ -0,0 +1,258 @@ +/************************************************************************* +** FilePath.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cctype> +#include "FilePath.h" +#include "FileSystem.h" +#include "MessageException.h" +#include "macros.h" + +using namespace std; + + +/** Removes redundant slashes from a given path. */ +static string& single_slashes (string &str) { + size_t pos=0; + while ((pos = str.find("//", pos)) != string::npos) + str.replace(pos, 2, "/"); + return str; +} + + +#ifdef __WIN32__ +static char strip_drive_letter (string &path) { + char letter = 0; + if (path.length() >= 2 && path[1] == ':' && isalpha(path[0])) { + letter = tolower(path[0]); + path.erase(0, 2); + } + return letter; +} + + +static char adapt_current_path (string &path, char target_drive) { + if (char current_drive = strip_drive_letter(path)) { + if (target_drive != current_drive) { + if (target_drive == 0) + target_drive = current_drive; + if (path.empty() || path[0] != '/') { + if (FileSystem::chdir((string(1, target_drive) + ":").c_str())) { + path.insert(0, FileSystem::getcwd()+"/"); + strip_drive_letter(path); + } + else + throw MessageException("drive " + string(1, target_drive) + ": not accessible"); + } + } + } + return target_drive; +} + + +static void tolower (string &str) { + for (size_t i=0; i < str.length(); ++i) + str[i] = tolower(str[i]); +} +#endif + + +/** Constructs a FilePath object from a given path. Relative paths are + * relative to the current working directory. + * @param[in] path absolute or relative path to a file or directory */ +FilePath::FilePath (const string &path) { + init(path, !FileSystem::isDirectory(path.c_str()), FileSystem::getcwd()); +} + + +/** Constructs a FilePath object. + * @param[in] path absolute or relative path to a file or directory + * @param[in] isfile true if 'path' references a file, false if a directory is referenced + * @param[in] current_dir if 'path' is a relative path expression it will be related to 'current_dir' */ +FilePath::FilePath (const string &path, bool isfile, string current_dir) { + init(path, isfile, current_dir); +} + + +/** Initializes a FilePath object. This method should be called by the constructors only. + * @param[in] path absolute or relative path to a file or directory + * @param[in] isfile true if 'path' references a file, false if a directory is referenced + * @param[in] current_dir if 'path' is a relative path expression it will be related to 'current_dir' */ +void FilePath::init (string path, bool isfile, string current_dir) { + single_slashes(path); + single_slashes(current_dir); +#ifdef __WIN32__ + tolower(path); + path = FileSystem::adaptPathSeperators(path); + _drive = strip_drive_letter(path); +#endif + if (isfile) { + size_t pos = path.rfind('/'); + _fname = path.substr((pos == string::npos) ? 0 : pos+1); + if (pos != string::npos) + path.erase(pos); + else + path.clear(); + } + if (current_dir.empty()) + current_dir = FileSystem::getcwd(); +#ifdef __WIN32__ + tolower(current_dir); + _drive = adapt_current_path(current_dir, _drive); +#endif + if (!path.empty()) { + if (path[0] == '/') + current_dir.clear(); + else if (current_dir[0] != '/') + current_dir = "/"; + else { + FilePath curr(current_dir, false, "/"); + current_dir = curr.absolute(); +#ifdef __WIN32__ + adapt_current_path(current_dir, _drive); +#endif + } + } + path.insert(0, current_dir + "/"); + string elem; + FORALL (path, string::const_iterator, it) { + if (*it == '/') { + add(elem); + elem.clear(); + } + else + elem += *it; + } + add(elem); +} + + +/** Adds a location step to the current path. */ +void FilePath::add (const string &dir) { + if (dir == ".." && !_dirs.empty()) + _dirs.pop_back(); + else if (dir.length() > 0 && dir != ".") + _dirs.push_back(dir); +} + + +/** Returns the suffix of the filename. If FilePath represents the + * location of a directory (and not of a file) an empty string + * is returned. */ +string FilePath::suffix () const { + size_t start = 0; + // ignore leading dots + while (start < _fname.length() && _fname[start] == '.') + start++; + string sub = _fname.substr(start); + size_t pos = sub.rfind('.'); + if (pos != string::npos && pos < sub.length()-1) + return sub.substr(pos+1); + return ""; +} + + +/** Changes the suffix of the filename. If FilePath represents the + * location of a directory (and not of a file) nothing happens. + * @param[in] s new suffix */ +void FilePath::suffix (const string &s) { + if (!_fname.empty()) { + string current_suffix = suffix(); + if (!current_suffix.empty()) + _fname.erase(_fname.length()-current_suffix.length()-1); + _fname += "."+s; + } +} + + +/** Returns the filename without suffix. + * Example: FilePath("/a/b/c.def", true) == "c" */ +string FilePath::basename () const { + if (!_fname.empty()) { + size_t len = suffix().length(); + if (len > 0) + len++; // strip dot too + return _fname.substr(0, _fname.length()-len); + } + return ""; +} + + +/** Returns the absolute path string of this FilePath. + * @param[in] with_filename if false, the filename is omitted + * @return the absolute path string */ +string FilePath::absolute (bool with_filename) const { + string path; + FORALL (_dirs, ConstIterator, it) { + path += "/" + *it; + } + if (path.empty()) + path = "/"; + if (with_filename && !_fname.empty()) + path += "/"+_fname; +#ifdef __WIN32__ + if (_drive) + path.insert(0, string(1, _drive) + ":"); +#endif + return single_slashes(path); +} + + +/** Returns a path string of this FilePath relative to reldir. If we wanted to + * navigate from /a/b/c/d to /a/b/e/f using the shell command "cd", we could do that + * with the relative path argument: "cd ../../e/f". This function returns such a relative + * path. Example: FilePath("/a/b/e/f").relative("/a/b/c/d") => "../../e/f". + * @param[in] reldir absolute path to a directory + * @param[in] with_filename if false, the filename is omitted + * @return the relative path string */ +string FilePath::relative (string reldir, bool with_filename) const { + if (reldir.empty()) + reldir = FileSystem::getcwd(); +#ifdef __WIN32__ + adapt_current_path(reldir, _drive); +#endif + if (reldir[0] != '/') + return absolute(); + FilePath rel(reldir, false); + string path; +#ifdef __WIN32__ + if (rel._drive && _drive && rel._drive != _drive) + path += string(1, _drive) + ":"; +#endif + ConstIterator i = _dirs.begin(); + ConstIterator j = rel._dirs.begin(); + while (i != _dirs.end() && j != rel._dirs.end() && *i == *j) + ++i, ++j; + for (; j != rel._dirs.end(); ++j) + path += "../"; + for (; i != _dirs.end(); ++i) + path += *i + "/"; + if (!path.empty()) + path.erase(path.length()-1, 1); // remove trailing slash + if (with_filename && !_fname.empty()) { + if (!path.empty() && path != "/") + path += "/"; + path += _fname; + } + if (path.empty()) + path = "."; + return single_slashes(path); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.h new file mode 100644 index 00000000000..c1c1bab7064 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FilePath.h @@ -0,0 +1,59 @@ +/************************************************************************* +** FilePath.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FILEPATH_H +#define DVISVGM_FILEPATH_H + +#include <string> +#include <vector> + +class FilePath +{ + typedef std::vector<std::string> Directories; + typedef Directories::iterator Iterator; + typedef Directories::const_iterator ConstIterator; + public: + FilePath (const std::string &path); + FilePath (const std::string &path, bool isfile, std::string current_dir=""); + std::string absolute (bool with_filename=true) const; + std::string relative (std::string reldir="", bool with_filename=true) const; + std::string basename () const; + std::string suffix () const; + void suffix (const std::string &s); + size_t depth () const {return _dirs.size();} + bool isFile () const {return !_fname.empty();} + bool empty () const {return _dirs.empty() && _fname.empty();} + const std::string& filename () const {return _fname;} + void filename (const std::string &fname) {_fname = fname;} + + protected: + void init (std::string path, bool isfile, std::string current_dir); + void add (const std::string &elem); + + private: + Directories _dirs; + std::string _fname; +#ifdef __WIN32__ + char _drive; +#endif +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.cpp new file mode 100644 index 00000000000..e938e65a207 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.cpp @@ -0,0 +1,330 @@ +/************************************************************************* +** FileSystem.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdlib> +#include <cstring> +#include <fstream> +#include "FileSystem.h" +#include "macros.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + + +using namespace std; + +#ifdef __WIN32__ + #include <direct.h> + #include <windows.h> + const char *FileSystem::DEVNULL = "nul"; + const char FileSystem::PATHSEP = '\\'; + #define unlink _unlink +#else + #include <dirent.h> + #include <pwd.h> + #include <sys/stat.h> + #include <sys/types.h> + const char *FileSystem::DEVNULL = "/dev/null"; + const char FileSystem::PATHSEP = '/'; +#endif + + +bool FileSystem::remove (const string &fname) { + return unlink(fname.c_str()) == 0; +} + + +/** Copies a file. + * @param[in] src path of file to copy + * @param[in] dest path of target file + * @param[in] remove_src remove file 'src' if true + * @return true on success */ +bool FileSystem::copy (const string &src, const string &dest, bool remove_src) { + ifstream ifs(src.c_str(), ios::in|ios::binary); + ofstream ofs(dest.c_str(), ios::out|ios::binary); + if (ifs && ofs) { + ofs << ifs.rdbuf(); + if (!ifs.fail() && !ofs.fail() && remove_src) { + ofs.close(); + ifs.close(); + return remove(src); + } + else + return !remove_src; + } + return false; +} + + +bool FileSystem::rename (const string &oldname, const string &newname) { + return ::rename(oldname.c_str(), newname.c_str()) == 0; +} + + +UInt64 FileSystem::filesize (const string &fname) { +#ifdef __WIN32__ + // unfortunately, stat doesn't work properly under Windows + // so we have to use this freaky code + WIN32_FILE_ATTRIBUTE_DATA attr; + GetFileAttributesExA(fname.c_str(), GetFileExInfoStandard, &attr); + return (static_cast<UInt64>(attr.nFileSizeHigh) << (8*sizeof(attr.nFileSizeLow))) | attr.nFileSizeLow; +#else + struct stat attr; + return (stat(fname.c_str(), &attr) == 0) ? attr.st_size : 0; +#endif +} + + +string FileSystem::adaptPathSeperators (string path) { + for (size_t i=0; i < path.length(); i++) + if (path[i] == PATHSEP) + path[i] = '/'; + return path; +} + + +string FileSystem::getcwd () { + char buf[1024]; +#ifdef __WIN32__ + return adaptPathSeperators(_getcwd(buf, 1024)); +#else + return ::getcwd(buf, 1024); +#endif +} + + +/** Changes the work directory. + * @param[in] dir path to new work directory + * @return true on success */ +bool FileSystem::chdir (const char *dir) { + bool success = false; + if (dir) { +#ifdef __WIN32__ + success = (_chdir(dir) == 0); +#else + success = (chdir(dir) == 0); +#endif + } + return success; +} + + +/** Returns the user's home directory. */ +const char* FileSystem::userdir () { +#ifdef __WIN32__ + const char *drive=getenv("HOMEDRIVE"); + const char *path=getenv("HOMEPATH"); + if (drive && path) { + static string ret = string(drive)+path; + if (!ret.empty()) + return ret.c_str(); + } + return 0; +#else + const char *dir=getenv("HOME"); + if (!dir) { + if (const char *user=getenv("USER")) { + if (struct passwd *pw=getpwnam(user)) + dir = pw->pw_dir; + } + } + return dir; +#endif +} + + +/** Private wrapper function for mkdir: creates a single folder. + * @param[in] dir folder name + * @return true on success */ +static bool s_mkdir (const char *dir) { + bool success = true; + if (!FileSystem::exists(dir)) { +#ifdef __WIN32__ + success = (_mkdir(dir) == 0); +#else + success = (mkdir(dir, 0776) == 0); +#endif + } + return success; +} + + +static bool inline s_rmdir (const char *dir) { +#ifdef __WIN32__ + return (_rmdir(dir) == 0); +#else + return (rmdir(dir) == 0); +#endif +} + + +/** Removes leading and trailing whitespace from a string. */ +static string trim (const string &str) { + int first=0, last=str.length()-1; + while (isspace(str[first])) + first++; + while (isspace(str[last])) + last--; + return str.substr(first, last-first+1); +} + + +/** Creates a new folder relative to the current work directory. If necessary, + * the parent folders are also created. + * @param[in] dir single folder name or path to folder + * @return true if folder(s) could be created */ +bool FileSystem::mkdir (const char *dir) { + bool success = false; + if (dir) { + success = true; + const string dirstr = adaptPathSeperators(trim(dir)); + for (size_t pos=1; success && (pos = dirstr.find('/', pos)) != string::npos; pos++) + success &= s_mkdir(dirstr.substr(0, pos).c_str()); + success &= s_mkdir(dirstr.c_str()); + } + return success; +} + + +/** Removes a directory and its contents. + * @param[in] dirname path to directory + * @return true on success */ +bool FileSystem::rmdir (const char *dirname) { + bool ok = false; + if (dirname && isDirectory(dirname)) { + ok = true; +#ifdef __WIN32__ + string pattern = string(dirname) + "/*"; + WIN32_FIND_DATA data; + HANDLE h = FindFirstFile(pattern.c_str(), &data); + bool ready = (h == INVALID_HANDLE_VALUE); + while (!ready && ok) { + const char *fname = data.cFileName; + string path = string(dirname) + "/" + fname; + if (isDirectory(path.c_str())) { + if (strcmp(fname, ".") != 0 && strcmp(fname, "..") != 0) + ok = rmdir(path.c_str()) && s_rmdir(path.c_str()); + } + else if (isFile(path.c_str())) + ok = remove(path); + else + ok = false; + ready = !FindNextFile(h, &data); + } + FindClose(h); +#else + if (DIR *dir = opendir(dirname)) { + struct dirent *ent; + while ((ent = readdir(dir)) && ok) { + const char *fname = ent->d_name; + string path = string(fname) + "/" + fname; + if (isDirectory(path.c_str())) { + if (strcmp(fname, ".") != 0 && strcmp(fname, "..") != 0) + ok = rmdir(path.c_str()) && s_rmdir(path.c_str()); + } + else if (isFile(path.c_str())) + ok = remove(path); + else + ok = false; + } + closedir(dir); + } +#endif + ok = s_rmdir(dirname); + } + return ok; +} + + +/** Checks if a file or directory exits. */ +bool FileSystem::exists (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + return GetFileAttributes(fname) != INVALID_FILE_ATTRIBUTES; +#else + struct stat attr; + return stat(fname, &attr) == 0; +#endif +} + + +/** Returns true if 'fname' references a directory. */ +bool FileSystem::isDirectory (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + return GetFileAttributes(fname) & FILE_ATTRIBUTE_DIRECTORY; +#else + struct stat attr; + return stat(fname, &attr) == 0 && S_ISDIR(attr.st_mode); +#endif +} + + +/** Returns true if 'fname' references a file. */ +bool FileSystem::isFile (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + ifstream ifs(fname); + return (bool)ifs; +#else + struct stat attr; + return stat(fname, &attr) == 0 && S_ISREG(attr.st_mode); +#endif +} + + +int FileSystem::collect (const char *dirname, vector<string> &entries) { + entries.clear(); +#ifdef __WIN32__ + string pattern = string(dirname) + "/*"; + WIN32_FIND_DATA data; + HANDLE h = FindFirstFile(pattern.c_str(), &data); + bool ready = (h == INVALID_HANDLE_VALUE); + while (!ready) { + string fname = data.cFileName; + string path = string(dirname)+"/"+fname; + string typechar = isFile(path.c_str()) ? "f" : isDirectory(path.c_str()) ? "d" : "?"; + if (fname != "." && fname != "..") + entries.push_back(typechar+fname); + ready = !FindNextFile(h, &data); + } + FindClose(h); +#else + if (DIR *dir = opendir(dirname)) { + struct dirent *ent; + while ((ent = readdir(dir))) { + string fname = ent->d_name; + string path = string(dirname)+"/"+fname; + string typechar = isFile(path.c_str()) ? "f" : isDirectory(path.c_str()) ? "d" : "?"; + if (fname != "." && fname != "..") + entries.push_back(typechar+fname); + } + closedir(dir); + } +#endif + return entries.size(); +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.h new file mode 100644 index 00000000000..f60fcd0ac86 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FileSystem.h @@ -0,0 +1,48 @@ +/************************************************************************* +** FileSystem.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FILESYSTEM_H +#define DVISVGM_FILESYSTEM_H + +#include <string> +#include <vector> +#include "types.h" + +struct FileSystem +{ + static bool remove (const std::string &fname); + static bool rename (const std::string &oldname, const std::string &newname); + static bool copy (const std::string &src, const std::string &dest, bool remove_src=false); + static UInt64 filesize (const std::string &fname); + static std::string adaptPathSeperators (std::string path); + static std::string getcwd (); + static bool chdir (const char *dir); + static bool exists (const char *file); + static bool mkdir (const char *dir); + static bool rmdir (const char *fname); + static int collect (const char *dirname, std::vector<std::string> &entries); + static bool isDirectory (const char *fname); + static bool isFile (const char *fname); + static const char* userdir (); + static const char* DEVNULL; + static const char PATHSEP; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.cpp new file mode 100644 index 00000000000..a7f78e80427 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.cpp @@ -0,0 +1,668 @@ +/************************************************************************* +** Font.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdlib> +#include <iostream> +#include <fstream> +#include <sstream> +#include "CMap.h" +#include "FileFinder.h" +#include "FileSystem.h" +#include "Font.h" +#include "FontEncoding.h" +#include "FontEngine.h" +#include "GFGlyphTracer.h" +#include "Glyph.h" +#include "Message.h" +#include "MetafontWrapper.h" +#include "TFM.h" +#include "VFReader.h" +#include "SignalHandler.h" +#include "Subfont.h" +#include "SVGTree.h" +#include "macros.h" + + +using namespace std; + + +/** Returns true if 'unicode' is a valid unicode value in XML documents. + * XML version 1.0 doesn't allow various unicode character references + * ( for example). */ +static bool valid_unicode (UInt32 unicode) { + if ((unicode & 0xffff) == 0xfffe || (unicode & 0xffff) == 0xffff) + return false; + + UInt32 ranges[] = { + 0x0000, 0x0020, + 0x007f, 0x0084, + 0x0086, 0x009f, + 0x202a, 0x202e, // bidi control characters + 0xd800, 0xdfff, + 0xfdd0, 0xfdef, + }; + for (size_t i=0; i < sizeof(ranges)/sizeof(UInt32)/2; i++) + if (unicode >= ranges[2*i] && unicode <= ranges[2*i+1]) + return false; + return true; +} + + +UInt32 Font::unicode (UInt32 c) const { + // @@ this should be optimized :-) + return valid_unicode(c) ? c : 0x3400+c; +} + + +/** Returns the encoding object of this font which is asigned in a map file. + * If there's no encoding assigned, the function returns 0. */ +const FontEncoding* Font::encoding () const { + if (const FontMap::Entry *entry = fontMapEntry()) + return FontEncoding::encoding(entry->encname); + return 0; +} + + +const FontMap::Entry* Font::fontMapEntry () const { + string fontname = name(); + size_t pos = fontname.rfind('.'); + if (pos != string::npos) + fontname = fontname.substr(0, pos); // strip extension + return FontMap::instance().lookup(fontname); +} + + +/** Compute the extents of a given glyph. + * @param[in] c character code of glyph + * @param[in] vertical true if is glyph is part of vertical aligned text + * @param[out] metrics the resulting extents */ +void Font::getGlyphMetrics (int c, bool vertical, GlyphMetrics &metrics) const { + double s = scaleFactor(); + if (vertical) { // get metrics for vertical text flow? + if (verticalLayout()) { // is the font designed for vertical texts? + metrics.wl = s*charDepth(c); + metrics.wr = s*charHeight(c); + metrics.h = 0; + metrics.d = s*charWidth(c); + } + else { // rotate box by 90 degrees for alphabetic text + metrics.wl = s*charDepth(c); + metrics.wr = s*charHeight(c); + metrics.h = 0; + metrics.d = s*(charWidth(c)+italicCorr(c)); + } + } + else { + metrics.wl = 0; + metrics.wr = s*(charWidth(c)+italicCorr(c)); + metrics.h = s*charHeight(c); + metrics.d = s*charDepth(c); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////// + +TFMFont::TFMFont (string name, UInt32 cs, double ds, double ss) + : _metrics(0), _fontname(name), _checksum(cs), _dsize(ds), _ssize(ss) +{ +} + + +TFMFont::~TFMFont () { + delete _metrics; +} + + +/** Returns a font metrics object for the current font. + * @throw FontException if TFM file can't be found */ +const FontMetrics* TFMFont::getMetrics () const { + if (!_metrics) { + try { + _metrics = FontMetrics::read(_fontname.c_str()); + if (!_metrics) { + _metrics = new NullFontMetric; + Message::wstream(true) << "can't find "+_fontname+".tfm\n"; + } + } + catch (FontMetricException &e) { + _metrics = new NullFontMetric; + Message::wstream(true) << e.what() << " in " << _fontname << ".tfm\n"; + } + } + return _metrics; +} + + +double TFMFont::charWidth (int c) const { + double w = getMetrics() ? getMetrics()->getCharWidth(c) : 0; + if (style()) { + w *= style()->extend; + w += fabs(style()->slant*charHeight(c)); // slant := tan(phi) = dx/height + } + return w; +} + + +double TFMFont::italicCorr (int c) const { + double w = getMetrics() ? getMetrics()->getItalicCorr(c) : 0; + if (style()) + w *= style()->extend; + return w; +} + + +double TFMFont::charDepth (int c) const {return getMetrics() ? getMetrics()->getCharDepth(c) : 0;} +double TFMFont::charHeight (int c) const {return getMetrics() ? getMetrics()->getCharHeight(c) : 0;} + + +/** Tests if the checksum of the font matches that of the corresponding TFM file. */ +bool TFMFont::verifyChecksums () const { + if (_checksum != 0 && getMetrics() && getMetrics()->getChecksum() != 0) + return _checksum == getMetrics()->getChecksum(); + return true; +} + +////////////////////////////////////////////////////////////////////////////// + +// static class variables +bool PhysicalFont::EXACT_BBOX = false; +bool PhysicalFont::KEEP_TEMP_FILES = false; +const char *PhysicalFont::CACHE_PATH = 0; +double PhysicalFont::METAFONT_MAG = 4; +FontCache PhysicalFont::_cache; + + +Font* PhysicalFont::create (string name, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type) { + return new PhysicalFontImpl(name, 0, checksum, dsize, ssize, type); +} + + +Font* PhysicalFont::create (string name, int fontindex, UInt32 checksum, double dsize, double ssize) { + return new PhysicalFontImpl(name, fontindex, checksum, dsize, ssize, PhysicalFont::TTC); +} + + +const char* PhysicalFont::path () const { + const char *ext=0; + switch (type()) { + case OTF: ext = "otf"; break; + case PFB: ext = "pfb"; break; + case TTC: ext = "ttc"; break; + case TTF: ext = "ttf"; break; + case MF : ext = "mf"; break; + default : ext = 0; + } + if (ext) + return FileFinder::lookup(name()+"."+ext); + return FileFinder::lookup(name()); +} + + +/** Returns true if this font is CID-based. */ +bool PhysicalFont::isCIDFont () const { + if (type() == MF) + return false; + FontEngine::instance().setFont(*this); + return FontEngine::instance().isCIDFont(); +} + + +/** Retrieve the IDs of all charachter maps available in the font file. + * @param[out] charMapIDs IDs of the found character maps + * @return number of found character maps */ +int PhysicalFont::collectCharMapIDs (std::vector<CharMapID> &charMapIDs) const { + if (type() == MF) + return 0; + FontEngine::instance().setFont(*this); + return FontEngine::instance().getCharMapIDs(charMapIDs); +} + + +/** Decodes a character code used in the DVI file to the code required to + * address the correct character in the font. + * @param[in] c DVI character to decode + * @return target character code or name */ +Character PhysicalFont::decodeChar (UInt32 c) const { + if (const FontEncoding *enc = encoding()) + return enc->decode(c); + return Character(Character::CHRCODE, c); +} + + +/** Returns the number of units per EM. The EM square is the virtual area a glyph is designed on. + * All coordinates used to specify portions of the glyph are relative to the origin (0,0) at the + * lower left corner of this square, while the upper right corner is located at (m,m), where m + * is an integer value defined with the font, and returned by this function. */ +int PhysicalFont::unitsPerEm() const { + if (type() == MF) + return 1000; + FontEngine::instance().setFont(*this); + return FontEngine::instance().getUnitsPerEM(); +} + + +int PhysicalFont::hAdvance () const { + if (type() == MF) + return 0; + FontEngine::instance().setFont(*this); + return FontEngine::instance().getHAdvance(); +} + + +double PhysicalFont::hAdvance (int c) const { + if (type() == MF) + return unitsPerEm()*charWidth(c)/designSize(); + FontEngine::instance().setFont(*this); + if (const FontMap::Entry *entry = fontMapEntry()) + if (Subfont *sf = entry->subfont) + c = sf->decode(c); + return FontEngine::instance().getHAdvance(decodeChar(c)); +} + + +double PhysicalFont::vAdvance (int c) const { + if (type() == MF) + return unitsPerEm()*charWidth(c)/designSize(); + FontEngine::instance().setFont(*this); + if (const FontMap::Entry *entry = fontMapEntry()) + if (Subfont *sf = entry->subfont) + c = sf->decode(c); + return FontEngine::instance().getVAdvance(decodeChar(c)); +} + + +string PhysicalFont::glyphName (int c) const { + if (type() == MF) + return ""; + FontEngine::instance().setFont(*this); + if (const FontMap::Entry *entry = fontMapEntry()) + if (Subfont *sf = entry->subfont) + c = sf->decode(c); + return FontEngine::instance().getGlyphName(decodeChar(c)); +} + + +double PhysicalFont::scaledAscent() const { + return ascent()*scaledSize()/unitsPerEm(); +} + + +int PhysicalFont::ascent () const { + if (type() == MF) + return 0; + FontEngine::instance().setFont(*this); + return FontEngine::instance().getAscender(); +} + + +int PhysicalFont::descent () const { + if (type() == MF) + return 0; + FontEngine::instance().setFont(*this); + return FontEngine::instance().getDescender(); +} + + +/** Extracts the glyph outlines of a given character. + * @param[in] c character code of requested glyph + * @param[out] glyph path segments of the glyph outline + * @param[in] cb optional callback object for tracer class + * @return true if outline could be computed */ +bool PhysicalFont::getGlyph (int c, GraphicPath<Int32> &glyph, GFGlyphTracer::Callback *cb) const { + if (type() == MF) { + const Glyph *cached_glyph=0; + if (CACHE_PATH) { + _cache.write(CACHE_PATH); + _cache.read(name().c_str(), CACHE_PATH); + cached_glyph = _cache.getGlyph(c); + } + if (cached_glyph) { + glyph = *cached_glyph; + return true; + } + else { + string gfname; + if (createGF(gfname)) { + try { + double ds = getMetrics() ? getMetrics()->getDesignSize() : 1; + GFGlyphTracer tracer(gfname, unitsPerEm()/ds, cb); + tracer.setGlyph(glyph); + tracer.executeChar(c); + glyph.closeOpenSubPaths(); + if (CACHE_PATH) + _cache.setGlyph(c, glyph); + return true; + } + catch (GFException &e) { + // @@ print error message + } + } + else { + Message::wstream(true) << "failed creating " << name() << ".gf\n"; + } + } + } + else { // vector fonts (OTF, PFB, TTF, TTC) + bool ok=true; + FontEngine::instance().setFont(*this); + if (const FontMap::Entry *entry = fontMapEntry()) + if (Subfont *sf = entry->subfont) + c = sf->decode(c); + ok = FontEngine::instance().traceOutline(decodeChar(c), glyph, false); + glyph.closeOpenSubPaths(); + return ok; + } + return false; +} + + +/** Creates a GF file for this font object. + * @param[out] gfname name of GF font file + * @return true on success */ +bool PhysicalFont::createGF (string &gfname) const { + SignalHandler::instance().check(); + gfname = name()+".gf"; + MetafontWrapper mf(name()); + bool ok = mf.make("ljfour", METAFONT_MAG); // call Metafont if necessary + return ok && mf.success() && getMetrics(); +} + + +/** Traces all glyphs of the current font and stores them in the cache. If caching is disabled, nothing happens. + * @param[in] includeCached if true, glyphs already cached are traced again + * @param[in] cb optional callback methods called by the tracer + * @return number of glyphs traced */ +int PhysicalFont::traceAllGlyphs (bool includeCached, GFGlyphTracer::Callback *cb) const { + int count = 0; + if (type() == MF && CACHE_PATH) { + if (const FontMetrics *metrics = getMetrics()) { + int fchar = metrics->firstChar(); + int lchar = metrics->lastChar(); + string gfname; + Glyph glyph; + if (createGF(gfname)) { + _cache.read(name().c_str(), CACHE_PATH); + double ds = getMetrics() ? getMetrics()->getDesignSize() : 1; + GFGlyphTracer tracer(gfname, unitsPerEm()/ds, cb); + tracer.setGlyph(glyph); + for (int i=fchar; i <= lchar; i++) { + if (includeCached || !_cache.getGlyph(i)) { + glyph.newpath(); + tracer.executeChar(i); + glyph.closeOpenSubPaths(); + _cache.setGlyph(i, glyph); + ++count; + } + } + _cache.write(CACHE_PATH); + } + } + } + return count; +} + + +/** Computes the exact bounding box of a glyph. + * @param[in] c character code of the glyph + * @param[out] bbox the computed bounding box + * @param[in] cb optional calback object forwarded to the tracer + * @return true if the box could be computed successfully */ +bool PhysicalFont::getExactGlyphBox(int c, BoundingBox& bbox, GFGlyphTracer::Callback* cb) const { + Glyph glyph; + if (getGlyph(c, glyph, cb)) { + glyph.computeBBox(bbox); + double s = scaledSize()/unitsPerEm(); + bbox.scale(s, s); + return true; + } + return false; +} + + +bool PhysicalFont::getExactGlyphBox (int c, GlyphMetrics &metrics, bool vertical, GFGlyphTracer::Callback *cb) const { + BoundingBox charbox; + if (!getExactGlyphBox(c, charbox, cb)) + return false; + if ((metrics.wl = -charbox.minX()) < 0) metrics.wl=0; + if ((metrics.wr = charbox.maxX()) < 0) metrics.wr=0; + if ((metrics.h = charbox.maxY()) < 0) metrics.h=0; + if ((metrics.d = -charbox.minY()) < 0) metrics.d=0; + if (vertical) { // vertical text orientation + if (verticalLayout()) { // font designed for vertical layout? + metrics.wl = metrics.wr = (metrics.wl+metrics.wr)/2; + metrics.d += metrics.h; + metrics.h = 0; + } + else { + double depth = metrics.d; + metrics.d = metrics.wr; + metrics.wr = metrics.h; + metrics.h = metrics.wl; + metrics.wl = depth; + } + } + return true; +} + + +Font* VirtualFont::create (string name, UInt32 checksum, double dsize, double ssize) { + return new VirtualFontImpl(name, checksum, dsize, ssize); +} + + +////////////////////////////////////////////////////////////////////////////// + + +PhysicalFontImpl::PhysicalFontImpl (string name, int fontindex, UInt32 cs, double ds, double ss, PhysicalFont::Type type) + : TFMFont(name, cs, ds, ss), + _filetype(type), _fontIndex(fontindex), _fontMapEntry(Font::fontMapEntry()), _encodingPair(Font::encoding()), _localCharMap(0) +{ +} + + +PhysicalFontImpl::~PhysicalFontImpl () { + if (CACHE_PATH) + _cache.write(CACHE_PATH); + if (!KEEP_TEMP_FILES) + tidy(); + delete _localCharMap; +} + + +const FontEncoding* PhysicalFontImpl::encoding () const { + if (!_encodingPair.enc1()) + return 0; + return &_encodingPair; +} + + +bool PhysicalFontImpl::findAndAssignBaseFontMap () { + const FontEncoding *enc = encoding(); + if (enc && enc->mapsToCharIndex()) { + // try to find a base font map that maps from character indexes to a suitable + // target encoding supported by the font file + if (const FontEncoding *bfmap = enc->findCompatibleBaseFontMap(this, _charmapID)) + _encodingPair.assign(bfmap); + else + return false; + } + else if (type() != MF) { + FontEngine::instance().setFont(*this); + if ((_localCharMap = FontEngine::instance().createCustomToUnicodeMap()) != 0) + _charmapID = FontEngine::instance().setCustomCharMap(); + else + _charmapID = FontEngine::instance().setUnicodeCharMap(); + } + return true; +} + + +UInt32 PhysicalFontImpl::unicode (UInt32 c) const { + if (type() == MF) + return Font::unicode(c); + Character chr = decodeChar(c); + if (chr.type() == Character::NAME || chr.number() == 0) + return Font::unicode(c); + + if (_localCharMap) { + if (UInt32 mapped_char = (*_localCharMap)[chr.number()]) + return mapped_char; + // No unicode equivalent found in font file. + // Now we should look for a smart alternative but at the moment + // it's sufficient to simply choose a valid unused unicode value... + // Can we use the charcode itself as a unicode replacement? + if (!_localCharMap->valueExists(chr.number()) && valid_unicode(chr.number())) + return chr.number(); + } + if (valid_unicode(chr.number())) + return chr.number(); + return Font::unicode(chr.number()); +} + + +/** Delete all temporary font files created by Metafont. */ +void PhysicalFontImpl::tidy () const { + if (type() == MF) { + const char *ext[] = {"gf", "tfm", "log", 0}; + for (const char **p=ext; *p; ++p) { + if (FileSystem::exists((name()+"."+(*p)).c_str())) + FileSystem::remove(name()+"."+(*p)); + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +string NativeFont::uniqueName (const string &path, const FontStyle &style) { + static map<string, int> ids; + ostringstream oss; + oss << path << "b" << style.bold << "e" << style.extend << "s" << style.slant; + map<string, int>::iterator it = ids.find(oss.str()); + int id = ids.size(); + if (it == ids.end()) + ids[oss.str()] = id; + else + id = it->second; + oss.str(""); + oss << "nf" << id; + return oss.str(); +} + + +string NativeFont::name () const { + return uniqueName(path(), _style); +} + + +PhysicalFont::Type NativeFont::type () const { + if (const char *filepath = path()) { + if (const char *p =strrchr(filepath, '.')) { + string ext = p+1; + if (ext == "otf") + return PhysicalFont::OTF; + if (ext == "ttf") + return PhysicalFont::TTF; + if (ext == "pfb") + return PhysicalFont::PFB; + } + } + return PhysicalFont::UNKNOWN; +} + + +double NativeFont::charWidth (int c) const { + FontEngine::instance().setFont(*this); + int upem = FontEngine::instance().getUnitsPerEM(); + double w = upem ? (scaledSize()*FontEngine::instance().getAdvance(c)/upem*_style.extend) : 0; + w += fabs(_style.slant*charHeight(c)); + return w; +} + + +double NativeFont::charHeight (int c) const { + FontEngine::instance().setFont(*this); + int upem = FontEngine::instance().getUnitsPerEM(); + return upem ? (scaledSize()*FontEngine::instance().getAscender()/upem) : 0; +} + + +double NativeFont::charDepth (int c) const { + FontEngine::instance().setFont(*this); + int upem = FontEngine::instance().getUnitsPerEM(); + return upem ? (-scaledSize()*FontEngine::instance().getDescender()/upem) : 0; +} + + +UInt32 NativeFont::unicode (UInt32 c) const { + UInt32 ucode = decodeChar(c).number(); + return valid_unicode(ucode) ? ucode : 0x3400+ucode; +} + + +bool NativeFontImpl::findAndAssignBaseFontMap () { + FontEngine &fe = FontEngine::instance(); + fe.setFont(*this); + fe.buildCharMap(true, _toUnicodeMap); + _charmapID = fe.setUnicodeCharMap(); + return true; +} + + +Character NativeFontImpl::decodeChar (UInt32 c) const { + return Character(Character::CHRCODE, _toUnicodeMap[c]); +} + +////////////////////////////////////////////////////////////////////////////// + +VirtualFontImpl::VirtualFontImpl (string name, UInt32 cs, double ds, double ss) + : TFMFont(name, cs, ds, ss) +{ +} + + +VirtualFontImpl::~VirtualFontImpl () { + // delete dvi vectors received by VFReaderAction + for (map<UInt32, DVIVector*>::iterator i=_charDefs.begin(); i != _charDefs.end(); ++i) + delete i->second; +} + + +const char* VirtualFontImpl::path () const { + return FileFinder::lookup(name()+".vf"); +} + + +void VirtualFontImpl::assignChar (UInt32 c, DVIVector *dvi) { + if (dvi) { + if (_charDefs.find(c) == _charDefs.end()) + _charDefs[c] = dvi; + else + delete dvi; + } +} + + +const vector<UInt8>* VirtualFontImpl::getDVI (int c) const { + map<UInt32,DVIVector*>::const_iterator it = _charDefs.find(c); + return (it == _charDefs.end() ? 0 : it->second); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.h new file mode 100644 index 00000000000..bc33f630004 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Font.h @@ -0,0 +1,388 @@ +/************************************************************************* +** Font.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONT_H +#define DVISVGM_FONT_H + +#include <map> +#include <string> +#include <vector> +#include "Character.h" +#include "CharMap.h" +#include "CharMapID.h" +#include "Color.h" +#include "FontCache.h" +#include "FontEncoding.h" +#include "FontMap.h" +#include "FontMetrics.h" +#include "GFGlyphTracer.h" +#include "Glyph.h" +#include "GraphicPath.h" +#include "MessageException.h" +#include "VFActions.h" +#include "VFReader.h" +#include "types.h" +#include "CharMap.h" + + +struct FontStyle; + + +struct GlyphMetrics +{ + GlyphMetrics () : wl(0), wr(0), h(0), d(0) {} + GlyphMetrics (double wwl, double wwr, double hh, double dd) : wl(wwl), wr(wwr), h(hh), d(dd) {} + double wl, wr, h, d; +}; + + +/** Abstract base for all font classes. */ +struct Font { + virtual ~Font () {} + virtual Font* clone (double ds, double sc) const =0; + virtual const Font* uniqueFont () const =0; + virtual std::string name () const =0; + virtual double designSize () const =0; + virtual double scaledSize () const =0; + virtual double scaleFactor () const {return scaledSize()/designSize();} + virtual double charWidth (int c) const =0; + virtual double charDepth (int c) const =0; + virtual double charHeight (int c) const =0; + virtual double italicCorr (int c) const =0; + virtual const FontMetrics* getMetrics () const =0; + virtual const char* path () const =0; + virtual const FontEncoding* encoding () const; + virtual bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const =0; + virtual void getGlyphMetrics (int c, bool vertical, GlyphMetrics &metrics) const; + virtual UInt32 unicode (UInt32 c) const; + virtual void tidy () const {} + virtual bool findAndAssignBaseFontMap () {return true;} + virtual bool verticalLayout () const {return getMetrics() ? getMetrics()->verticalLayout() : false;} + virtual bool verifyChecksums () const {return true;} + virtual int fontIndex () const {return 0;} + virtual const FontStyle* style () const {return 0;} + virtual Color color () const {return Color::BLACK;} + virtual const FontMap::Entry* fontMapEntry () const; +}; + + +/** Empty font without any glyphs. Instances of this class are used + * if no physical or virtual font file can be found. + * The metric values returned by the member functions are based on cmr10. */ +struct EmptyFont : public Font +{ + public: + EmptyFont (std::string name) : _fontname(name) {} + Font* clone (double ds, double sc) const {return new EmptyFont(*this);} + const Font* uniqueFont () const {return this;} + std::string name () const {return _fontname;} + double designSize () const {return 10;} // cmr10 design size in pt + double scaledSize () const {return 10;} // cmr10 scaled size in pt + double charWidth (int c) const {return 9.164;} // width of cmr10's 'M' in pt + double charHeight (int c) const {return 6.833;} // height of cmr10's 'M' in pt + double charDepth (int c) const {return 0;} + double italicCorr (int c) const {return 0;} + const FontMetrics* getMetrics () const {return 0;} + const char* path () const {return 0;} + bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const {return false;} + + private: + std::string _fontname; +}; + + +/** Interface for all physical fonts. */ +class PhysicalFont : public virtual Font +{ + public: + enum Type {MF, OTF, PFB, TTC, TTF, UNKNOWN}; + + static Font* create (std::string name, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type); + static Font* create (std::string name, int fontindex, UInt32 checksum, double dsize, double ssize); + virtual Type type () const =0; + virtual bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const; + virtual bool getExactGlyphBox (int c, BoundingBox &bbox, GFGlyphTracer::Callback *cb=0) const; + virtual bool getExactGlyphBox (int c, GlyphMetrics &metrics, bool vertical, GFGlyphTracer::Callback *cb=0) const; + virtual bool isCIDFont () const; + virtual int hAdvance () const; + virtual double hAdvance (int c) const; + virtual double vAdvance (int c) const; + std::string glyphName (int c) const; + virtual int unitsPerEm () const; + virtual double scaledAscent () const; + virtual int ascent () const; + virtual int descent () const; + virtual int traceAllGlyphs (bool includeCached, GFGlyphTracer::Callback *cb=0) const; + virtual int collectCharMapIDs (std::vector<CharMapID> &charmapIDs) const; + virtual CharMapID getCharMapID () const =0; + virtual void setCharMapID (const CharMapID &id) {} + virtual Character decodeChar (UInt32 c) const; + const char* path () const; + + protected: + bool createGF (std::string &gfname) const; + + public: + static bool EXACT_BBOX; + static bool KEEP_TEMP_FILES; + static const char *CACHE_PATH; ///< path to cache directory (0 if caching is disabled) + static double METAFONT_MAG; ///< magnification factor for Metafont calls + + protected: + static FontCache _cache; +}; + + +/** Interface for all virtual fonts. */ +class VirtualFont : public virtual Font +{ + friend class FontManager; + public: + typedef std::vector<UInt8> DVIVector; + + public: + static Font* create (std::string name, UInt32 checksum, double dsize, double ssize); + virtual const DVIVector* getDVI (int c) const =0; + bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const {return false;} + + protected: + virtual void assignChar (UInt32 c, DVIVector *dvi) =0; +}; + + +class TFMFont : public virtual Font +{ + public: + TFMFont (std::string name, UInt32 checksum, double dsize, double ssize); + ~TFMFont (); + const FontMetrics* getMetrics () const; + std::string name () const {return _fontname;} + double designSize () const {return _dsize;} + double scaledSize () const {return _ssize;} + double charWidth (int c) const; + double charDepth (int c) const; + double charHeight (int c) const; + double italicCorr (int c) const; + bool verifyChecksums () const; + + private: + mutable FontMetrics *_metrics; + std::string _fontname; + UInt32 _checksum; ///< cheksum to be compared with TFM checksum + double _dsize; ///< design size in PS point units + double _ssize; ///< scaled size in PS point units +}; + + +class PhysicalFontProxy : public PhysicalFont +{ + friend class PhysicalFontImpl; + public: + Font* clone (double ds, double sc) const {return new PhysicalFontProxy(*this, ds, sc);} + const Font* uniqueFont () const {return _pf;} + std::string name () const {return _pf->name();} + double designSize () const {return _dsize;} + double scaledSize () const {return _ssize;} + double charWidth (int c) const {return _pf->charWidth(c);} + double charDepth (int c) const {return _pf->charDepth(c);} + double charHeight (int c) const {return _pf->charHeight(c);} + double italicCorr (int c) const {return _pf->italicCorr(c);} + const FontMetrics* getMetrics () const {return _pf->getMetrics();} + Type type () const {return _pf->type();} + UInt32 unicode (UInt32 c) const {return _pf->unicode(c);} + int fontIndex () const {return _pf->fontIndex();} + const FontStyle* style () const {return _pf->style();} + const FontMap::Entry* fontMapEntry () const {return _pf->fontMapEntry();} + const FontEncoding* encoding () const {return _pf->encoding();} + CharMapID getCharMapID () const {return _pf->getCharMapID();} + int collectCharMapIDs (std::vector<CharMapID> &charmapIDs) const {return _pf->collectCharMapIDs(charmapIDs);} + + protected: + PhysicalFontProxy (const PhysicalFont *font, double ds, double ss) : _pf(font), _dsize(ds), _ssize(ss) {} + PhysicalFontProxy (const PhysicalFontProxy &proxy, double ds, double ss) : _pf(proxy._pf), _dsize(ds), _ssize(ss) {} + + private: + const PhysicalFont *_pf; + double _dsize; ///< design size in PS point units + double _ssize; ///< scaled size in PS point units +}; + + +class PhysicalFontImpl : public PhysicalFont, public TFMFont +{ + friend class PhysicalFont; + public: + ~PhysicalFontImpl(); + Font* clone (double ds, double ss) const {return new PhysicalFontProxy(this, ds, ss);} + const Font* uniqueFont () const {return this;} + Type type () const {return _filetype;} + int fontIndex() const {return _fontIndex;} + const FontStyle* style () const {return _fontMapEntry ? &_fontMapEntry->style : 0;} + const FontMap::Entry* fontMapEntry () const {return _fontMapEntry;} + const FontEncoding* encoding () const; + UInt32 unicode (UInt32 c) const; + bool findAndAssignBaseFontMap (); + void tidy () const; + CharMapID getCharMapID () const {return _charmapID;} + + protected: + PhysicalFontImpl (std::string name, int fontindex, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type); + + private: + Type _filetype; + int _fontIndex; + const FontMap::Entry *_fontMapEntry; + FontEncodingPair _encodingPair; + CharMapID _charmapID; ///< ID of the font's charmap to use + const CharMap *_localCharMap; +}; + + +class NativeFont : public PhysicalFont +{ + public: + virtual NativeFont* clone (double ptsize, const FontStyle &style, Color color) const =0; + virtual Font* clone (double ds, double sc) const =0; + std::string name () const; + Type type () const; + UInt32 unicode (UInt32 c) const; + double designSize () const {return _ptsize;} + double scaledSize () const {return _ptsize;} + double charWidth (int c) const; + double charDepth (int c) const; + double charHeight (int c) const; + double italicCorr (int c) const {return 0;} + const FontMetrics* getMetrics () const {return 0;} + const FontStyle* style () const {return &_style;} + Color color () const {return _color;} + const FontMap::Entry* fontMapEntry () const {return 0;} + static std::string uniqueName (const std::string &path, const FontStyle &style); + + protected: + NativeFont (double ptsize, const FontStyle &style, Color color) : _ptsize(ptsize), _style(style), _color(color) {} + + private: + double _ptsize; ///< font size in PS point units + FontStyle _style; + Color _color; +}; + + +class NativeFontProxy : public NativeFont +{ + friend class NativeFontImpl; + public: + NativeFont* clone (double ptsize, const FontStyle &style, Color color) const { + return new NativeFontProxy(this, ptsize, style, color); + } + + Font* clone (double ds, double sc) const {return new NativeFontProxy(this , sc, *style(), color());} + const Font* uniqueFont () const {return _nfont;} + const char* path () const {return _nfont->path();} + Character decodeChar (UInt32 c) const {return _nfont->decodeChar(c);} + CharMapID getCharMapID () const {return _nfont->getCharMapID();} + + protected: + NativeFontProxy (const NativeFont *nfont, double ptsize, const FontStyle &style, Color color) + : NativeFont(ptsize, style, color), _nfont(nfont) {} + + private: + const NativeFont *_nfont; +}; + + +class NativeFontImpl : public NativeFont +{ + public: + NativeFontImpl (const std::string &fname, double ptsize, const FontStyle &style, Color color) + : NativeFont(ptsize, style, color), _path(fname) {} + + NativeFont* clone (double ptsize, const FontStyle &style, Color color) const { + return new NativeFontProxy(this, ptsize, style, color); + } + + Font* clone (double ds, double sc) const {return new NativeFontProxy(this , sc, *style(), color());} + const Font* uniqueFont () const {return this;} + const char* path () const {return _path.c_str();} + bool findAndAssignBaseFontMap (); + CharMapID getCharMapID () const {return _charmapID;} + Character decodeChar (UInt32 c) const; + + private: + std::string _path; + CharMap _toUnicodeMap; ///< maps from char indexes to unicode point + CharMapID _charmapID; ///< unicode charmap ID +}; + + +class VirtualFontProxy : public VirtualFont +{ + friend class VirtualFontImpl; + public: + Font* clone (double ds, double ss) const {return new VirtualFontProxy(*this, ds, ss);} + const Font* uniqueFont () const {return _vf;} + std::string name () const {return _vf->name();} + const DVIVector* getDVI (int c) const {return _vf->getDVI(c);} + double designSize () const {return _dsize;} + double scaledSize () const {return _ssize;} + double charWidth (int c) const {return _vf->charWidth(c);} + double charDepth (int c) const {return _vf->charDepth(c);} + double charHeight (int c) const {return _vf->charHeight(c);} + double italicCorr (int c) const {return _vf->italicCorr(c);} + const FontMetrics* getMetrics () const {return _vf->getMetrics();} + const char* path () const {return _vf->path();} + + protected: + VirtualFontProxy (const VirtualFont *font, double ds, double ss) : _vf(font), _dsize(ds), _ssize(ss) {} + VirtualFontProxy (const VirtualFontProxy &proxy, double ds, double ss) : _vf(proxy._vf), _dsize(ds), _ssize(ss) {} + void assignChar (UInt32 c, DVIVector *dvi) {delete dvi;} + + private: + const VirtualFont *_vf; + double _dsize; ///< design size in PS point units + double _ssize; ///< scaled size in PS point units +}; + + +class VirtualFontImpl : public VirtualFont, public TFMFont +{ + friend class VirtualFont; + public: + ~VirtualFontImpl (); + Font* clone (double ds, double ss) const {return new VirtualFontProxy(this, ds, ss);} + const Font* uniqueFont () const {return this;} + const DVIVector* getDVI (int c) const; + const char* path () const; + + protected: + VirtualFontImpl (std::string name, UInt32 checksum, double dsize, double ssize); + void assignChar (UInt32 c, DVIVector *dvi); + + private: + std::map<UInt32, DVIVector*> _charDefs; ///< dvi subroutines defining the characters +}; + + +struct FontException : public MessageException +{ + FontException (std::string msg) : MessageException(msg) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.cpp new file mode 100644 index 00000000000..e617bc9fd34 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.cpp @@ -0,0 +1,390 @@ +/************************************************************************* +** FontCache.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + + +#include <config.h> +#include <algorithm> +#include <cstring> +#include <fstream> +#include <iomanip> +#include <sstream> +#include "CRC32.h" +#include "FileSystem.h" +#include "FontCache.h" +#include "Glyph.h" +#include "Pair.h" +#include "StreamReader.h" +#include "StreamWriter.h" +#include "types.h" + +using namespace std; + +const UInt8 FontCache::FORMAT_VERSION = 5; + + +static Pair32 read_pair (int bytes, StreamReader &sr) { + Int32 x = sr.readSigned(bytes); + Int32 y = sr.readSigned(bytes); + return Pair32(x, y); +} + + +FontCache::FontCache () : _changed(false) +{ +} + + +FontCache::~FontCache () { + clear(); +} + + +/** Removes all data from the cache. This does not affect the cache files. */ +void FontCache::clear () { + _glyphs.clear(); + _fontname.clear(); +} + + +/** Assigns glyph data to a character and adds it to the cache. + * @param[in] c character code + * @param[in] glyph font glyph data */ +void FontCache::setGlyph (int c, const Glyph &glyph) { + _glyphs[c] = glyph; + _changed = true; +} + + +/** Returns the corresponding glyph data of a given character of the current font. + * @param[in] c character code + * @return font glyph data (0 if no matching data was found) */ +const Glyph* FontCache::getGlyph (int c) const { + GlyphMap::const_iterator it = _glyphs.find(c); + return (it != _glyphs.end()) ? &it->second : 0; +} + + +/** Writes the current cache data to a file (only if anything changed after + * the last call of read()). + * @param[in] fontname name of current font + * @param[in] dir directory where the cache file should go + * @return true if writing was successful */ +bool FontCache::write (const char *fontname, const char *dir) const { + if (!_changed) + return true; + + if (fontname && strlen(fontname) > 0) { + string dirstr = (dir == 0 || strlen(dir) == 0) ? FileSystem::getcwd() : dir; + ostringstream oss; + oss << dirstr << '/' << fontname << ".fgd"; + ofstream ofs(oss.str().c_str(), ios::binary); + return write(fontname, ofs); + } + return false; +} + + +bool FontCache::write (const char* dir) const { + return _fontname.empty() ? false : write(_fontname.c_str(), dir); +} + + +/** Returns the minimal number of bytes needed to store the given value. */ +static int max_int_size (Int32 value) { + Int32 limit = 0x7f; + for (int i=1; i <= 4; i++) { + if ((value < 0 && -value <= limit+1) || (value >= 0 && value <= limit)) + return i; + limit = (limit << 8) | 0xff; + } + return 4; +} + + +/** Returns the minimal number of bytes needed to store the biggest + * pair component of the given vector. */ +static int max_int_size (const Pair<Int32> *pairs, size_t n) { + int ret=0; + for (size_t i=0; i < n; i++) { + ret = max(ret, max_int_size(pairs[i].x())); + ret = max(ret, max_int_size(pairs[i].y())); + } + return ret; +} + + +/** Writes the current cache data to a stream (only if anything changed after + * the last call of read()). + * @param[in] fontname name of current font + * @param[in] os output stream + * @return true if writing was successful */ +bool FontCache::write (const char *fontname, ostream &os) const { + if (!_changed) + return true; + if (!os) + return false; + + StreamWriter sw(os); + CRC32 crc32; + + struct WriteActions : Glyph::Actions { + WriteActions (StreamWriter &sw, CRC32 &crc32) : _sw(sw), _crc32(crc32) {} + + void draw (char cmd, const Glyph::Point *points, int n) { + int bytes = max_int_size(points, n); + int cmdchar = (bytes << 5) | (cmd - 'A'); + _sw.writeUnsigned(cmdchar, 1, _crc32); + for (int i=0; i < n; i++) { + _sw.writeSigned(points[i].x(), bytes, _crc32); + _sw.writeSigned(points[i].y(), bytes, _crc32); + } + } + StreamWriter &_sw; + CRC32 &_crc32; + } actions(sw, crc32); + + sw.writeUnsigned(FORMAT_VERSION, 1, crc32); + sw.writeUnsigned(0, 4); // space for checksum + sw.writeString(fontname, crc32, true); + sw.writeUnsigned(_glyphs.size(), 4, crc32); + FORALL(_glyphs, GlyphMap::const_iterator, it) { + const Glyph &glyph = it->second; + sw.writeUnsigned(it->first, 4, crc32); + sw.writeUnsigned(glyph.size(), 2, crc32); + glyph.iterate(actions, false); + } + os.seekp(1); + sw.writeUnsigned(crc32.get(), 4); // insert CRC32 checksum + os.seekp(0, ios::end); + return true; +} + + +/** Reads font glyph information from a file. + * @param[in] fontname name of font data to read + * @param[in] dir directory where the cache files are located + * @return true if reading was successful */ +bool FontCache::read (const char *fontname, const char *dir) { + if (!fontname || strlen(fontname) == 0) + return false; + if (_fontname == fontname) + return true; + clear(); + string dirstr = (dir == 0 || strlen(dir) == 0) ? FileSystem::getcwd() : dir; + ostringstream oss; + oss << dirstr << '/' << fontname << ".fgd"; + ifstream ifs(oss.str().c_str(), ios::binary); + return read(fontname, ifs); +} + + +/** Reads font glyph information from a stream. + * @param[in] fontname name of font data to read + * @param[in] is input stream to read the glyph data from + * @return true if reading was successful */ +bool FontCache::read (const char *fontname, istream &is) { + if (_fontname == fontname) + return true; + clear(); + _fontname = fontname; + if (!is) + return false; + + StreamReader sr(is); + CRC32 crc32; + if (sr.readUnsigned(1, crc32) != FORMAT_VERSION) + return false; + + UInt32 crc32_cmp = sr.readUnsigned(4); + crc32.update(is); + if (crc32.get() != crc32_cmp) + return false; + + is.clear(); + is.seekg(5); // continue reading after checksum + + string fname = sr.readString(); + if (fname != fontname) + return false; + + UInt32 num_glyphs = sr.readUnsigned(4); + while (num_glyphs-- > 0) { + UInt32 c = sr.readUnsigned(4); // character code + UInt16 s = sr.readUnsigned(2); // number of path commands + Glyph &glyph = _glyphs[c]; + while (s-- > 0) { + UInt8 cmdval = sr.readUnsigned(1); + UInt8 cmdchar = (cmdval & 0x1f) + 'A'; + int bytes = cmdval >> 5; + switch (cmdchar) { + case 'C': { + Pair32 p1 = read_pair(bytes, sr); + Pair32 p2 = read_pair(bytes, sr); + Pair32 p3 = read_pair(bytes, sr); + glyph.cubicto(p1, p2, p3); + break; + } + case 'L': + glyph.lineto(read_pair(bytes, sr)); + break; + case 'M': + glyph.moveto(read_pair(bytes, sr)); + break; + case 'Q': { + Pair32 p1 = read_pair(bytes, sr); + Pair32 p2 = read_pair(bytes, sr); + glyph.conicto(p1, p2); + break; + } + case 'Z': + glyph.closepath(); + } + } + } + _changed = false; + return true; +} + + +/** Collects font cache information. + * @param[in] dirname path to font cache directory + * @param[out] infos the collected font information + * @param[out] invalid names of outdated/corrupted cache files + * @return true on success */ +bool FontCache::fontinfo (const char *dirname, vector<FontInfo> &infos, vector<string> &invalid) { + infos.clear(); + invalid.clear(); + if (dirname) { + vector<string> fnames; + FileSystem::collect(dirname, fnames); + FORALL(fnames, vector<string>::iterator, it) { + if ((*it)[0] == 'f' && it->length() > 5 && it->substr(it->length()-4) == ".fgd") { + FontInfo info; + string path = string(dirname)+"/"+(it->substr(1)); + ifstream ifs(path.c_str(), ios::binary); + if (fontinfo(ifs, info)) + infos.push_back(info); + else + invalid.push_back(it->substr(1)); + } + } + } + return !infos.empty(); +} + + +/** Collects font cache information of a single font. + * @param[in] is input stream of the cache file + * @param[out] info the collected data + * @return true if data could be read, false if cache file is unavailable, outdated, or corrupted */ +bool FontCache::fontinfo (std::istream &is, FontInfo &info) { + info.name.clear(); + info.numchars = info.numbytes = info.numcmds = 0; + if (is) { + is.clear(); + is.seekg(0); + try { + StreamReader sr(is); + CRC32 crc32; + if ((info.version = sr.readUnsigned(1, crc32)) != FORMAT_VERSION) + return false; + + info.checksum = sr.readUnsigned(4); + crc32.update(is); + if (crc32.get() != info.checksum) + return false; + + is.clear(); + is.seekg(5); // continue reading after checksum + + info.name = sr.readString(); + info.numchars = sr.readUnsigned(4); + for (UInt32 i=0; i < info.numchars; i++) { + sr.readUnsigned(4); // character code + UInt16 s = sr.readUnsigned(2); // number of path commands + while (s-- > 0) { + UInt8 cmdval = sr.readUnsigned(1); + UInt8 cmdchar = (cmdval & 0x1f) + 'A'; + int bytes = cmdval >> 5; + int bc = 0; + switch (cmdchar) { + case 'C': bc = 6*bytes; break; + case 'H': + case 'L': + case 'M': + case 'T': + case 'V': bc = 2*bytes; break; + case 'Q': + case 'S': bc = 4*bytes; break; + case 'Z': break; + default : return false; + } + info.numbytes += bc+1; // command length + command + info.numcmds++; + is.seekg(bc, ios_base::cur); + } + info.numbytes += 6; // number of path commands + char code + } + info.numbytes += 6+info.name.length(); // version + 0-byte + fontname + number of chars + } + catch (StreamReaderException &e) { + return false; + } + } + return true; +} + + +/** Collects font cache information and write it to a stream. + * @param[in] dirname path to font cache directory + * @param[in] os output is written to this stream + * @param[in] purge if true, outdated and corrupted cache files are removed */ +void FontCache::fontinfo (const char *dirname, ostream &os, bool purge) { + if (dirname) { + ios::fmtflags osflags(os.flags()); + vector<FontInfo> infos; + vector<string> invalid_files; + if (fontinfo(dirname, infos, invalid_files)) { + os << "cache format version " << infos[0].version << endl; + typedef map<string,FontInfo*> SortMap; + SortMap sortmap; + FORALL(infos, vector<FontInfo>::iterator, it) + sortmap[it->name] = &(*it); + + FORALL(sortmap, SortMap::iterator, it) { + os << dec << setfill(' ') << left + << setw(10) << left << it->second->name + << setw(5) << right << it->second->numchars << " glyph" << (it->second->numchars == 1 ? ' ':'s') + << setw(10) << right << it->second->numcmds << " cmd" << (it->second->numcmds == 1 ? ' ':'s') + << setw(12) << right << it->second->numbytes << " byte" << (it->second->numbytes == 1 ? ' ':'s') + << setw(6) << "crc:" << setw(8) << hex << right << setfill('0') << it->second->checksum + << endl; + } + } + else + os << "cache is empty\n"; + FORALL(invalid_files, vector<string>::iterator, it) { + string path=string(dirname)+"/"+(*it); + if (FileSystem::remove(path)) + os << "invalid cache file " << (*it) << " removed\n"; + } + os.flags(osflags); // restore format flags + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.h new file mode 100644 index 00000000000..c6c868edf49 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontCache.h @@ -0,0 +1,70 @@ +/************************************************************************* +** FontCache.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTCACHE_H +#define DVISVGM_FONTCACHE_H + +#include <iostream> +#include <string> +#include <map> +#include "types.h" +#include "Glyph.h" + + +class FontCache +{ + typedef std::map<int, Glyph> GlyphMap; + + public: + struct FontInfo + { + std::string name; // fontname + UInt16 version; // file format version + UInt32 checksum; // CRC32 checksum of file data + UInt32 numchars; // number of characters + UInt32 numbytes; // number of bytes + UInt32 numcmds; // number of path commands + }; + + public: + FontCache (); + ~FontCache (); + bool read (const char *fontname, const char *dir); + bool read (const char *fontname, std::istream &is); + bool write (const char *dir) const; + bool write (const char *fontname, const char *dir) const; + bool write (const char *fontname, std::ostream &os) const; + const Glyph* getGlyph (int c) const; + void setGlyph (int c, const Glyph &glyph); + void clear (); + const std::string& fontname () const {return _fontname;} + + static bool fontinfo (const char *dirname, std::vector<FontInfo> &infos, std::vector<std::string> &invalid); + static bool fontinfo (std::istream &is, FontInfo &info); + static void fontinfo (const char *dirname, std::ostream &os, bool purge=false); + + private: + static const UInt8 FORMAT_VERSION; + std::string _fontname; + GlyphMap _glyphs; + bool _changed; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.cpp new file mode 100644 index 00000000000..dfa5b6c750e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.cpp @@ -0,0 +1,98 @@ +/************************************************************************* +** FontEncoding.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "CMap.h" +#include "CMapManager.h" +#include "EncFile.h" +#include "FileFinder.h" +#include "FontEncoding.h" + +using namespace std; + + +struct EncodingMap : public map<string, EncFile*> +{ + ~EncodingMap () { + for (EncodingMap::iterator it=begin(); it != end(); ++it) + delete it->second; + } +}; + + +/** Returns the encoding object for a given encoding name. + * @param[in] encname name of the encoding to lookup + * @return pointer to encoding object, or 0 if there is no encoding defined */ +FontEncoding* FontEncoding::encoding (const string &encname) { + if (encname.empty()) + return 0; + // initially, try to find an .enc file with the given name + static EncodingMap encmap; + EncodingMap::const_iterator it = encmap.find(encname); + if (it != encmap.end()) + return it->second; + if (FileFinder::lookup(encname + ".enc", false)) { + EncFile *enc = new EncFile(encname); + encmap[encname] = enc; + return enc; + } + // no .enc file found => try to find a CMap + if (CMap *cmap = CMapManager::instance().lookup(encname)) + return cmap; + return 0; +} + +///////////////////////////////////////////////////////////////////////// + +Character FontEncodingPair::decode (UInt32 c) const { + if (_enc1) { + Character chr = _enc1->decode(c); + if (_enc2 && chr.type() != Character::NAME) + chr = _enc2->decode(chr.number()); + return chr; + } + return Character(Character::INDEX, 0); +} + + +bool FontEncodingPair::mapsToCharIndex () const { + if (_enc2) + return _enc2->mapsToCharIndex(); + if (_enc1) + return _enc1->mapsToCharIndex(); + return false; +} + + +const FontEncoding* FontEncodingPair::findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const { + if (_enc2) + return _enc2->findCompatibleBaseFontMap(font, charmapID); + if (_enc1) + return _enc1->findCompatibleBaseFontMap(font, charmapID); + return 0; +} + + +void FontEncodingPair::assign (const FontEncoding *enc) { + if (!_enc1) + _enc1 = enc; + else + _enc2 = enc; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.h new file mode 100644 index 00000000000..4c366182632 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEncoding.h @@ -0,0 +1,65 @@ +/************************************************************************* +** FontEncoding.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTENCODING_H +#define DVISVGM_FONTENCODING_H + +#include <string> +#include "Character.h" +#include "types.h" + + +struct CharMapID; +class PhysicalFont; + +struct FontEncoding +{ + virtual ~FontEncoding () {} + virtual Character decode (UInt32 c) const =0; + virtual bool mapsToCharIndex () const =0; + virtual const FontEncoding* findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const {return 0;} + static FontEncoding* encoding (const std::string &encname); +}; + + +struct NamedFontEncoding : public FontEncoding +{ + virtual const char* name () const =0; + virtual const char* path () const =0; +}; + + +class FontEncodingPair : public FontEncoding +{ + public: + FontEncodingPair (const FontEncoding *enc1) : _enc1(enc1), _enc2(0) {} + FontEncodingPair (const FontEncoding *enc1, const FontEncoding *enc2) : _enc1(enc1), _enc2(enc2) {} + Character decode (UInt32 c) const; + bool mapsToCharIndex () const; + const FontEncoding* findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const; + const FontEncoding* enc1 () const {return _enc1;} + const FontEncoding* enc2 () const {return _enc2;} + void assign (const FontEncoding *enc); + + private: + const FontEncoding *_enc1, *_enc2; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.cpp new file mode 100644 index 00000000000..5bfeba236d2 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.cpp @@ -0,0 +1,426 @@ +/************************************************************************* +** FontEngine.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <iostream> +#include <sstream> +#include <ft2build.h> +#include FT_ADVANCES_H +#include FT_GLYPH_H +#include FT_OUTLINE_H +#include FT_TRUETYPE_TABLES_H +#include FT_TYPES_H +#include "Font.h" +#include "FontEngine.h" +#include "FontStyle.h" +#include "Message.h" + +using namespace std; + + +/** Converts a floating point value to a 16.16 fixed point value. */ +static inline FT_Fixed to_16dot16 (double val) { + return static_cast<FT_Fixed>(val*65536.0 + 0.5); +} + +/** Converts an integer to a 16.16 fixed point value. */ +static inline FT_Fixed to_16dot16 (int val) { + return static_cast<FT_Fixed>(val) << 16; +} + + +static inline double conv_16dot16_to_double (FT_Fixed fixed) { + return static_cast<double>(fixed)/(1 << 16); +} + + +/** Converts a floating point value to a 26.6 fixed point value. */ +static inline FT_F26Dot6 to_26dot6 (double val) { + return static_cast<FT_F26Dot6>(val*64.0 + 0.5); +} + +/** Converts an integer to a 26.6 fixed point value. */ +static inline FT_F26Dot6 to_26dot6 (int val) { + return static_cast<FT_F26Dot6>(val) << 6; +} + + +/////////////////////////////////////////////////////////////////////////// + + +FontEngine::FontEngine () : _currentFace(0), _currentFont(0) +{ + _currentChar = _currentGlyphIndex = 0; + _horDeviceRes = _vertDeviceRes = 300; + if (FT_Init_FreeType(&_library)) + Message::estream(true) << "FontEngine: error initializing FreeType library\n"; +} + + +FontEngine::~FontEngine () { + if (_currentFace && FT_Done_Face(_currentFace)) + Message::estream(true) << "FontEngine: error removing glyph\n"; + if (FT_Done_FreeType(_library)) + Message::estream(true) << "FontEngine: error removing FreeType library\n"; +} + + +/** Returns the singleton instance of this class. */ +FontEngine& FontEngine::instance () { + static FontEngine engine; + return engine; +} + + +string FontEngine::version () { + FT_Int major, minor, patch; + FT_Library &lib = instance()._library; + FT_Library_Version(lib, &major, &minor, &patch); + ostringstream oss; + oss << major << '.' << minor << '.' << patch; + return oss.str(); +} + + +void FontEngine::setDeviceResolution (int x, int y) { + _horDeviceRes = x; + _vertDeviceRes = y; +} + + +/** Sets the font to be used. + * @param[in] fname path to font file + * @param[in] fontindex index of font in font collection (multi-font files, like TTC) + * @return true on success */ +bool FontEngine::setFont (const string &fname, int fontindex, const CharMapID &charMapID) { + if (FT_New_Face(_library, fname.c_str(), fontindex, &_currentFace)) { + Message::estream(true) << "FontEngine: error reading file " << fname << '\n'; + return false; + } + if (charMapID.valid()) + setCharMap(charMapID); + return true; +} + + +bool FontEngine::setFont (const Font &font) { + if (!_currentFont || _currentFont->name() != font.name()) { + const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(&font); + _currentFont = &font; + return setFont(font.path(), font.fontIndex(), pf ? pf->getCharMapID() : CharMapID()); + } + return true; +} + + +bool FontEngine::isCIDFont() const { + FT_Bool cid_keyed; + return FT_Get_CID_Is_Internally_CID_Keyed(_currentFace, &cid_keyed) == 0 && cid_keyed; +} + + +bool FontEngine::setCharMap (const CharMapID &charMapID) { + for (int i=0; i < _currentFace->num_charmaps; i++) { + FT_CharMap ft_cmap = _currentFace->charmaps[i]; + if (ft_cmap->platform_id == charMapID.platform_id && ft_cmap->encoding_id == charMapID.encoding_id) { + FT_Set_Charmap(_currentFace, ft_cmap); + return true; + } + } + return false; +} + + +/** Returns a character map that maps from character codes of the current + * encoding to character indexes, or vice versa. + * @param[in] invert if true, the resulting charmap maps from char indexes to char codes + * @param[out] charmap the resultig charmap */ +void FontEngine::buildCharMap (bool invert, CharMap &charmap) { + charmap.clear(); + FT_UInt glyph_index; + UInt32 charcode = FT_Get_First_Char(_currentFace, &glyph_index); + while (glyph_index) { + if (invert) + charmap.append(glyph_index, charcode); + else + charmap.append(charcode, glyph_index); + charcode = FT_Get_Next_Char(_currentFace, charcode, &glyph_index); + } + charmap.sort(); +} + + +/** Creates a charmap that maps from the custom character encoding to unicode. + * @return pointer to charmap if is could be created, 0 otherwise */ +const CharMap* FontEngine::createCustomToUnicodeMap () { + FT_CharMap ftcharmap = _currentFace->charmap; + if (FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) != 0) + return 0; + CharMap index_to_source_chrcode; + buildCharMap(true, index_to_source_chrcode); + if (FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) != 0) + return 0; + CharMap *charmap = new CharMap; + FT_UInt glyph_index; + UInt32 charcode = FT_Get_First_Char(_currentFace, &glyph_index); + while (glyph_index) { + charmap->append(index_to_source_chrcode[glyph_index], charcode); + charcode = FT_Get_Next_Char(_currentFace, charcode, &glyph_index); + } + charmap->sort(); + FT_Set_Charmap(_currentFace, ftcharmap); + return charmap; +} + + +const char* FontEngine::getFamilyName () const { + return _currentFace ? _currentFace->family_name : 0; +} + + +const char* FontEngine::getStyleName () const { + return _currentFace ? _currentFace->style_name : 0; +} + + +int FontEngine::getUnitsPerEM () const { + return _currentFace ? _currentFace->units_per_EM : 0; +} + + +/** Returns the ascender of the current font in font units. */ +int FontEngine::getAscender () const { + return _currentFace ? _currentFace->ascender : 0; +} + + +/** Returns the descender of the current font in font units. */ +int FontEngine::getDescender () const { + return _currentFace ? _currentFace->descender : 0; +} + + +int FontEngine::getAdvance (int c) const { + if (_currentFace) { + FT_Fixed adv=0; + FT_Get_Advance(_currentFace, c, FT_LOAD_NO_SCALE, &adv); + return adv; + } + return 0; +} + + +int FontEngine::getHAdvance () const { + if (_currentFace) { + TT_OS2 *table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2)); + return table ? table->xAvgCharWidth : 0; + } + return 0; +} + + +int FontEngine::getHAdvance (const Character &c) const { + if (_currentFace) { + FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); + return _currentFace->glyph->metrics.horiAdvance; + } + return 0; +} + + +int FontEngine::getVAdvance (const Character &c) const { + if (_currentFace) { + FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); + if (FT_HAS_VERTICAL(_currentFace)) + return _currentFace->glyph->metrics.vertAdvance; + return _currentFace->glyph->metrics.horiAdvance; + } + return 0; +} + + +int FontEngine::charIndex (const Character &c) const { + switch (c.type()) { + case Character::CHRCODE: + return FT_Get_Char_Index(_currentFace, (FT_ULong)c.number()); + case Character::NAME: + return FT_Get_Name_Index(_currentFace, (FT_String*)c.name()); + default: + return c.number(); + } +} + + +/** Get first available character of the current font face. */ +int FontEngine::getFirstChar () const { + if (_currentFace) + return _currentChar = FT_Get_First_Char(_currentFace, &_currentGlyphIndex); + return 0; +} + + +/** Get the next available character of the current font face. */ +int FontEngine::getNextChar () const { + if (_currentFace && _currentGlyphIndex) + return _currentChar = FT_Get_Next_Char(_currentFace, _currentChar, &_currentGlyphIndex); + return getFirstChar(); +} + + +/** Returns the glyph name for a given charater code. + * @param[in] c char code + * @return glyph name */ +string FontEngine::getGlyphName (const Character &c) const { + if (c.type() == Character::NAME) + return c.name(); + + if (_currentFace && FT_HAS_GLYPH_NAMES(_currentFace)) { + char buf[256]; + FT_Get_Glyph_Name(_currentFace, charIndex(c), buf, 256); + return string(buf); + } + return ""; +} + + +vector<int> FontEngine::getPanose () const { + vector<int> panose(10); + if (_currentFace) { + TT_OS2 *table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2)); + if (table) + for (int i=0; i < 10; i++) + panose[i] = table->panose[i]; + } + return panose; +} + + +int FontEngine::getCharMapIDs (vector<CharMapID> &charmapIDs) const { + charmapIDs.clear(); + if (_currentFace) { + for (int i=0; i < _currentFace->num_charmaps; i++) { + FT_CharMap charmap = _currentFace->charmaps[i]; + charmapIDs.push_back(CharMapID(charmap->platform_id, charmap->encoding_id)); + } + } + return charmapIDs.size(); +} + + +CharMapID FontEngine::setUnicodeCharMap () { + if (_currentFace && FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) == 0) + return CharMapID(_currentFace->charmap->platform_id, _currentFace->charmap->encoding_id); + return CharMapID(); +} + + +CharMapID FontEngine::setCustomCharMap () { + if (_currentFace && FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) == 0) + return CharMapID(_currentFace->charmap->platform_id, _currentFace->charmap->encoding_id); + return CharMapID(); +} + + +// handle API change in freetype version 2.2.1 +#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && (FREETYPE_MINOR > 2 || (FREETYPE_MINOR == 2 && FREETYPE_PATCH >= 1))) + typedef const FT_Vector *FTVectorPtr; +#else + typedef FT_Vector *FTVectorPtr; +#endif + + +// Callback functions used by trace_outline/FT_Outline_Decompose +static int moveto (FTVectorPtr to, void *user) { + Glyph *glyph = static_cast<Glyph*>(user); + glyph->moveto(to->x, to->y); + return 0; +} + + +static int lineto (FTVectorPtr to, void *user) { + Glyph *glyph = static_cast<Glyph*>(user); + glyph->lineto(to->x, to->y); + return 0; +} + + +static int conicto (FTVectorPtr control, FTVectorPtr to, void *user) { + Glyph *glyph = static_cast<Glyph*>(user); + glyph->conicto(control->x, control->y, to->x, to->y); + return 0; +} + + +static int cubicto (FTVectorPtr control1, FTVectorPtr control2, FTVectorPtr to, void *user) { + Glyph *glyph = static_cast<Glyph*>(user); + glyph->cubicto(control1->x, control1->y, control2->x, control2->y, to->x, to->y); + return 0; +} + + +/** Traces the outline of a glyph by calling the corresponding "drawing" functions. + * Each glyph is composed of straight lines, quadratic (conic) or cubic B�zier curves. + * This function creates a Glyph object representing these graphics segments. + * @param[in] face FreeType object representing the font to scan + * @param[in] font corresponding Font object providing additional data + * @param[in] index index of the glyph to be traced + * @param[out] glyph resulting Glyph object containing the graphics segments + * @param[in] scale if true the current pt size will be considered otherwise the plain TrueType units are used. + * @return false on errors */ +static bool trace_outline (FT_Face face, const Font *font, int index, Glyph &glyph, bool scale) { + if (face) { + if (FT_Load_Glyph(face, index, scale ? FT_LOAD_DEFAULT : FT_LOAD_NO_SCALE)) { + Message::estream(true) << "can't load glyph " << int(index) << '\n'; + return false; + } + if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) { + Message::estream(true) << "no outlines found in glyph " << int(index) << '\n'; + return false; + } + FT_Outline outline = face->glyph->outline; + // apply style parameters if set + if (const FontStyle *style = font->style()) { + FT_Matrix matrix = {to_16dot16(style->extend), to_16dot16(style->slant), 0, to_16dot16(1)}; + FT_Outline_Transform(&outline, &matrix); + if (style->bold != 0) + FT_Outline_Embolden(&outline, style->bold/font->scaledSize()*face->units_per_EM); + } + const FT_Outline_Funcs funcs = {moveto, lineto, conicto, cubicto, 0, 0}; + FT_Outline_Decompose(&outline, &funcs, &glyph); + return true; + } + Message::wstream(true) << "FontEngine: can't trace outline, no font face selected\n"; + return false; +} + + +/** Traces the outline of a glyph by calling the corresponding "drawing" functions. + * Each glyph is composed of straight lines, quadratic (conic) or cubic B�zier curves. + * This function creates a Glyph object representing these graphics segments. + * @param[in] c the glyph of this character will be traced + * @param[out] glyph resulting Glyph object containing the graphics segments + * @param[in] scale if true the current pt size will be considered otherwise the plain TrueType units are used. + * @return false on errors */ +bool FontEngine::traceOutline (const Character &c, Glyph &glyph, bool scale) const { + if (_currentFace) + return trace_outline(_currentFace, _currentFont, charIndex(c), glyph, scale); + Message::wstream(true) << "FontEngine: can't trace outline, no font face selected\n"; + return false; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.h new file mode 100644 index 00000000000..353613a40ef --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontEngine.h @@ -0,0 +1,84 @@ +/************************************************************************* +** FontEngine.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTENGINE_H +#define DVISVGM_FONTENGINE_H + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_CID_H +#include <map> +#include <string> +#include <vector> +#include "Character.h" +#include "CharMap.h" +#include "CharMapID.h" +#include "Font.h" +#include "Glyph.h" +#include "types.h" + + +/** This class provides methods to handle font files and font data. + * It's a wrapper for the Freetype font library. */ +class FontEngine +{ + public: + ~FontEngine (); + static FontEngine& instance (); + static std::string version (); + void setDeviceResolution (int x, int y); + bool setFont (const Font &font); + bool isCIDFont() const; + bool traceOutline (const Character &c, Glyph &glyph, bool scale=true) const; + const char* getFamilyName () const; + const char* getStyleName () const; + int getUnitsPerEM () const; + int getAscender () const; + int getDescender () const; + int getAdvance (int c) const; + int getHAdvance () const; + int getHAdvance (const Character &c) const; + int getVAdvance (const Character &c) const; + int getFirstChar () const; + int getNextChar () const; + int getCharMapIDs (std::vector<CharMapID> &charmapIDs) const; + CharMapID setUnicodeCharMap (); + CharMapID setCustomCharMap (); + std::vector<int> getPanose () const; + std::string getGlyphName (const Character &c) const; + int getCharByGlyphName (const char *name) const; + bool setCharMap (const CharMapID &charMapID); + void buildCharMap (bool invert, CharMap &charmap); + const CharMap* createCustomToUnicodeMap (); + + protected: + FontEngine (); + bool setFont (const std::string &fname, int fontindex, const CharMapID &charmapID); + int charIndex (const Character &c) const; + + private: + int _horDeviceRes, _vertDeviceRes; + mutable unsigned int _currentChar, _currentGlyphIndex; + FT_Face _currentFace; + FT_Library _library; + const Font *_currentFont; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.cpp new file mode 100644 index 00000000000..7db9bad13bb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.cpp @@ -0,0 +1,344 @@ +/************************************************************************* +** FontManager.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <cstdlib> +#include <fstream> +#include <set> +#include "CMap.h" +#include "Font.h" +#include "FontManager.h" +#include "FontMap.h" +#include "FileFinder.h" +#include "FileSystem.h" +#include "Message.h" +#include "macros.h" +#include "CMapManager.h" + +using namespace std; + + +FontManager::~FontManager () { + FORALL(_fonts, vector<Font*>::iterator, i) + delete *i; +} + + +/** Returns the singleton instance */ +FontManager& FontManager::instance () { + static FontManager fm; + return fm; +} + + +/** Returns a unique ID that identifies the font. + * @param[in] n local font number, as used in DVI and VF files + * @return non-negative font ID if font was found, -1 otherwise */ +int FontManager::fontID (int n) const { + if (_vfStack.empty()) { + Num2IdMap::const_iterator it = _num2id.find(n); + return (it == _num2id.end()) ? -1 : it->second; + } + VfNum2IdMap::const_iterator vit = _vfnum2id.find(_vfStack.top()); + if (vit == _vfnum2id.end()) + return -1; + const Num2IdMap &num2id = vit->second; + Num2IdMap::const_iterator it = num2id.find(n); + return (it == num2id.end()) ? -1 : it->second; +} + + +/** Returns a unique ID that identifies the font. Not the font object but the + * font pointer is looked up to get the ID. Thus, two different pointers + * referencing different objects of the same font are mapped to different IDs. + * @param[in] font pointer to font object to be identified + * @return non-negative font ID if font was found, -1 otherwise */ +int FontManager::fontID (const Font *font) const { + for (size_t i=0; i < _fonts.size(); i++) + if (_fonts[i] == font) + return i; + return -1; +} + + +/** Returns a unique ID that identifies the font. + * @param[in] name name of font to be identified, e.g. cmr10 + * @return non-negative font ID if font was found, -1 otherwise */ +int FontManager::fontID (const string &name) const { + map<string,int>::const_iterator it = _name2id.find(name); + if (it == _name2id.end()) + return -1; + return it->second; +} + + +int FontManager::fontnum (int id) const { + if (id < 0 || size_t(id) > _fonts.size()) + return -1; + if (_vfStack.empty()) { + FORALL(_num2id, Num2IdMap::const_iterator, i) + if (i->second == id) + return i->first; + } + else { + VfNum2IdMap::const_iterator it = _vfnum2id.find(_vfStack.top()); + if (it == _vfnum2id.end()) + return -1; + const Num2IdMap &num2id = it->second; + FORALL(num2id, Num2IdMap::const_iterator, i) + if (i->second == id) + return i->first; + } + return -1; +} + + +int FontManager::vfFirstFontNum (VirtualFont *vf) const { + VfFirstFontMap::const_iterator it = _vfFirstFontMap.find(vf); + return (it == _vfFirstFontMap.end()) ? -1 : (int) it->second; +} + + +/** Returns a previously registered font. + * @param[in] n local font number, as used in DVI and VF files + * @return pointer to font if font was found, 0 otherwise */ +Font* FontManager::getFont (int n) const { + int id = fontID(n); + return (id < 0) ? 0 : _fonts[id]; +} + + +Font* FontManager::getFont (const string &name) const { + int id = fontID(name); + if (id < 0) + return 0; + return _fonts[id]; +} + + +Font* FontManager::getFontById (int id) const { + if (id < 0 || size_t(id) >= _fonts.size()) + return 0; + return _fonts[id]; +} + + +/** Returns the current active virtual font. */ +VirtualFont* FontManager::getVF () const { + return _vfStack.empty() ? 0 : _vfStack.top(); +} + + +static Font* create_font (const string &filename, const string &fontname, int fontindex, UInt32 checksum, double dsize, double ssize) { + string ext; + if (const char *dot = strrchr(filename.c_str(), '.')) + ext = dot+1; + if (!ext.empty() && FileFinder::lookup(filename)) { + if (ext == "pfb") + return PhysicalFont::create(fontname, checksum, dsize, ssize, PhysicalFont::PFB); + if (ext == "otf") + return PhysicalFont::create(fontname, checksum, dsize, ssize, PhysicalFont::OTF); + if (ext == "ttf") + return PhysicalFont::create(fontname, checksum, dsize, ssize, PhysicalFont::TTF); + if (ext == "ttc") + return PhysicalFont::create(fontname, fontindex, checksum, dsize, ssize); + if (ext == "vf") + return VirtualFont::create(fontname, checksum, dsize, ssize); + if (ext == "mf") + return PhysicalFont::create(fontname, checksum, dsize, ssize, PhysicalFont::MF); + } + return 0; +} + + +/** Registers a new font to be managed by the FontManager. If there is + * already a registered font assigned to number n, nothing happens. + * @param[in] fontnum local font number, as used in DVI and VF files + * @param[in] name TFM fontname given in DVI file, e.g. cmr10 + * @param[in] checksum checksum to be compared with TFM checksum + * @param[in] dsize design size in PS point units + * @param[in] ssize scaled size in PS point units + * @return id of registered font */ +int FontManager::registerFont (UInt32 fontnum, string name, UInt32 checksum, double dsize, double ssize) { + int id = fontID(fontnum); + if (id >= 0) + return id; + + Font *newfont = 0; + const int newid = _fonts.size(); // the new font gets this ID + Name2IdMap::iterator it = _name2id.find(name); + if (it != _name2id.end()) { // font with same name already registered? + Font *font = _fonts[it->second]; + newfont = font->clone(dsize, ssize); + } + else { + string filename = name; + int fontindex = 0; + const FontMap::Entry *map_entry = FontMap::instance().lookup(name); + if (map_entry) { + filename = map_entry->fontname; + fontindex = map_entry->fontindex; + } + // try to find font file with the exact given name + if (filename.rfind(".") != string::npos) + newfont = create_font(filename, name, fontindex, checksum, dsize, ssize); + else { + // try various font file formats if the given file has no extension + const char *exts[] = {"pfb", "otf", "ttc", "ttf", "vf", "mf", 0}; + for (const char **p = exts; *p && !newfont; ++p) + newfont = create_font(filename+"."+*p, name, fontindex, checksum, dsize, ssize); + } + if (newfont) { + if (!newfont->findAndAssignBaseFontMap()) + Message::wstream(true) << "no suitable encoding table found for font " << filename << "\n"; + if (!newfont->verifyChecksums()) + Message::wstream(true) << "checksum mismatch in font " << name << '\n'; + } + else { + // create dummy font as a placeholder if the proper font is not available + newfont = new EmptyFont(name); + if (filename.rfind(".") == string::npos) + filename += ".mf"; + // print warning message about missing font file (only once for each filename) + static set<string> missing_fonts; + if (missing_fonts.find(filename) == missing_fonts.end()) { + Message::wstream(true) << "font file '" << filename << "' not found\n"; + missing_fonts.insert(filename); + } + } + _name2id[name] = newid; + } + _fonts.push_back(newfont); + if (_vfStack.empty()) // register font referenced in dvi file? + _num2id[fontnum] = newid; + else { // register font referenced in vf file + VirtualFont *vf = const_cast<VirtualFont*>(_vfStack.top()); + _vfnum2id[vf][fontnum] = newid; + if (_vfFirstFontMap.find(vf) == _vfFirstFontMap.end()) // first fontdef of VF? + _vfFirstFontMap[vf] = fontnum; + } + return newid; +} + + + +int FontManager::registerFont (UInt32 fontnum, string filename, double ptsize, const FontStyle &style, Color color) { + int id = fontID(fontnum); + if (id >= 0) + return id; + + if (!filename.empty() && filename[0] == '[' && filename[filename.size()-1] == ']') + filename = filename.substr(1, filename.size()-2); + string fontname = NativeFont::uniqueName(filename, style); + const char *path = filename.c_str(); + Font *newfont=0; + const int newid = _fonts.size(); // the new font gets this ID + Name2IdMap::iterator it = _name2id.find(fontname); + if (it != _name2id.end()) { // font with same name already registered? + if (NativeFont *font = dynamic_cast<NativeFont*>(_fonts[it->second])) + newfont = font->clone(ptsize, style, color); + } + else { + if (!FileSystem::exists(path)) + path = FileFinder::lookup(filename, false); + if (path) { + newfont = new NativeFontImpl(path, ptsize, style, color); + newfont->findAndAssignBaseFontMap(); + } + if (!newfont) { + // create dummy font as a placeholder if the proper font is not available + newfont = new EmptyFont(filename); + // print warning message about missing font file (only once for each filename) + static set<string> missing_fonts; + if (missing_fonts.find(filename) == missing_fonts.end()) { + Message::wstream(true) << "font file '" << filename << "' not found\n"; + missing_fonts.insert(filename); + } + } + _name2id[fontname] = newid; + } + _fonts.push_back(newfont); + _num2id[fontnum] = newid; + return newid; +} + + +/** Enters a new virtual font frame. + * This method must be called before processing a VF character. + * @param[in] vf virtual font */ +void FontManager::enterVF (VirtualFont *vf) { + if (vf) + _vfStack.push(vf); +} + + +/** Leaves a previously entered virtual font frame. */ +void FontManager::leaveVF () { + if (!_vfStack.empty()) + _vfStack.pop(); +} + + +/** Assigns a sequence of DVI commands to a char code. + * @param[in] c character code + * @param[in] dvi points to vector with DVI commands */ +void FontManager::assignVfChar (int c, vector<UInt8> *dvi) { + if (!_vfStack.empty() && dvi) + _vfStack.top()->assignChar(c, dvi); +} + + +ostream& FontManager::write (ostream &os, Font *font, int level) { +#if 0 + if (font) { + int id = -1; + for (int i=0; i < fonts.size() && id < 0; i++) + if (fonts[i] == font) + id = i; + + VirtualFont *vf = dynamic_cast<VirtualFont*>(font); + for (int j=0; j < level+1; j++) + os << " "; + os << "id " << id + << " fontnum " << fontnum(id) << " " + << (vf ? "VF" : "PF") << " " + << font->name() + << endl; + + if (vf) { + enterVF(vf); + const Num2IdMap &num2id = vfnum2id.find(vf)->second; + FORALL(num2id, Num2IdMap::const_iterator, i) { + Font *font = fonts[i->second]; + write(os, font, level+1); + } + leaveVF(); + } + } + else { + for (int i=0; i < fonts.size(); i++) + write(os, fonts[i], level); + os << endl; + } +#endif + return os; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.h new file mode 100644 index 00000000000..24402f5ae5e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontManager.h @@ -0,0 +1,84 @@ +/************************************************************************* +** FontManager.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTMANAGER_H +#define DVISVGM_FONTMANAGER_H + +#include <map> +#include <ostream> +#include <set> +#include <string> +#include <stack> +#include <vector> +#include "Color.h" +#include "FontStyle.h" +#include "types.h" + + +struct FileFinder; +struct Font; +class VirtualFont; + +/** This class provides methods for easy DVI font handling. + * DVI and VF files use local font numbers to reference fonts. For SVG output + * we need a single list with unique IDs of all physical fonts. Characters of + * virtual fonts are completely replaced by their DVI description so they don't + * appear anywhere in the output. */ +class FontManager +{ + typedef std::map<UInt32,int> Num2IdMap; + typedef std::map<std::string,int> Name2IdMap; + typedef std::map<VirtualFont*,Num2IdMap> VfNum2IdMap; + typedef std::map<VirtualFont*, UInt32> VfFirstFontMap; + typedef std::stack<VirtualFont*> VfStack; + + public: + ~FontManager (); + static FontManager& instance (); + int registerFont (UInt32 fontnum, std::string fontname, UInt32 checksum, double dsize, double scale); + int registerFont (UInt32 fontnum, std::string fname, double ptsize, const FontStyle &style, Color color); + Font* getFont (int n) const; + Font* getFont (const std::string &name) const; + Font* getFontById (int id) const; + VirtualFont* getVF () const; + int fontID (int n) const; + int fontID (const Font *font) const; + int fontID (const std::string &name) const; + int fontnum (int id) const; + int vfFirstFontNum (VirtualFont *vf) const; + void enterVF (VirtualFont *vf); + void leaveVF (); + void assignVfChar (int c, std::vector<UInt8> *dvi); + const std::vector<Font*>& getFonts () const {return _fonts;} + std::ostream& write (std::ostream &os, Font *font=0, int level=0); + + protected: + FontManager () {} + + private: + std::vector<Font*> _fonts; ///< all registered Fonts + Num2IdMap _num2id; ///< DVI font number -> fontID + Name2IdMap _name2id; ///< fontname -> fontID + VfNum2IdMap _vfnum2id; + VfStack _vfStack; ///< stack of currently processed virtual fonts + VfFirstFontMap _vfFirstFontMap; ///< VF -> local font number of first font defined in VF +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.cpp new file mode 100644 index 00000000000..a094093b2f1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.cpp @@ -0,0 +1,305 @@ +/************************************************************************* +** FontMap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <fstream> +#include <iostream> +#include <limits> +#include <vector> +#include "CMap.h" +#include "Directory.h" +#include "FileFinder.h" +#include "FontManager.h" +#include "FontMap.h" +#include "MapLine.h" +#include "Message.h" +#include "Subfont.h" + +using namespace std; + + +FontMap::~FontMap () { + for (Iterator it=_entries.begin(); it != _entries.end(); ++it) + delete it->second; +} + + +/** Returns the singleton instance. */ +FontMap& FontMap::instance() { + static FontMap fontmap; + return fontmap; +} + + +/** Reads and evaluates a single font map file. + * @param[in] fname name of map file to read + * @param[in] mode selects how to integrate the map file entries into the global map tree + * @return true if file could be opened */ +bool FontMap::read (const string &fname, FontMap::Mode mode) { + ifstream ifs(fname.c_str()); + if (!ifs) + return false; + + int line_number = 1; + while (ifs) { + int c = ifs.peek(); + if (c < 0 || strchr("\n&#%;*", c)) // comment or empty line? + ifs.ignore(numeric_limits<int>::max(), '\n'); + else { + try { + MapLine mapline(ifs); + apply(mapline, mode); + } + catch (const MapLineException &e) { + Message::wstream(true) << fname << ", line " << line_number << ": " << e.what() << '\n'; + } + catch (const SubfontException &e) { + Message::wstream(true) << e.filename(); + if (e.lineno() > 0) + Message::wstream(false) << ", line " << e.lineno(); + Message::wstream(false) << e.what() << '\n'; + } + } + line_number++; + } + return true; +} + + +bool FontMap::read (const string &fname, char modechar) { + Mode mode; + switch (modechar) { + case '=': mode = FM_REPLACE; break; + case '-': mode = FM_REMOVE; break; + default : mode = FM_APPEND; + } + return read(fname, mode); +} + + +/** Applies a mapline according to the given mode (append, remove, replace). + * @param[in] mapline the mapline to be applied + * @param[in] mode mode to use + * @return true in case of success */ +bool FontMap::apply (const MapLine& mapline, FontMap::Mode mode) { + switch (mode) { + case FM_APPEND: + return append(mapline); + case FM_REMOVE: + return remove(mapline); + default: + return replace(mapline); + } +} + + +/** Applies a mapline according to the given mode (append, remove, replace). + * @param[in] mapline the mapline to be applied + * @param[in] modechar character that denotes the mode (+, -, or =) + * @return true in case of success */ +bool FontMap::apply (const MapLine& mapline, char modechar) { + Mode mode; + switch (modechar) { + case '=': mode = FM_REPLACE; break; + case '-': mode = FM_REMOVE; break; + default : mode = FM_APPEND; + } + return apply(mapline, mode); +} + + +/** Reads and evaluates a sequence of map files. Each map file is looked up in the local + * directory and the TeX file tree. + * @param[in] fname_seq comma-separated list of map file names + * @return true if at least one of the given map files was found */ +bool FontMap::read (const string &fname_seq) { + bool found = false; + size_t left=0; + while (left < fname_seq.length()) { + const char modechar = fname_seq[left]; + if (strchr("+-=", modechar)) + left++; + string fname; + size_t right = fname_seq.find(',', left); + if (right != string::npos) + fname = fname_seq.substr(left, right-left); + else { + fname = fname_seq.substr(left); + right = fname_seq.length(); + } + if (!fname.empty()) { + if (!read(fname, modechar)) { + if (const char *path = FileFinder::lookup(fname, false)) + found = found || read(path, modechar); + else + Message::wstream(true) << "map file " << fname << " not found\n"; + } + } + left = right+1; + } + return found; +} + + +/** Appends given map line data to the font map if there is no entry for the corresponding + * font in the map yet. + * @param[in] mapline parsed font data + * @return true if data has been appended */ +bool FontMap::append (const MapLine &mapline) { + bool ret = false; + if (!mapline.texname().empty()) { + if (!mapline.fontfname().empty() || !mapline.encname().empty()) { + vector<Subfont*> subfonts; + if (mapline.sfd()) + mapline.sfd()->subfonts(subfonts); + else + subfonts.push_back(0); + for (size_t i=0; i < subfonts.size(); i++) { + string fontname = mapline.texname()+(subfonts[i] ? subfonts[i]->id() : ""); + Iterator it = _entries.find(fontname); + if (it == _entries.end()) { + _entries[fontname] = new Entry(mapline, subfonts[i]); + ret = true; + } + } + } + } + return ret; +} + + +/** Replaces the map data of the given font. + * If the font is locked (because it's already in use) nothing happens. + * @param[in] mapline parsed font data + * @return true if data has been replaced */ +bool FontMap::replace (const MapLine &mapline) { + if (mapline.texname().empty()) + return false; + if (mapline.fontfname().empty() && mapline.encname().empty()) + return remove(mapline); + + vector<Subfont*> subfonts; + if (mapline.sfd()) + mapline.sfd()->subfonts(subfonts); + else + subfonts.push_back(0); + for (size_t i=0; i < subfonts.size(); i++) { + string fontname = mapline.texname()+(subfonts[i] ? subfonts[i]->id() : ""); + Iterator it = _entries.find(fontname); + if (it == _entries.end()) + _entries[fontname] = new Entry(mapline, subfonts[i]); + else if (!it->second->locked) + *it->second = Entry(mapline, subfonts[i]); + } + return true; +} + + +/** Removes the map entry of the given font. + * If the font is locked (because it's already in use) nothing happens. + * @param[in] mapline parsed font data + * @return true if entry has been removed */ +bool FontMap::remove (const MapLine &mapline) { + bool ret = false; + if (!mapline.texname().empty()) { + vector<Subfont*> subfonts; + if (mapline.sfd()) + mapline.sfd()->subfonts(subfonts); + else + subfonts.push_back(0); + for (size_t i=0; i < subfonts.size(); i++) { + string fontname = mapline.texname()+(subfonts[i] ? subfonts[i]->id() : ""); + Iterator it = _entries.find(fontname); + if (it != _entries.end() && !it->second->locked) { + _entries.erase(it); + ret = true; + } + } + } + return ret; +} + + +ostream& FontMap::write (ostream &os) const { + for (ConstIterator it=_entries.begin(); it != _entries.end(); ++it) + os << it->first << " -> " << it->second->fontname << " [" << it->second->encname << "]\n"; + return os; +} + + +/** Reads and evaluates all map files in the given directory. + * @param[in] dirname path to directory containing the map files to be read */ +void FontMap::readdir (const string &dirname) { + Directory dir(dirname); + while (const char *fname = dir.read(Directory::ET_FILE)) { + if (strlen(fname) >= 4 && strcmp(fname+strlen(fname)-4, ".map") == 0) { + string path = dirname + "/" + fname; + read(path.c_str()); + } + } +} + + +/** Returns name of font that is mapped to a given font. + * @param[in] fontname name of font whose mapped name is retrieved + * @returns name of mapped font */ +const FontMap::Entry* FontMap::lookup (const string &fontname) const { + ConstIterator it = _entries.find(fontname); + if (it == _entries.end()) + return 0; + return it->second; +} + + +/** Sets the lock flag for the given font in order to avoid changing the map data of this font. + * @param[in] fontname name of font to be locked */ +void FontMap::lockFont (const string& fontname) { + Iterator it = _entries.find(fontname); + if (it != _entries.end()) + it->second->locked = true; +} + + +/** Removes all (unlocked) entries from the font map. + * @param[in] unlocked_only if true, only unlocked entries are removed */ +void FontMap::clear (bool unlocked_only) { + if (!unlocked_only) + _entries.clear(); + else { + Iterator it=_entries.begin(); + while (it != _entries.end()) { + if (it->second->locked) + ++it; + else { + delete it->second; + _entries.erase(it++); + } + } + } +} + +///////////////////////////////////////////////// + +FontMap::Entry::Entry (const MapLine &mapline, Subfont *sf) + : fontname(mapline.fontfname()), encname(mapline.encname()), subfont(sf), fontindex(mapline.fontindex()), + locked(false), style(mapline.bold(), mapline.extend(), mapline.slant()) +{ +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.h new file mode 100644 index 00000000000..8bd2f712340 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMap.h @@ -0,0 +1,78 @@ +/************************************************************************* +** FontMap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTMAP_H +#define DVISVGM_FONTMAP_H + +#include <map> +#include <ostream> +#include <string> +#include "FontStyle.h" + + +struct FontEncoding; +class MapLine; +class Subfont; + +class FontMap +{ + public: + struct Entry + { + Entry (const MapLine &mapline, Subfont *subfont=0); + std::string fontname; ///< target font name + std::string encname; ///< name of font encoding + Subfont *subfont; + int fontindex; ///< index of font in multi-font file + bool locked; + FontStyle style; + }; + + protected: + typedef std::map<std::string,Entry*>::iterator Iterator; + typedef std::map<std::string,Entry*>::const_iterator ConstIterator; + + public: + enum Mode {FM_APPEND, FM_REMOVE, FM_REPLACE}; + + ~FontMap (); + static FontMap& instance (); + bool read (const std::string &fname, Mode mode); + bool read (const std::string &fname, char modechar); + bool read (const std::string &fname_seq); + void readdir (const std::string &dirname); + bool apply (const MapLine &mapline, Mode mode); + bool apply (const MapLine &mapline, char modechar); + bool append (const MapLine &mapline); + bool replace (const MapLine &mapline); + bool remove (const MapLine &mapline); + void lockFont (const std::string &fontname); + void clear (bool unlocked_only=false); + std::ostream& write (std::ostream &os) const; + const Entry* lookup(const std::string &fontname) const; + + protected: + FontMap () {} + + private: + std::map<std::string,Entry*> _entries; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.cpp new file mode 100644 index 00000000000..3920e4e6e76 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.cpp @@ -0,0 +1,41 @@ +/************************************************************************* +** FontMetrics.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <fstream> +#include "FileFinder.h" +#include "FontMetrics.h" +#include "JFM.h" +#include "TFM.h" + +using namespace std; + + +FontMetrics* FontMetrics::read (const char *fontname) { + const char *path = FileFinder::lookup(string(fontname) + ".tfm"); + ifstream ifs(path, ios::binary); + if (!ifs) + return 0; + UInt16 id = 256*ifs.get(); + id += ifs.get(); + if (id == 9 || id == 11) // Japanese font metric file? + return new JFM(ifs); + return new TFM(ifs); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.h new file mode 100644 index 00000000000..50207211d2c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontMetrics.h @@ -0,0 +1,64 @@ +/************************************************************************* +** FontMetrics.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_FONTMETRICS_H +#define DVISVGM_FONTMETRICS_H + +#include <istream> +#include "MessageException.h" +#include "types.h" + +struct FontMetrics +{ + virtual ~FontMetrics () {} + virtual double getDesignSize () const =0; + virtual double getCharWidth (int c) const =0; + virtual double getCharHeight (int c) const =0; + virtual double getCharDepth (int c) const =0; + virtual double getItalicCorr (int c) const =0; + virtual bool verticalLayout () const =0; + virtual UInt32 getChecksum () const =0; + virtual UInt16 firstChar () const =0; + virtual UInt16 lastChar () const =0; + static FontMetrics* read (const char *fontname); +}; + + +struct NullFontMetric : public FontMetrics +{ + double getDesignSize () const {return 1;} + double getCharWidth (int c) const {return 0;} + double getCharHeight (int c) const {return 0;} + double getCharDepth (int c) const {return 0;} + double getItalicCorr (int c) const {return 0;} + bool verticalLayout () const {return false;} + UInt32 getChecksum () const {return 0;} + UInt16 firstChar () const {return 0;} + UInt16 lastChar () const {return 0;} +}; + + +struct FontMetricException : public MessageException +{ + FontMetricException (const std::string &msg) : MessageException(msg) {} +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontStyle.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontStyle.h new file mode 100644 index 00000000000..932c09291cc --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/FontStyle.h @@ -0,0 +1,12 @@ +#ifndef FONTSTYLE +#define FONTSTYLE + +struct FontStyle { + FontStyle () : bold(0), extend(1), slant(0) {} + FontStyle (float b, float e, float s) : bold(b), extend(e), slant(s) {} + double bold; ///< stroke width in pt used to draw the glyph outlines + double extend; ///< factor to strech/shrink the glyphs horizontally + double slant; ///< horizontal slanting/skewing value (= tan(phi)) +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.cpp new file mode 100644 index 00000000000..4eff0912d42 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.cpp @@ -0,0 +1,93 @@ +/************************************************************************* +** GFGlyphTracer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "GFGlyphTracer.h" +#include "Pair.h" + +using namespace std; + +GFGlyphTracer::GFGlyphTracer () : GFTracer(_ifs, 0), _glyph(0), _callback(0) +{ +} + +/** Constructs a new glyph tracer. + * @param[in] is GF input stream + * @param[in] upp target units per PS point */ +GFGlyphTracer::GFGlyphTracer (string &fname, double upp, Callback *cb) + : GFTracer(_ifs, upp), _glyph(0), _callback(cb) +{ + if (_callback) + _callback->setFont(fname); + _ifs.open(fname.c_str(), ios::binary); +} + + +void GFGlyphTracer::reset (string &fname, double upp) { + if (_callback) + _callback->setFont(fname); + if (_ifs.is_open()) + _ifs.close(); + unitsPerPoint(upp); + _ifs.open(fname.c_str(), ios::binary); +} + + +bool GFGlyphTracer::executeChar (UInt8 c) { + if (_glyph) { + if (_callback) + _callback->beginChar(c); + bool ok = GFTracer::executeChar(c); + if (_callback) { + if (ok) + _callback->endChar(c); + else + _callback->emptyChar(c); + return ok; + } + } + return false; +} + + +void GFGlyphTracer::moveTo (double x, double y) { + _glyph->moveto(int(x), int(y)); +} + + +void GFGlyphTracer::lineTo (double x, double y) { + _glyph->lineto(int(x), int(y)); +} + + +void GFGlyphTracer::curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y) { + _glyph->cubicto(int(c1x), int(c1y), int(c2x), int(c2y), int(x), int(y)); +} + + +void GFGlyphTracer::closePath () { + _glyph->closepath(); +} + + +void GFGlyphTracer::endChar (UInt32 c) { + _glyph->newpath(); + GFTracer::endChar(c); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.h new file mode 100644 index 00000000000..84063a994b5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFGlyphTracer.h @@ -0,0 +1,60 @@ +/************************************************************************* +** GFGlyphTracer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GFGLYPHTRACER_H +#define DVISVGM_GFGLYPHTRACER_H + +#include <fstream> +#include <string> +#include "GFTracer.h" +#include "Glyph.h" + +class GFGlyphTracer : public GFTracer +{ + public: + struct Callback { + virtual ~Callback () {} + virtual void setFont (const std::string &fontname) {} + virtual void beginChar (UInt8 c) {} + virtual void endChar (UInt8 c) {} + virtual void emptyChar (UInt8 c) {} + }; + + public: + GFGlyphTracer (); + GFGlyphTracer (std::string &fname, double upp, Callback *cb=0); + void reset (std::string &fname, double upp); + void setCallback (Callback *cb) {_callback = cb;} + bool executeChar (UInt8 c); + void moveTo (double x, double y); + void lineTo (double x, double y); + void curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y); + void closePath (); + void endChar (UInt32 c); + void setGlyph (Glyph &glyph) {_glyph = &glyph;} + const Glyph& getGlyph () const {return *_glyph;} + + private: + std::ifstream _ifs; + Glyph *_glyph; + Callback *_callback; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.cpp new file mode 100644 index 00000000000..0c0238b5766 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.cpp @@ -0,0 +1,357 @@ +/************************************************************************* +** GFReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <iostream> +#include <sstream> +#include "GFReader.h" +#include "macros.h" +#include "SignalHandler.h" + +using namespace std; + +struct GFCommand +{ + void (GFReader::*method)(int); + int numBytes; +}; + + +static inline double fix2double (Int32 fix) { + return double(fix)/(1 << 20)*72/72.27; +} + + +static inline double scaled2double (Int32 scaled) { + return double(scaled)/(1 << 16); +} + + +GFReader::GFReader (istream &is) : _in(is), _penDown(false) +{ + _minX = _maxX = _minY = _maxY = _x = _y = 0; + _currentChar = 0; + _designSize = 0; + _hppp = _vppp = 0; + _checksum = 0; +} + + +UInt32 GFReader::readUnsigned (int bytes) { + UInt32 ret = 0; + for (int i=bytes-1; i >= 0 && !_in.eof(); i--) { + UInt32 b = _in.get(); + ret |= b << (8*i); + } + return ret; +} + + +Int32 GFReader::readSigned (int bytes) { + Int32 ret = _in.get(); + if (ret & 128) // negative value? + ret |= 0xffffff00; + for (int i=bytes-2; i >= 0 && !_in.eof(); i--) + ret = (ret << 8) | _in.get(); + return ret; +} + + +string GFReader::readString (int bytes) { + vector<char> buf(bytes+1); + if (bytes > 0) + _in.get(&buf[0], bytes+1); // reads 'bytes' bytes (pos. bytes+1 is set to 0) + else + buf[0] = 0; + return &buf[0]; +} + + +/** Reads a single GF command from the current position of the input stream and calls the + * corresponding cmdFOO method. + * @return opcode of the executed command */ +int GFReader::executeCommand () { + SignalHandler::instance().check(); + /* Each cmdFOO command reads the necessary number of bytes from the stream so executeCommand + doesn't need to know the exact GF command format. Some cmdFOO methods are used for multiple + GF commands because they only differ in the size of their parameters. */ + static const GFCommand commands[] = { + {&GFReader::cmdPaint, 1}, {&GFReader::cmdPaint, 2}, {&GFReader::cmdPaint, 3}, // 64-66 + {&GFReader::cmdBoc, 0}, {&GFReader::cmdBoc1, 0}, // 67-68 + {&GFReader::cmdEoc, 0}, // 69 + {&GFReader::cmdSkip, 0}, {&GFReader::cmdSkip, 1}, {&GFReader::cmdSkip, 2},{&GFReader::cmdSkip, 3}, // 70-73 + {&GFReader::cmdXXX, 1}, {&GFReader::cmdXXX, 2}, {&GFReader::cmdXXX, 3}, {&GFReader::cmdXXX, 4}, // 239-242 + {&GFReader::cmdYYY, 0}, // 243 + {&GFReader::cmdNop, 0}, // 244 + {&GFReader::cmdCharLoc, 0}, {&GFReader::cmdCharLoc0, 0}, // 245-246 + {&GFReader::cmdPre, 0}, {&GFReader::cmdPost, 0}, {&GFReader::cmdPostPost, 0} // 247-249 + }; + + int opcode = _in.get(); + if (opcode < 0) // at end of file? + throw GFException("unexpected end of file"); + + if (opcode >= 0 && opcode <= 63) + cmdPaint0(opcode); + else if (opcode >= 74 && opcode <= 238) + cmdNewRow(opcode-74); + else if (opcode >= 250) { + ostringstream oss; + oss << "undefined GF command (opcode " << opcode << ")"; + throw GFException(oss.str()); + } + else { + int offset = opcode <= 73 ? 64 : 239-(73-64+1); + const GFCommand &cmd = commands[opcode-offset]; + if (cmd.method) + (this->*cmd.method)(cmd.numBytes); + } + return opcode; +} + + +bool GFReader::executeChar (UInt8 c) { + _in.clear(); + if (_charInfoMap.empty()) + executePostamble(); // read character info + _in.clear(); + Iterator it = _charInfoMap.find(c); + if (_in && it != _charInfoMap.end()) { + _in.seekg(it->second.location, ios_base::beg); + while (executeCommand() != 69); // execute all commands until eoc is reached + return true; + } + return false; +} + + +bool GFReader::executeAllChars () { + _in.clear(); + if (_charInfoMap.empty()) + executePostamble(); // read character info + _in.clear(); + if (_in) { + _in.seekg(0); + while (executeCommand() != 248); // execute all commands until postamble is reached + return true; + } + return false; +} + + +bool GFReader::executePostamble () { + _in.clear(); + if (!_in) + return false; + _in.seekg(-1, ios_base::end); + while (_in.peek() == 223) // skip fill bytes + _in.seekg(-1, ios_base::cur); + _in.seekg(-4, ios_base::cur); + UInt32 q = readUnsigned(4); // pointer to begin of postamble + _in.seekg(q, ios_base::beg); // now on begin of postamble + while (executeCommand() != 249); // execute all commands until postpost is reached + return true; +} + + +/** Returns the design size of this font int PS point units. */ +double GFReader::getDesignSize () const { + return fix2double(_designSize); +} + +/** Returns the number of horizontal pixels per point. */ +double GFReader::getHPixelsPerPoint () const { + return scaled2double(_hppp)*72/72.27; +} + +/** Returns the number of vertical pixels per point. */ +double GFReader::getVPixelsPerPoint () const { + return scaled2double(_vppp)*72/72.27; +} + +/** Returns the width of character c in PS point units */ +double GFReader::getCharWidth (UInt32 c) const { + ConstIterator it = _charInfoMap.find(c%256); + return it == _charInfoMap.end() ? 0 : it->second.width*getDesignSize()/(1<<24); +} + +/////////////////////// + + +/** Reads the preamble. */ +void GFReader::cmdPre (int) { + UInt32 i = readUnsigned(1); + if (i == 131) { + UInt32 k = readUnsigned(1); + string s = readString(k); + preamble(s); + } + else + throw GFException("invalid identification number in GF preamble"); +} + + +/** Reads the postamble. */ +void GFReader::cmdPost (int) { + readUnsigned(4); // pointer to byte after final eoc + _designSize = readUnsigned(4); // design size of font in points + _checksum = readUnsigned(4); // checksum + _hppp = readUnsigned(4); // horizontal pixels per point (scaled int) + _vppp = readUnsigned(4); // vertical pixels per point (scaled int) + _in.seekg(16, ios_base::cur); // skip x and y bounds + postamble(); +} + + +/** Reads trailing bytes at end of stream. */ +void GFReader::cmdPostPost (int) { + readUnsigned(4); // pointer to begin of postamble + UInt32 i = readUnsigned(1); + if (i == 131) + while (readUnsigned(1) == 223); // skip fill bytes + else + throw GFException("invalid identification number in GF preamble"); +} + + +/** Inverts "paint color" (black to white or vice versa) of n pixels + * and advances the cursor by n. + * @param[in] n number of pixels to be inverted */ +void GFReader::cmdPaint0 (int n) { + if (_penDown) // set pixels? + _bitmap.setBits(_y, _x, n); + _x += n; + _penDown = !_penDown; // inverse pen state +} + + +/** Inverts "paint color" (black to white or vice versa) of n pixels + * and advances the cursor by n. The number n of pixels is read from + * the input stream. + * @param[in] len size of n in bytes */ +void GFReader::cmdPaint (int len) { + UInt32 pixels = readUnsigned(len); + cmdPaint0(pixels); +} + + +/** Beginning of character (generic format). */ +void GFReader::cmdBoc (int) { + _currentChar = readSigned(4); + readSigned(4); // pointer to previous boc with same c mod 256 + _minX = readSigned(4); + _maxX = readSigned(4); + _minY = readSigned(4); + _maxY = readSigned(4); + _x = _minX; + _y = _maxY; + _penDown = false; + _bitmap.resize(_minX, _maxX, _minY, _maxY); + beginChar(_currentChar); +} + + +/** Beginning of character (compact format). */ +void GFReader::cmdBoc1 (int) { + _currentChar = readUnsigned(1); + UInt32 dx = readUnsigned(1); + _maxX = readUnsigned(1); + _minX = _maxX - dx; + UInt32 dy = readUnsigned(1); + _maxY = readUnsigned(1); + _minY = _maxY - dy; + _x = _minX; + _y = _maxY; + _penDown = false; + _bitmap.resize(_minX, _maxX, _minY, _maxY); + beginChar(_currentChar); +} + + +/** End of character. */ +void GFReader::cmdEoc (int) { + endChar(_currentChar); +} + + +/** Moves cursor to the beginning of a following row and sets + * paint color to white. + * @param[in] len if 0: move to next row, otherwise: number of bytes to read. + * The read value denotes the number of rows to be skipped. */ +void GFReader::cmdSkip (int len) { + if (len == 0) + _y--; + else + _y -= readUnsigned(len)+1; + _x = _minX; + _penDown = false; +} + + +/** Moves cursor to pixel number 'col' in the next row and sets + * the paint color to black. + * @param[in] col pixel/column number */ +void GFReader::cmdNewRow (int col) { + _x = _minX + col ; + _y--; + _penDown = true; +} + + +void GFReader::cmdXXX (int len) { + UInt32 n = readUnsigned(len); + string str = readString(n); + special(str); +} + + +void GFReader::cmdYYY (int) { + Int32 y = readSigned(4); + numspecial(y); +} + + +/** Does nothing. */ +void GFReader::cmdNop (int) { +} + + +/** Reads character locator (part of postamble) */ +void GFReader::cmdCharLoc0 (int) { + UInt8 c = readUnsigned(1); // character code mod 256 + UInt8 dm = readUnsigned(1); // + Int32 w = readSigned(4); // (1<<24)*characterWidth/designSize + Int32 p = readSigned(4); // pointer to begin of (last) character data + Int32 dx = 65536*dm; + Int32 dy = 0; + _charInfoMap[c] = CharInfo(dx, dy, w, p); +} + + +/** Reads character locator (part of postamble) */ +void GFReader::cmdCharLoc (int) { + UInt32 c = readUnsigned(1); // character code mod 256 + Int32 dx = readSigned(4); // horizontal escapement (scaled pixel units) + Int32 dy = readSigned(4); // vertical escapement (scaled pixel units) + Int32 w = readSigned(4); // (1<<24)*characterWidth/designSize + Int32 p = readSigned(4); // pointer to begin of (last) character data + _charInfoMap[c] = CharInfo(dx, dy, w, p); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.h new file mode 100644 index 00000000000..62c36a0498b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFReader.h @@ -0,0 +1,110 @@ +/************************************************************************* +** GFReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GFREADER_H +#define DVISVGM_GFREADER_H + +#include <istream> +#include <map> +#include <string> +#include "Bitmap.h" +#include "MessageException.h" +#include "types.h" + + +class CharInfo; + + +struct GFException : public MessageException +{ + GFException (const std::string &msg) : MessageException(msg) {} +}; + + +class GFReader +{ + struct CharInfo + { + CharInfo () : dx(0), dy(0), width(0), location(0) {} + CharInfo (Int32 dxx, Int32 dyy, Int32 w, UInt32 p) : dx(dxx), dy(dyy), width(w), location(p) {} + + Int32 dx, dy; + Int32 width; // 2^24 * (true width)/(design size) + UInt32 location; + }; + + typedef std::map<UInt8,CharInfo>::iterator Iterator; + typedef std::map<UInt8,CharInfo>::const_iterator ConstIterator; + public: + GFReader (std::istream &is); + virtual ~GFReader () {} + bool executeChar (UInt8 c); + bool executeAllChars (); + bool executePostamble (); + virtual void preamble (const std::string &str) {} + virtual void postamble () {} + virtual void beginChar (UInt32 c) {} + virtual void endChar (UInt32 c) {} + virtual void special (std::string str) {} + virtual void numspecial (Int32 y) {} + const Bitmap& getBitmap () const {return _bitmap;} + double getDesignSize () const; + double getHPixelsPerPoint () const; + double getVPixelsPerPoint () const; + double getCharWidth (UInt32 c) const; + UInt32 getChecksum () const {return _checksum;} + + protected: + Int32 readSigned (int bytes); + UInt32 readUnsigned (int bytes); + std::string readString (int len); + int executeCommand (); + std::istream& getInputStream () const {return _in;} + + void cmdPre (int); + void cmdPost (int); + void cmdPostPost (int); + void cmdPaint0 (int pixels); + void cmdPaint (int len); + void cmdBoc (int); + void cmdBoc1 (int); + void cmdEoc (int); + void cmdSkip (int len); + void cmdNewRow (int col); + void cmdXXX (int len); + void cmdYYY (int); + void cmdNop (int); + void cmdCharLoc0 (int); + void cmdCharLoc (int); + + private: + std::istream &_in; + Int32 _minX, _maxX, _minY, _maxY; + Int32 _x, _y; // current pen location (pixel units) + Int32 _currentChar; + Bitmap _bitmap; // bitmap of current char + FixWord _designSize; // designSize + ScaledInt _hppp, _vppp; // horizontal and vertical pixel per point + UInt32 _checksum; + std::map<UInt8,CharInfo> _charInfoMap; + bool _penDown; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.cpp new file mode 100644 index 00000000000..89ff4359fda --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.cpp @@ -0,0 +1,103 @@ +/************************************************************************* +** GFTracer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <iostream> +#include <fstream> +#include <sstream> +#include "GFTracer.h" +#include "Glyph.h" +#include "Message.h" + +#ifdef __MSVC__ +#include <potracelib.h> +#else +extern "C" { +#include <potracelib.h> +} +#endif + +using namespace std; + + +GFTracer::GFTracer (istream &is) + : GFReader(is), _unitsPerPoint(0.0) +{ +} + + +/** Constructs a new GFTracer. + * @param[in] is GF file is read from this stream + * @param[in] upp target units per PS point */ +GFTracer::GFTracer (istream &is, double upp) + : GFReader(is), _unitsPerPoint(upp) +{ +} + + +void GFTracer::beginChar (UInt32 c) { +} + + +void GFTracer::endChar (UInt32 c) { + const Bitmap &bitmap = getBitmap(); + if (bitmap.empty()) + return; + + // prepare potrace's bitmap structure + vector<potrace_word> buffer; + potrace_bitmap_t pobitmap; + pobitmap.w = bitmap.width(); + pobitmap.h = bitmap.height(); + pobitmap.dy = bitmap.copy(buffer); + pobitmap.map = &buffer[0]; + potrace_param_t *param = potrace_param_default(); + potrace_state_t *state = potrace_trace(param, &pobitmap); + potrace_param_free(param); + + if (!state || state->status == POTRACE_STATUS_INCOMPLETE) + Message::wstream(true) << "error while tracing character\n"; + else { + double hsf=1.0, vsf=1.0; // horizontal a d vertical scale factor + if (_unitsPerPoint != 0.0) { + hsf = _unitsPerPoint/getHPixelsPerPoint(); // horizontal scale factor + vsf = _unitsPerPoint/getVPixelsPerPoint(); // vertical scale factor + } + for (potrace_path_t *path = state->plist; path; path = path->next) { + potrace_dpoint_t &p = path->curve.c[path->curve.n-1][2]; // start/end point + moveTo(hsf*(p.x+bitmap.xshift()), vsf*(p.y+bitmap.yshift())); + for (int i=0; i < path->curve.n; i++) { + if (path->curve.tag[i] == POTRACE_CURVETO) { + curveTo(hsf*(path->curve.c[i][0].x+bitmap.xshift()), vsf*(path->curve.c[i][0].y+bitmap.yshift()), + hsf*(path->curve.c[i][1].x+bitmap.xshift()), vsf*(path->curve.c[i][1].y+bitmap.yshift()), + hsf*(path->curve.c[i][2].x+bitmap.xshift()), vsf*(path->curve.c[i][2].y+bitmap.yshift())); + } + else { + lineTo(hsf*(path->curve.c[i][1].x+bitmap.xshift()), vsf*(path->curve.c[i][1].y+bitmap.yshift())); + if (i == path->curve.n-1) + closePath(); + else + lineTo(hsf*(path->curve.c[i][2].x+bitmap.xshift()), vsf*(path->curve.c[i][2].y+bitmap.yshift())); + } + } + } + } + potrace_state_free(state); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.h new file mode 100644 index 00000000000..7171ac1e3aa --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GFTracer.h @@ -0,0 +1,47 @@ +/************************************************************************* +** GFTracer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GFTRACER_H +#define DVISVGM_GFTRACER_H + +#include <istream> +#include "GFReader.h" + +class GFTracer : public GFReader +{ + public: + GFTracer (std::istream &is); + GFTracer (std::istream &is, double upp); + virtual ~GFTracer () {} + virtual void moveTo (double x, double y) {} + virtual void lineTo (double x, double y) {} + virtual void curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y) {} + virtual void closePath () {} + void beginChar (UInt32 c); + void endChar (UInt32 c); + + protected: + void unitsPerPoint(double upp) {_unitsPerPoint = upp;} + + private: + double _unitsPerPoint; ///< target units per PS point +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.cpp new file mode 100644 index 00000000000..5a872960774 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.cpp @@ -0,0 +1,299 @@ +/************************************************************************* +** Ghostscript.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "Ghostscript.h" +#if !defined(DISABLE_GS) +#include <cstring> +#include <iomanip> +#include <sstream> +#if defined(HAVE_LIBGS) + #include <ghostscript/ierrors.h> +#else + #include "ierrors.h" + #include "FileFinder.h" +#endif + +using namespace std; + +// name of Ghostscript shared library set by the user +string Ghostscript::LIBGS_NAME; + + +#ifndef HAVE_LIBGS +/** Try to detect name of the Ghostscript shared library depending on the user settings. + * @param[in] fname path/filename given by the user + * @return name of Ghostscript shared library */ +static string get_libgs (const string &fname) { + if (!fname.empty()) + return fname; +#ifdef MIKTEX +#if defined(__WIN64__) + const char *gsdll = "mgsdll64.dll"; +#elif defined(__WIN32__) + const char *gsdll = "mgsdll32.dll"; +#endif + // try to look up the Ghostscript DLL coming with MiKTeX + if (const char *gsdll_path = FileFinder::lookup(gsdll)) + return gsdll_path; +#endif // MIKTEX +#if defined(__WIN64__) + return "gsdll64.dll"; +#elif defined(__WIN32__) + return "gsdll32.dll"; +#else + // try to find libgs.so.X on the user's system + const int abi_min=7, abi_max=9; // supported libgs ABI versions + for (int i=abi_max; i >= abi_min; i--) { + ostringstream oss; + oss << "libgs.so." << i; + DLLoader loader(oss.str().c_str()); + if (loader.loaded()) + return oss.str(); + } +#endif + // no appropriate library found + return ""; +} +#endif // HAVE_LIBGS + + +/** Loads the Ghostscript library but does not create an instance. This + * constructor should only be used to call available() and revision(). */ +Ghostscript::Ghostscript () +#if !defined(HAVE_LIBGS) + : DLLoader(get_libgs(LIBGS_NAME).c_str()) +#endif +{ + _inst = 0; +} + + +/** Tries to load the shared library and to initialize Ghostscript. + * @param[in] argc number of parameters in array argv + * @param[in] argv parameters passed to Ghostscript + * @param[in] caller this parameter is passed to all callback functions */ +Ghostscript::Ghostscript (int argc, const char **argv, void *caller) +#if !defined(HAVE_LIBGS) + : DLLoader(get_libgs(LIBGS_NAME).c_str()) +#endif +{ + _inst = 0; + init(argc, argv, caller); +} + + +/** Exits Ghostscript and unloads the dynamic library. */ +Ghostscript::~Ghostscript () { + if (_inst) { + exit(); + delete_instance(); + } +} + + +bool Ghostscript::init (int argc, const char **argv, void *caller) { + if (!_inst) { + int status = new_instance(&_inst, caller); + if (status < 0) + _inst = 0; + else { + init_with_args(argc, (char**)argv); + } + } + return _inst != 0; +} + + +/** Returns true if Ghostscript library was found and can be loaded. */ +bool Ghostscript::available () { +#if defined(HAVE_LIBGS) + return true; +#else + gsapi_revision_t rev; + return loaded() && revision(&rev); +#endif +} + + +/** Retrieves version information about Ghostscript. + * @param[out] r takes the revision information (see GS API documentation for further details) + * @return true on success */ +bool Ghostscript::revision (gsapi_revision_t *r) { +#if defined(HAVE_LIBGS) + return (gsapi_revision(r, sizeof(gsapi_revision_t)) == 0); +#else + if (PFN_gsapi_revision fn = (PFN_gsapi_revision)loadSymbol("gsapi_revision")) + return (fn(r, sizeof(gsapi_revision_t)) == 0); + return false; +#endif +} + + +/** Returns product name and revision number of the GS library. + * @param[in] revonly if true, only the revision number is returned */ +string Ghostscript::revision (bool revonly) { + gsapi_revision_t r; + if (revision(&r)) { + ostringstream oss; + if (!revonly) + oss << r.product << ' '; + oss << (r.revision/100) << '.' << setfill('0') << setw(2) << (r.revision%100); + return oss.str(); + } + return ""; +} + + +/** Creates a new instance of Ghostscript. This method is called by the constructor and + * should not be used elsewhere. + * @param[out] psinst handle of newly created instance (or 0 on error) + * @param[in] caller pointer forwarded to callback functions */ +int Ghostscript::new_instance (void **psinst, void *caller) { +#if defined(HAVE_LIBGS) + return gsapi_new_instance(psinst, caller); +#else + if (PFN_gsapi_new_instance fn = (PFN_gsapi_new_instance)loadSymbol("gsapi_new_instance")) + return fn(psinst, caller); + *psinst = 0; + return 0; +#endif +} + + +/** Destroys the current instance of Ghostscript. This method is called by the destructor + * and should not be used elsewhere. */ +void Ghostscript::delete_instance () { +#if defined(HAVE_LIBGS) + gsapi_delete_instance(_inst); +#else + if (PFN_gsapi_delete_instance fn = (PFN_gsapi_delete_instance)loadSymbol("gsapi_delete_instance")) + fn(_inst); +#endif +} + + +/** Exits the interpreter. Must be called before destroying the GS instance. */ +int Ghostscript::exit () { +#if defined(HAVE_LIBGS) + return gsapi_exit(_inst); +#else + if (PFN_gsapi_exit fn = (PFN_gsapi_exit)loadSymbol("gsapi_exit")) + return fn(_inst); + return 0; +#endif +} + + +/** Sets the I/O callback functions. + * @param[in] in pointer to stdin handler + * @param[in] out pointer to stdout handler + * @param[in] err pointer to stderr handler */ +int Ghostscript::set_stdio (Stdin in, Stdout out, Stderr err) { +#if defined(HAVE_LIBGS) + return gsapi_set_stdio(_inst, in, out, err); +#else + if (PFN_gsapi_set_stdio fn = (PFN_gsapi_set_stdio)loadSymbol("gsapi_set_stdio")) + return fn(_inst, in, out, err); + return 0; +#endif +} + + +/** Initializes Ghostscript with a set of optional parameters. This + * method is called by the constructor and should not be used elsewhere. + * @param[in] argc number of paramters + * @param[in] argv parameters passed to Ghostscript */ +int Ghostscript::init_with_args (int argc, char **argv) { +#if defined(HAVE_LIBGS) + return gsapi_init_with_args(_inst, argc, argv); +#else + if (PFN_gsapi_init_with_args fn = (PFN_gsapi_init_with_args)loadSymbol("gsapi_init_with_args")) + return fn(_inst, argc, argv); + return 0; +#endif +} + + +/** Tells Ghostscript that several calls of run_string_continue will follow. */ +int Ghostscript::run_string_begin (int user_errors, int *pexit_code) { +#if defined(HAVE_LIBGS) + return gsapi_run_string_begin(_inst, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_begin fn = (PFN_gsapi_run_string_begin)loadSymbol("gsapi_run_string_begin")) + return fn(_inst, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + + +/** Executes a chunk of PostScript commands given by a buffer of characters. The size of + * this buffer must not exceed 64KB. Longer programs can be split into arbitrary smaller chunks + * and passed to Ghostscript by successive calls of run_string_continue. + * @param[in] str buffer containing the PostScript code + * @param[in] length number of characters in buffer + * @param[in] user_errors if non-negative, the default PS error values will be generated, otherwise this value is returned + * @param[out] pexit_code takes the PS error code */ +int Ghostscript::run_string_continue (const char *str, unsigned length, int user_errors, int *pexit_code) { +#if defined(HAVE_LIBGS) + return gsapi_run_string_continue(_inst, str, length, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_continue fn = (PFN_gsapi_run_string_continue)loadSymbol("gsapi_run_string_continue")) + return fn(_inst, str, length, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + + +/** Terminates the successive code feeding. Must be called after the last call of run_string_continue. */ +int Ghostscript::run_string_end (int user_errors, int *pexit_code) { +#if defined(HAVE_LIBGS) + return gsapi_run_string_end(_inst, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_end fn = (PFN_gsapi_run_string_end)loadSymbol("gsapi_run_string_end")) + return fn(_inst, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + + +const char* Ghostscript::error_name (int code) { + if (code < 0) + code = -code; + const char *error_names[] = { ERROR_NAMES }; + if (code == 0 || (size_t)code > sizeof(error_names)/sizeof(error_names[0])) + return 0; +#if defined(HAVE_LIBGS) + // use array defined in libgs to avoid linking the error strings into the binary + return gs_error_names[code-1]; +#elif defined(__WIN32__) + // gs_error_names is private in the Ghostscript DLL so we can't access it here + return error_names[code-1]; +#else + if (const char **error_names = (const char**)loadSymbol("gs_error_names")) + return error_names[code-1]; + return 0; +#endif +} + +#endif // !DISABLE_GS diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.h new file mode 100644 index 00000000000..d223ad04edf --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Ghostscript.h @@ -0,0 +1,103 @@ +/************************************************************************* +** Ghostscript.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GHOSTSCRIPT_H +#define DVISVGM_GHOSTSCRIPT_H + +#include <config.h> +#include <string> + +#if defined(DISABLE_GS) + #include "iapi.h" +#elif defined(HAVE_LIBGS) + #include <ghostscript/iapi.h> +#else + #include "DLLoader.h" + #include "iapi.h" +#endif + +#if defined(__WIN32__) && !defined(_Windows) + #define _Windows +#endif + +#if defined(DISABLE_GS) +struct Ghostscript +{ + typedef int (GSDLLCALLPTR Stdin) (void *caller, char *buf, int len); + typedef int (GSDLLCALLPTR Stdout) (void *caller, const char *str, int len); + typedef int (GSDLLCALLPTR Stderr) (void *caller, const char *str, int len); + + Ghostscript () {} + Ghostscript (int argc, const char **argv, void *caller=0) {} + bool init (int argc, const char **argv, void *caller=0) {return false;} + bool available () {return false;} + bool revision (gsapi_revision_t *r) {return false;} + std::string revision (bool revonly=false) {return "";} + int set_stdio (Stdin in, Stdout out, Stderr err) {return 0;} + int run_string_begin (int user_errors, int *pexit_code) {return 0;} + int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code) {return 0;} + int run_string_end (int user_errors, int *pexit_code) {return 0;} + int exit () {return 0;} + const char* error_name (int code) {return 0;} +}; + +#else + +/** Wrapper class of (a subset of) the Ghostscript API. */ +class Ghostscript +#if !defined(HAVE_LIBGS) +: public DLLoader +#endif +{ + public: + typedef int (GSDLLCALLPTR Stdin) (void *caller, char *buf, int len); + typedef int (GSDLLCALLPTR Stdout) (void *caller, const char *str, int len); + typedef int (GSDLLCALLPTR Stderr) (void *caller, const char *str, int len); + + public: + Ghostscript (); + Ghostscript (int argc, const char **argv, void *caller=0); + ~Ghostscript (); + bool init (int argc, const char **argv, void *caller=0); + bool available (); + bool revision (gsapi_revision_t *r); + std::string revision (bool revonly=false); + int set_stdio (Stdin in, Stdout out, Stderr err); + int run_string_begin (int user_errors, int *pexit_code); + int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code); + int run_string_end (int user_errors, int *pexit_code); + int exit (); + const char* error_name (int code); + + static std::string LIBGS_NAME; + + protected: + Ghostscript (const Ghostscript &gs) : _inst(0) {} + int init_with_args (int argc, char **argv); + int new_instance (void **psinst, void *caller); + void delete_instance (); + + private: + void *_inst; ///< Ghostscript handle needed to call the gsapi_foo functions +}; + +#endif // DISABLE_GS + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Glyph.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Glyph.h new file mode 100644 index 00000000000..5a003a2196b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Glyph.h @@ -0,0 +1,28 @@ +/************************************************************************* +** Glyph.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GLYPH_H +#define DVISVGM_GLYPH_H + +#include "GraphicPath.h" + +typedef GraphicPath<Int32> Glyph; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GlyphTracerMessages.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GlyphTracerMessages.h new file mode 100644 index 00000000000..6256bb843a0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GlyphTracerMessages.h @@ -0,0 +1,65 @@ +/************************************************************************* +** GlyphTracerMessages.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GLYPHTRACERMESSAGES_H +#define DVISVGM_GLYPHTRACERMESSAGES_H + +#include <sstream> +#include "GFGlyphTracer.h" +#include "Message.h" +#include "types.h" + +class GlyphTracerMessages : public GFGlyphTracer::Callback +{ + public: + GlyphTracerMessages (bool sfmsg=true, bool autonl=true) : _sfmsg(sfmsg), _autonl(autonl) {} + + ~GlyphTracerMessages () { + if (_autonl) + Message::mstream() << '\n'; + } + + void endChar (UInt8 c) { + std::ostringstream oss; + oss << '['; + if (isprint(c)) + oss << c; + else + oss << '#' << unsigned(c); + oss << ']'; + Message::mstream(false, Message::MC_TRACING) << oss.str(); + } + + void setFont (const std::string &fname) { + if (_sfmsg && fname != _fname) { + if (!_fname.empty()) + Message::mstream() << '\n'; + Message::mstream(false, Message::MC_STATE) << "tracing glyphs of " << fname.substr(0, fname.length()-3) << '\n'; + _fname = fname; + } + } + + private: + std::string _fname; + bool _sfmsg, _autonl; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GraphicPath.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GraphicPath.h new file mode 100644 index 00000000000..e1bd457d554 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/GraphicPath.h @@ -0,0 +1,340 @@ +/************************************************************************* +** GraphicPath.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_GRAPHICPATH_H +#define DVISVGM_GRAPHICPATH_H + +#include <list> +#include <ostream> +#include <vector> +#include "BoundingBox.h" +#include "Matrix.h" +#include "Pair.h" +#include "XMLString.h" + + +template <typename T> +class GraphicPath +{ + public: + typedef Pair<T> Point; + + struct Command { + enum Type {MOVETO, LINETO, CONICTO, CUBICTO, CLOSEPATH}; + + Command (Type t) : type(t) {} + + Command (Type t, const Point &p) : type(t) { + params[0] = p; + } + + Command (Type t, const Point &p1, const Point &p2) : type(t) { + params[0] = p1; + params[1] = p2; + } + + Command (Type t, const Point &p1, const Point &p2, const Point &p3) : type(t) { + params[0] = p1; + params[1] = p2; + params[2] = p3; + } + + int numParams () const { + switch (type) { + case CLOSEPATH : return 0; + case MOVETO : + case LINETO : return 1; + case CONICTO : return 2; + case CUBICTO : return 3; + } + return 0; + } + + void transform (const Matrix &matrix) { + for (int i=0; i < numParams(); i++) + params[i] = matrix * params[i]; + } + + Type type; + Point params[3]; + }; + + struct Actions + { + virtual ~Actions () {} + virtual void moveto (const Point &p) {} + virtual void lineto (const Point &p) {} + virtual void hlineto (const T &y) {} + virtual void vlineto (const T &x) {} + virtual void sconicto (const Point &p) {} + virtual void conicto (const Point &p1, const Point &p2) {} + virtual void scubicto (const Point &p1, const Point &p2) {} + virtual void cubicto (const Point &p1, const Point &p2, const Point &p3) {} + virtual void closepath () {} + virtual void draw (char cmd, const Point *points, int n) {} + virtual bool quit () {return false;} + }; + + typedef typename std::vector<Command>::iterator Iterator; + typedef typename std::vector<Command>::const_iterator ConstIterator; + typedef typename std::vector<Command>::const_reverse_iterator ConstRevIterator; + + public: + void newpath () { + _commands.clear(); + } + + /// Returns true if path is empty (there is nothing to draw) + bool empty () const { + return _commands.empty(); + } + + + /// Returns the number of path commands used to describe the path. + size_t size () const { + return _commands.size(); + } + + void moveto (const T &x, const T &y) { + moveto(Point(x, y)); + } + + void moveto (const Point &p) { + // avoid sequences of several MOVETOs; always use latest + if (_commands.empty() || _commands.back().type != Command::MOVETO) + _commands.push_back(Command(Command::MOVETO, p)); + else + _commands.back().params[0] = p; + } + + void lineto (const T &x, const T &y) { + lineto(Point(x, y)); + } + + void lineto (const Point &p) { + _commands.push_back(Command(Command::LINETO, p)); + } + + void conicto (const T &x1, const T &y1, const T &x2, const T &y2) { + conicto(Point(x1, y1), Point(x2, y2)); + } + + void conicto (const Point &p1, const Point &p2) { + _commands.push_back(Command(Command::CONICTO, p1, p2)); + } + + void cubicto (const T &x1, const T &y1, const T &x2, const T &y2, const T &x3, const T &y3) { + cubicto(Point(x1, y1), Point(x2, y2), Point(x3, y3)); + } + + void cubicto (const Point &p1, const Point &p2, const Point &p3) { + _commands.push_back(Command(Command::CUBICTO, p1, p2, p3)); + } + + void closepath () { + _commands.push_back(Command(Command::CLOSEPATH)); + } + + + const std::vector<Command>& commands () const { + return _commands; + } + + + /** Detects all open subpaths and closes them by adding a closePath command. + * Most font formats only support closed outline paths so there are no explicit closePath statements + * in the glyph's outline description. All open paths are automatically closed by the renderer. + * This method detects all open paths and adds the missing closePath statement. */ + void closeOpenSubPaths () { + Command *prevCommand = 0; + FORALL(_commands, Iterator, it) { + if (it->type == Command::MOVETO && prevCommand && prevCommand->type != Command::CLOSEPATH) { + prevCommand = &(*it); + it = _commands.insert(it, Command(Command::CLOSEPATH))+1; +// ++it; // skip inserted closePath command in next iteration step + } + else + prevCommand = &(*it); + } + if (!_commands.empty() && _commands.back().type != Command::CLOSEPATH) + closepath(); + } + + + /** Writes the path data as SVG path drawing command to a given output stream. + * @param[in] os output stream used to write the SVG commands to + * @param[in] sx horizontal scale factor + * @param[in] sy vertical scale factor + * @param[in] dx horizontal translation in PS point units + * @param[in] dy vertical translation in PS point units */ + void writeSVG (std::ostream &os, double sx=1.0, double sy=1.0, double dx=0.0, double dy=0.0) const { + struct WriteActions : Actions { + WriteActions (std::ostream &os, double sx, double sy, double dx, double dy) + : _os(os), _sx(sx), _sy(sy), _dx(dx), _dy(dy) {} + + void draw (char cmd, const Point *points, int n) { + _os << cmd; + switch (cmd) { + case 'H': _os << XMLString(_sx*points->x()+_dx); break; + case 'V': _os << XMLString(_sy*points->y()+_dy); break; + default : + for (int i=0; i < n; i++) { + if (i > 0) + _os << ' '; + _os << XMLString(_sx*points[i].x()+_dx) << ' ' << XMLString(_sy*points[i].y()+_dy); + } + } + } + std::ostream &_os; + double _sx, _sy, _dx, _dy; + } actions(os, sx, sy, dx, dy); + iterate(actions, true); + } + + + /** Computes the bounding box of the current path. + * @param[out] bbox the computed bounding box */ + void computeBBox (BoundingBox &bbox) const { + struct BBoxActions : Actions { + BBoxActions (BoundingBox &bb) : bbox(bb) {} + void moveto (const Point &p) {bbox.embed(p);} + void lineto (const Point &p) {bbox.embed(p);} + void conicto (const Point &p1, const Point &p2) {bbox.embed(p1); bbox.embed(p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {bbox.embed(p1); bbox.embed(p2); bbox.embed(p3);} + BoundingBox &bbox; + } actions(bbox); + iterate(actions, false); + } + + + /** Checks whether the current path describes a dot/point only (with no extent). + * @param[out] p coordinates of the point if path describes a dot + * @return true if path is a dot/point */ + bool isDot (Point &p) const { + struct DotActions : Actions { + DotActions () : differs(false) {} + void moveto (const Point &p) {point = p;} + void lineto (const Point &p) {differs = (p != point);} + void conicto (const Point &p1, const Point &p2) {differs = (point != p1 || point != p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {differs = (point != p1 || point != p2 || point != p3);} + bool quit () {return differs;} + Point point; + bool differs; + } actions; + iterate(actions, false); + p = actions.point; + return !actions.differs; + } + + + /** Transforms the path according to a given Matrix. + * @param[in] matrix Matrix describing the affine transformation */ + void transform (const Matrix &matrix) { + FORALL(_commands, Iterator, it) + it->transform(matrix); + } + + void iterate (Actions &actions, bool optimize) const; + + private: + std::vector<Command> _commands; +}; + + +/** Iterates over all commands defining this path and calls the corresponding template methods. + * In the case of successive bezier curve sequences, control points or tangent slopes are often + * identical so that the path description contains redundant information. SVG provides shorthand + * curve commands that require less parameters. If 'optimize' is true, this method detects such + * command sequences. + * @param[in] actions template methods called by each iteration step + * @param[in] optimize if true, shorthand drawing commands (sconicto, scubicto,...) are considered */ +template <typename T> +void GraphicPath<T>::iterate (Actions &actions, bool optimize) const { + ConstIterator prev = _commands.end(); // pointer to preceding command + Point fp; // first point of current path + Point cp; // current point + Point pstore[2]; + for (ConstIterator it=_commands.begin(); it != _commands.end() && !actions.quit(); ++it) { + const Point *params = it->params; + switch (it->type) { + case Command::MOVETO: + actions.moveto(params[0]); + actions.draw('M', params, 1); + fp = params[0]; + break; + case Command::LINETO: + if (optimize) { + if (cp.x() == params[0].x()) { + actions.vlineto(params[0].y()); + actions.draw('V', params, 1); + } + else if (cp.y() == params[0].y()) { + actions.hlineto(params[0].x()); + actions.draw('H', params, 1); + } + else { + actions.lineto(params[0]); + actions.draw('L', params, 1); + } + } + else { + actions.lineto(params[0]); + actions.draw('L', params, 1); + } + break; + case Command::CONICTO: + if (optimize && prev != _commands.end() && prev->type == Command::CONICTO && params[0] == pstore[1]*T(2)-pstore[0]) { + actions.sconicto(params[1]); + actions.draw('T', params+1, 1); + } + else { + actions.conicto(params[0], params[1]); + actions.draw('Q', params, 2); + } + pstore[0] = params[0]; // store control point and + pstore[1] = params[1]; // curve endpoint + break; + case Command::CUBICTO: + // is first control point reflection of preceding second control point? + if (optimize && prev != _commands.end() && prev->type == Command::CUBICTO && params[0] == pstore[1]*T(2)-pstore[0]) { + actions.scubicto(params[1], params[2]); + actions.draw('S', params+1, 2); + } + else { + actions.cubicto(params[0], params[1], params[2]); + actions.draw('C', params, 3); + } + pstore[0] = params[1]; // store second control point and + pstore[1] = params[2]; // curve endpoint + break; + case Command::CLOSEPATH: + actions.closepath(); + actions.draw('Z', params, 0); + cp = fp; + } + // update current point + const int np = it->numParams(); + if (np > 0) + cp = it->params[np-1]; + prev = it; + } +} + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.cpp new file mode 100644 index 00000000000..29ae75b5821 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.cpp @@ -0,0 +1,263 @@ +/************************************************************************* +** HtmlSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "HtmlSpecialHandler.h" +#include "InputReader.h" +#include "Message.h" +#include "SVGTree.h" +#include "XMLNode.h" + +using namespace std; + +// variable to select the link marker variant (none, underlined, boxed, or colored background) +HtmlSpecialHandler::MarkerType HtmlSpecialHandler::MARKER_TYPE = HtmlSpecialHandler::MT_LINE; +Color HtmlSpecialHandler::LINK_BGCOLOR; +Color HtmlSpecialHandler::LINK_LINECOLOR; +bool HtmlSpecialHandler::USE_LINECOLOR = false; + + +bool HtmlSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (!actions) + return true; + _actions = actions; + StreamInputReader ir(is); + ir.skipSpace(); + map<string,string> attribs; + map<string,string>::iterator it; + if (ir.check("<a ") && ir.parseAttributes(attribs, '"') > 0) { + if ((it = attribs.find("href")) != attribs.end()) // <a href="URI"> + hrefAnchor(it->second); + else if ((it = attribs.find("name")) != attribs.end()) // <a name="ID"> + nameAnchor(it->second); + else + return false; // none or only invalid attributes + } + else if (ir.check("</a>")) + closeAnchor(); + else if (ir.check("<img src=")) { + } + else if (ir.check("<base ") && ir.parseAttributes(attribs, '"') > 0 && (it = attribs.find("href")) != attribs.end()) + _base = it->second; + return true; +} + + +/** Handles anchors with href attribute: <a href="URI">...</a> + * @param uri value of href attribute */ +void HtmlSpecialHandler::hrefAnchor (string uri) { + closeAnchor(); + int id=0; + if (uri[0] == '#') { // reference to named anchor? + string name = uri.substr(1); + NamedAnchors::iterator it = _namedAnchors.find(name); + if (it == _namedAnchors.end()) { + id = _namedAnchors.size()+1; + _namedAnchors[name] = NamedAnchor(-id, 0); + } + } + if (!_base.empty() && uri.find("://") != string::npos) { + if (*_base.rbegin() != '/' && uri[0] != '/' && uri[0] != '#') + uri = "/" + uri; + uri = _base + uri; + } + XMLElementNode *anchor = new XMLElementNode("a"); + anchor->addAttribute("xlink:href", id ? "#loc"+XMLString(id) : uri); + anchor->addAttribute("xlink:title", uri); + _actions->pushContextElement(anchor); + _actions->bbox("{anchor}", true); // start computing the bounding box of the linked area + _depthThreshold = _actions->getDVIStackDepth(); + _anchorType = AT_HREF; +} + + +/** Handles anchors with name attribute: <a name="NAME">...</a> + * @param name value of name attribute */ +void HtmlSpecialHandler::nameAnchor (const string &name) { + closeAnchor(); + _anchorName = name; + NamedAnchors::iterator it = _namedAnchors.find(name); + if (it == _namedAnchors.end()) { // first occurrence of this anchor + int id = _namedAnchors.size()+1; + _namedAnchors[name] = NamedAnchor(id, _actions->getY()); + } + else if (it->second.id < 0) { // anchor referenced but not defined yet + it->second.id *= -1; + it->second.pos = _actions->getY(); + } + else + Message::wstream(true) << "named hyperref anchor '" << name << "' redefined\n"; + _anchorType = AT_NAME; +} + + +/** Handles the closing tag (</a> of the current anchor element. */ +void HtmlSpecialHandler::closeAnchor () { + if (_anchorType == AT_HREF) { + markLinkedBox(); + _actions->popContextElement(); + _depthThreshold = 0; + } + else if (_anchorType == AT_NAME) + _anchorName.clear(); + _anchorType = AT_NONE; +} + + +/** Marks a single rectangular area of the linked part of the document with a line or + * a box so that it's noticeable by the user. Additionally, an invisible rectangle is + * placed over this area in order to avoid flickering of the mouse cursor when moving + * it over the hyperlinked area. */ +void HtmlSpecialHandler::markLinkedBox () { + const BoundingBox &bbox = _actions->bbox("{anchor}"); + if (bbox.width() > 0 && bbox.height() > 0) { // does the bounding box extend in both dimensions? + if (MARKER_TYPE != MT_NONE) { + const double linewidth = min(0.5, bbox.height()/15); + XMLElementNode *rect = new XMLElementNode("rect"); + double x = bbox.minX(); + double y = bbox.maxY()+linewidth; + double w = bbox.width(); + double h = linewidth; + const Color &linecolor = USE_LINECOLOR ? LINK_LINECOLOR : _actions->getColor(); + if (MARKER_TYPE == MT_LINE) + rect->addAttribute("fill", linecolor.rgbString()); + else { + x -= linewidth; + y = bbox.minY()-linewidth; + w += 2*linewidth; + h += bbox.height()+linewidth; + if (MARKER_TYPE == MT_BGCOLOR) { + rect->addAttribute("fill", LINK_BGCOLOR.rgbString()); + if (USE_LINECOLOR) { + rect->addAttribute("stroke", linecolor.rgbString()); + rect->addAttribute("stroke-width", linewidth); + } + } + else { // LM_BOX + rect->addAttribute("fill", "none"); + rect->addAttribute("stroke", linecolor.rgbString()); + rect->addAttribute("stroke-width", linewidth); + } + } + rect->addAttribute("x", x); + rect->addAttribute("y", y); + rect->addAttribute("width", w); + rect->addAttribute("height", h); + _actions->prependToPage(rect); + if (MARKER_TYPE == MT_BOX || MARKER_TYPE == MT_BGCOLOR) { + // slightly enlarge the boxed area + x -= linewidth; + y -= linewidth; + w += 2*linewidth; + h += 2*linewidth; + } + _actions->embed(BoundingBox(x, y, x+w, y+h)); + } + // Create an invisible rectangle around the linked area so that it's easier to access. + // This is only necessary when using paths rather than real text elements together with fonts. + if (!SVGTree::USE_FONTS) { + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", bbox.minX()); + rect->addAttribute("y", bbox.minY()); + rect->addAttribute("width", bbox.width()); + rect->addAttribute("height", bbox.height()); + rect->addAttribute("fill", "white"); + rect->addAttribute("fill-opacity", 0); + _actions->appendToPage(rect); + } + } +} + + +/** This method is called every time the DVI position changes. */ +void HtmlSpecialHandler::dviMovedTo (double x, double y) { + if (_actions && _anchorType != AT_NONE) { + // Start a new box if the current depth of the DVI stack underruns + // the initial threshold which indicates a line break. + if (_actions->getDVIStackDepth() < _depthThreshold) { + markLinkedBox(); + _depthThreshold = _actions->getDVIStackDepth(); + _actions->bbox("{anchor}", true); // start a new box on the new line + } + } +} + + +void HtmlSpecialHandler::dviEndPage (unsigned pageno) { + if (_actions) { + // create views for all collected named anchors defined on the recent page + const BoundingBox &pagebox = _actions->bbox(); + for (NamedAnchors::iterator it=_namedAnchors.begin(); it != _namedAnchors.end(); ++it) { + if (it->second.id > 0) { // current anchor referenced? + ostringstream oss; + oss << pagebox.minX() << ' ' << it->second.pos << ' ' + << pagebox.width() << ' ' << pagebox.height(); + XMLElementNode *view = new XMLElementNode("view"); + view->addAttribute("id", "loc"+XMLString(it->second.id)); + view->addAttribute("viewBox", oss.str()); + _actions->appendToDefs(view); + } + } + closeAnchor(); + _namedAnchors.clear(); + _actions = 0; + } +} + + +/** Sets the appearance of the link markers. + * @param[in] marker string specifying the marker (format: type[:linecolor]) + * @return true on success */ +bool HtmlSpecialHandler::setLinkMarker (const string &marker) { + string type; // "none", "box", "line", or a background color specifier + string color; // optional line color specifier + size_t seppos = marker.find(":"); + if (seppos == string::npos) + type = marker; + else { + type = marker.substr(0, seppos); + color = marker.substr(seppos+1); + } + if (type.empty() || type == "none") + MARKER_TYPE = MT_NONE; + else if (type == "line") + MARKER_TYPE = MT_LINE; + else if (type == "box") + MARKER_TYPE = MT_BOX; + else { + if (!LINK_BGCOLOR.set(type, false)) + return false; + MARKER_TYPE = MT_BGCOLOR; + } + USE_LINECOLOR = false; + if (MARKER_TYPE != MT_NONE && !color.empty()) { + if (!LINK_LINECOLOR.set(color, false)) + return false; + USE_LINECOLOR = true; + } + return true; +} + + +const char** HtmlSpecialHandler::prefixes () const { + static const char *pfx[] = {"html:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.h new file mode 100644 index 00000000000..e94b3800e1d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/HtmlSpecialHandler.h @@ -0,0 +1,75 @@ +/************************************************************************* +** HtmlSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_HTMLSPECIALHANDLER_H +#define DVISVGM_HTMLSPECIALHANDLER_H + +#include <map> +#include <string> +#include "Color.h" +#include "SpecialHandler.h" + +struct SpecialActions; + +class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, public DVIPositionListener +{ + struct NamedAnchor { + NamedAnchor () : id(0), pos(0) {} + NamedAnchor (int i, double p) : id(i), pos(p) {} + int id; ///< unique numerical ID (< 0 if anchor is unreferenced) + double pos; ///< vertical position of named anchor (in PS point units) + }; + + enum AnchorType {AT_NONE, AT_HREF, AT_NAME}; + typedef std::map<std::string, NamedAnchor> NamedAnchors; + + public: + HtmlSpecialHandler () : _actions(0), _anchorType(AT_NONE), _depthThreshold(0) {} + bool process (const char *prefix, std::istream &in, SpecialActions *actions); + const char* name () const {return "html";} + const char* info () const {return "hyperref specials";} + const char** prefixes () const; + + static bool setLinkMarker (const std::string &type); + + protected: + void hrefAnchor (std::string uri); + void nameAnchor (const std::string &name); + void dviEndPage (unsigned pageno); + void dviMovedTo (double x, double y); + void closeAnchor (); + void markLinkedBox (); + + enum MarkerType {MT_NONE, MT_LINE, MT_BOX, MT_BGCOLOR}; + static MarkerType MARKER_TYPE; ///< selects how linked areas are marked + static Color LINK_BGCOLOR; ///< background color if linkmark type == LT_BGCOLOR + static Color LINK_LINECOLOR; ///< line color if linkmark type is LM_LINE or LM_BOX + static bool USE_LINECOLOR; ///< if true, LINK_LINECOLOR is applied + + private: + SpecialActions *_actions; + AnchorType _anchorType; ///< type of active anchor + int _depthThreshold; ///< break anchor box if the DVI stack depth underruns this threshold + std::string _anchorName; ///< name of currently active named anchor + std::string _base; ///< base URL that is prepended to all relative targets + NamedAnchors _namedAnchors; ///< information about all named anchors processed +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.cpp new file mode 100644 index 00000000000..79e0dcf39c7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.cpp @@ -0,0 +1,138 @@ +/************************************************************************* +** InputBuffer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <cstring> +#include "InputBuffer.h" + +using namespace std; + + +StreamInputBuffer::StreamInputBuffer (istream &is, size_t bufsize) + : _is(is), _bufsize(bufsize), _buf1(new UInt8[_bufsize]), _buf2(new UInt8[_bufsize]), _bufptr(_buf1) +{ + _size1 = fillBuffer(_buf1); + _size2 = fillBuffer(_buf2); +} + + +StreamInputBuffer::~StreamInputBuffer () { + delete [] _buf1; + delete [] _buf2; +} + + +int StreamInputBuffer::get () { + if (pos() == _size1) { + if (_size2 == 0) + return -1; + swap(_buf1, _buf2); + _size1 = _size2; + _bufptr = _buf1; + _size2 = fillBuffer(_buf2); + } + UInt8 c = *_bufptr++; + return c; +} + + +/** Returns the next character to be read without skipping it. + * Same as peek(0). */ +int StreamInputBuffer::peek () const { + if (pos() < _size1) + return *_bufptr; + return _size2 > 0 ? *_buf2 : -1; +} + + +/** Returns the n-th next character without skipping it. */ +int StreamInputBuffer::peek (size_t n) const { + if (pos()+n < _size1) + return *(_bufptr+n); + if (pos()+n < _size1+_size2) + return *(_buf2 + pos()+n-_size1); + return -1; +} + + +/** Fills the buffer by reading a sequence of characters from the assigned + * input stream. + * @param[in] buf pointer to character buffer to be filled + * @return number of characters read */ +int StreamInputBuffer::fillBuffer (UInt8 *buf) { + if (_is && !_is.eof()) { + _is.read((char*)buf, _bufsize); + return _is.gcount(); + } + return 0; +} + +/////////////////////////////////////////////// + +SplittedCharInputBuffer::SplittedCharInputBuffer (const char *buf1, size_t s1, const char *buf2, size_t s2) { + _buf[0] = buf1; + _buf[1] = buf2; + _size[0] = buf1 ? s1 : 0; + _size[1] = buf2 ? s2 : 0; + _index = _size[0] ? 0 : 1; +} + + +int SplittedCharInputBuffer::get () { + if (_size[_index] == 0) + return -1; + int ret = *_buf[_index]++; + _size[_index]--; + if (_index == 0 && _size[0] == 0) + _index++; + return ret; +} + + +int SplittedCharInputBuffer::peek () const { + return _size[_index] ? *_buf[_index] : -1; +} + + +int SplittedCharInputBuffer::peek (size_t n) const { + if (n < _size[_index]) + return _buf[_index][n]; + n -= _size[_index]; + if (_index == 0 && n < _size[1]) + return _buf[1][n]; + return -1; +} + +/////////////////////////////////////////////// + + +int TextStreamInputBuffer::get () { + int c = StreamInputBuffer::get(); + if (c == '\n') { + _line++; + _col = 1; + } + else + _col++; + return c; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.h new file mode 100644 index 00000000000..c29a943a7e7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputBuffer.h @@ -0,0 +1,145 @@ +/************************************************************************* +** InputBuffer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_INPUTBUFFER_H +#define DVISVGM_INPUTBUFFER_H + +#include <algorithm> +#include <cstring> +#include <istream> +#include <string> +#include <ostream> +#include "types.h" + +struct InputBuffer +{ + virtual ~InputBuffer () {} + virtual int get () =0; + virtual int peek () const =0; + virtual int peek (size_t n) const =0; + virtual bool eof () const =0; + virtual void invalidate () =0; +}; + + +class StreamInputBuffer : public InputBuffer +{ + public: + StreamInputBuffer (std::istream &is, size_t bufsize=1024); + ~StreamInputBuffer (); + int get (); + int peek () const; + int peek (size_t n) const; + bool eof () const {return pos() == _size1 && _size2 == 0;} + void invalidate () {_bufptr = _buf1+_size1; _size2 = 0;} + + protected: + int fillBuffer (UInt8 *buf); + size_t pos () const {return _bufptr-_buf1;} + + private: + std::istream &_is; + const size_t _bufsize; ///< maximal number of bytes each buffer can hold + UInt8 *_buf1; ///< pointer to first buffer + UInt8 *_buf2; ///< pointer to second buffer + size_t _size1; ///< number of bytes in buffer 1 + size_t _size2; ///< number of bytes in buffer 2 + UInt8 *_bufptr; ///< pointer to next byte to read +}; + + +class StringInputBuffer : public InputBuffer +{ + public: + StringInputBuffer (const std::string &str) : _str(str), _pos(0) {} + int get () {return _pos < _str.length() ? _str[_pos++] : -1;} + int peek () const {return _pos < _str.length() ? _str[_pos] : -1;} + int peek (size_t n) const {return _pos+n < _str.length() ? _str[_pos+n] : -1;} + bool eof () const {return _pos >= _str.length();} + void invalidate () {_pos = _str.length();} + + private: + const std::string &_str; + size_t _pos; +}; + + +class CharInputBuffer : public InputBuffer +{ + public: + CharInputBuffer (const char *buf, size_t size) : _pos(buf), _size(buf ? size : 0) {} + + int get () { + if (_size == 0) + return -1; + else { + _size--; + return *_pos++; + } + } + + + void assign (const char *buf, size_t size) { + _pos = buf; + _size = size; + } + + void assign (const char *buf) {assign(buf, std::strlen(buf));} + int peek () const {return _size > 0 ? *_pos : -1;} + int peek (size_t n) const {return _size >= n ? _pos[n] : -1;} + bool eof () const {return _size == 0;} + void invalidate () {_size = 0;} + + private: + const char *_pos; + size_t _size; +}; + + +class SplittedCharInputBuffer : public InputBuffer +{ + public: + SplittedCharInputBuffer (const char *buf1, size_t s1, const char *buf2, size_t s2); + int get (); + int peek () const; + int peek (size_t n) const; + bool eof () const {return _size[_index] == 0;} + void invalidate () {_size[_index] = 0;} + + private: + const char *_buf[2]; + size_t _size[2]; + int _index; +}; + + +class TextStreamInputBuffer : public StreamInputBuffer +{ + public: + TextStreamInputBuffer (std::istream &is) : StreamInputBuffer(is), _line(1), _col(1) {} + int get (); + int line () const {return _line;} + int col () const {return _col;} + + private: + int _line, _col; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.cpp new file mode 100644 index 00000000000..b2f01f5ea1e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.cpp @@ -0,0 +1,330 @@ +/************************************************************************* +** InputReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <vector> +#include "InputReader.h" + +using namespace std; + + +/** Skips n characters. */ +void InputReader::skip (size_t n) { + while (n-- > 0) + get(); +} + + +/** Moves the buffer pointer to the next non-space character. A following call + * of get() returns this character. */ +void InputReader::skipSpace () { + while (isspace(peek())) + get(); +} + + +/** Tries to find a given string and skips all characters preceding that string. + * @param[in] s string to look for (must not be longer than the maximal buffer size) + * @param[in] consume if true, the buffer pointer is moved to the first character following string s + * @return true if s was found */ +bool InputReader::skipUntil (const char *s, bool consume) { + bool found = false; + while (!eof() && !(found = check(s, consume))) + get(); + return found; +} + + +/** Looks for the first occurrence of a given character. + * @param[in] c character to lookup + * @return position of character relative to current location, -1 if character was not found */ +int InputReader::find (char c) const { + int pos = 0; + int cc; + while ((cc = peek(pos)) >= 0 && cc != c) + pos++; + return cc < 0 ? -1 : pos; +} + + +/** Checks if the next characters to be read match a given string. + * @param[in] s string to be matched + * @param[in] consume if true, the characters of the matched string are skipped + * @return true if s matches */ +bool InputReader::check (const char *s, bool consume) { + size_t count = 0; + for (const char *p=s; *p; p++) { + if (peek(count++) != *p) + return false; + } + if (consume) + skip(count); + return true; +} + + +int InputReader::compare (const char *s, bool consume) { + size_t count = 0; + for (const char *p=s; *p; p++) { + int c = peek(count++); + if (c != *p) + return *p < c ? -1 : 1; + } + if (consume) + skip(count); + return 0; +} + + +/** Reads an integer from the buffer. All characters that are part of + * the read integer constant are skipped. If this function returns false, + * the buffer pointer points to the same position as before the function call. + * @param[out] val contains the read integer value on success + * @param[in] accept_sign if false, only positive integers (without sign) are accepted + * @return true if integer could be read */ +bool InputReader::parseInt (int &val, bool accept_sign) { + val = 0; + int fac=1; + char sign; // explicitly given sign + if (accept_sign && ((sign = peek()) == '+' || sign == '-')) { + if (isdigit(peek(1))) { + get(); // skip sign + if (sign == '-') + fac = -1; + } + else + return false; + } + else if (!isdigit(peek())) + return false; + + while (isdigit(peek())) + val = val*10 + (get()-'0'); + val *= fac; + return true; +} + + +bool InputReader::parseUInt (unsigned &val) { + val = 0; + if (!isdigit(peek())) + return false; + while (isdigit(peek())) + val = val*10 + (get()-'0'); + return true; +} + + +bool InputReader::parseInt (int base, int &val) { + if (base < 2 || base > 32) + return false; + + const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + const char maxdigit = digits[base-1]; + char c; + if (!isalnum(c = tolower(peek())) || c > maxdigit) + return false; + + val = 0; + while (isalnum(c = tolower(peek())) && c <= maxdigit) { + get(); + int digit = c - (c <= '9' ? '0' : 'a'-10); + val = val*base + digit; + } + return true; +} + + +/** Reads a double from the buffer. All characters that are part of + * the read double constant are skipped. If this function returns false, + * the buffer pointer points to the same position as before the function call. + * @param[out] val contains the read double value on success + * @return number details: 0=no number, 'i'=integer, 'f'=floating point number */ +char InputReader::parseDouble (double &val) { + int fac=1; + int int_part=0; + bool is_float = false; + skipSpace(); + char sign = peek(); + if (parseInt(int_part)) { // match [+-]?[0-9]+\.? + if (peek() == '.') { + get(); + is_float = true; + } + if (int_part < 0 || sign == '-') { + fac = -1; + int_part = -int_part; + } + } + else { // match [+-]?\. + char sign; // explicitly given sign + if ((sign = peek()) == '+' || sign == '-') { // match [+-]?\.[0-9] + if (peek(1) != '.' || !isdigit(peek(2))) + return 0; + if (sign == '-') + fac = -1; + skip(2); // skip sign and dot + } + else if (peek() == '.' && isdigit(peek(1))) + get(); + else + return 0; + is_float = true; + } + // parse fractional part + double frac_part=0.0; + for (double u=10; isdigit(peek()); u*=10) + frac_part += (get()-'0')/u; + val = (int_part + frac_part) * fac; + // parse exponent + char c; + if (tolower(peek()) == 'e' && (isdigit(c=peek(1)) || ((c == '+' || c == '-') && isdigit(peek(2))))) { + get(); // skip 'e' + int exp; + parseInt(exp); + val *= pow(10.0, exp); + is_float = true; + } + return is_float ? 'f' : 'i'; +} + + +/** Reads an integer value from the buffer. If no valid integer constant + * could be found at the current position 0 is returned. */ +int InputReader::getInt () { + skipSpace(); + int val; + return parseInt(val) ? val : 0; +} + + +/** Reads an double value from the buffer. If no valid double constant + * could be found at the current position 0 is returned. */ +double InputReader::getDouble () { + skipSpace(); + double val; + return parseDouble(val) ? val : 0.0; +} + + +string InputReader::getWord () { + string ret; + skipSpace(); + while (isalpha(peek())) + ret += get(); + return ret; +} + + +char InputReader::getPunct () { + skipSpace(); + if (ispunct(peek())) + return get(); + return 0; +} + + +/** Reads a string delimited by a given quotation character. + * Before reading the string, all leading whitespace is skipped. Then, the function checks + * for the given quotation character. If it is found, all characters until the second + * appearance of the quotation char are appended to the result. Otherwise, an empty string + * is returned. If the quotation character is 0, the behavior of this function is identical to + * a call of getString(). + * @param[in] quotechar the quotation character bounding the string to be read + * @return the string read */ +string InputReader::getQuotedString (char quotechar) { + if (quotechar == 0) + return getString(); + + string ret; + skipSpace(); + if (peek() == quotechar) { + get(); + while (!eof() && peek() != quotechar) + ret += get(); + get(); + } + return ret; +} + + +/** Reads a string delimited by whitespace and/or invisible characters. + * Before reading the string, all leading whitespace is skipped. Then, the function adds + * all printable characters to the result until a whitespace, an unprintable character, or + * EOF is found. + * @return the string read */ +string InputReader::getString () { + string ret; + skipSpace(); + while (!eof() && !isspace(peek()) && isprint(peek())) + ret += get(); + return ret; +} + + +/** Reads a given number of characters and returns the resulting string. + * @param n number of character to read + * @return the string read */ +string InputReader::getString (size_t n) { + string ret; + while (n-- > 0) + ret += get(); + return ret; +} + + +/** Parses a sequence of key-value pairs of the form KEY=VALUE or KEY="VALUE" + * @param[out] attr the scanned atributes + * @param[in] quotechar quote character used to enclose the attribute values + * @return number of attributes scanned */ +int InputReader::parseAttributes (map<string,string> &attr, char quotechar) { + bool ready=false; + while (!eof() && !ready) { + string key; + skipSpace(); + while (isalnum(peek())) + key += get(); + skipSpace(); + if (peek() == '=') { + get(); + skipSpace(); + string val = getQuotedString(quotechar); + attr[key] = val; + } + else + ready = true; + } + return attr.size(); +} + +////////////////////////////////////////// + + +int StreamInputReader::peek (size_t n) const { + if (n == 0) + return peek(); + vector<char> chars(n); + _is.read(&chars[0], n); + int ret = peek(); + for (int i=n-1; i >= 0; i--) + _is.putback(chars[i]); + return ret; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.h new file mode 100644 index 00000000000..c0d726424f6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/InputReader.h @@ -0,0 +1,89 @@ +/************************************************************************* +** InputReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_INPUTREADER_H +#define DVISVGM_INPUTREADER_H + +#include <istream> +#include <map> +#include <string> +#include "InputBuffer.h" + + +class InputReader +{ + public: + virtual ~InputReader() {} + virtual int get () =0; + virtual int peek () const =0; + virtual int peek (size_t n) const =0; + virtual bool eof () const =0; + virtual bool check (char c) const {return peek() == c;} + virtual bool check (const char *s, bool consume=true); + virtual int compare (const char *s, bool consume=true); + virtual void skip (size_t n); + virtual bool skipUntil (const char *s, bool consume=true); + virtual int find (char c) const; + virtual void skipSpace (); + virtual int getInt (); + virtual bool parseInt (int &val, bool accept_sign=true); + virtual bool parseInt (int base, int &val); + virtual bool parseUInt (unsigned &val); + virtual char parseDouble (double &val); + virtual double getDouble (); + virtual std::string getWord (); + virtual char getPunct (); + virtual std::string getQuotedString (char quotechar); + virtual std::string getString (); + virtual std::string getString (size_t n); + virtual int parseAttributes (std::map<std::string,std::string> &attr, char quotechar=0); + virtual operator bool () const {return !eof();} +}; + + +class StreamInputReader : public InputReader +{ + public: + StreamInputReader (std::istream &is) : _is(is) {} + int get () {return _is.get();} + int peek () const {return _is.peek();} + int peek (size_t n) const; + bool eof () const {return !_is || _is.eof();} + + private: + std::istream &_is; +}; + + +class BufferInputReader : public InputReader +{ + public: + BufferInputReader (InputBuffer &ib) : _ib(&ib) {} + void assign (InputBuffer &ib) {_ib = &ib;} + int get () {return _ib->get();} + int peek () const {return _ib->peek();} + int peek (size_t n) const {return _ib->peek(n);} + bool eof () const {return _ib->eof();} + + private: + InputBuffer *_ib; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.cpp new file mode 100644 index 00000000000..89c4796616c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.cpp @@ -0,0 +1,99 @@ +/************************************************************************* +** JFM.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cstring> +#include <fstream> +#include <sstream> +#include "JFM.h" +#include "StreamReader.h" + +using namespace std; + + +JFM::JFM (istream &is) { + is.seekg(0); + StreamReader sr(is); + UInt16 id = UInt16(sr.readUnsigned(2)); // JFM ID (9 or 11) + if (id != 9 && id != 11) { + ostringstream oss; + oss << "invalid JFM identifier " << id << " (9 or 11 expected)"; + throw FontMetricException(oss.str()); + } + _vertical = (id == 9); + UInt16 nt = UInt16(sr.readUnsigned(2)); // length of character type table + UInt16 lf = UInt16(sr.readUnsigned(2)); // length of entire file in 4 byte words + UInt16 lh = UInt16(sr.readUnsigned(2)); // length of header in 4 byte words + UInt16 bc = UInt16(sr.readUnsigned(2)); // smallest character code in font + UInt16 ec = UInt16(sr.readUnsigned(2)); // largest character code in font + UInt16 nw = UInt16(sr.readUnsigned(2)); // number of words in width table + UInt16 nh = UInt16(sr.readUnsigned(2)); // number of words in height table + UInt16 nd = UInt16(sr.readUnsigned(2)); // number of words in depth table + UInt16 ni = UInt16(sr.readUnsigned(2)); // number of words in italic corr. table + UInt16 nl = UInt16(sr.readUnsigned(2)); // number of words in glue/kern table + UInt16 nk = UInt16(sr.readUnsigned(2)); // number of words in kern table + UInt16 ng = UInt16(sr.readUnsigned(2)); // number of words in glue table + UInt16 np = UInt16(sr.readUnsigned(2)); // number of font parameter words + + if (7+nt+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ng+np != lf) + throw FontMetricException("inconsistent length values"); + + setCharRange(bc, ec); + readHeader(sr); + is.seekg(28+lh*4); + readTables(sr, nt, nw, nh, nd, ni); +} + + +void JFM::readTables (StreamReader &sr, int nt, int nw, int nh, int nd, int ni) { + // determine smallest charcode with chartype > 0 + UInt16 minchar=0xFFFF, maxchar=0; + for (int i=0; i < nt; i++) { + UInt16 c = (UInt16)sr.readUnsigned(2); + UInt16 t = (UInt16)sr.readUnsigned(2); + if (t > 0) { + minchar = min(minchar, c); + maxchar = max(maxchar, c); + } + } + // build charcode to chartype map + if (minchar <= maxchar) { + _minchar = minchar; + _charTypeTable.resize(maxchar-minchar+1); + memset(&_charTypeTable[0], 0, nt*sizeof(UInt16)); + sr.seek(-nt*4, ios::cur); + for (int i=0; i < nt; i++) { + UInt16 c = (UInt16)sr.readUnsigned(2); + UInt16 t = (UInt16)sr.readUnsigned(2); + if (c >= minchar) + _charTypeTable[c-minchar] = t; + } + } + TFM::readTables(sr, nw, nh, nd, ni); +} + + +int JFM::charIndex (int c) const { + UInt16 chartype = 0; + if (!_charTypeTable.empty() && c >= _minchar && size_t(c) < _minchar+_charTypeTable.size()) + chartype = _charTypeTable[c-_minchar]; + return TFM::charIndex(chartype); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.h new file mode 100644 index 00000000000..86585477f74 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/JFM.h @@ -0,0 +1,44 @@ +/************************************************************************* +** JFM.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_JFM_H +#define DVISVGM_JFM_H + +#include <istream> +#include "TFM.h" + + +class JFM : public TFM +{ + public: + JFM (std::istream &is); + bool verticalLayout () const {return _vertical;} + + protected: + void readTables (StreamReader &sr, int nt, int nw, int nh, int nd, int ni); + int charIndex (int c) const; + + private: + UInt16 _minchar; ///< character code of first entry in character type table + bool _vertical; ///< true if metrics refer to vertical text layout + std::vector<UInt16> _charTypeTable; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.cpp new file mode 100644 index 00000000000..63d1509d3fd --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.cpp @@ -0,0 +1,85 @@ +/************************************************************************* +** Length.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "InputReader.h" +#include "Length.h" + +#define UNIT(c1,c2) ((c1 << 8)|c2) + +using namespace std; + + +void Length::set (const string &len) { + switch (len.length()) { + case 0: + _pt = 0; + break; + case 1: + if (isdigit(len[0])) + _pt = len[0] - '0'; + else + throw UnitException("invalid length: "+len); + break; + default: + istringstream iss(len); + StreamInputReader ir(iss); + double val; + if (!ir.parseDouble(val)) + throw UnitException("invalid length: "+len); + string unit = ir.getWord(); + set(val, unit); + } +} + + +void Length::set (double val, Unit unit) { + switch (unit) { + case PT: _pt = val; break; + case BP: _pt = val*72.27/72; break; + case IN: _pt = val*72.27; break; + case CM: _pt = val/2.54*72.27; break; + case MM: _pt = val/25.4*72.27; break; + case PC: _pt = val/12*72.27; break; + } +} + + +void Length::set (double val, string unitstr) { + if (unitstr.empty()) + unitstr = "pt"; + else if (unitstr.length() != 2) + throw UnitException("invalid length unit: "+unitstr); + + Unit unit; + switch (UNIT(unitstr[0], unitstr[1])) { + case UNIT('p','t'): unit = PT; break; + case UNIT('b','p'): unit = BP; break; + case UNIT('i','n'): unit = IN; break; + case UNIT('c','m'): unit = CM; break; + case UNIT('m','m'): unit = MM; break; + case UNIT('p','c'): unit = PC; break; + default: + throw UnitException("invalid length unit: "+unitstr); + } + set(val, unit); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.h new file mode 100644 index 00000000000..f2e4f5d4114 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Length.h @@ -0,0 +1,62 @@ +/************************************************************************* +** Length.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_LENGTH_H +#define DVISVGM_LENGTH_H + +#include <string> +#include "MessageException.h" + +#ifdef IN +#undef IN +#endif + +struct UnitException : MessageException +{ + UnitException (const std::string &msg) : MessageException(msg) {} +}; + + +class Length +{ + public: + enum Unit {PT, BP, CM, MM, IN, PC}; + + public: + Length () : _pt(0) {} + Length (double val, Unit unit=PT) {set(val, unit);} + Length (double val, const std::string &unit) {set(val, unit);} + Length (const std::string &len) {set(len);} + void set (double val, Unit unit); + void set (double val, std::string unit); + void set (const std::string &len); + + double pt () const {return _pt;} + double in () const {return _pt/72.27;} + double bp () const {return in()*72;} + double cm () const {return in()*2.54;} + double mm () const {return cm()*10;} + double pc () const {return in()*12;} + + private: + double _pt; // length in TeX point units +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Makefile.am new file mode 100644 index 00000000000..b504093a3bf --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Makefile.am @@ -0,0 +1,53 @@ +:## This file is part of dvisvgm +## Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> +## +## Process this file with automake. + +bin_PROGRAMS = dvisvgm +noinst_LIBRARIES = libdvisvgm.a + +dvisvgm_SOURCES = gzstream.h \ + dvisvgm.cpp gzstream.cpp + +dvisvgm_LDADD = $(noinst_LIBRARIES) @EXTRA_LIBS@ +dvisvgm_DEPENDENCIES = $(noinst_LIBRARIES) @EXTRA_LIBS@ + +libdvisvgm_a_SOURCES = Bitmap.h BoundingBox.h BgColorSpecialHandler.h Calculator.h Character.h CharMap.h CharMapID.h CMap.h \ + CMapManager.h CMapReader.h CmdLineParserBase.h Color.h CRC32.h ColorSpecialHandler.h CommandLine.h Directory.h DLLoader.h \ + DVIActions.h DVIReader.h DvisvgmSpecialHandler.h DVIToSVG.h DVIToSVGActions.h EncFile.h EmSpecialHandler.h EPSFile.h EPSToSVG.h \ + FileFinder.h FilePath.h FileSystem.h Font.h FontCache.h FontEncoding.h FontEngine.h FontManager.h FontMap.h FontMetrics.h \ + FontStyle.h GFReader.h GFTracer.h GFGlyphTracer.h Ghostscript.h Glyph.h GlyphTracerMessages.h GraphicPath.h HtmlSpecialHandler.h \ + InputBuffer.h InputReader.h JFM.h Length.h macros.h MapLine.h Matrix.h Message.h MessageException.h MetafontWrapper.h \ + NoPsSpecialHandler.h PageRanges.h PageSize.h Pair.h PdfSpecialHandler.h Process.h PSFilter.h PSInterpreter.h PSPattern.h \ + PSPreviewFilter.h PsSpecialHandler.h SignalHandler.h SpecialActions.h SpecialHandler.h SpecialManager.h StreamReader.h \ + StreamWriter.h Subfont.h SVGOutputBase.h SVGTree.h System.h Terminal.h TpicSpecialHandler.h TFM.h types.h VectorStream.h \ + VFActions.h VFReader.h XMLDocument.h XMLNode.h XMLString.h \ + BgColorSpecialHandler.cpp Bitmap.cpp BoundingBox.cpp Calculator.cpp CharMap.cpp CharMapID.cpp CMap.cpp CMapManager.cpp \ + CMapReader.cpp CmdLineParserBase.cpp Color.cpp ColorSpecialHandler.cpp CommandLine.cpp CRC32.cpp Directory.cpp DLLoader.cpp \ + DVIReader.cpp DvisvgmSpecialHandler.cpp DVIToSVG.cpp DVIToSVGActions.cpp EmSpecialHandler.cpp EncFile.cpp \ + EPSFile.cpp EPSToSVG.cpp FileFinder.cpp FilePath.cpp FileSystem.cpp Font.cpp FontCache.cpp FontEncoding.cpp FontEngine.cpp \ + FontManager.cpp FontMap.cpp FontMetrics.cpp GFReader.cpp GFGlyphTracer.cpp GFTracer.cpp Ghostscript.cpp HtmlSpecialHandler.cpp \ + InputBuffer.cpp InputReader.cpp JFM.cpp Length.cpp MapLine.cpp Matrix.cpp Message.cpp MetafontWrapper.cpp NoPsSpecialHandler.cpp \ + PageRanges.cpp PageSize.cpp PdfSpecialHandler.cpp Process.cpp psdefs.cpp PSInterpreter.cpp PSPattern.cpp PSPreviewFilter.cpp \ + PsSpecialHandler.cpp SignalHandler.cpp SpecialManager.cpp StreamReader.cpp StreamWriter.cpp Subfont.cpp SVGTree.cpp System.cpp \ + Terminal.cpp TFM.cpp TpicSpecialHandler.cpp VFReader.cpp XMLDocument.cpp XMLNode.cpp XMLString.cpp + +EXTRA_DIST = options.xml iapi.h ierrors.h MiKTeXCom.h MiKTeXCom.cpp + +AM_CXXFLAGS = -Wall -Wnon-virtual-dtor + +# the command-line parser is generated from options.xml by opt2cpp +CommandLine.cpp: options.xml + if test -f opt2cpp.xsl; then \ + rm -f $@ $*.h; \ + xsltproc opt2cpp.xsl $<; \ + fi + +# Create a C string definition containing the PostScript routines psdefs.ps needed by class PSInterpreter +$(srcdir)/psdefs.cpp: psdefs.ps + if test -f $<; then \ + ps2c PSInterpreter::PSDEFS $< >$@; \ + fi + +psdefs.ps: ; + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.cpp new file mode 100644 index 00000000000..b225b0ba4fd --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.cpp @@ -0,0 +1,276 @@ +/************************************************************************* +** MapLine.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <sstream> +#include "InputBuffer.h" +#include "InputReader.h" +#include "MapLine.h" +#include "Subfont.h" + +using namespace std; + + +/** Constructs a MapLine object by parsing a single mapline from the given stream. */ +MapLine::MapLine (istream &is) + : _sfd(0), _fontindex(0), _slant(0), _bold(0), _extend(1) +{ + char buf[256]; + is.getline(buf, 256); + parse(buf); +} + + +// Some of the following functions have been derived from the dvipdfmx source file fontmap.c: +// http://cvs.ktug.or.kr/viewcvs/dvipdfmx/src/fontmap.c?revision=1.43&view=markup + + +/** Returns true if the given string is in dvips mapline format, and false if it's in dvipdfm format. + @param[in] line string to check */ +bool MapLine::isDVIPSFormat (const char *line) const { + if (strchr(line, '"') || strchr(line, '<')) // these chars are only present in dvips maps + return true; + char prevchar = ' '; + int entry_count=0; + for (const char *p=line; *p; ++p) { + if (isspace(prevchar)) { + if (*p == '-') // options starting with '-' are only present in dvipdfm map files + return false; + if (!isspace(*p)) + entry_count++; + } + prevchar = *p; + } + // tfm_name and ps_name only => dvips map + return entry_count == 2; +} + + +/** Separates main font name and subfont definition name from a given combined name. + * Example: "basename@sfdname@10" => {"basename10", "sfdname"} + * @param[in,out] fontname complete fontname; after separation: main fontname only + * @param[out] sfdname name of subfont definition + * @return true on success */ +static bool split_fontname (string &fontname, string &sfdname) { + size_t pos1; // index of first '@' + if ((pos1 = fontname.find('@')) != string::npos && pos1 > 0) { + size_t pos2; // index of second '@' + if ((pos2 = fontname.find('@', pos1+1)) != string::npos && pos2 > pos1+1) { + sfdname = fontname.substr(pos1+1, pos2-pos1-1); + fontname = fontname.substr(0, pos1) + fontname.substr(pos2+1); + return true; + } + } + return false; +} + + +/** Parses a single mapline and stores the scanned data in member variables. + * The line may either be given in dvips or dvipdfmx mapfile format. + * @param[in] line the mapline */ +void MapLine::parse (const char *line) { + CharInputBuffer ib(line, strlen(line)); + BufferInputReader ir(ib); + _texname = ir.getString(); + string sfdname; + split_fontname(_texname, sfdname); + if (!sfdname.empty()) + _sfd = SubfontDefinition::lookup(sfdname); + if (isDVIPSFormat(line)) + parseDVIPSLine(ir); + else + parseDVIPDFMLine(ir); +} + + +/** Parses a single line in dvips mapfile format. + * @param[in] ir the input stream must be assigned to this reader */ +void MapLine::parseDVIPSLine (InputReader &ir) { + ir.skipSpace(); + if (ir.peek() != '<' && ir.peek() != '"') + _psname = ir.getString(); + ir.skipSpace(); + while (ir.peek() == '<' || ir.peek() == '"') { + if (ir.peek() == '<') { + ir.get(); + if (ir.peek() == '[') + ir.get(); + string name = ir.getString(); + if (name.length() > 4 && name.substr(name.length()-4) == ".enc") + _encname = name.substr(0, name.length()-4); + else + _fontfname = name; + } + else { // ir.peek() == '"' => list of PS font operators + string options = ir.getQuotedString('"'); + StringInputBuffer sib(options); + BufferInputReader sir(sib); + while (!sir.eof()) { + double number; + if (sir.parseDouble(number)) { + // operator with preceding numeric parameter (value opstr) + string opstr = sir.getString(); + if (opstr == "SlantFont") + _slant = number; + else if (opstr == "ExtendFont") + _extend = number; + } + else { + // operator without parameter => skip for now + sir.getString(); + } + } + } + ir.skipSpace(); + } +} + + +static void throw_number_expected (char opt, bool integer_only=false) { + ostringstream oss; + oss << "option -" << opt << ": " << (integer_only ? "integer" : "floating point") << " value expected"; + throw MapLineException(oss.str()); +} + + +/** Parses a single line in dvipdfmx mapfile format. + * @param[in] ir the input stream must be assigned to this reader */ +void MapLine::parseDVIPDFMLine (InputReader &ir) { + ir.skipSpace(); + if (ir.peek() != '-') { + _encname = ir.getString(); + if (_encname == "default" || _encname == "none") + _encname.clear(); + } + ir.skipSpace(); + if (ir.peek() != '-') + _fontfname = ir.getString(); + if (!_fontfname.empty()) { + parseFilenameOptions(_fontfname); + } + ir.skipSpace(); + while (ir.peek() == '-') { + ir.get(); + char option = ir.get(); + if (!isprint(option)) + throw MapLineException("option character expected"); + ir.skipSpace(); + switch (option) { + case 's': // slant + if (!ir.parseDouble(_slant)) + throw_number_expected('s'); + break; + case 'e': // extend + if (!ir.parseDouble(_extend)) + throw_number_expected('e'); + break; + case 'b': // bold + if (!ir.parseDouble(_bold)) + throw_number_expected('b'); + break; + case 'r': //remap (deprecated) + break; + case 'i': // ttc index + if (!ir.parseInt(_fontindex, false)) + throw_number_expected('i', true); + break; + case 'p': // UCS plane + int dummy; + if (!ir.parseInt(dummy, false)) + throw_number_expected('p', true); + break; + case 'u': // to unicode + ir.getString(); + break; + case 'v': // stemV + int stemv; + if (!ir.parseInt(stemv, true)) + throw_number_expected('v', true); + break; + case 'm': // map single chars + ir.skipUntil("-"); + break; + case 'w': // writing mode (horizontal=0, vertical=1) + int vertical; + if (!ir.parseInt(vertical, false)) + throw_number_expected('w', true); + break; + default: + ostringstream oss; + oss << "invalid option: -" << option; + throw MapLineException(oss.str()); + } + ir.skipSpace(); + } +} + + +/** [:INDEX:][!]FONTNAME[/CSI][,VARIANT] */ +void MapLine::parseFilenameOptions (string fname) { + _fontfname = fname; + StringInputBuffer ib(fname); + BufferInputReader ir(ib); + if (ir.peek() == ':' && isdigit(ir.peek(1))) { // index given? + ir.get(); + _fontindex = ir.getInt(); // font index of file with multiple fonts + if (ir.peek() == ':') + ir.get(); + else + _fontindex = 0; + } + if (ir.peek() == '!') // no embedding + ir.get(); + + bool csi_given=false, style_given=false; + int pos; + if ((pos = ir.find('/')) >= 0) { // csi delimiter + csi_given = true; + _fontfname = ir.getString(pos); + } + else if ((pos = ir.find(',')) >= 0) { + style_given = true; + _fontfname = ir.getString(pos); + } + else + _fontfname = ir.getString(); + + if (csi_given) { + if ((pos = ir.find(',')) >= 0) { + style_given = true; + ir.getString(pos); // charcoll + } + else if (ir.eof()) + throw MapLineException("CSI specifier expected"); + else + ir.getString(); // charcoll + } + if (style_given) { + ir.get(); // skip ',' + if (ir.check("BoldItalic")) { + } + else if (ir.check("Bold")) { + } + else if (ir.check("Italic")) { + } + if (!ir.eof()) + throw MapLineException("invalid style given"); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.h new file mode 100644 index 00000000000..16ee9687ae3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MapLine.h @@ -0,0 +1,72 @@ +/************************************************************************* +** MapLine.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MAPLINE_H +#define DVISVGM_MAPLINE_H + +#include <istream> +#include <string> +#include "MessageException.h" + + +class InputReader; +class SubfontDefinition; + + +struct MapLineException : MessageException +{ + MapLineException (const std::string &msg) : MessageException(msg) {} +}; + + +class MapLine +{ + public: + MapLine (std::istream &is); + const std::string& texname () const {return _texname;} + const std::string& psname () const {return _psname;} + const std::string& fontfname () const {return _fontfname;} + const std::string& encname () const {return _encname;} + int fontindex () const {return _fontindex;} + double bold () const {return _bold;} + double slant () const {return _slant;} + double extend () const {return _extend;} + SubfontDefinition* sfd () const {return _sfd;} + + protected: + void init (); + bool isDVIPSFormat (const char *line) const; + void parse (const char *line); + void parseDVIPSLine (InputReader &ir); + void parseDVIPDFMLine (InputReader &ir); + void parseFilenameOptions (std::string opt); + + private: + std::string _texname; ///< TeX font name + std::string _psname; ///< PS font name + std::string _fontfname; ///< name of fontfile + std::string _encname; ///< name of encoding (without file suffix ".enc") + SubfontDefinition *_sfd; ///< subfont definition to be used + int _fontindex; ///< font index of file with multiple fonts (e.g. ttc files) + double _slant, _bold, _extend; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.cpp new file mode 100644 index 00000000000..9eb956f0529 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.cpp @@ -0,0 +1,491 @@ +/************************************************************************* +** Matrix.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cmath> +#include <limits> +#include <sstream> +#include "Calculator.h" +#include "Matrix.h" +#include "XMLString.h" + +using namespace std; + + + +/** Computes the determinant of a given matrix */ +double det (const Matrix &m) { + double sum=0; + for (int i=0; i < 3; ++i) { + sum += m._values[0][i] * m._values[1][(i+1)%3] * m._values[2][(i+2)%3] + - m._values[0][2-i] * m._values[1][(4-i)%3] * m._values[2][(3-i)%3]; + } + return sum; +} + + +/** Computes the determinant of the 2x2 submatrix of m where a given + * row and column were removed. + * @param[in] m base matrix + * @param[in] row row to remove + * @param[in] col column to remove */ +double det (const Matrix &m, int row, int col) { + int c1 = (col+1)%3, c2 = (col+2)%3; + int r1 = (row+1)%3, r2 = (row+2)%3; + if (c1 > c2) + swap(c1, c2); + if (r1 > r2) + swap(r1, r2); + return m._values[r1][c1] * m._values[r2][c2] + - m._values[r1][c2] * m._values[r2][c1]; +} + + +static inline double deg2rad (double deg) { + const double PI = acos(-1.0); + return PI*deg/180.0; +} + + +/** Creates a diagonal matrix ((d,0,0),(0,d,0),(0,0,d)). + * @param[in] d value of diagonal elements */ +Matrix::Matrix (double d) { + set(d); +} + + +/** Creates the matrix ((v0,v1,v2),(v3,v4,v5),(v6,v7,v8)). + * Expects that array v consists of 'size' elements. If size is less than 9, the + * remaining matrix components will be set to those of the identity matrix. + * @param[in] v array containing the matrix components + * @param[in] size size of array v */ +Matrix::Matrix (double v[], unsigned size) { + set(v, size); +} + + +/** Creates the matrix ((v0,v1,v2),(v3,v4,v5),(v6,v7,v8)). + * If vector v has less than 9 elements, the remaining matrix components will be set to + * those of the identity matrix. + * @param[in] v array containing the matrix components + * @param[in] start use vector components start,...,start+8 */ +Matrix::Matrix (const std::vector<double> &v, int start) { + set(v, start); +} + + +Matrix::Matrix (const string &cmds, Calculator &calc) { + parse(cmds, calc); +} + + +Matrix& Matrix::set (double d) { + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + _values[i][j] = (i==j ? d : 0); + return *this; +} + + +Matrix& Matrix::set (double v[], unsigned size) { + size = min(size, 9u); + for (unsigned i=0; i < size; i++) + _values[i/3][i%3] = v[i]; + for (unsigned i=size; i < 9; i++) + _values[i/3][i%3] = (i%4 ? 0 : 1); + return *this; +} + + +/** Set matrix values ((v0,v1,v2),(v3,v4,v5),(v6,v7,v8)). + * If vector v has less than 9 elements, the remaining matrix components will be set to + * those of the identity matrix. + * @param[in] v array containing the matrix components + * @param[in] start use vector components start,...,start+8 */ +Matrix& Matrix::set (const vector<double> &v, int start) { + unsigned size = min((unsigned)v.size()-start, 9u); + for (unsigned i=0; i < size; i++) + _values[i/3][i%3] = v[i+start]; + for (unsigned i=size; i < 9; i++) + _values[i/3][i%3] = (i%4 ? 0 : 1); + return *this; +} + + +Matrix& Matrix::set(const string &cmds, Calculator &calc) { + parse(cmds, calc); + return *this; +} + + +Matrix& Matrix::translate (double tx, double ty) { + if (tx != 0 || ty != 0) { + TranslationMatrix t(tx, ty); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::scale (double sx, double sy) { + if (sx != 1 || sy != 1) { + ScalingMatrix s(sx, sy); + rmultiply(s); + } + return *this; +} + + +/** Multiplies this matrix by ((cos d, -sin d, 0), (sin d, cos d, 0), (0,0,1)) that + * describes an anti-clockwise rotation by d degrees. + * @param[in] deg rotation angle in degrees */ +Matrix& Matrix::rotate (double deg) { + RotationMatrix r(deg); + rmultiply(r); + return *this; +} + + +Matrix& Matrix::xskewByAngle (double deg) { + if (fmod(fabs(deg)-90, 180) != 0) + return xskewByRatio(tan(deg2rad(deg))); + return *this; +} + + +Matrix& Matrix::xskewByRatio (double xyratio) { + if (xyratio != 0) { + double v[] = {1, xyratio}; + Matrix t(v, 2); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::yskewByAngle (double deg) { + if (fmod(fabs(deg)-90, 180) != 0) + return yskewByRatio(tan(deg2rad(deg))); + return *this; +} + + +Matrix& Matrix::yskewByRatio (double xyratio) { + if (xyratio != 0) { + double v[] = {1, 0, 0, xyratio}; + Matrix t(v, 4); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::flip (bool haxis, double a) { + double s = 1; + if (haxis) // mirror at horizontal axis? + s = -1; + double v[] = {-s, 0, (haxis ? 0 : 2*a), 0, s, (haxis ? 2*a : 0), 0, 0, 1}; + Matrix t(v); + rmultiply(t); + return *this; +} + + +/** Swaps rows and columns of the matrix. */ +Matrix& Matrix::transpose () { + for (int i=0; i < 3; i++) + for (int j=i+1; j < 3; j++) + swap(_values[i][j], _values[j][i]); + return *this; +} + + +/** Multiplies this matrix M with matrix tm (tm is the factor on the left side): M := tm * M */ +Matrix& Matrix::lmultiply (const Matrix &tm) { + Matrix ret; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + for (int k=0; k < 3; k++) + ret._values[i][j] += _values[i][k] * tm._values[k][j]; + return *this = ret; +} + + +/** Multiplies this matrix M with matrix tm (tm is the factor on the right side): M := M * tm */ +Matrix& Matrix::rmultiply (const Matrix &tm) { + Matrix ret; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + for (int k=0; k < 3; k++) + ret._values[i][j] += tm._values[i][k] * _values[k][j]; + return *this = ret; +} + + +Matrix& Matrix::invert () { + Matrix ret; + if (double denom = det(*this)) { + for (int i=0; i < 3; ++i) { + for (int j=0; j < 3; ++j) { + ret._values[i][j] = det(*this, i, j)/denom; + if ((i+j)%2 != 0) + ret._values[i][j] *= -1; + } + } + return *this = ret; + } + throw exception(); +} + + +Matrix& Matrix::operator *= (double c) { + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + _values[i][j] *= c; + return *this; +} + + +DPair Matrix::operator * (const DPair &p) const { + double pp[] = {p.x(), p.y(), 1}; + double ret[]= {0, 0}; + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + ret[i] += _values[i][j] * pp[j]; + return DPair(ret[0], ret[1]); +} + + +/** Returns true if this matrix equals. Checks equality by comparing the matrix components. */ +bool Matrix::operator == (const Matrix &m) const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + if (_values[i][j] != m._values[i][j]) + return false; + return true; +} + + +/** Returns true if this matrix doesn't equal m. Checks inequality by comparing the matrix components. */ +bool Matrix::operator != (const Matrix &m) const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + if (_values[i][j] != m._values[i][j]) + return true; + return false; +} + + +/** Returns true if this matrix is the identity matrix ((1,0,0),(0,1,0),(0,0,1)). */ +bool Matrix::isIdentity() const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) { + const double &v = _values[i][j]; + if ((i == j && v != 1) || (i != j && v != 0)) + return false; + } + return true; +} + + +/** Checks whether this matrix describes a plain translation (without any other transformations). + * If so, the parameters tx and ty are filled with the translation components. + * @param[out] tx horizontal translation + * @param[out] ty vertical translation + * @return true if matrix describes a pure translation */ +bool Matrix::isTranslation (double &tx, double &ty) const { + tx = _values[0][2]; + ty = _values[1][2]; + for (int i=0; i < 3; i++) + for (int j=0; j < 2; j++) { + const double &v = _values[i][j]; + if ((i == j && v != 1) || (i != j && v != 0)) + return false; + } + return _values[2][2] == 1; +} + + +/** Gets a parameter for the transformation command. + * @param[in] is parameter chars are read from this stream + * @param[in] calc parameters can be arithmetic expressions, so we need a calculator to evaluate them + * @param[in] def default value if parameter is optional + * @param[in] optional true if parameter is optional + * @param[in] leadingComma true if first non-blank must be a comma + * @return value of argument */ +static double getArgument (istream &is, Calculator &calc, double def, bool optional, bool leadingComma) { + while (isspace(is.peek())) + is.get(); + if (!optional && leadingComma && is.peek() != ',') + throw ParserException("',' expected"); + if (is.peek() == ',') { + is.get(); // skip comma + optional = false; // now we expect a parameter + } + string expr; + while (is && !isupper(is.peek()) && is.peek() != ',') + expr += (char)is.get(); + if (expr.length() == 0) { + if (optional) + return def; + else + throw ParserException("parameter expected"); + } + return calc.eval(expr); +} + + +Matrix& Matrix::parse (istream &is, Calculator &calc) { + *this = Matrix(1); + while (is) { + while (isspace(is.peek())) + is.get(); + int cmd = is.get(); + switch (cmd) { + case 'T': { + double tx = getArgument(is, calc, 0, false, false); + double ty = getArgument(is, calc, 0, true, true); + translate(tx, ty); + break; + } + case 'S': { + double sx = getArgument(is, calc, 1, false, false); + double sy = getArgument(is, calc, sx, true, true ); + scale(sx, sy); + break; + } + case 'R': { + double a = getArgument(is, calc, 0, false, false); + double x = getArgument(is, calc, calc.getVariable("ux")+calc.getVariable("w")/2, true, true); + double y = getArgument(is, calc, calc.getVariable("uy")+calc.getVariable("h")/2, true, true); + translate(-x, -y); + rotate(a); + translate(x, y); + break; + } + case 'F': { + int c = is.get(); + if (c != 'H' && c != 'V') + throw ParserException("'H' or 'V' expected"); + double a = getArgument(is, calc, 0, false, false); + flip(c == 'H', a); + break; + } + case 'K': { + int c = is.get(); + if (c != 'X' && c != 'Y') + throw ParserException("transformation command 'K' must be followed by 'X' or 'Y'"); + double a = getArgument(is, calc, 0, false, false); + if (fabs(cos(deg2rad(a))) <= numeric_limits<double>::epsilon()) { + ostringstream oss; + oss << "illegal skewing angle: " << a << " degrees"; + throw ParserException(oss.str()); + } + if (c == 'X') + xskewByAngle(a); + else + yskewByAngle(a); + break; + } + case 'M': { + double v[9]; + for (int i=0; i < 6; i++) + v[i] = getArgument(is, calc, i%4 ? 0 : 1, i!=0, i!=0); + // third row (0, 0, 1) + v[6] = v[7] = 0; + v[8] = 1; + Matrix tm(v); + rmultiply(tm); + break; + } + default: + ostringstream oss; + oss << "transformation command expected (found '" << cmd << "' instead)"; + throw ParserException(oss.str()); + } + } + return *this; +} + + +Matrix& Matrix::parse (const string &cmds, Calculator &calc) { + istringstream iss; + iss.str(cmds); + return parse(iss, calc); +} + + +/** Returns an SVG matrix expression that can be used in transform attributes. + * ((a,b,c),(d,e,f),(0,0,1)) => matrix(a d b e c f) */ +string Matrix::getSVG () const { + ostringstream oss; + oss << "matrix("; + for (int i=0; i < 3; i++) { + for (int j=0; j < 2; j++) { + if (i > 0 || j > 0) + oss << ' '; + oss << XMLString(_values[j][i]); + } + } + oss << ')'; + return oss.str(); +} + + +ostream& Matrix::write (ostream &os) const { + os << '('; + for (int i=0; i < 3; i++) { + os << '(' << _values[i][0]; + for (int j=1; j < 3; j++) + os << ',' << _values[i][j]; + os << ')'; + if (i < 2) + os << ','; + } + os << ')'; + return os; +} + + +////////////////////////////////////////////////////////////////// + + +TranslationMatrix::TranslationMatrix (double tx, double ty) { + double v[] = {1, 0, tx, 0, 1, ty}; + set(v, 6); +} + + +ScalingMatrix::ScalingMatrix (double sx, double sy) { + double v[] = {sx, 0, 0, 0, sy}; + set(v, 5); +} + + +RotationMatrix::RotationMatrix (double deg) { + double rad = deg2rad(deg); + double c = cos(rad); + double s = sin(rad); + double v[] = {c, -s, 0, s, c}; + set(v, 5); +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.h new file mode 100644 index 00000000000..1da461d99a0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Matrix.h @@ -0,0 +1,108 @@ +/************************************************************************* +** Matrix.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MATRIX_H +#define DVISVGM_MATRIX_H + +#include <istream> +#include <string> +#include <vector> +#include "MessageException.h" +#include "Pair.h" + + +struct ParserException : public MessageException +{ + ParserException (const std::string &msg) : MessageException(msg) {} +}; + +class Calculator; + +class Matrix +{ + friend double det (const Matrix &m); + friend double det (const Matrix &m, int row, int col); + + public: + Matrix (const std::string &cmds, Calculator &calc); + Matrix (double d=0); + Matrix (double v[], unsigned size=9); + Matrix (const std::vector<double> &v, int start=0); + Matrix& set (double d); + Matrix& set (double v[], unsigned size); + Matrix& set (const std::vector<double> &v, int start=0); + Matrix& set (const std::string &cmds, Calculator &calc); + double get (int row, int col) const {return _values[row][col];} + Matrix& transpose (); + Matrix& invert (); + Matrix& parse (std::istream &is, Calculator &c); + Matrix& parse (const std::string &cmds, Calculator &c); + Matrix& lmultiply (const Matrix &tm); + Matrix& rmultiply (const Matrix &tm); + Matrix& translate (double tx, double ty); + Matrix& scale (double sx, double sy); + Matrix& rotate (double deg); + Matrix& xskewByAngle (double deg); + Matrix& yskewByAngle (double deg); + Matrix& xskewByRatio (double xyratio); + Matrix& yskewByRatio (double xyratio); + Matrix& flip (bool h, double a); + Matrix& operator *= (double c); + DPair operator * (const DPair &p) const; + bool operator == (const Matrix &m) const; + bool operator != (const Matrix &m) const; + bool isIdentity() const; + bool isTranslation (double &tx, double &ty) const; + std::string getSVG () const; + std::ostream& write (std::ostream &os) const; + + private: + double _values[3][3]; // row x col +}; + + +struct TranslationMatrix : public Matrix +{ + TranslationMatrix (double tx, double ty); +}; + + +struct ScalingMatrix : public Matrix +{ + ScalingMatrix (double sx, double sy); +}; + + +struct RotationMatrix : public Matrix +{ + RotationMatrix (double deg); +}; + + +inline std::ostream& operator << (std::ostream &os, const Matrix &m) { + return m.write(os); +} + + +double det (const Matrix &m); +double det (const Matrix &m, int row, int col); + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.cpp new file mode 100644 index 00000000000..c875109633f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.cpp @@ -0,0 +1,274 @@ +/************************************************************************* +** Message.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdarg> +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <map> +#include "Message.h" +#include "Terminal.h" + +using namespace std; + +MessageStream::MessageStream () : _os(0), _nl(false), _col(1), _indent(0) { +} + + +MessageStream::MessageStream (std::ostream &os) + : _os(&os), _nl(true), _col(1), _indent(0) +{ + Terminal::init(os); +} + + +MessageStream::~MessageStream () { + if (_os && Message::COLORIZE) + Terminal::finish(*_os); +} + + +void MessageStream::putChar (const char c, ostream &os) { + switch (c) { + case '\r': + os << '\r'; + _nl = true; + _col = 1; + return; + case '\n': + if (!_nl) { + _col = 1; + _nl = true; + os << '\n'; + } + return; + default: + if (_nl) { + os << string(_indent, ' '); + _col += _indent; + } + else { + const int cols = Terminal::columns(); + if (cols > 0 && _col >= cols) { +#ifndef __WIN32__ + // move cursor to next line explicitly (not necessary in Windows/DOS terminal) + os << '\n'; +#endif + os << string(_indent, ' '); + _col = _indent+1; + } + else + _col++; + } + _nl = false; + if (!_nl || c != '\n') + os << c; + } +} + + +MessageStream& MessageStream::operator << (const char *str) { + if (_os && str) { + const char *first = str; + while (*first) { + const char *last = strchr(first, '\n'); + if (!last) + last = first+strlen(first)-1; +#ifndef __WIN32__ + // move cursor to next line explicitly (not necessary in Windows/DOS terminal) + const int cols = Terminal::columns(); + int len = last-first+1; + if (cols > 0 && _col+len > cols && _indent+len <= cols) + putChar('\n', *_os); +#endif + while (first <= last) + putChar(*first++, *_os); + first = last+1; + } + } + return *this; +} + + +MessageStream& MessageStream::operator << (const char &c) { + if (_os) + putChar(c, *_os); + return *this; +} + + +void MessageStream::indent (bool reset) { + if (reset) + _indent = 0; + _indent += 2; +} + + +void MessageStream::outdent (bool all) { + if (all) + _indent = 0; + else if (_indent > 0) + _indent -= 2; +} + + +void MessageStream::clearline () { + if (_os) { + int cols = Terminal::columns(); + *_os << '\r' << string(cols ? cols-1 : 79, ' ') << '\r'; + _nl = true; + _col = 1; + } +} + +static MessageStream nullStream; +static MessageStream messageStream(cerr); + + +////////////////////////////// + +// maximal verbosity +int Message::LEVEL = Message::MESSAGES | Message::WARNINGS | Message::ERRORS; +bool Message::COLORIZE = false; +bool Message::_initialized = false; +Message::Color Message::_classColors[9]; + + +/** Returns the stream for usual messages. */ +MessageStream& Message::mstream (bool prefix, MessageClass mclass) { + init(); + MessageStream *ms = (LEVEL & MESSAGES) ? &messageStream : &nullStream; + if (COLORIZE && ms && ms->os()) { + Terminal::fgcolor(_classColors[mclass].foreground, *ms->os()); + Terminal::bgcolor(_classColors[mclass].background, *ms->os()); + } + if (prefix) + *ms << "\nMESSAGE: "; + return *ms; +} + + +/** Returns the stream for warning messages. */ +MessageStream& Message::wstream (bool prefix) { + init(); + MessageStream *ms = (LEVEL & WARNINGS) ? &messageStream : &nullStream; + if (COLORIZE && ms && ms->os()) { + Terminal::fgcolor(_classColors[MC_WARNING].foreground, *ms->os()); + Terminal::bgcolor(_classColors[MC_WARNING].background, *ms->os()); + } + if (prefix) + *ms << "\nWARNING: "; + return *ms; +} + + +/** Returns the stream for error messages. */ +MessageStream& Message::estream (bool prefix) { + init(); + MessageStream *ms = (LEVEL & ERRORS) ? &messageStream : &nullStream; + if (COLORIZE && ms && ms->os()) { + Terminal::fgcolor(_classColors[MC_ERROR].foreground, *ms->os()); + Terminal::bgcolor(_classColors[MC_ERROR].background, *ms->os()); + } + if (prefix) + *ms << "\nERROR: "; + return *ms; +} + + +static bool colorchar2int (char colorchar, int *val) { + colorchar = tolower(colorchar); + if (colorchar >= '0' && colorchar <= '9') + *val = int(colorchar-'0'); + else if (colorchar >= 'a' && colorchar <= 'f') + *val = int(colorchar-'a'+10); + else if (colorchar == '*') + *val = -1; + else + return false; + return true; +} + + +/** Initializes the Message class. Sets the colors for each message set. + * The colors can be changed via environment variable DVISVGM_COLORS. Its + * value must be a sequence of color entries of the form gg:BF where the + * two-letter ID gg specifies a message set, B the hex digit of the + * background, and F the hex digit of the foreground/text color. + * Color codes: + * - 1: red, 2: green, 4: blue + * - 0-7: dark colors + * - 8-F: light colors + * - *: default color + * Example: num:01 sets page number messages to red on black background */ +void Message::init () { + if (_initialized || !Message::COLORIZE) + return; + + // set default message colors + _classColors[MC_ERROR] = Color(Terminal::RED, true); + _classColors[MC_WARNING] = Color(Terminal::YELLOW); + _classColors[MC_PAGE_NUMBER] = Color(Terminal::BLUE, true); + _classColors[MC_PAGE_SIZE] = Color(Terminal::MAGENTA); + _classColors[MC_PAGE_WRITTEN] = Color(Terminal::GREEN); + _classColors[MC_STATE] = Color(Terminal::CYAN); + _classColors[MC_TRACING] = Color(Terminal::BLUE); + _classColors[MC_PROGRESS] = Color(Terminal::MAGENTA); + + if (const char *color_str = getenv("DVISVGM_COLORS")) { + map<string, MessageClass> classes; + classes["er"] = MC_ERROR; + classes["wn"] = MC_WARNING; + classes["pn"] = MC_PAGE_NUMBER; + classes["ps"] = MC_PAGE_SIZE; + classes["fw"] = MC_PAGE_WRITTEN; + classes["sm"] = MC_STATE; + classes["tr"] = MC_TRACING; + classes["pi"] = MC_PROGRESS; + const char *p=color_str; + + // skip leading whitespace + while (isspace(*p)) + ++p; + + // iterate over color assignments + while (strlen(p) >= 5) { + map<string, MessageClass>::iterator it = classes.find(string(p, 2)); + if (it != classes.end() && p[2] == '=') { + int bgcolor, fgcolor; + if (colorchar2int(p[3], &bgcolor) && colorchar2int(p[4], &fgcolor)) { + _classColors[it->second].background = bgcolor; + _classColors[it->second].foreground = fgcolor; + } + } + p += 5; + + // skip trailing characters in a malformed entry + while (!isspace(*p) && *p != ':' && *p != ';') + ++p; + // skip separation characters + while (isspace(*p) || *p == ':' || *p == ';') + ++p; + } + } + _initialized = true; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.h new file mode 100644 index 00000000000..7c39127dbd4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Message.h @@ -0,0 +1,114 @@ +/************************************************************************* +** Message.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MESSAGE_H +#define DVISVGM_MESSAGE_H + +#include <algorithm> +#include <string> +#include <ostream> +#include <sstream> +#include "Terminal.h" +#include "types.h" + + +class Message; + +class MessageStream +{ + friend class Message; + + public: + MessageStream (); + MessageStream (std::ostream &os); + ~MessageStream (); + + template <typename T> + MessageStream& operator << (const T &obj) { + std::ostringstream oss; + oss << obj; + (*this) << oss.str(); + return *this; + } + + MessageStream& operator << (const char *str); + MessageStream& operator << (const char &c); + MessageStream& operator << (const std::string &str) {return (*this) << str.c_str();} + + void indent (int level) {_indent = std::max(0, level*2);} + void indent (bool reset=false); + void outdent (bool all=false); + void clearline (); + + protected: + void putChar (const char c, std::ostream &os); + std::ostream* os () {return _os;} + + private: + std::ostream *_os; + bool _nl; ///< true if previous character was a newline + int _col; ///< current terminal column + int _indent; ///< indentation width (number of columns/characters) +}; + + +class Message +{ + struct Color { + Color () : foreground(-1), background(-1) {} + Color (Int8 fgcolor) : foreground(fgcolor), background(-1) {} + Color (Int8 fgcolor, bool light) : foreground(fgcolor + (light ? 8 : 0)), background(-1) {} + Color (Int8 fgcolor, Int8 bgcolor) : foreground(fgcolor), background(bgcolor) {} + Int8 foreground; + Int8 background; + }; + + public: + enum MessageClass { + MC_ERROR, + MC_WARNING, + MC_MESSAGE, + MC_PAGE_NUMBER, + MC_PAGE_SIZE, + MC_PAGE_WRITTEN, + MC_STATE, + MC_TRACING, + MC_PROGRESS, + }; + + public: + static MessageStream& mstream (bool prefix=false, MessageClass mclass=MC_MESSAGE); + static MessageStream& estream (bool prefix=false); + static MessageStream& wstream (bool prefix=false); + + enum {ERRORS=1, WARNINGS=2, MESSAGES=4}; + static int LEVEL; + static bool COLORIZE; + + protected: + static void init (); + + + private: + static Color _classColors[]; + static bool _initialized; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MessageException.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MessageException.h new file mode 100644 index 00000000000..48ae4b5bb4c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MessageException.h @@ -0,0 +1,39 @@ +/************************************************************************* +** MessageException.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MESSAGEEXCEPTION_H +#define DVISVGM_MESSAGEEXCEPTION_H + +#include <exception> +#include <string> + + +class MessageException : public std::exception +{ + public: + MessageException (const std::string &msg) : _message(msg) {} + virtual ~MessageException () throw() {} + const char* what () const throw() {return _message.c_str();} + + private: + std::string _message; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.cpp new file mode 100644 index 00000000000..d7922b1825b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.cpp @@ -0,0 +1,134 @@ +/************************************************************************* +** MetafontWrapper.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdlib> +#include <cctype> +#include <fstream> +#include <sstream> +#include "FileSystem.h" +#include "FileFinder.h" +#include "Message.h" +#include "MetafontWrapper.h" +#include "Process.h" +#include "SignalHandler.h" +#include "macros.h" + +using namespace std; + + +MetafontWrapper::MetafontWrapper (const string &fname) : _fontname(fname) +{ +} + + +/** Calls Metafont and evaluates the logfile. If a gf file was successfully + * generated the dpi value is stripped from the filename + * (e.g. cmr10.600gf => cmr10.gf). This makes life easier... + * @param[in] mode Metafont mode, e.g. "ljfour" + * @param[in] mag magnification factor + * @return true on success */ +bool MetafontWrapper::call (const string &mode, double mag) { + if (!FileFinder::lookup(_fontname+".mf")) + return false; // mf file not available => no need to call the "slow" Metafont + FileSystem::remove(_fontname+".gf"); + +#ifdef __WIN32__ +#ifdef TEXLIVEWIN32 + const char *mfname = "mf-nowin.exe"; +#else + const char *mfname = "mf.exe"; +#endif + const char *cmd = FileFinder::lookup(mfname, false); + if (!cmd) { + Message::estream(true) << "can't run Metafont (" << mfname << " not found)\n"; + return false; + } +#else + const char *cmd = "mf"; +#endif + ostringstream oss; + oss << "\"\\mode=" << mode << ";" + "mag:=" << mag << ";" + "batchmode;" + "input " << _fontname << "\""; + Message::mstream(false, Message::MC_STATE) << "\nrunning Metafont for " << _fontname << '\n'; + Process mf_process(cmd, oss.str().c_str()); + mf_process.run(); + + // try to read Metafont's logfile and get name of created GF file + ifstream ifs((_fontname+".log").c_str()); + if (ifs) { + char buf[128]; + while (ifs) { + ifs.getline(buf, 128); + string line = buf; + if (line.substr(0, 15) == "! Interruption.") + SignalHandler::instance().trigger(true); + if (line.substr(0, 17) == "Output written on") { + size_t pos = line.find("gf ", 18+_fontname.length()); + if (pos != string::npos) { + string gfname = line.substr(18, pos-16); // GF filename found + FileSystem::rename(gfname, _fontname+".gf"); + } + break; + } + } + } + ifstream gf((_fontname+".gf").c_str()); + return (bool)gf; +} + + +/** Calls Metafont if output files (tfm and gf) don't already exist. + * @param[in] mode Metafont mode to be used (e.g. 'ljfour') + * @param[in] mag magnification factor + * @return true on success */ +bool MetafontWrapper::make (const string &mode, double mag) { + ifstream tfm((_fontname+".tfm").c_str()); + ifstream gf((_fontname+".gf").c_str()); + if (gf && tfm) // @@ distinguish between gf and tfm + return true; + return call(mode, mag); +} + + +bool MetafontWrapper::success () const { + ifstream tfm((_fontname+".tfm").c_str()); + ifstream gf((_fontname+".gf").c_str()); + return tfm && gf; +} + + +/** Remove all files created by a Metafont call (tfm, gf, log). + * @param[in] keepGF if true, GF files won't be removed */ +void MetafontWrapper::removeOutputFiles (bool keepGF) { + removeOutputFiles(_fontname, keepGF); +} + + +/** Remove all files created by a Metafont call for a given font (tfm, gf, log). + * @param[in] fontname name of font whose temporary files should be removed + * @param[in] keepGF if true, GF files will be kept */ +void MetafontWrapper::removeOutputFiles (const string &fontname, bool keepGF) { + const char *ext[] = {"gf", "tfm", "log", 0}; + for (const char **p = keepGF ? ext+2 : ext; *p; ++p) + FileSystem::remove(fontname + "." + *p); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.h new file mode 100644 index 00000000000..3b2485122d0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MetafontWrapper.h @@ -0,0 +1,43 @@ +/************************************************************************* +** MetafontWrapper.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_METAFONTWRAPPER_H +#define DVISVGM_METAFONTWRAPPER_H + +#include <string> + + +struct FileFinder; + +class MetafontWrapper +{ + public: + MetafontWrapper (const std::string &fontname); + bool call (const std::string &mode, double mag); + bool make (const std::string &mode, double mag); + bool success () const; + void removeOutputFiles (bool keepGF=false); + static void removeOutputFiles (const std::string &fontname, bool keepGF=false); + + private: + std::string _fontname; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.cpp new file mode 100644 index 00000000000..bb4353f8ee4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.cpp @@ -0,0 +1,106 @@ +/************************************************************************* +** MiKTeXCom.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <comdef.h> +#include <string> +#include "MessageException.h" +#include "MiKTeXCom.h" +#include "macros.h" + +using namespace std; + + +MiKTeXCom::MiKTeXCom () : _session(0) { + if (FAILED(CoInitialize(0))) + throw MessageException("COM library could not be initialized\n"); +#ifdef _MSC_VER + HRESULT hres = _session.CreateInstance(L"MiKTeX.Session"); +#elif defined(__WIN64__) + HRESULT hres = CoCreateInstance(CLSID_MiKTeXSession2_9, 0, CLSCTX_LOCAL_SERVER, IID_ISession2, (void**)&_session); +#else + HRESULT hres = CoCreateInstance(CLSID_MiKTeXSession2_9, 0, CLSCTX_INPROC_SERVER, IID_ISession2, (void**)&_session); +#endif + if (FAILED(hres)) { + CoUninitialize(); + throw MessageException("MiKTeX.Session could not be initialized"); + } +} + + +MiKTeXCom::~MiKTeXCom () { + if (_session) { +#ifdef _MSC_VER + _session.Release(); +#else + _session->Release(); +#endif + _session = 0; // avoid automatic calling of Release() after CoUninitialize() + } + CoUninitialize(); +} + + +string MiKTeXCom::getVersion () { +#ifdef _MSC_VER + MiKTeXSetupInfo info = _session->GetMiKTeXSetupInfo(); +#else + MiKTeXSetupInfo info; + _session->GetMiKTeXSetupInfo(&info); +#endif + _bstr_t version = info.version; + return string(version); +} + + +string MiKTeXCom::getBinDir () { +#ifdef _MSC_VER + MiKTeXSetupInfo info = _session->GetMiKTeXSetupInfo(); +#else + MiKTeXSetupInfo info; + _session->GetMiKTeXSetupInfo(&info); +#endif + _bstr_t bindir = info.binDirectory; + return string(bindir); +} + + +const char* MiKTeXCom::findFile (const char *fname) { + try { + _bstr_t path; + static string ret; +#ifdef _MSC_VER + HRESULT hres = _session->FindFile(fname, path.GetAddress()); + bool found = (hres != 0); +#else + VARIANT_BOOL found_var; + _session->FindFile(_bstr_t(fname), path.GetAddress(), &found_var); + bool found = (found_var == VARIANT_TRUE); +#endif + if (found) { + ret = _bstr_t(path); + return ret.c_str(); + } + return 0; + } + catch (_com_error &e) { + throw MessageException((const char*)e.Description()); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.h new file mode 100644 index 00000000000..dcb6271a4bc --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/MiKTeXCom.h @@ -0,0 +1,52 @@ +/************************************************************************* +** MiKTeXCom.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MIKTEXCOM_H +#define DVISVGM_MIKTEXCOM_H + +#include <string> + +#ifdef _MSC_VER +#import <MiKTeX209-session.tlb> +using namespace MiKTeXSession2_9; +#else +#include "miktex209-session.h" +#endif + + +class MiKTeXCom +{ + public: + MiKTeXCom (); + ~MiKTeXCom (); + std::string getBinDir (); + std::string getVersion (); + const char* findFile (const char* fname); + + private: +#ifdef _MSC_VER + ISession2Ptr _session; +#else + ISession2 *_session; +#endif +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.cpp new file mode 100644 index 00000000000..0a5119f6938 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.cpp @@ -0,0 +1,46 @@ +/************************************************************************* +** NoPsSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "Message.h" +#include "NoPsSpecialHandler.h" + +using namespace std; + + +bool NoPsSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + _count++; + return true; +} + + +void NoPsSpecialHandler::dviEndPage (unsigned pageno) { + if (_count > 0) { + string suffix = (_count > 1 ? "s" : ""); + Message::wstream(true) << _count << " PostScript special" << suffix << " ignored. The resulting SVG might look wrong.\n"; + _count = 0; + } +} + + +const char** NoPsSpecialHandler::prefixes () const { + static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.h new file mode 100644 index 00000000000..7a017fecb06 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/NoPsSpecialHandler.h @@ -0,0 +1,42 @@ +/************************************************************************* +** NoPsSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_NOPSSPECIALHANDLER_H +#define DVISVGM_NOPSSPECIALHANDLER_H + +#include "SpecialHandler.h" + +class NoPsSpecialHandler : public SpecialHandler, public DVIEndPageListener +{ + public: + NoPsSpecialHandler () : _count(0) {} + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + const char* name () const {return 0;} + const char* info () const {return 0;} + const char** prefixes () const; + + protected: + void dviEndPage (unsigned pageno); + + private: + unsigned _count; // number of PS specials skipped +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSFilter.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSFilter.h new file mode 100644 index 00000000000..e2c5c092dd3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSFilter.h @@ -0,0 +1,41 @@ +/************************************************************************* +** PSFilter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PSFILTER_H +#define DVISVGM_PSFILTER_H + +class PSInterpreter; + +class PSFilter +{ + public: + PSFilter (PSInterpreter &psi) : _psi(psi) {} + virtual ~PSFilter () {} + virtual void execute (const char *code, size_t len) =0; + virtual bool active () const =0; + + protected: + PSInterpreter& psInterpreter () {return _psi;} + + private: + PSInterpreter &_psi; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.cpp new file mode 100644 index 00000000000..9ca5ed39c27 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.cpp @@ -0,0 +1,357 @@ +/************************************************************************* +** PSInterpreter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include <fstream> +#include <iostream> +#include <sstream> +#include "FileFinder.h" +#include "InputReader.h" +#include "Message.h" +#include "PSFilter.h" +#include "PSInterpreter.h" +#include "SignalHandler.h" + +using namespace std; + + +const char *PSInterpreter::GSARGS[] = { + "gs", // dummy name + "-q", // be quiet, suppress gs banner + "-dSAFER", // disallow writing of files + "-dNODISPLAY", // we don't need a display device + "-dNOPAUSE", // keep going + "-dWRITESYSTEMDICT", // leave systemdict writable as some operators must be replaced + "-dNOPROMPT", +// "-dNOBIND", +}; + + +/** Constructs a new PSInterpreter object. + * @param[in] actions template methods to be executed after recognizing the corresponding PS operator. */ +PSInterpreter::PSInterpreter (PSActions *actions) + : _mode(PS_NONE), _actions(actions), _filter(0), _bytesToRead(0), _inError(false), _initialized(false) +{ +} + + +void PSInterpreter::init () { + if (!_initialized) { + _gs.init(sizeof(GSARGS)/sizeof(char*), GSARGS, this); + _gs.set_stdio(input, output, error); + _initialized = true; + // Before executing any random PS code redefine some operators and run + // initializing PS code. This cannot be done in the constructor because we + // need the completely initialized PSInterpreter object here. + execute(PSDEFS); + } +} + + +PSActions* PSInterpreter::setActions (PSActions *actions) { + PSActions *old_actions = _actions; + _actions = actions; + return old_actions; +} + + +/** Checks if the given status value returned by Ghostscript indicates an error. + * @param[in] status status value returned by Ghostscript after the execution of a PS snippet + * @throw PSException if the status value indicates a PostScript error */ +void PSInterpreter::checkStatus (int status) { + if (status < 0) { + _mode = PS_QUIT; + if (status < -100) + throw PSException("fatal error"); + if (_errorMessage.empty()) + throw PSException(_gs.error_name(status)); + throw PSException(_errorMessage); + } +} + + +/** Executes a chunk of PostScript code. + * @param[in] str buffer containing the code + * @param[in] len number of characters in buffer + * @param[in] flush If true, a final 'flush' is sent which forces the output buffer to be written immediately. + * @return true if the assigned number of bytes have been read */ +bool PSInterpreter::execute (const char *str, size_t len, bool flush) { + init(); + if (_mode == PS_QUIT) + return false; + + int status=0; + if (_mode == PS_NONE) { + _gs.run_string_begin(0, &status); + _mode = PS_RUNNING; + } + checkStatus(status); + + bool complete=false; + if (_bytesToRead > 0 && len >= _bytesToRead) { + len = _bytesToRead; + complete = true; + } + + if (_filter && _filter->active()) { + PSFilter *filter = _filter; + _filter = 0; // prevent recursion when filter calls execute() + filter->execute(str, len); + if (filter->active()) // filter still active after execution? + _filter = filter; + return complete; + } + + // feed Ghostscript with code chunks that are not larger than 64KB + // => see documentation of gsapi_run_string_foo() + const char *p=str; + while (PS_RUNNING && len > 0) { + SignalHandler::instance().check(); + size_t chunksize = min(len, (size_t)0xffff); + _gs.run_string_continue(p, chunksize, 0, &status); + p += chunksize; + len -= chunksize; + if (_bytesToRead > 0) + _bytesToRead -= chunksize; + if (status == -101) // e_Quit + _mode = PS_QUIT; + else + checkStatus(status); + } + if (flush) { + // force writing contents of output buffer + _gs.run_string_continue("\nflush ", 7, 0, &status); + } + return complete; +} + + +/** Executes a chunk of PostScript code read from a stream. The method returns on EOF. + * @param[in] is the input stream + * @param[in] flush If true, a final 'flush' is sent which forces the output buffer to be written immediately. + * @return true if the assigned number of bytes have been read */ +bool PSInterpreter::execute (istream &is, bool flush) { + char buf[4096]; + bool finished = false; + while (is && !is.eof() && !finished) { + is.read(buf, 4096); + finished = execute(buf, is.gcount(), false); + } + execute("\n", 1, flush); + return finished; +} + + +bool PSInterpreter::executeRaw (const string &str, int n) { + _rawData.clear(); + ostringstream oss; + oss << str << ' ' << n << " (raw) prcmd\n"; + execute(oss.str()); + return !_rawData.empty(); +} + + +/** This callback function handles input from stdin to Ghostscript. Currently not needed. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf takes the read characters + * @param[in] len size of buffer buf + * @return number of characters read */ +int GSDLLCALL PSInterpreter::input (void *inst, char *buf, int len) { + return 0; +} + + +/** This callback function handles output from Ghostscript to stdout. It looks for + * emitted commands staring with "dvi." and executes them by calling method callActions. + * Ghostscript sends the text in chunks by several calls of this function. + * Unfortunately, the PostScript specification wants error messages also to be sent to stdout + * instead of stderr. Thus, we must collect and concatenate the chunks until an evaluable text + * snippet is completely received. Furthermore, error messages have to be recognized and to be + * filtered out. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf contains the characters to be output + * @param[in] len number of characters in buf + * @return number of processed characters (equals 'len') */ +int GSDLLCALL PSInterpreter::output (void *inst, const char *buf, int len) { + PSInterpreter *self = static_cast<PSInterpreter*>(inst); + if (self && self->_actions) { + const size_t MAXLEN = 512; // maximal line length (longer lines are of no interest) + const char *end = buf+len-1; // last position of buf + for (const char *first=buf, *last=buf; first <= end; last++, first=last) { + // move first and last to begin and end of the next line, respectively + while (last < end && *last != '\n') + last++; + size_t linelength = last-first+1; + if (linelength > MAXLEN) // skip long lines since they don't contain any relevant information + continue; + + vector<char> &linebuf = self->_linebuf; // just a shorter name... + if ((*last == '\n' || !self->active()) || self->_inError) { + if (linelength + linebuf.size() > 1) { // prefix "dvi." plus final newline + SplittedCharInputBuffer ib(linebuf.empty() ? 0 : &linebuf[0], linebuf.size(), first, linelength); + BufferInputReader in(ib); + if (self->_inError) + self->_errorMessage += string(first, linelength); + else { + in.skipSpace(); + if (in.check("Unrecoverable error: ")) { + self->_errorMessage.clear(); + while (!in.eof()) + self->_errorMessage += in.get(); + self->_inError = true; + } + else if (in.check("dvi.")) + self->callActions(in); + } + } + linebuf.clear(); + } + else { // no line end found => + // save remaining characters and prepend them to the next incoming chunk of characters + if (linebuf.size() + linelength > MAXLEN) + linebuf.clear(); // don't care for long lines + else { + size_t currsize = linebuf.size(); + linebuf.resize(currsize+linelength); + memcpy(&linebuf[currsize], first, linelength); + } + } + } + } + return len; +} + + +/** Converts a vector of strings to a vector of doubles. + * @param[in] str the strings to be converted + * @param[out] d the resulting doubles */ +static void str2double (const vector<string> &str, vector<double> &d) { + for (size_t i=0; i < str.size(); i++) { + istringstream iss(str[i]); + iss >> d[i]; + } +} + + +/** Evaluates a command emitted by Ghostscript and invokes the corresponding + * method of interface class PSActions. + * @param[in] in reader pointing to the next command */ +void PSInterpreter::callActions (InputReader &in) { + // array of currently supported operators (must be ascendingly sorted) + static const struct Operator { + const char *name; // name of operator + int pcount; // number of parameters (< 0 : variable number of parameters) + void (PSActions::*op)(vector<double> &p); // operation handler + } operators [] = { + {"applyscalevals", 3, &PSActions::applyscalevals}, + {"clip", 0, &PSActions::clip}, + {"closepath", 0, &PSActions::closepath}, + {"curveto", 6, &PSActions::curveto}, + {"eoclip", 0, &PSActions::eoclip}, + {"eofill", 0, &PSActions::eofill}, + {"fill", 0, &PSActions::fill}, + {"grestore", 0, &PSActions::grestore}, + {"grestoreall", 0, &PSActions::grestoreall}, + {"gsave", 0, &PSActions::gsave}, + {"initclip", 0, &PSActions::initclip}, + {"lineto", 2, &PSActions::lineto}, + {"makepattern", -1, &PSActions::makepattern}, + {"moveto", 2, &PSActions::moveto}, + {"newpath", 0, &PSActions::newpath}, + {"querypos", 2, &PSActions::querypos}, + {"raw", -1, 0}, + {"restore", 1, &PSActions::restore}, + {"rotate", 1, &PSActions::rotate}, + {"save", 1, &PSActions::save}, + {"scale", 2, &PSActions::scale}, + {"setcmykcolor", 4, &PSActions::setcmykcolor}, + {"setdash", -1, &PSActions::setdash}, + {"setgray", 1, &PSActions::setgray}, + {"sethsbcolor", 3, &PSActions::sethsbcolor}, + {"setlinecap", 1, &PSActions::setlinecap}, + {"setlinejoin", 1, &PSActions::setlinejoin}, + {"setlinewidth", 1, &PSActions::setlinewidth}, + {"setmatrix", 6, &PSActions::setmatrix}, + {"setmiterlimit", 1, &PSActions::setmiterlimit}, + {"setopacityalpha", 1, &PSActions::setopacityalpha}, + {"setpattern", -1, &PSActions::setpattern}, + {"setrgbcolor", 3, &PSActions::setrgbcolor}, + {"stroke", 0, &PSActions::stroke}, + {"translate", 2, &PSActions::translate}, + }; + if (_actions) { + in.skipSpace(); + // binary search + int first=0, last=sizeof(operators)/sizeof(Operator)-1; + while (first <= last) { + int mid = first+(last-first)/2; + int cmp = in.compare(operators[mid].name); + if (cmp > 0) + last = mid-1; + else if (cmp < 0) + first = mid+1; + else { + if (!operators[mid].op) { // raw string data received + _rawData.clear(); + in.skipSpace(); + while (!in.eof()) { + _rawData.push_back(in.getString()); + in.skipSpace(); + } + } + else { + // collect parameters and call handler + vector<string> params; + int pcount = operators[mid].pcount; + if (pcount < 0) { // variable number of parameters? + in.skipSpace(); + while (!in.eof()) { // read all available parameters + params.push_back(in.getString()); + in.skipSpace(); + } + } + else { // fix number of parameters + for (int i=0; i < pcount; i++) { + in.skipSpace(); + params.push_back(in.getString()); + } + } + vector<double> v(params.size()); + str2double(params, v); + (_actions->*operators[mid].op)(v); + _actions->executed(); + } + break; + } + } + } +} + + +/** This callback function handles output from Ghostscript to stderr. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf contains the characters to be output + * @param[in] len number of chars in buf + * @return number of processed characters */ +int GSDLLCALL PSInterpreter::error (void *inst, const char *buf, int len) { + return len; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.h new file mode 100644 index 00000000000..c1f30598e16 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSInterpreter.h @@ -0,0 +1,127 @@ +/************************************************************************* +** PSInterpreter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PSINTERPRETER_H +#define DVISVGM_PSINTERPRETER_H + +#include <cstring> +#include <istream> +#include <string> +#include <vector> +#include "Ghostscript.h" +#include "InputReader.h" +#include "MessageException.h" + + +struct PSException : public MessageException +{ + PSException (const std::string &msg) : MessageException(msg) {} +}; + + +/** This interface provides the template methods called by PSInterpreter when executing a PS snippet. + * Each method corresponds to a PostScript operator of the same name. */ +struct PSActions +{ + virtual ~PSActions () {} + virtual void applyscalevals (std::vector<double> &p) =0; + virtual void clip (std::vector<double> &p) =0; + virtual void closepath (std::vector<double> &p) =0; + virtual void curveto (std::vector<double> &p) =0; + virtual void eoclip (std::vector<double> &p) =0; + virtual void eofill (std::vector<double> &p) =0; + virtual void fill (std::vector<double> &p) =0; + virtual void gsave (std::vector<double> &p) =0; + virtual void grestore (std::vector<double> &p) =0; + virtual void grestoreall (std::vector<double> &p) =0; + virtual void initclip (std::vector<double> &p) =0; + virtual void lineto (std::vector<double> &p) =0; + virtual void makepattern (std::vector<double> &p) =0; + virtual void moveto (std::vector<double> &p) =0; + virtual void newpath (std::vector<double> &p) =0; + virtual void querypos (std::vector<double> &p) =0; + virtual void restore (std::vector<double> &p) =0; + virtual void rotate (std::vector<double> &p) =0; + virtual void save (std::vector<double> &p) =0; + virtual void scale (std::vector<double> &p) =0; + virtual void setcmykcolor (std::vector<double> &cmyk) =0; + virtual void setdash (std::vector<double> &p) =0; + virtual void setgray (std::vector<double> &p) =0; + virtual void sethsbcolor (std::vector<double> &hsb) =0; + virtual void setlinecap (std::vector<double> &p) =0; + virtual void setlinejoin (std::vector<double> &p) =0; + virtual void setlinewidth (std::vector<double> &p) =0; + virtual void setmatrix (std::vector<double> &p) =0; + virtual void setmiterlimit (std::vector<double> &p) =0; + virtual void setopacityalpha (std::vector<double> &p) =0; + virtual void setpattern (std::vector<double> &p) =0; + virtual void setrgbcolor (std::vector<double> &rgb) =0; + virtual void stroke (std::vector<double> &p) =0; + virtual void translate (std::vector<double> &p) =0; + virtual void executed () {} // triggered if one of the above PS operators has been executed +}; + +class PSFilter; + +/** This class provides methods to execute chunks of PostScript code and calls + * several template methods on invocation of selected PS operators (see PSActions). */ +class PSInterpreter +{ + enum Mode {PS_NONE, PS_RUNNING, PS_QUIT}; + + public: + PSInterpreter (PSActions *actions=0); + bool execute (const char *str, size_t len, bool flush=true); + bool execute (const char *str, bool flush=true) {return execute(str, std::strlen(str), flush);} + bool execute (const std::string &str, bool flush=true) {return execute(str.c_str(), flush);} + bool execute (std::istream &is, bool flush=true); + bool executeRaw (const std::string &str, int n); + bool active () const {return _mode != PS_QUIT;} + void limit (size_t max_bytes) {_bytesToRead = max_bytes;} + void setFilter (PSFilter *filter) {_filter = filter;} + PSActions* setActions (PSActions *actions); + const std::vector<std::string>& rawData () const {return _rawData;} + + protected: + void init (); + // callback functions + static int GSDLLCALL input (void *inst, char *buf, int len); + static int GSDLLCALL output (void *inst, const char *buf, int len); + static int GSDLLCALL error (void *inst, const char *buf, int len); + + void checkStatus (int status); + void callActions (InputReader &cib); + + private: + Ghostscript _gs; + Mode _mode; ///< current execution mode + PSActions *_actions; ///< actions to be performed + PSFilter *_filter; ///< active filter used to process PS code + size_t _bytesToRead; ///< if > 0, maximal number of bytes to be processed by following calls of execute() + std::vector<char> _linebuf; + std::string _errorMessage; ///< text of error message + bool _inError; ///< true if scanning error message + bool _initialized; ///< true if PSInterpreter has been completely initialized + std::vector<std::string> _rawData; ///< raw data received + static const char *GSARGS[]; ///< parameters passed to Ghostscript + static const char *PSDEFS; ///< initial PostScript definitions +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.cpp new file mode 100644 index 00000000000..107dac4f795 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.cpp @@ -0,0 +1,175 @@ +/************************************************************************* +** PSPattern.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include <vector> +#include "BoundingBox.h" +#include "PSPattern.h" +#include "SpecialActions.h" +#include "SVGTree.h" +#include "XMLNode.h" + +using namespace std; + + +string PSPattern::svgID () const { + return XMLString("pat")+XMLString(_id); +} + + +/** Appends the definition of this pattern to the "def" section of the SVG tree. */ +void PSPattern::apply (SpecialActions *actions) { + if (XMLElementNode *pattern = createPatternNode()) + actions->appendToDefs(pattern); +} + + +///////////////////////////////////////////////////////////////////////////// + +PSTilingPattern::PSTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep) + : PSPattern(id), _bbox(bbox), _matrix(matrix), _xstep(xstep), _ystep(ystep), _groupNode(0) +{ + _groupNode = PSTilingPattern::createGroupNode(); +} + + +PSTilingPattern::~PSTilingPattern () { + delete _groupNode; +} + + +/** Creates a new pattern element representing the pattern defined in the PS code. */ +XMLElementNode* PSTilingPattern::createPatternNode () const { + if (!_groupNode) + return 0; + BoundingBox box(_bbox.minX(), _bbox.minY(), _bbox.minX()+_xstep, _bbox.minY()+_ystep); + XMLElementNode *pattern = new XMLElementNode("pattern"); + pattern->addAttribute("id", svgID()); + pattern->addAttribute("x", box.minX()); + pattern->addAttribute("y", box.minY()); + pattern->addAttribute("width", box.width()); + pattern->addAttribute("height", box.height()); + pattern->addAttribute("viewBox", box.toSVGViewBox()); + pattern->addAttribute("patternUnits", "userSpaceOnUse"); + if (!_matrix.isIdentity()) + pattern->addAttribute("patternTransform", _matrix.getSVG()); + if (_xstep < _bbox.width() || _ystep < _bbox.height()) { // overlapping tiles? + // disable clipping at the tile borders => tiles become "transparent" + pattern->addAttribute("overflow", "visible"); + } + if (XMLElementNode *clip=createClipNode()) + pattern->append(clip); + pattern->append(_groupNode); + return pattern; +} + + +/** Creates a new clip element restricting the drawing area to the + * dimensions given in the definition of the pattern. */ +XMLElementNode* PSTilingPattern::createClipNode() const { + XMLElementNode *clip = new XMLElementNode("clipPath"); + clip->addAttribute("id", "pc"+XMLString(psID())); + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", _bbox.minX()); + rect->addAttribute("y", _bbox.minY()); + rect->addAttribute("width", _bbox.width()); + rect->addAttribute("height", _bbox.height()); + clip->append(rect); + return clip; +} + + +/** Creates a new group element that contains all "drawing" elements that + * define the pattern graphic. */ +XMLElementNode* PSTilingPattern::createGroupNode () const { + // add all succeeding path elements to this group + XMLElementNode *group = new XMLElementNode("g"); + group->addAttribute("clip-path", XMLString("url(#pc")+XMLString(psID())+")"); + return group; +} + + +void PSTilingPattern::apply (SpecialActions *actions) { + PSPattern::apply(actions); + _groupNode = 0; +} + + +///////////////////////////////////////////////////////////////////////////// + +PSColoredTilingPattern::PSColoredTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep) + : PSTilingPattern(id, bbox, matrix, xstep, ystep) +{ +} + + +///////////////////////////////////////////////////////////////////////////// + +PSUncoloredTilingPattern::PSUncoloredTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep) + : PSTilingPattern(id, bbox, matrix, xstep, ystep), _applied(false) +{ +} + + +PSUncoloredTilingPattern::~PSUncoloredTilingPattern () { + if (_applied) + setGroupNode(0); // prevent deleting the group node in the parent destructor +} + + +/** Returns an SVG id value that identifies this pattern with the current color applied. */ +string PSUncoloredTilingPattern::svgID () const { + ostringstream oss; + oss << PSPattern::svgID() << '-' << hex << _currentColor; + return oss.str(); +} + + +/** Appends the definition of this pattern with the current color applied + * to the "def" section of the SVG tree. */ +void PSUncoloredTilingPattern::apply (SpecialActions* actions) { + set<Color>::iterator it=_colors.find(_currentColor); + if (it == _colors.end()) { + if (_applied) + setGroupNode(static_cast<XMLElementNode*>(getGroupNode()->clone())); + // assign current color to the pattern graphic + vector<XMLElementNode*> colored_elems; + const char *attribs[] = {"fill", "stroke"}; + for (int i=0; i < 2; i++) { + getGroupNode()->findDescendants(0, attribs[i], colored_elems); + for (vector<XMLElementNode*>::iterator it=colored_elems.begin(); it != colored_elems.end(); ++it) + if (string((*it)->getAttributeValue(attribs[i])) != "none") + (*it)->addAttribute(attribs[i], _currentColor.rgbString()); + colored_elems.clear(); + } + PSPattern::apply(actions); + _colors.insert(_currentColor); + _applied = true; + } +} + + +XMLElementNode* PSUncoloredTilingPattern::createClipNode() const { + // only the first instance of this patterns get a clip element + if (_colors.empty()) + return PSTilingPattern::createClipNode(); + return 0; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.h new file mode 100644 index 00000000000..db11b59f0e0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPattern.h @@ -0,0 +1,100 @@ +/************************************************************************* +** PSPattern.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PSPATTERN_H +#define DVISVGM_PSPATTERN_H + +#include <set> +#include <string> +#include "BoundingBox.h" +#include "Color.h" +#include "Matrix.h" + + +struct SpecialActions; +class SVGTree; +class XMLElementNode; + +class PSPattern +{ + public: + virtual ~PSPattern () {} + virtual int psID () const {return _id;} + virtual std::string svgID () const; + virtual void apply (SpecialActions *actions); + + protected: + PSPattern (int id) : _id(id) {} + virtual XMLElementNode* createPatternNode () const =0; + + private: + int _id; ///< PostSCript ID of this pattern +}; + + +class PSTilingPattern : public PSPattern +{ + public: + ~PSTilingPattern (); + virtual XMLElementNode* getContainerNode () {return _groupNode;} + void apply (SpecialActions *actions); + + protected: + PSTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep); + XMLElementNode* createPatternNode () const; + virtual XMLElementNode* createClipNode () const; + virtual XMLElementNode* createGroupNode () const; + virtual XMLElementNode* getGroupNode () const {return _groupNode;} + virtual void setGroupNode (XMLElementNode *node) {_groupNode = node;} + + private: + BoundingBox _bbox; ///< bounding box of the tile graphics + Matrix _matrix; ///< tile transformation + double _xstep, _ystep; ///< horizontal and vertical distance between neighboured tiles + XMLElementNode *_groupNode; ///< group containing the drawing elements +}; + + +class PSColoredTilingPattern : public PSTilingPattern +{ + public: + PSColoredTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep); +}; + + +class PSUncoloredTilingPattern : public PSTilingPattern +{ + public: + PSUncoloredTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep); + ~PSUncoloredTilingPattern (); + std::string svgID () const; + void setColor (Color color) {_currentColor = color;} + void apply (SpecialActions *actions); + + protected: + XMLElementNode* createClipNode () const; + + private: + std::set<Color> _colors; ///< colors this pattern has already been drawn with + Color _currentColor; ///< current color to be applied + bool _applied; ///< has pattern with current group node already been applied to the SVG tree? +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.cpp new file mode 100644 index 00000000000..c9b3b080118 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.cpp @@ -0,0 +1,118 @@ +/************************************************************************* +** PSPreviewFilter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <vector> +#include "InputBuffer.h" +#include "InputReader.h" +#include "PSInterpreter.h" +#include "PSPreviewFilter.h" +#include "SpecialActions.h" + + +using namespace std; + +PSPreviewFilter::PSPreviewFilter (PSInterpreter &psi) + : PSFilter(psi), _active(false), _tightpage(false), _dvi2bp(1.0/65536.0) +{ +} + + +/** Activates this filter so that the PS code will be redirected through it if + * it's hooked into the PSInterpreter. */ +void PSPreviewFilter::activate () { + if (_tightpage) // reactivate filter? + _active = true; + else { // first activation? + _tightpage = _active = false; + // try to retrieve version string of preview package set in the PS header section + if (psInterpreter().executeRaw("SDict begin currentdict/preview@version known{preview@version}{0}ifelse end", 1)) + _version = psInterpreter().rawData()[0]; + // check if tightpage option was set + if (_version != "0" && psInterpreter().executeRaw("SDict begin preview@tightpage end", 1)) { + _tightpage = (psInterpreter().rawData()[0] == "true"); + _active = true; + } + } + _boxExtents.clear(); +} + + +/** Tries to extract the bounding box information from a chunk of PostScript code. + * @param[in] code pointer to buffer with PS code to filter + * @param[in] len number of bytes in buffer */ +void PSPreviewFilter::execute (const char *code, size_t len) { + // If the "tightpage" option was set in the TeX file, 7 integers representing the + // extent of the bounding box are present at the begin of each page. + if (!_tightpage) + psInterpreter().execute(code, len); + else { + CharInputBuffer ib(code, len); + BufferInputReader ir(ib); + ir.skipSpace(); + int val; + while (ir.parseInt(val) && _boxExtents.size() <= 7) { + _boxExtents.push_back(val); + ir.skipSpace(); + } + } + _active = false; // no further processing required +} + + +/** Returns the bounding box defined by the preview package. */ +bool PSPreviewFilter::getBoundingBox (BoundingBox &bbox) const { + if (_boxExtents.size() < 7) + return false; + double left = -_boxExtents[0]*_dvi2bp; + bbox = BoundingBox(-left, -height(), width()-left, depth()); + return true; +} + + +/** Gets the 4 border values set by the preview package. + * @return true if the border data is available */ +bool PSPreviewFilter::getBorders (double &left, double &right, double &top, double &bottom) const { + if (_boxExtents.size() < 4) + return false; + left = -_boxExtents[0]*_dvi2bp; + top = -_boxExtents[1]*_dvi2bp; + right = _boxExtents[2]*_dvi2bp; + bottom = _boxExtents[3]*_dvi2bp; + return true; +} + + +/** Returns the box height in PS points, or -1 if no data was found or read yet. */ +double PSPreviewFilter::height () const { + return _boxExtents.size() > 4 ? (_boxExtents[4]-_boxExtents[1])*_dvi2bp : -1; +} + + +/** Returns the box depth in PS points, or -1 if no data was found or read yet. */ +double PSPreviewFilter::depth () const { + return _boxExtents.size() > 5 ? (_boxExtents[5]+_boxExtents[3])*_dvi2bp : -1; +} + + +/** Returns the box width in PS points, or -1 if no data was found or read yet. */ +double PSPreviewFilter::width () const { + return _boxExtents.size() > 6 ? (_boxExtents[6]+_boxExtents[2]-_boxExtents[0])*_dvi2bp : -1; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.h new file mode 100644 index 00000000000..bbed9640aab --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PSPreviewFilter.h @@ -0,0 +1,56 @@ +/************************************************************************* +** PSPreviewFilter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PSPREVIEWFILTER_H +#define DVISVGM_PSPREVIEWFILTER_H + +#include <string> +#include <vector> +#include "BoundingBox.h" +#include "PSFilter.h" + +struct SpecialActions; + +class PSPreviewFilter : public PSFilter +{ + public: + PSPreviewFilter (PSInterpreter &psi); + void activate (); + void execute (const char *code, size_t len); + bool active () const {return _active;} + std::string version () const {return _version;} + bool tightpage () const {return _tightpage;} + void setDviScaleFactor (double dvi2bp) {_dvi2bp = dvi2bp;} + bool getBorders (double &left, double &right, double &top, double &bottom) const; + void assignBorders (BoundingBox &bbox) const; + bool getBoundingBox (BoundingBox &bbox) const; + double height () const; + double depth () const; + double width () const; + + private: + std::string _version; ///< version string of preview package + bool _active; ///< true if filter is active + bool _tightpage; ///< true if tightpage option was given + double _dvi2bp; ///< factor to convert dvi units to PS points + std::vector<int> _boxExtents; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.cpp new file mode 100644 index 00000000000..71650753d67 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.cpp @@ -0,0 +1,135 @@ +/************************************************************************* +** PageRanges.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "InputBuffer.h" +#include "InputReader.h" +#include "PageRanges.h" + +#include "macros.h" + +using namespace std; + + +/** Analyzes a string describing a range sequence. + * Syntax: ([0-9]+(-[0-9]*)?)|(-[0-9]+)(,([0-9]+(-[0-9]*)?)|(-[0-9]+))* + * @param[in] str string to parse + * @param[in] max_page greatest allowed value + * @return true on success; false denotes a syntax error */ +bool PageRanges::parse (string str, int max_page) { + StringInputBuffer ib(str); + BufferInputReader ir(ib); + while (ir) { + int first=1; + int last=max_page; + ir.skipSpace(); + if (!isdigit(ir.peek()) && ir.peek() != '-') + return false; + + if (isdigit(ir.peek())) + first = ir.getInt(); + ir.skipSpace(); + if (ir.peek() == '-') { + while (ir.peek() == '-') + ir.get(); + ir.skipSpace(); + if (isdigit(ir.peek())) + last = ir.getInt(); + } + else + last = first; + ir.skipSpace(); + if (ir.peek() == ',') { + ir.get(); + if (ir.eof()) + return false; + } + else if (!ir.eof()) + return false; + if (first > last) + swap(first, last); + first = max(1, first); + last = max(first, last); + if (max_page > 0) { + first = min(first, max_page); + last = min(last, max_page); + } + insert(first, last); + } + return true; +} + + +/** Adds a page range to the range collection. + * @param[in] first first page of new range + * @param[in] last last page of new range */ +void PageRanges::insert (int first, int last) { + if (first > last) + swap(first, last); + Container::iterator it = _ranges.begin(); + while (it != _ranges.end() && first > it->first+1 && first > it->second+1) + ++it; + if (it == _ranges.end() || last < it->first-1 || first > it->second+1) + it = _ranges.insert(it, Range(first, last)); + else if ((first < it->first && last >= it->first-1) || (first <= it->second+1 && last > it->second)) { + it->first = min(it->first, first); + it->second = max(it->second, last); + } + // merge adjacent ranges + if (it != _ranges.end()) { + Container::iterator l = it; + Container::iterator r = it; + if (l == _ranges.begin()) + l = _ranges.end(); + else + --l; + ++r; + bool l_modified = false; + bool r_modified = false; + if (l != _ranges.end() && l->second >= it->first-1) { + l->first = min(l->first, it->first); + l->second = max(l->second, it->second); + l_modified = true; + } + if (r != _ranges.end() && r->first <= it->second+1) { + r->first = min(r->first, it->first); + r->second = max(r->second, it->second); + r_modified = true; + } + if (l_modified || r_modified) { + _ranges.erase(it); + if (l_modified && r_modified && l->second >= r->first-1) { + l->first = min(l->first, r->first); + l->second = max(l->second, r->second); + _ranges.erase(r); + } + } + } +} + + +/** Returns the number of pages. */ +size_t PageRanges::pages () const { + size_t sum=0; + for (ConstIterator it=_ranges.begin(); it != _ranges.end(); ++it) + sum += it->second - it->first + 1; + return sum; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.h new file mode 100644 index 00000000000..57b47b91e44 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageRanges.h @@ -0,0 +1,49 @@ +/************************************************************************* +** PageRanges.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PAGERANGES_H +#define DVISVGM_PAGERANGES_H + +#include <list> +#include <string> +#include <utility> + +class PageRanges +{ + public: + typedef std::pair<int,int> Range; + typedef std::list<Range> Container; + typedef Container::iterator Iterator; + typedef Container::const_iterator ConstIterator; + + public: + bool parse (std::string str, int max_page=0); + void insert (int first, int last); + size_t pages () const; + size_t size () const {return _ranges.size();} + const Container& ranges () const {return _ranges;} + ConstIterator begin () const {return _ranges.begin();} + ConstIterator end () const {return _ranges.end();} + + private: + Container _ranges; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.cpp new file mode 100644 index 00000000000..2cc3f36512d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.cpp @@ -0,0 +1,157 @@ +/************************************************************************* +** PageSize.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <cctype> +#include <cmath> +#include <sstream> +#include "PageSize.h" + +using namespace std; + +// make sure tolower is a function (and not a macro) +// so that 'transform' can be applied +static int my_tolower (int c) { + return tolower(c); +} + + +/** Computes width and height of ISO/DIN An in millimeters. + * @param[in] n the A level (e.g. n=4 => DIN A4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeASize (int n, double &width, double &height) { + double sqrt2 = sqrt(2.0); + height = floor(1189.0/pow(sqrt2, n)+0.5); + width = floor(height/sqrt2+0.5); +} + + +/** Computes width and height of ISO/DIN Bn in millimeters. + * @param[in] n the B level (e.g. n=4 => DIN B4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeBSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeASize(n-1, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Computes width and height of ISO/DIN Cn in millimeters. + * @param[in] n the C level (e.g. n=4 => DIN C4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeCSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeBSize(n, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Computes width and height of ISO/DIN Dn in millimeters. + * @param[in] n the D level (e.g. n=4 => DIN D4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeDSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeBSize(n+1, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Constructs a PageSize object of given size. + * @param[in] name specifies the page size, e.g. "A4" or "letter" */ +PageSize::PageSize (string name) : _width(0), _height(0) { + resize(name); +} + + +void PageSize::resize (double w, double h) { + _width = w; + _height = h; +} + +void PageSize::resize (string name) { + if (name.length() < 2) + throw PageSizeException("unknown page format: "+name); + + transform(name.begin(), name.end(), name.begin(), my_tolower); + // extract optional suffix + size_t pos = name.rfind("-"); + bool landscape = false; + if (pos != string::npos) { + string suffix = name.substr(pos); + name = name.substr(0, pos); + if (suffix == "-l" || suffix == "-landscape") + landscape = true; + else if (suffix != "-p" && suffix != "-portrait") + throw PageSizeException("invalid page format suffix: " + suffix); + } + + if (name == "invoice") { + _width = 140; + _height = 216; + } + else if (name == "executive") { + _width = 184; + _height = 267; + } + else if (name == "legal") { + _width = 216; + _height = 356; + } + else if (name == "letter") { + _width = 216; + _height = 279; + } + else if (name == "ledger") { + _width = 279; + _height = 432; + } + else if (isdigit(name[1]) && name.length() < 5) { // limit length of number to prevent arithmetic errors + istringstream iss(name.substr(1)); + int n; + iss >> n; + switch (name[0]) { + case 'a' : computeASize(n, _width, _height); break; + case 'b' : computeBSize(n, _width, _height); break; + case 'c' : computeCSize(n, _width, _height); break; + case 'd' : computeDSize(n, _width, _height); break; + default : throw PageSizeException("invalid page format: "+name); + } + } + if (_width == 0 || _height == 0) + throw PageSizeException("unknown page format: "+name); + if (landscape) + swap(_width, _height); + + const double bppmm = 72/25.4; // PS points per millimeter (72pt = 1in = 25.4mm) + _width *= bppmm; + _height *= bppmm; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.h new file mode 100644 index 00000000000..77cbdbcc44d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PageSize.h @@ -0,0 +1,48 @@ +/************************************************************************* +** PageSize.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PAGESIZE_H +#define DVISVGM_PAGESIZE_H + +#include "MessageException.h" + +struct PageSizeException : public MessageException +{ + PageSizeException (const std::string &msg) : MessageException(msg) {} +}; + +class PageSize +{ + public: + PageSize (double w=0, double h=0) : _width(w), _height(h) {} + PageSize (std::string name); + void resize (std:: string name); + void resize (double w, double h); + double widthInBP () const {return _width;} + double heightInBP () const {return _height;} + double widthInMM () const {return _width*25.4/72;} + double heightInMM () const {return _height*25.4/72;} + bool valid () const {return _width > 0 && _height > 0;} + + private: + double _width, _height; // in PS points +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Pair.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Pair.h new file mode 100644 index 00000000000..4c2d465e7c0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Pair.h @@ -0,0 +1,79 @@ +/************************************************************************* +** Pair.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PAIR_H +#define DVISVGM_PAIR_H + +#include <cmath> +#include <ostream> +#include "macros.h" +#include "types.h" + +template <typename T> +class Pair +{ + public: + Pair (T x=0, T y=0) : _x(x), _y(y) {} + Pair operator += (const Pair &p) {_x += p._x; _y += p._y; return *this;} + Pair operator -= (const Pair &p) {_x -= p._x; _y -= p._y; return *this;} + Pair operator *= (T c) {_x *= c; _y *= c; return *this;} + Pair operator /= (T c) {_x /= c; _y /= c; return *this;} + Pair ortho () const {return Pair(-_y, _x);} + double length () const {return std::sqrt(_x*_x + _y*_y);} + bool operator == (const Pair &p) const {return _x == p._x && _y == p._y;} + bool operator != (const Pair &p) const {return _x != p._x || _y != p._y;} + T x () const {return _x;} + T y () const {return _y;} + void x (const T &xx) {_x = xx;} + void y (const T &yy) {_y = yy;} + std::ostream& write (std::ostream &os) const {return os << '(' << _x << ',' << _y << ')';} + + private: + T _x, _y; +}; + + +struct Pair32 : public Pair<Int32> +{ + Pair32 (Int32 x=0, Int32 y=0) : Pair<Int32>(x, y) {} + explicit Pair32 (double x, double y) : Pair<Int32>(Int32(x+0.5), Int32(y+0.5)) {} + Pair32 (const Pair<Int32> &p) : Pair<Int32>(p) {} +// operator Pair<Int32> () {return *this;} +}; + +typedef Pair<double> DPair; + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR(Pair<T>, +) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR(Pair<T>, -) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR2(Pair<T>, T, *) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR2(Pair<T>, T, /) + +template <typename T> +IMPLEMENT_OUTPUT_OPERATOR(Pair<T>) + +IMPLEMENT_ARITHMETIC_OPERATOR2(Pair32, Int32, *) +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.cpp new file mode 100644 index 00000000000..998b8016eae --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.cpp @@ -0,0 +1,77 @@ +/************************************************************************* +** PdfSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstring> +#include "InputReader.h" +#include "MapLine.h" +#include "PdfSpecialHandler.h" +#include "FontMap.h" +#include "Message.h" + +using namespace std; + + +PdfSpecialHandler::PdfSpecialHandler () : _maplineProcessed(false) +{ +} + + +bool PdfSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (!actions) + return true; + StreamInputReader ir(is); + ir.skipSpace(); + string cmd = ir.getWord(); + ir.skipSpace(); + if (cmd == "mapline" || cmd == "mapfile") { + // read mode selector ('+', '-', or '=') + char modechar = '+'; // default mode (append if new, do not replace existing mapping) + if (strchr("=+-", ir.peek())) // leading modifier given? + modechar = ir.get(); + else if (!_maplineProcessed) { // no modifier given? + // remove default map entries if this is the first mapline/mapfile special called + FontMap::instance().clear(); + } + + if (cmd == "mapline") { + try { + MapLine mapline(is); + FontMap::instance().apply(mapline, modechar); + } + catch (const MapLineException &ex) { + Message::wstream(true) << "pdf:mapline: " << ex.what() << '\n'; + } + } + else { // mapfile + string fname = ir.getString(); + if (!FontMap::instance().read(fname, modechar)) + Message::wstream(true) << "can't open map file " << fname << '\n'; + } + _maplineProcessed = true; + } + return true; +} + + +const char** PdfSpecialHandler::prefixes () const { + static const char *pfx[] = {"pdf:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.h new file mode 100644 index 00000000000..a5391fbf141 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PdfSpecialHandler.h @@ -0,0 +1,39 @@ +/************************************************************************* +** PdfSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PDFSPECIALHANDLER_H +#define DVISVGM_PDFSPECIALHANDLER_H + +#include "SpecialHandler.h" + +class PdfSpecialHandler : public SpecialHandler +{ + public: + PdfSpecialHandler (); + const char* info () const {return "pdfTeX font map specials";} + const char* name () const {return "pdf";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + + private: + bool _maplineProcessed; ///< true if a mapline or mapfile special has already been processed +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.cpp new file mode 100644 index 00000000000..41c3bec0daa --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.cpp @@ -0,0 +1,190 @@ +/************************************************************************* +** Process.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> + +#ifdef __WIN32__ + #include <windows.h> +#else + #include <fcntl.h> + #include <sys/wait.h> + #include <unistd.h> + #include <signal.h> +#endif + +#include <cstdlib> +#include "FileSystem.h" +#include "Process.h" +#include "SignalHandler.h" +#include "macros.h" + +using namespace std; + +Process::Process (const string &cmd, const string ¶mstr) + : _cmd(cmd), _paramstr(paramstr) +{ +} + + +#ifdef __WIN32__ +static void pipe_read (HANDLE handle, string &out) { + char buf[4096]; + out.clear(); + for (;;) { + DWORD num_chars; + bool success = ReadFile(handle, buf, 1024, &num_chars, NULL); + if (!success || num_chars == 0) + break; + out.append(buf, num_chars); + } + // remove trailing space + if (!out.empty()) { + int pos = out.size()-1; + while (pos >= 0 && isspace(out[pos])) + pos--; + out.erase(pos+1); + } +} + + +static inline void close_handle (HANDLE handle) { + if (handle != NULL) + CloseHandle(handle); +} + +#else + +/** Extracts whitespace-sparated parameters from a string. + * @param[in] paramstr the parameter string + * @param[out] params vector holding the extracted parameters */ +static void split_paramstr (string paramstr, vector<const char*> ¶ms) { + size_t left=0, right=0; // index of first and last character of current parameter + char quote=0; // current quote character, 0=none + const size_t len = paramstr.length(); + while (left <= right && right < len) { + while (left < len && isspace(paramstr[left])) + ++left; + if (left < len && (paramstr[left] == '"' || paramstr[left] == '\'')) + quote = paramstr[left++]; + right = left; + while (right < len && (quote || !isspace(paramstr[right]))) { + if (quote && paramstr[right] == quote) { + quote=0; + break; + } + else + ++right; + } + if (right < len) + paramstr[right]=0; + if (left < len) + params.push_back(¶mstr[left]); + left = ++right; + } +} + +#endif + + +/** Runs the process and waits until it's finished. + * @param[out] out takes the output written to stdout by the executed process + * @return true if process terminated properly + * @throw SignalException if CTRL-C was pressed during execution */ +bool Process::run (string *out) { +#ifdef __WIN32__ + SECURITY_ATTRIBUTES sa; + ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = true; + + STARTUPINFO si; + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.dwFlags = STARTF_USESTDHANDLES; + HANDLE devnull = NULL; + HANDLE proc_read_handle = NULL; + HANDLE proc_write_handle = NULL; + if (out) { + CreatePipe(&proc_read_handle, &proc_write_handle, &sa, 0); + SetHandleInformation(proc_read_handle, HANDLE_FLAG_INHERIT, 0); + si.hStdOutput = proc_write_handle; + } + else { + devnull = CreateFile("nul", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + si.hStdOutput = devnull; + } + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + DWORD exitcode = DWORD(-1); + string cmdline = _cmd+" "+_paramstr; + bool success = CreateProcess(NULL, (LPSTR)cmdline.c_str(), NULL, NULL, true, 0, NULL, NULL, &si, &pi); + if (success) { + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &exitcode); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + close_handle(proc_write_handle); // must be closed before reading from pipe to prevent blocking + if (success && out) + pipe_read(proc_read_handle, *out); + close_handle(proc_read_handle); + close_handle(devnull); + return exitcode == 0; +#else + pid_t pid = fork(); + if (pid == 0) { // child process + if (!out) { + int devnull = open(FileSystem::DEVNULL, O_WRONLY); + if (devnull >= 0) { + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + } + } + vector<const char*> params; + params.push_back(_cmd.c_str()); + split_paramstr(_paramstr, params); + params.push_back(0); // trailing NULL marks end + execvp(_cmd.c_str(), const_cast<char* const*>(¶ms[0])); + exit(1); + } + if (pid > 0) { // main process + int status; + for (;;) { + waitpid(pid, &status, WNOHANG); + if (WIFEXITED(status)) // child process exited normally + return WEXITSTATUS(status) == 0; + + try { + SignalHandler::instance().check(); + } + catch (SignalException &e) { // caught ctrl-c + kill(pid, SIGKILL); + throw; + } + } + } + return false; +#endif +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.h new file mode 100644 index 00000000000..df2e0545049 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Process.h @@ -0,0 +1,41 @@ +/************************************************************************* +** Process.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PROCESS_H +#define DVISVGM_PROCESS_H + +#include <string> + +class Process +{ + public: + Process (const std::string &cmd, const std::string ¶mstr); + bool run (std::string *out=0); + + protected: + Process (const Process& orig) {} + + private: + std::string _cmd; + std::string _paramstr; +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.cpp new file mode 100644 index 00000000000..f0742a36194 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.cpp @@ -0,0 +1,874 @@ +/************************************************************************* +** PsSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <fstream> +#include <iostream> +#include <sstream> +#include "EPSFile.h" +#include "FileFinder.h" +#include "Ghostscript.h" +#include "Message.h" +#include "PSPattern.h" +#include "PSPreviewFilter.h" +#include "PsSpecialHandler.h" +#include "SpecialActions.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + +static inline double str2double (const string &str) { + double ret; + istringstream iss(str); + iss >> ret; + return ret; +} + + +PsSpecialHandler::PsSpecialHandler () : _psi(this), _actions(0), _previewFilter(_psi), _psSection(PS_NONE), _xmlnode(0) +{ +} + + +PsSpecialHandler::~PsSpecialHandler () { + _psi.setActions(0); // ensure no further PS actions are performed + for (map<int, PSPattern*>::iterator it=_patterns.begin(); it != _patterns.end(); ++it) + delete it->second; +} + + +/** Initializes the PostScript handler. It's called by the first use of process(). The + * deferred initialization speeds up the conversion of DVI files that doesn't contain + * PS specials. */ +void PsSpecialHandler::initialize () { + if (_psSection == PS_NONE) { + // initial values of graphics state + _linewidth = 1; + _linecap = _linejoin = 0; + _miterlimit = 4; + _xmlnode = _savenode = 0; + _opacityalpha = 1; // fully opaque + _sx = _sy = _cos = 1.0; + _pattern = 0; + + // execute dvips prologue/header files + const char *headers[] = {"tex.pro", "texps.pro", "special.pro", /*"color.pro",*/ 0}; + for (const char **p=headers; *p; ++p) + processHeaderFile(*p); + _psSection = PS_HEADERS; // allow to process header specials now + } +} + + +void PsSpecialHandler::processHeaderFile (const char *name) { + if (const char *path = FileFinder::lookup(name, false)) { + ifstream ifs(path); + _psi.execute(string("%%BeginProcSet: ")+name+" 0 0\n", false); + _psi.execute(ifs, false); + _psi.execute("%%EndProcSet\n", false); + } + else + Message::wstream(true) << "PostScript header file " << name << " not found\n"; +} + + +void PsSpecialHandler::enterBodySection () { + if (_psSection == PS_HEADERS) { + _psSection = PS_BODY; // don't process any PS header code + ostringstream oss; + // process collected header code + if (!_headerCode.empty()) { + oss << "\nTeXDict begin @defspecial " << _headerCode << "\n@fedspecial end"; + _headerCode.clear(); + } + // push dictionary "TeXDict" with dvips definitions on dictionary stack + // and initialize basic dvips PostScript variables + oss << "\nTeXDict begin 0 0 1000 72 72 () @start 0 0 moveto "; + if (_actions) { + float r, g, b; + _actions->getColor().getRGB(r, g, b); + oss << r << ' ' << g << ' ' << b << " setrgbcolor "; + } + _psi.execute(oss.str(), false); + // Check for information generated by preview.sty. If the tightpage options + // was set, don't execute the bop-hook but allow the PS filter to read + // the bbox data present at the beginning of the page. + _psi.setFilter(&_previewFilter); + _previewFilter.activate(); + if (!_previewFilter.tightpage()) + _psi.execute("userdict/bop-hook known{bop-hook}if\n", false); + } +} + + +/** Move PS graphic position to current DVI location. */ +void PsSpecialHandler::moveToDVIPos () { + if (_actions) { + const double x = _actions->getX(); + const double y = _actions->getY(); + ostringstream oss; + oss << '\n' << x << ' ' << y << " moveto "; + _psi.execute(oss.str()); + _currentpoint = DPair(x, y); + } +} + + +/** Executes a PS snippet and moves the DVI cursor to the current DVI position afterwards. + * It's just a shorthand function as this action sequence is required several times. + * @param[in] psi PS interpreter instance + * @param[in] is stream to read the PS code from + * @param[in] pos current PS graphic position + * @param[in] actions special actions */ +static void exec_and_syncpos (PSInterpreter &psi, istream &is, const DPair &pos, SpecialActions *actions) { + psi.execute(is); + psi.execute("\nquerypos "); // retrieve current PS position (stored in 'pos') + if (actions) { + actions->setX(pos.x()); + actions->setY(pos.y()); + } +} + + + +bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + _actions = actions; + initialize(); + if (_psSection != PS_BODY && *prefix != '!' && strcmp(prefix, "header=") != 0) + enterBodySection(); + + if (*prefix == '"') { + // read and execute literal PostScript code (isolated by a wrapping save/restore pair) + moveToDVIPos(); + _psi.execute("\n@beginspecial @setspecial "); + _psi.execute(is); + _psi.execute("\n@endspecial "); + } + else if (*prefix == '!') { + if (_psSection == PS_HEADERS) { + _headerCode += "\n"; + _headerCode += string(istreambuf_iterator<char>(is), istreambuf_iterator<char>()); + } + } + else if (strcmp(prefix, "header=") == 0) { + if (_psSection == PS_HEADERS) { + // read and execute PS header file + string fname; + is >> fname; + processHeaderFile(fname.c_str()); + } + } + else if (strcmp(prefix, "psfile=") == 0 || strcmp(prefix, "PSfile=") == 0) { + if (_actions) { + StreamInputReader in(is); + string fname = in.getQuotedString(in.peek() == '"' ? '"' : 0); + map<string,string> attr; + in.parseAttributes(attr); + psfile(fname, attr); + } + } + else if (strcmp(prefix, "ps::") == 0) { + if (_actions) + _actions->finishLine(); // reset DVI position on next DVI command + if (is.peek() == '[') { + // collect characters inside the brackets + string code; + for (int i=0; i < 9 && is.peek() != ']' && !is.eof(); ++i) + code += is.get(); + if (is.peek() == ']') + code += is.get(); + + if (code == "[begin]" || code == "[nobreak]") { + moveToDVIPos(); + exec_and_syncpos(_psi, is, _currentpoint, _actions); + } + else { + // no move to DVI position here + if (code != "[end]") // PS array? + _psi.execute(code); + exec_and_syncpos(_psi, is, _currentpoint, _actions); + } + } + else { // ps::<code> behaves like ps::[end]<code> + // no move to DVI position here + exec_and_syncpos(_psi, is, _currentpoint, _actions); + } + } + else { // ps: ... + if (_actions) + _actions->finishLine(); + moveToDVIPos(); + StreamInputReader in(is); + if (in.check(" plotfile ")) { // ps: plotfile fname + string fname = in.getString(); + ifstream ifs(fname.c_str()); + if (ifs) + _psi.execute(ifs); + else + Message::wstream(true) << "file '" << fname << "' not found in ps: plotfile\n"; + } + else { + // ps:<code> is almost identical to ps::[begin]<code> but does + // a final repositioning to the current DVI location + exec_and_syncpos(_psi, is, _currentpoint, _actions); + moveToDVIPos(); + } + } + return true; +} + + +/** Handles psfile special. + * @param[in] fname EPS file to be included + * @param[in] attr attributes given with \\special psfile */ +void PsSpecialHandler::psfile (const string &fname, const map<string,string> &attr) { + EPSFile epsfile(fname); + istream &is = epsfile.istream(); + if (!is) + Message::wstream(true) << "file '" << fname << "' not found in special 'psfile'\n"; + else { + map<string,string>::const_iterator it; + + // bounding box of EPS figure + double llx = (it = attr.find("llx")) != attr.end() ? str2double(it->second) : 0; + double lly = (it = attr.find("lly")) != attr.end() ? str2double(it->second) : 0; + double urx = (it = attr.find("urx")) != attr.end() ? str2double(it->second) : 0; + double ury = (it = attr.find("ury")) != attr.end() ? str2double(it->second) : 0; + + // desired width/height of resulting figure + double rwi = (it = attr.find("rwi")) != attr.end() ? str2double(it->second)/10.0 : -1; + double rhi = (it = attr.find("rhi")) != attr.end() ? str2double(it->second)/10.0 : -1; + if (rwi == 0 || rhi == 0 || urx-llx == 0 || ury-lly == 0) + return; + + // user transformations (default values chosen according to dvips manual) + double hoffset = (it = attr.find("hoffset")) != attr.end() ? str2double(it->second) : 0; + double voffset = (it = attr.find("voffset")) != attr.end() ? str2double(it->second) : 0; +// double hsize = (it = attr.find("hsize")) != attr.end() ? str2double(it->second) : 612; +// double vsize = (it = attr.find("vsize")) != attr.end() ? str2double(it->second) : 792; + double hscale = (it = attr.find("hscale")) != attr.end() ? str2double(it->second) : 100; + double vscale = (it = attr.find("vscale")) != attr.end() ? str2double(it->second) : 100; + double angle = (it = attr.find("angle")) != attr.end() ? str2double(it->second) : 0; + + Matrix m(1); + m.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); + BoundingBox bbox(llx, lly, urx, ury); + bbox.transform(m); + + double sx = rwi/bbox.width(); + double sy = rhi/bbox.height(); + if (sx < 0) sx = sy; + if (sy < 0) sy = sx; + if (sx < 0) sx = sy = 1.0; + + // save current DVI position (in pt units) + const double x = _actions->getX(); + const double y = _actions->getY(); + + // all following drawings are relative to (0,0) + _actions->setX(0); + _actions->setY(0); + moveToDVIPos(); + + _xmlnode = new XMLElementNode("g"); + _psi.execute("\n@beginspecial @setspecial "); // enter \special environment + _psi.limit(epsfile.pslength()); // limit the number of bytes to be processed + _psi.execute(is); // process EPS file + _psi.limit(0); // disable limitation + _psi.execute("\n@endspecial "); // leave special environment + if (!_xmlnode->empty()) { // has anything been drawn? + Matrix m(1); + m.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); + m.translate(-llx, lly); + m.scale(sx, sy); // resize image to width "rwi" and height "rhi" + m.translate(x, y); // move image to current DVI position + _xmlnode->addAttribute("transform", m.getSVG()); + _actions->appendToPage(_xmlnode); + } + else + delete _xmlnode; + _xmlnode = 0; + + // restore DVI position + _actions->setX(x); + _actions->setY(y); + moveToDVIPos(); + + // update bounding box + m.scale(sx, -sy); + m.translate(x, y); + bbox = BoundingBox(0, 0, fabs(urx-llx), fabs(ury-lly)); + bbox.transform(m); + _actions->embed(bbox); + } +} + + +/** Apply transformation to width, height, and depth set by preview package. + * @param[in] matrix transformation matrix to apply + * @param[out] w width + * @param[out] h height + * @param[out] d depth + * @return true if the baseline is still horizontal after the transformation */ +static bool transform_box_extents (const Matrix &matrix, double &w, double &h, double &d) { + DPair shift = matrix*DPair(0,0); // the translation component of the matrix + DPair ex = matrix*DPair(1,0)-shift; + DPair ey = matrix*DPair(0,1)-shift; + if (ex.y() != 0 && ey.x() != 0) // rotation != mod 90 degrees? + return false; // => non-horizontal baseline, can't compute meaningful extents + + if (ex.y() == 0) // horizontal scaling or skewing? + w *= fabs(ex.x()); + if (ey.x()==0 || ex.y()==0) { // vertical scaling? + if (ey.y() < 0) swap(h, d); + if (double sy = fabs(ey.y())/ey.length()) { + h *= fabs(ey.y()/sy); + d *= fabs(ey.y()/sy); + } + else + h = d = 0; + } + return true; +} + + +void PsSpecialHandler::dviEndPage (unsigned) { + BoundingBox bbox; + if (_previewFilter.getBoundingBox(bbox)) { + double w = _previewFilter.width(); + double h = _previewFilter.height(); + double d = _previewFilter.depth(); + bool horiz_baseline = true; + if (_actions) { + _actions->bbox() = bbox; + // apply page transformations to box extents + Matrix pagetrans; + _actions->getPageTransform(pagetrans); + horiz_baseline = transform_box_extents(pagetrans, w, h, d); + _actions->bbox().lock(); + } + Message::mstream() << "\napplying bounding box set by preview package (version " << _previewFilter.version() << ")\n"; + if (horiz_baseline) + Message::mstream() << "width=" << XMLString(w) << "pt, " "height=" << XMLString(h) << "pt, " "depth=" << XMLString(d) << "pt\n"; + else + Message::mstream() << "can't determine height, width, and depth due to non-horizontal baseline\n"; + } + // close dictionary TeXDict and execute end-hook if defined + if (_psSection == PS_BODY) { + _psi.execute("\nend userdict/end-hook known{end-hook}if "); + _psSection = PS_HEADERS; + } +} + +/////////////////////////////////////////////////////// + +void PsSpecialHandler::gsave (vector<double> &p) { + _clipStack.dup(); +} + + +void PsSpecialHandler::grestore (vector<double> &p) { + _clipStack.pop(); +} + + +void PsSpecialHandler::grestoreall (vector<double> &p) { + _clipStack.pop(-1, true); +} + + +void PsSpecialHandler::save (vector<double> &p) { + _clipStack.dup(static_cast<int>(p[0])); +} + + +void PsSpecialHandler::restore (vector<double> &p) { + _clipStack.pop(static_cast<int>(p[0])); +} + + +void PsSpecialHandler::moveto (vector<double> &p) { + _path.moveto(p[0], p[1]); +} + + +void PsSpecialHandler::lineto (vector<double> &p) { + _path.lineto(p[0], p[1]); +} + + +void PsSpecialHandler::curveto (vector<double> &p) { + _path.cubicto(p[0], p[1], p[2], p[3], p[4], p[5]); +} + + +void PsSpecialHandler::closepath (vector<double> &p) { + _path.closepath(); +} + + +/** Draws the current path recorded by previously executed path commands (moveto, lineto,...). + * @param[in] p not used */ +void PsSpecialHandler::stroke (vector<double> &p) { + if (!_path.empty() && _actions) { + BoundingBox bbox; + if (!_actions->getMatrix().isIdentity()) { + _path.transform(_actions->getMatrix()); + if (!_xmlnode) + bbox.transform(_actions->getMatrix()); + } + + XMLElementNode *path=0; + Pair<double> point; + if (_path.isDot(point)) { // zero-length path? + if (_linecap == 1) { // round line ends? => draw dot + double x = point.x(); + double y = point.y(); + double r = _linewidth/2.0; + path = new XMLElementNode("circle"); + path->addAttribute("cx", x); + path->addAttribute("cy", y); + path->addAttribute("r", r); + path->addAttribute("fill", _actions->getColor().rgbString()); + bbox = BoundingBox(x-r, y-r, x+r, y+r); + } + } + else { + // compute bounding box + _path.computeBBox(bbox); + bbox.expand(_linewidth/2); + + ostringstream oss; + _path.writeSVG(oss); + path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + path->addAttribute("stroke", _actions->getColor().rgbString()); + path->addAttribute("fill", "none"); + if (_linewidth != 1) + path->addAttribute("stroke-width", _linewidth); + if (_miterlimit != 4) + path->addAttribute("stroke-miterlimit", _miterlimit); + if (_linecap > 0) // default value is "butt", no need to set it explicitly + path->addAttribute("stroke-linecap", _linecap == 1 ? "round" : "square"); + if (_linejoin > 0) // default value is "miter", no need to set it explicitly + path->addAttribute("stroke-linejoin", _linecap == 1 ? "round" : "bevel"); + if (_opacityalpha < 1) + path->addAttribute("stroke-opacity", _opacityalpha); + if (!_dashpattern.empty()) { + ostringstream oss; + for (size_t i=0; i < _dashpattern.size(); i++) { + if (i > 0) + oss << ','; + oss << XMLString(_dashpattern[i]); + } + path->addAttribute("stroke-dasharray", oss.str()); + if (_dashoffset != 0) + path->addAttribute("stroke-dashoffset", _dashoffset); + } + } + if (path && _clipStack.top()) { + // assign clipping path and clip bounding box + path->addAttribute("clip-path", XMLString("url(#clip")+XMLString(_clipStack.topID())+")"); + BoundingBox clipbox; + _clipStack.top()->computeBBox(clipbox); + bbox.intersect(clipbox); + } + + if (_xmlnode) + _xmlnode->append(path); + else { + _actions->appendToPage(path); + _actions->embed(bbox); + } + _path.newpath(); + } +} + + +/** Draws a closed path filled with the current color. + * @param[in] p not used + * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ +void PsSpecialHandler::fill (vector<double> &p, bool evenodd) { + if (!_path.empty() && _actions) { + // compute bounding box + BoundingBox bbox; + _path.computeBBox(bbox); + if (!_actions->getMatrix().isIdentity()) { + _path.transform(_actions->getMatrix()); + if (!_xmlnode) + bbox.transform(_actions->getMatrix()); + } + + ostringstream oss; + _path.writeSVG(oss); + XMLElementNode *path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + if (_pattern) + path->addAttribute("fill", XMLString("url(#")+_pattern->svgID()+")"); + else if (_actions->getColor() != Color::BLACK || _savenode) + path->addAttribute("fill", _actions->getColor().rgbString()); + if (_clipStack.top()) { + // assign clipping path and clip bounding box + path->addAttribute("clip-path", XMLString("url(#clip")+XMLString(_clipStack.topID())+")"); + BoundingBox clipbox; + _clipStack.top()->computeBBox(clipbox); + bbox.intersect(clipbox); + } + if (evenodd) // SVG default fill rule is "nonzero" algorithm + path->addAttribute("fill-rule", "evenodd"); + if (_opacityalpha < 1) + path->addAttribute("fill-opacity", _opacityalpha); + if (_xmlnode) + _xmlnode->append(path); + else { + _actions->appendToPage(path); + _actions->embed(bbox); + } + _path.newpath(); + } +} + + +/** Creates a Matrix object out of a given sequence of 6 double values. + * The given values must be arranged in PostScript matrix order. + * @param[in] v vector containing the matrix values + * @param[in] startindex vector index of first component + * @param[out] matrix the generated matrix */ +static void create_matrix (vector<double> &v, int startindex, Matrix &matrix) { + // Ensure vector p has 6 elements. If necessary, add missing ones + // using corresponding values of the identity matrix. + if (v.size()-startindex < 6) { + v.resize(6+startindex); + for (int i=v.size()-startindex; i < 6; ++i) + v[i+startindex] = (i%3 ? 0 : 1); + } + // PS matrix [a b c d e f] equals ((a,b,0),(c,d,0),(e,f,1)). + // Since PS uses left multiplications, we must transpose and reorder + // the matrix to ((a,c,e),(b,d,f),(0,0,1)). This is done by the + // following swaps. + swap(v[startindex+1], v[startindex+2]); // => (a, c, b, d, e, f) + swap(v[startindex+2], v[startindex+4]); // => (a, c, e, d, b, f) + swap(v[startindex+3], v[startindex+4]); // => (a, c, e, b, d, f) + matrix.set(v, startindex); +} + + +/** Starts the definition of a new fill pattern. This operator + * expects 9 parameters for tiling patterns (see PS reference 4.9.2): + * @param[in] p the 9 values defining a tiling pattern (see PS reference 4.9.2): + * 0: pattern type (0:none, 1:tiling, 2:shading) + * 1: pattern ID + * 2-5: lower left and upper right coordinates of pattern box + * 6: horizontal distance of adjacent tiles + * 7: vertical distance of adjacent tiles + * 8: paint type (1: colored pattern, 2: uncolored pattern) + * 9-14: pattern matrix */ +void PsSpecialHandler::makepattern (vector<double> &p) { + int pattern_type = static_cast<int>(p[0]); + int id = static_cast<int>(p[1]); + switch (pattern_type) { + case 0: + // pattern definition completed + if (_savenode) { + _xmlnode = _savenode; + _savenode = 0; + } + break; + case 1: { // tiling pattern + BoundingBox bbox(p[2], p[3], p[4], p[5]); + const double &xstep=p[6], &ystep=p[7]; // horizontal and vertical distance of adjacent tiles + int paint_type = static_cast<int>(p[8]); + + Matrix matrix; // transformation matrix given together with pattern definition + create_matrix(p, 9, matrix); + matrix.rmultiply(_actions->getMatrix()); + + PSTilingPattern *pattern=0; + if (paint_type == 1) + pattern = new PSColoredTilingPattern(id, bbox, matrix, xstep, ystep); + else + pattern = new PSUncoloredTilingPattern(id, bbox, matrix, xstep, ystep); + _patterns[id] = pattern; + _savenode = _xmlnode; + _xmlnode = pattern->getContainerNode(); // insert the following SVG elements into this node + break; + } + case 2: { + // define a shading pattern + } + } +} + + +/** Selects a previously defined fill pattern. + * 0: pattern ID + * 1-3: (optional) RGB values for uncolored tiling patterns + * further parameters depend on the pattern type */ +void PsSpecialHandler::setpattern (vector<double> &p) { + int pattern_id = p[0]; + Color color; + if (p.size() == 4) + color.set((float)p[1], (float)p[2], (float)p[3]); + map<int,PSPattern*>::iterator it = _patterns.find(pattern_id); + if (it == _patterns.end()) + _pattern = 0; + else { + if (PSUncoloredTilingPattern *pattern = dynamic_cast<PSUncoloredTilingPattern*>(it->second)) + pattern->setColor(color); + it->second->apply(_actions); + if (PSTilingPattern *pattern = dynamic_cast<PSTilingPattern*>(it->second)) + _pattern = pattern; + else + _pattern = 0; + } +} + + +/** Clears the current clipping path. + * @param[in] p not used */ +void PsSpecialHandler::initclip (vector<double> &p) { + _clipStack.push(); // push empty path +} + + +/** Assigns a new clipping path. + * @param[in] p not used + * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ +void PsSpecialHandler::clip (vector<double> &p, bool evenodd) { + // when this method is called, _path contains the clipping path + if (!_path.empty() && _actions) { + if (!_actions->getMatrix().isIdentity()) + _path.transform(_actions->getMatrix()); + + int oldID = _clipStack.topID(); + _clipStack.replace(_path); + int newID = _clipStack.topID(); + + ostringstream oss; + _path.writeSVG(oss); + XMLElementNode *path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + if (evenodd) + path->addAttribute("clip-rule", "evenodd"); + + XMLElementNode *clip = new XMLElementNode("clipPath"); + clip->addAttribute("id", XMLString("clip")+XMLString(newID)); + if (oldID) + clip->addAttribute("clip-path", XMLString("url(#clip")+XMLString(oldID)+")"); + + clip->append(path); + _actions->appendToDefs(clip); + } +} + + +/** Clears current path */ +void PsSpecialHandler::newpath (vector<double> &p) { + _path.newpath(); +} + + +void PsSpecialHandler::setmatrix (vector<double> &p) { + if (_actions) { + Matrix m; + create_matrix(p, 0, m); + _actions->setMatrix(m); + } +} + + +// In contrast to SVG, PostScript transformations are applied in +// reverse order (M' = T*M). Thus, the transformation matrices must be +// left-multiplied in the following methods scale(), translate() and rotate(). + + +void PsSpecialHandler::scale (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + ScalingMatrix s(p[0], p[1]); + m.lmultiply(s); + _actions->setMatrix(m); + } +} + + +void PsSpecialHandler::translate (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + TranslationMatrix t(p[0], p[1]); + m.lmultiply(t); + _actions->setMatrix(m); + } +} + + +void PsSpecialHandler::rotate (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + RotationMatrix r(p[0]); + m.lmultiply(r); + _actions->setMatrix(m); + } +} + + +void PsSpecialHandler::setgray (vector<double> &p) { + _pattern = 0; + if (_actions) { + Color c; + c.setGray((float)p[0]); + _actions->setColor(c); + } +} + + +void PsSpecialHandler::setrgbcolor (vector<double> &p) { + _pattern= 0; + if (_actions) + _actions->setColor(Color((float)p[0], (float)p[1], (float)p[2])); +} + + +void PsSpecialHandler::setcmykcolor (vector<double> &p) { + _pattern = 0; + if (_actions) { + Color c; + c.setCMYK((float)p[0], (float)p[1], (float)p[2], (float)p[3]); + _actions->setColor(c); + } +} + + +void PsSpecialHandler::sethsbcolor (vector<double> &p) { + _pattern = 0; + if (_actions) { + Color c; + c.setHSB((float)p[0], (float)p[1], (float)p[2]); + _actions->setColor(c); + } +} + + +/** Sets the dash parameters used for stroking. + * @param[in] p dash pattern array m1,...,mn plus trailing dash offset */ +void PsSpecialHandler::setdash (vector<double> &p) { + _dashpattern.clear(); + for (size_t i=0; i < p.size()-1; i++) + _dashpattern.push_back(scale(p[i])); + _dashoffset = scale(p.back()); +} + + +/** This method is called by the PSInterpreter if an PS operator has been executed. */ +void PsSpecialHandler::executed () { + if (_actions) + _actions->progress("ps"); +} + +//////////////////////////////////////////// + +void PsSpecialHandler::ClippingStack::push () { + if (!_stack.empty()) + _stack.push(Entry(0, -1)); +} + + +void PsSpecialHandler::ClippingStack::push (const Path &path, int saveID) { + if (path.empty()) + _stack.push(Entry(0, saveID)); + else { + _paths.push_back(path); + _stack.push(Entry(_paths.size(), saveID)); + } +} + + +/** Pops a single or several elements from the clipping stack. + * The method distingushes between the following cases: + * 1) saveID < 0 and grestoreall == false: + * pop top element if it was pushed by gsave (its saveID is < 0 as well) + * 2) saveID < 0 and grestoreall == true + * repeat popping until stack is empty or the top element was pushed + * by save (its saveID is >= 0) + * 3) saveID >= 0: + * pop all elements until the saveID of the top element equals parameter saveID */ +void PsSpecialHandler::ClippingStack::pop (int saveID, bool grestoreall) { + if (!_stack.empty()) { + if (saveID < 0) { // grestore? + if (_stack.top().saveID < 0) // pushed by 'gsave'? + _stack.pop(); + // pop all further elements pushed by 'gsave' if grestoreall == true + while (grestoreall && !_stack.empty() && _stack.top().saveID < 0) + _stack.pop(); + } + else { + // pop elements pushed by 'gsave' + while (!_stack.empty() && _stack.top().saveID != saveID) + _stack.pop(); + // pop element pushed by 'save' + if (!_stack.empty()) + _stack.pop(); + } + } +} + + +/** Returns a pointer to the path on top of the stack, or 0 if the stack is empty. */ +const PsSpecialHandler::Path* PsSpecialHandler::ClippingStack::top () const { + return (!_stack.empty() && _stack.top().pathID) + ? &_paths[_stack.top().pathID-1] + : 0; +} + + +/** Pops all elements from the stack. */ +void PsSpecialHandler::ClippingStack::clear() { + _paths.clear(); + while (!_stack.empty()) + _stack.pop(); +} + + +/** Replaces the top element by a new one. + * @param[in] path new path to be on top of the stack */ +void PsSpecialHandler::ClippingStack::replace (const Path &path) { + if (_stack.empty()) + push(path, -1); + else { + _paths.push_back(path); + _stack.top().pathID = _paths.size(); + } +} + + +/** Duplicates the top element, i.e. the top element is pushed again. */ +void PsSpecialHandler::ClippingStack::dup (int saveID) { + _stack.push(_stack.empty() ? Entry(0, -1) : _stack.top()); + _stack.top().saveID = saveID; +} + + +const char** PsSpecialHandler::prefixes () const { + static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", 0}; + return pfx; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.h new file mode 100644 index 00000000000..8fc3d6b5ae3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/PsSpecialHandler.h @@ -0,0 +1,149 @@ +/************************************************************************* +** PsSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_PSSPECIALHANDLER_H +#define DVISVGM_PSSPECIALHANDLER_H + +#include <set> +#include <stack> +#include <string> +#include <vector> +#include "GraphicPath.h" +#include "PSInterpreter.h" +#include "SpecialHandler.h" +#include "PSPattern.h" +#include "PSPreviewFilter.h" + + +class PSPattern; +class XMLElementNode; + +class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, protected PSActions +{ + typedef GraphicPath<double> Path; + + class ClippingStack + { + public: + void push (); + void push (const Path &path, int saveID=-1); + void replace (const Path &path); + void dup (int saveID=-1); + void pop (int saveID=-1, bool grestore=false); + void clear (); + bool empty () const {return _stack.empty();} + const Path* top () const; + int topID () const {return _stack.empty() ? 0 : _stack.top().pathID;} + + private: + struct Entry { + int pathID; ///< index referencing a path of the pool + int saveID; ///< if >=0, path was pushed by 'save', and saveID holds the ID of the + Entry (int pid, int sid) : pathID(pid), saveID(sid) {} + }; + std::vector<Path> _paths; ///< pool of all clipping paths + std::stack<Entry> _stack; + }; + + enum PsSection {PS_NONE, PS_HEADERS, PS_BODY}; + + public: + PsSpecialHandler (); + ~PsSpecialHandler (); + const char* name () const {return "ps";} + const char* info () const {return "dvips PostScript specials";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + void setDviScaleFactor (double dvi2bp) {_previewFilter.setDviScaleFactor(dvi2bp);} + void enterBodySection (); + + protected: + void initialize (); + void moveToDVIPos (); + void processHeaderFile (const char *fname); + void psfile (const std::string &fname, const std::map<std::string,std::string> &attr); + void dviEndPage (unsigned pageno); + + /// scale given value by current PS scale factors + double scale (double v) const {return v*(_sx*_cos*_cos + _sy*(1-_cos*_cos));} + + void applyscalevals (std::vector<double> &p) {_sx = p[0]; _sy = p[1]; _cos = p[2];} + void clip (std::vector<double> &p) {clip(p, false);} + void clip (std::vector<double> &p, bool evenodd); + void closepath (std::vector<double> &p); + void curveto (std::vector<double> &p); + void eoclip (std::vector<double> &p) {clip(p, true);} + void eofill (std::vector<double> &p) {fill(p, true);} + void fill (std::vector<double> &p, bool evenodd); + void fill (std::vector<double> &p) {fill(p, false);} + void grestore (std::vector<double> &p); + void grestoreall (std::vector<double> &p); + void gsave (std::vector<double> &p); + void initclip (std::vector<double> &p); + void lineto (std::vector<double> &p); + void makepattern (std::vector<double> &p); + void moveto (std::vector<double> &p); + void newpath (std::vector<double> &p); + void querypos (std::vector<double> &p) {_currentpoint = DPair(p[0], p[1]);} + void restore (std::vector<double> &p); + void rotate (std::vector<double> &p); + void save (std::vector<double> &p); + void scale (std::vector<double> &p); + void setcmykcolor (std::vector<double> &cmyk); + void setdash (std::vector<double> &p); + void setgray (std::vector<double> &p); + void sethsbcolor (std::vector<double> &hsb); + void setlinecap (std::vector<double> &p) {_linecap = UInt8(p[0]);} + void setlinejoin (std::vector<double> &p) {_linejoin = UInt8(p[0]);} + void setlinewidth (std::vector<double> &p) {_linewidth = p[0] ? scale(p[0])*1.00375 : 0.5;} + void setmatrix (std::vector<double> &p); + void setmiterlimit (std::vector<double> &p) {_miterlimit = p[0]*1.00375;} + void setopacityalpha (std::vector<double> &p){_opacityalpha = p[0];} + void setpattern (std::vector<double> &p); + void setrgbcolor (std::vector<double> &rgb); + void stroke (std::vector<double> &p); + void translate (std::vector<double> &p); + void executed (); + + private: + PSInterpreter _psi; + SpecialActions *_actions; + PSPreviewFilter _previewFilter; ///< filter to extract information generated by the preview package + PsSection _psSection; ///< current section processed (nothing yet, headers, or body specials) + XMLElementNode *_xmlnode; ///< if != 0, created SVG elements are appended to this node + XMLElementNode *_savenode; ///< pointer to temporaryly store _xmlnode + std::string _headerCode; ///< collected literal PS header code + Path _path; + DPair _currentpoint; ///< current PS position in bp units + double _sx, _sy; ///< horizontal and vertical scale factors retrieved by operator "applyscalevals" + double _cos; ///< cosine of angle between (1,0) and transform(1,0) + double _linewidth; ///< current linewidth + double _miterlimit; ///< current miter limit + double _opacityalpha; ///< opacity level (0=fully transparent, ..., 1=opaque) + UInt8 _linecap : 2; ///< current line cap (0=butt, 1=round, 2=projecting square) + UInt8 _linejoin : 2; ///< current line join (0=miter, 1=round, 2=bevel) + double _dashoffset; ///< current dash offset + std::vector<double> _dashpattern; + ClippingStack _clipStack; + std::map<int, PSPattern*> _patterns; + PSTilingPattern *_pattern; ///< current pattern +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGOutputBase.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGOutputBase.h new file mode 100644 index 00000000000..cad892ea068 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGOutputBase.h @@ -0,0 +1,33 @@ +/************************************************************************* +** SVGOutputBase.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SVGOUTPUTBASE_H +#define DVISVGM_SVGOUTPUTBASE_H + +#include <ostream> +#include <string> + +struct SVGOutputBase { + virtual ~SVGOutputBase () {} + virtual std::ostream& getPageStream (int page, int numPages) const =0; + virtual std::string filename (int page, int numPages) const =0; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.cpp new file mode 100644 index 00000000000..a1f375a5f9a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.cpp @@ -0,0 +1,433 @@ +/************************************************************************* +** SVGTree.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <algorithm> +#include <sstream> +#include <string> +#include "BoundingBox.h" +#include "DVIToSVG.h" +#include "Font.h" +#include "FontManager.h" +#include "SVGTree.h" +#include "XMLDocument.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +// static class variables +bool SVGTree::CREATE_STYLE=true; +bool SVGTree::USE_FONTS=true; +bool SVGTree::CREATE_USE_ELEMENTS=false; +double SVGTree::ZOOM_FACTOR=1.0; + + +SVGTree::SVGTree () : _vertical(false), _font(0), _color(Color::BLACK), _matrix(1) { + _xchanged = _ychanged = false; + _fontnum = 0; + reset(); +} + + +/** Clears the SVG tree and initializes the root element. */ +void SVGTree::reset () { + _doc.clear(); + _root = new XMLElementNode("svg"); + _root->addAttribute("version", "1.1"); + _root->addAttribute("xmlns", "http://www.w3.org/2000/svg"); + _root->addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + _doc.setRootNode(_root); + _page = _text = _span = _defs = 0; +} + + +/** Sets the bounding box of the document. + * @param[in] bbox bounding box in PS point units */ +void SVGTree::setBBox (const BoundingBox &bbox) { + if (ZOOM_FACTOR >= 0) { + _root->addAttribute("width", XMLString(bbox.width()*ZOOM_FACTOR)+"pt"); + _root->addAttribute("height", XMLString(bbox.height()*ZOOM_FACTOR)+"pt"); + } + _root->addAttribute("viewBox", bbox.toSVGViewBox()); +} + + +void SVGTree::setColor (const Color &c) { + if (!_font.get() || _font.get()->color() == Color::BLACK) + _color.set(c); +} + + +void SVGTree::setFont (int num, const Font *font) { + _font.set(font); + _fontnum = num; + // set default color assigned to the font + if (font->color() != Color::BLACK && _color.get() != font->color()) + _color.set(font->color()); +} + + +/** Starts a new page. + * @param[in] pageno number of new page */ +void SVGTree::newPage (int pageno) { + _page = new XMLElementNode("g"); + if (pageno >= 0) + _page->addAttribute("id", string("page")+XMLString(pageno)); + _root->append(_page); + _text = _span = 0; + while (!_pageContainerStack.empty()) + _pageContainerStack.pop(); +} + + +void SVGTree::appendToDefs (XMLNode *node) { + if (!_defs) { + _defs = new XMLElementNode("defs"); + _root->prepend(_defs); + } + _defs->append(node); +} + + +void SVGTree::appendToPage (XMLNode *node) { + if (_pageContainerStack.empty()) + _page->append(node); + else + _pageContainerStack.top()->append(node); +} + + +void SVGTree::prependToPage (XMLNode *node) { + if (_pageContainerStack.empty()) + _page->prepend(node); + else + _pageContainerStack.top()->prepend(node); +} + + +/** Appends a single charater to the current text node. If necessary, and depending on output mode + * and further output states, new XML elements (text, tspan, g, ...) are created. + * @param[in] c character to be added + * @param[in] x x coordinate + * @param[in] y y coordinate + * @param[in] font font to be used */ +void SVGTree::appendChar (int c, double x, double y, const Font &font) { + XMLElementNode *node=_span; + if (USE_FONTS) { + // changes of fonts and transformations require a new text element + if (!_text || _font.changed() || _matrix.changed() || _vertical.changed()) { + newTextNode(x, y); + node = _text; + _color.changed(true); + } + if (_xchanged || _ychanged || (_color.changed() && _color.get() != Color::BLACK)) { + // if drawing position was explicitly changed, create a new tspan element + _span = new XMLElementNode("tspan"); + if (_xchanged) { + if (_vertical) { + // align glyphs designed for horizontal layout properly + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get())) + if (!pf->getMetrics()->verticalLayout()) + x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset + } + _span->addAttribute("x", x); + _xchanged = false; + } + if (_ychanged) { + _span->addAttribute("y", y); + _ychanged = false; + } + if (_color.get() != font.color()) { + _span->addAttribute("fill", _color.get().rgbString()); + _color.changed(false); + } + _text->append(_span); + node = _span; + } + if (!node) { + if (!_text) + newTextNode(x, y); + node = _text; + } + node->append(XMLString(font.unicode(c), false)); + } + else { + if (_color.changed() || _matrix.changed()) { + bool set_color = (_color.changed() && _color.get() != Color::BLACK); + bool set_matrix = (_matrix.changed() && !_matrix.get().isIdentity()); + if (set_color || set_matrix) { + _span = new XMLElementNode("g"); + if (_color.get() != Color::BLACK) + _span->addAttribute("fill", _color.get().rgbString()); + if (!_matrix.get().isIdentity()) + _span->addAttribute("transform", _matrix.get().getSVG()); + appendToPage(_span); + node = _span; + _color.changed(false); + _matrix.changed(false); + } + else if (_color.get() == Color::BLACK && _matrix.get().isIdentity()) + node = _span = 0; + } + if (!node) + node = _pageContainerStack.empty() ? _page : _pageContainerStack.top(); + if (font.verticalLayout()) { + // move glyph graphics so that its origin is located at the top center position + GlyphMetrics metrics; + font.getGlyphMetrics(c, _vertical, metrics); + x -= metrics.wl; + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(&font)) { + // Center glyph between top and bottom border of the TFM box. + // This is just an approximation used until I find a way to compute + // the exact location in vertical mode. + GlyphMetrics exact_metrics; + pf->getExactGlyphBox(c, exact_metrics, false); + y += exact_metrics.h+(metrics.d-exact_metrics.h-exact_metrics.d)/2; + } + else + y += metrics.d; + } + Matrix rotation(1); + if (_vertical && !font.verticalLayout()) { + // alphabetic text designed for horizontal mode + // must be rotated by 90 degrees if in vertical mode + rotation.translate(-x, -y); + rotation.rotate(90); + rotation.translate(x, y); + } + if (CREATE_USE_ELEMENTS) { + ostringstream oss; + oss << "#g" << FontManager::instance().fontID(_font) << '-' << c; + XMLElementNode *use = new XMLElementNode("use"); + use->addAttribute("x", XMLString(x)); + use->addAttribute("y", XMLString(y)); + use->addAttribute("xlink:href", oss.str()); + if (!rotation.isIdentity()) + use->addAttribute("transform", rotation.getSVG()); + node->append(use); + } + else { + Glyph glyph; + const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(&font); + if (pf && pf->getGlyph(c, glyph)) { + double sx = pf->scaledSize()/pf->unitsPerEm(); + double sy = -sx; + ostringstream oss; + glyph.writeSVG(oss, sx, sy, x, y); + XMLElementNode *glyph_node = new XMLElementNode("path"); + glyph_node->addAttribute("d", oss.str()); + if (!rotation.isIdentity()) + glyph_node->addAttribute("transform", rotation.getSVG()); + node->append(glyph_node); + } + } + } +} + + +/** Creates a new text element. This is a helper function used by appendChar(). + * @param[in] x current x coordinate + * @param[in] y current y coordinate */ +void SVGTree::newTextNode (double x, double y) { + _text = new XMLElementNode("text"); + _span = 0; // no tspan in text element yet + if (USE_FONTS) { + const Font *font = _font.get(); + if (CREATE_STYLE || !font) + _text->addAttribute("class", string("f")+XMLString(_fontnum)); + else { + _text->addAttribute("font-family", font->name()); + _text->addAttribute("font-size", font->scaledSize()); + if (font->color() != Color::BLACK) + _text->addAttribute("fill", font->color().rgbString()); + } + if (_vertical) { + _text->addAttribute("writing-mode", "tb"); + // align glyphs designed for horizontal layout properly + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get())) + if (!pf->getMetrics()->verticalLayout()) { // alphabetic text designed for horizontal layout? + x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset + _text->addAttribute("glyph-orientation-vertical", 90); // ensure rotation + } + } + } + _text->addAttribute("x", x); + _text->addAttribute("y", y); + if (!_matrix.get().isIdentity()) + _text->addAttribute("transform", _matrix.get().getSVG()); + appendToPage(_text); + _vertical.changed(false); + _font.changed(false); + _matrix.changed(false); + _xchanged = false; + _ychanged = false; +} + + +void SVGTree::transformPage (const Matrix *usermatrix) { + if (usermatrix && !usermatrix->isIdentity()) + _page->addAttribute("transform", usermatrix->getSVG()); +} + + +/** Creates an SVG element for a single glyph. + * @param[in] c character number + * @param[in] font font to extract the glyph from + * @param[in] cb pointer to callback object for sending feedback to the glyph tracer (may be 0) + * @return pointer to element node if glyph exists, 0 otherwise */ +static XMLElementNode* createGlyphNode (int c, const PhysicalFont &font, GFGlyphTracer::Callback *cb) { + Glyph glyph; + if (!font.getGlyph(c, glyph, cb) || (!SVGTree::USE_FONTS && !SVGTree::CREATE_USE_ELEMENTS)) + return 0; + + double sx=1.0, sy=1.0; + double upem = font.unitsPerEm(); + XMLElementNode *glyph_node=0; + if (SVGTree::USE_FONTS) { + double extend = font.style() ? font.style()->extend : 1; + glyph_node = new XMLElementNode("glyph"); + glyph_node->addAttribute("unicode", XMLString(font.unicode(c), false)); + glyph_node->addAttribute("horiz-adv-x", XMLString(font.hAdvance(c)*extend)); + glyph_node->addAttribute("vert-adv-y", XMLString(font.vAdvance(c))); + string name = font.glyphName(c); + if (!name.empty()) + glyph_node->addAttribute("glyph-name", name); + } + else { + ostringstream oss; + oss << 'g' << FontManager::instance().fontID(&font) << '-' << c; + glyph_node = new XMLElementNode("path"); + glyph_node->addAttribute("id", oss.str()); + sx = font.scaledSize()/upem; + sy = -sx; + } + ostringstream oss; + glyph.writeSVG(oss, sx, sy); + glyph_node->addAttribute("d", oss.str()); + return glyph_node; +} + + +void SVGTree::appendFontStyles (const set<const Font*> &fonts) { + if (CREATE_STYLE && USE_FONTS && !fonts.empty() && _defs) { + XMLElementNode *styleNode = new XMLElementNode("style"); + styleNode->addAttribute("type", "text/css"); + _root->insertAfter(styleNode, _defs); + typedef map<int, const Font*> SortMap; + SortMap sortmap; + FORALL(fonts, set<const Font*>::const_iterator, it) + if (!dynamic_cast<const VirtualFont*>(*it)) // skip virtual fonts + sortmap[FontManager::instance().fontID(*it)] = *it; + ostringstream style; + // add font style definitions in ascending order + FORALL(sortmap, SortMap::const_iterator, it) { + style << "text.f" << it->first << ' ' + << "{font-family:" << it->second->name() + << ";font-size:" << it->second->scaledSize() << "px"; + if (it->second->color() != Color::BLACK) + style << ";fill:" << it->second->color().rgbString(); + style << "}\n"; + } + XMLCDataNode *cdata = new XMLCDataNode(style.str()); + styleNode->append(cdata); + } +} + + +/** Appends glyph definitions of a given font to the defs section of the SVG tree. + * @param[in] font font to be appended + * @param[in] chars codes of the characters whose glyph outlines should be appended + * @param[in] cb pointer to callback object for sending feedback to the glyph tracer (may be 0) */ +void SVGTree::append (const PhysicalFont &font, const set<int> &chars, GFGlyphTracer::Callback *cb) { + if (chars.empty()) + return; + + if (USE_FONTS) { + XMLElementNode *fontNode = new XMLElementNode("font"); + string fontname = font.name(); + fontNode->addAttribute("id", fontname); + fontNode->addAttribute("horiz-adv-x", XMLString(font.hAdvance())); + appendToDefs(fontNode); + + XMLElementNode *faceNode = new XMLElementNode("font-face"); + faceNode->addAttribute("font-family", fontname); + faceNode->addAttribute("units-per-em", XMLString(font.unitsPerEm())); + if (font.type() != PhysicalFont::MF && !font.verticalLayout()) { + faceNode->addAttribute("ascent", XMLString(font.ascent())); + faceNode->addAttribute("descent", XMLString(font.descent())); + } + fontNode->append(faceNode); + + // add required missing-glyph element + XMLElementNode *missing = new XMLElementNode("missing-glyph"); + missing->addAttribute("d", ""); + fontNode->append(missing); + FORALL(chars, set<int>::const_iterator, i) + fontNode->append(createGlyphNode(*i, font, cb)); + } + else if (CREATE_USE_ELEMENTS && &font != font.uniqueFont()) { + // If the same character is used in various sizes, we don't want to embed the complete (lengthy) path + // descriptions multiple times. Because they would only differ by a scale factor, it's better to + // reference the already embedded path together with a transformation attribute and let the SVG renderer + // scale the glyphs properly. This is only necessary if we don't want to use font but path elements. + FORALL(chars, set<int>::const_iterator, it) { + ostringstream oss; + XMLElementNode *use = new XMLElementNode("use"); + oss << 'g' << FontManager::instance().fontID(&font) << '-' << *it; + use->addAttribute("id", oss.str()); + oss.str(""); + oss << "#g" << FontManager::instance().fontID(font.uniqueFont()) << '-' << *it; + use->addAttribute("xlink:href", oss.str()); + double scale = font.scaledSize()/font.uniqueFont()->scaledSize(); + if (scale != 1.0) { + oss.str(""); + oss << "scale(" << scale << ')'; + use->addAttribute("transform", oss.str()); + } + appendToDefs(use); + } + } + else { + FORALL(chars, set<int>::const_iterator, i) + appendToDefs(createGlyphNode(*i, font, cb)); + } +} + + +/** Pushes a new context element that will take all following nodes added to the page. */ +void SVGTree::pushContextElement (XMLElementNode *node) { + if (_pageContainerStack.empty()) + _page->append(node); + else + _pageContainerStack.top()->append(node); + _pageContainerStack.push(node); + _text = _span = 0; // ensure the creation of a new text element for the following characters added +} + + +/** Pops the current context element and restored the previous one. */ +void SVGTree::popContextElement () { + if (!_pageContainerStack.empty()) { + _pageContainerStack.pop(); + _text = _span = 0; // ensure the creation of a new text element for the following characters added + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.h new file mode 100644 index 00000000000..541d299971c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SVGTree.h @@ -0,0 +1,111 @@ +/************************************************************************* +** SVGTree.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SVGTREE_H +#define DVISVGM_SVGTREE_H + +#include <map> +#include <set> +#include <stack> +#include "Color.h" +#include "GFGlyphTracer.h" +#include "Matrix.h" +#include "XMLDocument.h" +#include "XMLNode.h" + +class BoundingBox; +class Color; +struct Font; +class Matrix; +class PhysicalFont; + +class SVGTree +{ + template <typename T> + class Property { + public: + Property (const T &v) : _value(v), _changed(false) {} + + void set (const T &v) { + if (v != _value) { + _value = v; + _changed = true; + } + } + + const T& get () const {return _value;} + operator const T& () {return _value;} + bool changed () const {return _changed;} + void changed (bool c) {_changed = c;} + + private: + T _value; + bool _changed; + }; + + public: + SVGTree (); + void reset (); + void write (std::ostream &os) const {_doc.write(os);} + void newPage (int pageno); + void appendToDefs (XMLNode *node); + void appendToPage (XMLNode *node); + void prependToPage (XMLNode *node); + void appendToDoc (XMLNode *node) {_doc.append(node);} + void appendToRoot (XMLNode *node) {_root->append(node);} + void appendChar (int c, double x, double y, const Font &font); + void appendFontStyles (const std::set<const Font*> &fonts); + void append (const PhysicalFont &font, const std::set<int> &chars, GFGlyphTracer::Callback *cb=0); + void pushContextElement (XMLElementNode *node); + void popContextElement (); + void setBBox (const BoundingBox &bbox); + void setFont (int id, const Font *font); + void setX (double x) {_xchanged = true;} + void setY (double y) {_ychanged = true;} + void setMatrix (const Matrix &m) {_matrix.set(m);} + void setColor (const Color &c); + void setVertical (bool state) {_vertical.set(state);} + void transformPage (const Matrix *m); + const Color& getColor () const {return _color.get();} + const Matrix& getMatrix () const {return _matrix.get();} + XMLElementNode* rootNode () const {return _root;} + + public: + static bool USE_FONTS; ///< if true, create font references and don't draw paths directly + static bool CREATE_STYLE; ///< should style elements and class attributes be used to reference fonts? + static bool CREATE_USE_ELEMENTS; ///< allow generation of <use/> elements? + static double ZOOM_FACTOR; ///< factor applied to width/height attribute + + protected: + void newTextNode (double x, double y); + + private: + XMLDocument _doc; + XMLElementNode *_root, *_page, *_text, *_span, *_defs; + bool _xchanged, _ychanged; + Property<bool> _vertical; ///< true if in vertical writing mode + Property<const Font*> _font; + Property<Color> _color; + Property<Matrix> _matrix; + int _fontnum; + std::stack<XMLElementNode*> _pageContainerStack; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.cpp new file mode 100644 index 00000000000..6e91a05442d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.cpp @@ -0,0 +1,86 @@ +/************************************************************************* +** SignalHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cerrno> +#include <csignal> +#include <cstdlib> +#include "SignalHandler.h" + +using namespace std; + +bool SignalHandler::_break = false; + + +SignalHandler::~SignalHandler() { + stop(); +} + + +/** Returns the singleton handler object. */ +SignalHandler& SignalHandler::instance() { + static SignalHandler handler; + return handler; +} + + +/** Starts listening to CTRL-C signals. + * @return true if handler was activated. */ +bool SignalHandler::start () { + if (!_active) { + _break = false; + if (signal(SIGINT, SignalHandler::callback) != SIG_ERR) { + _active = true; + return true; + } + } + return false; +} + + +/** Stops listening for CTRL-C signals. */ +void SignalHandler::stop () { + if (_active) { + signal(SIGINT, SIG_DFL); + _active = false; + } +} + + +/** Checks for incoming signals and throws an exception if CTRL-C was caught. + * @throw SignalException */ +void SignalHandler::check() { + if (_break) + throw SignalException(); +} + + +void SignalHandler::trigger (bool notify) { + _break = true; + if (notify) + check(); +} + + +/** This function is called on CTRL-C signals. */ +void SignalHandler::callback (int) { + _break = true; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.h new file mode 100644 index 00000000000..dfece9963e4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SignalHandler.h @@ -0,0 +1,50 @@ +/************************************************************************* +** SignalHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SIGNALHANDLER_H +#define DVISVGM_SIGNALHANDLER_H + +#include <exception> + +struct SignalException : public std::exception { +}; + + +class SignalHandler +{ + public: + ~SignalHandler (); + static SignalHandler& instance (); + bool start (); + void stop (); + void check (); + void trigger (bool notify); + bool active () const {return _active;} + + protected: + SignalHandler () : _active(false) {} + static void callback (int signal); + + private: + bool _active; ///< true if listening for signals + static bool _break; ///< true if signal has been caught +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialActions.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialActions.h new file mode 100644 index 00000000000..e7b4503d148 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialActions.h @@ -0,0 +1,91 @@ +/************************************************************************* +** SpecialActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SPECIALACTIONS_H +#define DVISVGM_SPECIALACTIONS_H + +#include <string> +#include "BoundingBox.h" +#include "Color.h" +#include "Matrix.h" + + +struct XMLNode; +class XMLElementNode; + +struct SpecialActions +{ + virtual ~SpecialActions () {} + virtual double getX () const =0; + virtual double getY () const =0; + virtual void setX (double x) =0; + virtual void setY (double y) =0; + virtual void finishLine () =0; + virtual void setColor (const Color &color) =0; + virtual Color getColor () const =0; + virtual void setMatrix (const Matrix &m) =0; + virtual const Matrix& getMatrix () const =0; + virtual void getPageTransform (Matrix &matrix) const =0; + virtual void setBgColor (const Color &color) =0; + virtual void appendToPage (XMLNode *node) =0; + virtual void appendToDefs (XMLNode *node) =0; + virtual void prependToPage (XMLNode *node) =0; + virtual void pushContextElement (XMLElementNode *node) =0; + virtual void popContextElement () =0; + virtual BoundingBox& bbox () =0; + virtual BoundingBox& bbox (const std::string &name, bool reset=false) =0; + virtual void embed (const BoundingBox &bbox) =0; + virtual void embed (const DPair &p, double r=0) =0; + virtual void progress (const char *id) {} + virtual int getDVIStackDepth () const {return 0;} +}; + + +class SpecialEmptyActions : public SpecialActions +{ + public: + double getX () const {return 0;} + double getY () const {return 0;} + void setX (double x) {} + void setY (double y) {} + void finishLine () {} + void setColor (const Color &color) {} + void setBgColor (const Color &color) {} + Color getColor () const {return Color::BLACK;} + void setMatrix (const Matrix &m) {} + const Matrix& getMatrix () const {return _matrix;} + void getPageTransform (Matrix &matrix) const {} + void appendToPage (XMLNode *node) {} + void appendToDefs (XMLNode *node) {} + void prependToPage (XMLNode *node) {} + void pushContextElement (XMLElementNode *node) {} + void popContextElement () {} + BoundingBox& bbox () {return _bbox;} + BoundingBox& bbox (const std::string &name, bool reset=false) {return _bbox;} + void embed (const BoundingBox &bbox) {} + void embed (const DPair &p, double r=0) {} + + private: + BoundingBox _bbox; + Matrix _matrix; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialHandler.h new file mode 100644 index 00000000000..b11bab4782c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialHandler.h @@ -0,0 +1,66 @@ +/************************************************************************* +** SpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SPECIALHANDLER_H +#define DVISVGM_SPECIALHANDLER_H + +#include <istream> +#include <list> +#include "MessageException.h" + + +struct SpecialActions; +class SpecialManager; + + +struct SpecialException : public MessageException +{ + SpecialException (const std::string &msg) : MessageException(msg) {} +}; + + +struct DVIEndPageListener +{ + virtual ~DVIEndPageListener () {} + virtual void dviEndPage (unsigned pageno) =0; +}; + + +struct DVIPositionListener +{ + virtual ~DVIPositionListener () {} + virtual void dviMovedTo (double x, double y) =0; +}; + + +struct SpecialHandler +{ + friend class SpecialManager; + + virtual ~SpecialHandler () {} + virtual const char** prefixes () const=0; + virtual const char* info () const=0; + virtual const char* name () const=0; + virtual void setDviScaleFactor (double dvi2bp) {} + virtual bool process (const char *prefix, std::istream &is, SpecialActions *actions)=0; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.cpp new file mode 100644 index 00000000000..86aca42cd02 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.cpp @@ -0,0 +1,170 @@ +/************************************************************************* +** SpecialManager.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <iomanip> +#include <sstream> +#include "SpecialActions.h" +#include "SpecialHandler.h" +#include "SpecialManager.h" +#include "PsSpecialHandler.h" +#include "macros.h" + +using namespace std; + + +SpecialManager::~SpecialManager () { + unregisterHandlers(); +} + + +/** Remove all registered handlers. */ +void SpecialManager::unregisterHandlers () { + FORALL(_pool, vector<SpecialHandler*>::iterator, it) + delete *it; + _pool.clear(); + _handlers.clear(); + _endPageListeners.clear(); + _positionListeners.clear(); +} + + +/** Registers a single special handler. This method doesn't check if a + * handler of the same class is already registered. + * @param[in] handler pointer to handler to be registered */ +void SpecialManager::registerHandler (SpecialHandler *handler) { + if (handler) { + // get array of prefixes this handler is responsible for + _pool.push_back(handler); + for (const char **p=handler->prefixes(); *p; ++p) + _handlers[*p] = handler; + if (DVIEndPageListener *listener = dynamic_cast<DVIEndPageListener*>(handler)) + _endPageListeners.push_back(listener); + if (DVIPositionListener *listener = dynamic_cast<DVIPositionListener*>(handler)) + _positionListeners.push_back(listener); + } +} + + +/** Registers several special handlers at once. + * If ignorelist == 0, all given handlers are registered. To exclude selected sets of + * specials, the corresponding names can be given separated by non alpha-numeric characters, + * e.g. "color, ps, em" or "color: ps em" etc. + * @param[in] handlers pointer to zero-terminated array of handlers to be registered + * @param[in] ignorelist list of special names to be ignored */ +void SpecialManager::registerHandlers (SpecialHandler **handlers, const char *ignorelist) { + if (handlers) { + string ign = ignorelist ? ignorelist : ""; + FORALL(ign, string::iterator, it) + if (!isalnum(*it)) + *it = '%'; + ign = "%"+ign+"%"; + + for (; *handlers; handlers++) { + if (!(*handlers)->name() || ign.find("%"+string((*handlers)->name())+"%") == string::npos) + registerHandler(*handlers); + else + delete *handlers; + } + } +} + + +/** Looks for an appropriate handler for a given special prefix. + * @param[in] prefix the special prefix, e.g. "color" or "em" + * @return in case of success: pointer to handler, 0 otherwise */ +SpecialHandler* SpecialManager::findHandler (const string &prefix) const { + ConstIterator it = _handlers.find(prefix); + if (it != _handlers.end()) + return it->second; + return 0; +} + + +static string extract_prefix (istream &is) { + int c; + string prefix; + while (isalnum(c=is.get())) + prefix += c; + if (ispunct(c)) // also add seperation character to identifying prefix + prefix += c; + if (prefix == "ps:" && is.peek() == ':') + prefix += is.get(); + return prefix; +} + + +/** Executes a special command. + * @param[in] special the special expression + * @param[in] dvi2bp factor to convert DVI units to PS points + * @param[in] actions actions the special handlers can perform + * @param[in] listener object that wants to be notified about the processing state + * @return true if the special could be processed successfully + * @throw SpecialException in case of errors during special processing */ +bool SpecialManager::process (const string &special, double dvi2bp, SpecialActions *actions, Listener *listener) const { + istringstream iss(special); + string prefix = extract_prefix(iss); + bool success=false; + if (SpecialHandler *handler = findHandler(prefix)) { + if (listener) + listener->beginSpecial(prefix.c_str()); + handler->setDviScaleFactor(dvi2bp); + success = handler->process(prefix.c_str(), iss, actions); + if (listener) + listener->endSpecial(prefix.c_str()); + } + return success; +} + + +void SpecialManager::leavePSHeaderSection () const { + if (PsSpecialHandler *pshandler = dynamic_cast<PsSpecialHandler*>(findHandler("!"))) + pshandler->enterBodySection(); +} + + +void SpecialManager::notifyEndPage (unsigned pageno) const { + FORALL(_endPageListeners, vector<DVIEndPageListener*>::const_iterator, it) + (*it)->dviEndPage(pageno); +} + + +void SpecialManager::notifyPositionChange (double x, double y) const { + FORALL(_positionListeners, vector<DVIPositionListener*>::const_iterator, it) + (*it)->dviMovedTo(x, y); +} + + +void SpecialManager::writeHandlerInfo (ostream &os) const { + ios::fmtflags osflags(os.flags()); + typedef map<string, SpecialHandler*> SortMap; + SortMap m; + FORALL(_handlers, ConstIterator, it) + if (it->second->name()) + m[it->second->name()] = it->second; + FORALL(m, SortMap::iterator, it) { + os << setw(10) << left << it->second->name() << ' '; + if (it->second->info()) + os << it->second->info(); + os << endl; + } + os.flags(osflags); // restore format flags +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.h new file mode 100644 index 00000000000..a0cdd26ac91 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/SpecialManager.h @@ -0,0 +1,72 @@ +/************************************************************************* +** SpecialManager.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SPECIALMANAGER_H +#define DVISVGM_SPECIALMANAGER_H + +#include <map> +#include <ostream> +#include <string> +#include <vector> +#include "SpecialHandler.h" + +struct SpecialActions; + +class SpecialManager +{ + public: + struct Listener + { + virtual ~Listener () {} + virtual void beginSpecial (const char *prefix)=0; + virtual void endSpecial (const char *prefix)=0; + }; + + private: + typedef std::vector<SpecialHandler*> HandlerPool; + typedef std::map<std::string,SpecialHandler*> HandlerMap; + typedef HandlerMap::iterator Iterator; + typedef HandlerMap::const_iterator ConstIterator; + + public: + SpecialManager () {} + virtual ~SpecialManager (); + void registerHandler (SpecialHandler *handler); + void registerHandlers (SpecialHandler **handlers, const char *ignorelist); + void unregisterHandlers (); + bool process (const std::string &special, double dvi2bp, SpecialActions *actions, Listener *listener=0) const; + void notifyEndPage (unsigned pageno) const; + void notifyPositionChange (double x, double y) const; + void writeHandlerInfo (std::ostream &os) const; + void leavePSHeaderSection () const; + + protected: + SpecialManager (const SpecialManager &) {} + void operator = (const SpecialManager &) {} + SpecialHandler* findHandler (const std::string &prefix) const; + + private: + HandlerPool _pool; ///< stores pointers to all handlers + HandlerMap _handlers; ///< pointers to handlers for corresponding prefixes + std::vector<DVIEndPageListener*> _endPageListeners; + std::vector<DVIPositionListener*> _positionListeners; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.cpp new file mode 100644 index 00000000000..1464b9fdcf6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.cpp @@ -0,0 +1,165 @@ +/************************************************************************* +** StreamReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "CRC32.h" +#include "StreamReader.h" +#include "macros.h" + +using namespace std; + +StreamReader::StreamReader (istream &s) + : _is(&s) +{ +} + + +istream& StreamReader::replaceStream (istream &in) { + istream &ret = *_is; + _is = ∈ + return ret; +} + + +/** Reads an unsigned integer from assigned input stream. + * @param[in] bytes number of bytes to read (max. 4) + * @return read integer */ +UInt32 StreamReader::readUnsigned (int bytes) { + UInt32 ret = 0; + for (bytes--; bytes >= 0 && !_is->eof(); bytes--) { + UInt32 b = _is->get(); + ret |= b << (8*bytes); + } + return ret; +} + + +/** Reads an unsigned integer from assigned input stream and updates the CRC32 checksum. + * @param[in] bytes number of bytes to read (max. 4) + * @param[in,out] crc32 checksum to be updated + * @return read integer */ +UInt32 StreamReader::readUnsigned (int bytes, CRC32 &crc32) { + UInt32 ret = readUnsigned(bytes); + crc32.update(ret, bytes); + return ret; +} + + +/** Reads an signed integer from assigned input stream. + * @param[in] bytes number of bytes to read (max. 4) + * @return read integer */ +Int32 StreamReader::readSigned (int bytes) { + Int32 ret = _is->get(); + if (ret & 128) // negative value? + ret |= 0xffffff00; + for (bytes-=2; bytes >= 0 && !_is->eof(); bytes--) + ret = (ret << 8) | _is->get(); + return ret; +} + + +/** Reads an signed integer from assigned input stream and updates the CRC32 checksum. + * @param[in] bytes number of bytes to read (max. 4) + * @param[in,out] crc32 checksum to be updated + * @return read integer */ +Int32 StreamReader::readSigned (int bytes, CRC32 &crc32) { + Int32 ret = readSigned(bytes); + crc32.update(ret, bytes); + return ret; +} + + +/** Reads a string terminated by a 0-byte. */ +string StreamReader::readString () { + if (!_is) + throw StreamReaderException("no stream assigned"); + string ret; + while (!_is->eof() && _is->peek() > 0) + ret += _is->get(); + _is->get(); // skip 0-byte + return ret; +} + + +/** Reads a string terminated by a 0-byte and updates the CRC32 checksum. + * @param[in,out] crc32 checksum to be updated + * @param[in] finalZero consider final 0-byte in checksum + * @return the string read */ +string StreamReader::readString (CRC32 &crc32, bool finalZero) { + string ret = readString(); + crc32.update((const UInt8*)ret.c_str(), ret.length()); + if (finalZero) + crc32.update(0, 1); + return ret; +} + + +/** Reads a string of a given length. + * @param[in] length number of characters to read + * @return the string read */ +string StreamReader::readString (int length) { + if (!_is) + throw StreamReaderException("no stream assigned"); + char *buf = new char[length+1]; + if (length <= 0) + *buf = 0; + else { + _is->read(buf, length); // reads 'length' bytes + buf[length] = 0; + } + string ret = buf; + delete [] buf; + return ret; +} + + +/** Reads a string of a given length and updates the CRC32 checksum. + * @param[in] length number of characters to read + * @param[in,out] crc32 checksum to be updated + * @return the string read */ +string StreamReader::readString (int length, CRC32 &crc32) { + string ret = readString(length); + crc32.update(ret.c_str()); + return ret; +} + + +vector<UInt8>& StreamReader::readBytes (int n, vector<UInt8> &bytes) { + if (n > 0) + in().read((char*)&bytes[0], n); + return bytes; +} + + +vector<UInt8>& StreamReader::readBytes (int n, vector<UInt8> &bytes, CRC32 &crc32) { + readBytes(n, bytes); + crc32.update(&bytes[0], bytes.size()); + return bytes; +} + + +int StreamReader::readByte (CRC32 &crc32) { + int ret = readByte(); + if (ret >= 0) { + const UInt8 c = UInt8(ret & 0xff); + crc32.update(&c, 1); + } + return ret; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.h new file mode 100644 index 00000000000..a35bae2d91f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamReader.h @@ -0,0 +1,65 @@ +/************************************************************************* +** StreamReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_STREAMREADER_H +#define DVISVGM_STREAMREADER_H + +#include <istream> +#include <string> +#include <vector> +#include "MessageException.h" +#include "types.h" + +class CRC32; + +class StreamReader +{ + public: + StreamReader (std::istream &s); + virtual ~StreamReader () {} + std::istream& replaceStream (std::istream &s); + UInt32 readUnsigned (int n); + UInt32 readUnsigned (int n, CRC32 &crc32); + Int32 readSigned (int n); + Int32 readSigned (int n, CRC32 &crc32); + std::string readString (); + std::string readString (CRC32 &crc32, bool finalZero=false); + std::string readString (int length); + std::string readString (int length, CRC32 &crc32); + std::vector<UInt8>& readBytes (int n, std::vector<UInt8> &bytes); + std::vector<UInt8>& readBytes (int n, std::vector<UInt8> &bytes, CRC32 &crc32); + int readByte () {return _is->get();} + int readByte (CRC32 &crc32); + void seek (std::istream::streampos pos, std::ios::seekdir dir) {_is->seekg(pos, dir);} + + protected: + std::istream& in () {return *_is;} + + private: + std::istream *_is; +}; + + +struct StreamReaderException : public MessageException +{ + StreamReaderException (const std::string &msg) : MessageException(msg) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.cpp new file mode 100644 index 00000000000..203a1788f87 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.cpp @@ -0,0 +1,82 @@ +/************************************************************************* +** StreamWriter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "CRC32.h" +#include "StreamWriter.h" + +using namespace std; + + +/** Writes an unsigned integer to the output stream. + * @param[in] val the value to write + * @param[in] n number of bytes to be considered */ +void StreamWriter::writeUnsigned (UInt32 val, int n) { + for (n--; n >= 0; n--) + _os.put((val >> (8*n)) & 0xff); +} + + +/** Writes a signed integer to the output stream. + * @param[in] val the value to write + * @param[in] n number of bytes to be considered */ +void StreamWriter::writeSigned (Int32 val, int n) { + writeUnsigned((UInt32)val, n); +} + + +/** Writes a signed integer to the output stream. + * @param[in] val the value to write + * @param[in] finalZero if true, a final 0-byte is appended */ +void StreamWriter::writeString (const string &str, bool finalZero) { + for (size_t i=0; i < str.length(); i++) + _os.put(str[i]); + if (finalZero) + _os.put(0); +} + + +/** Writes an unsigned integer to the output stream. + * @param[in] val the value to write + * @param[in] n number of bytes to be considered + * @param[in,out] crc32 checksum to be updated */ +void StreamWriter::writeUnsigned (UInt32 val, int n, CRC32 &crc32) { + writeUnsigned(val, n); + crc32.update(val, n); +} + + +/** Writes a signed integer to the output stream and updates the CRC32 checksum. + * @param[in] val the value to write + * @param[in] n number of bytes to be considered + * @param[in,out] crc32 checksum to be updated */ +void StreamWriter::writeSigned (Int32 val, int n, CRC32 &crc32) { + writeUnsigned((UInt32)val, n, crc32); +} + + +/** Writes a string to the output stream and updates the CRC32 checksum. + * @param[in] str the string to write + * @param[in,out] crc32 checksum to be updated + * @param[in] finalZero if true, a final 0-byte is appended */ +void StreamWriter::writeString (const std::string &str, CRC32 &crc32, bool finalZero) { + writeString(str, finalZero); + crc32.update((const UInt8*)str.c_str(), str.length() + (finalZero ? 1 : 0)); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.h new file mode 100644 index 00000000000..05999c48fb5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/StreamWriter.h @@ -0,0 +1,46 @@ +/************************************************************************* +** StreamWriter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_STREAMWRITER_H +#define DVISVGM_STREAMWRITER_H + +#include <ostream> +#include "types.h" + + +class CRC32; + +class StreamWriter +{ + public: + StreamWriter (std::ostream &os) : _os(os) {} + virtual ~StreamWriter () {} + void writeUnsigned (UInt32 val, int n); + void writeSigned (Int32 val, int n); + void writeString (const std::string &str, bool finalZero=false); + void writeUnsigned (UInt32 val, int n, CRC32 &crc32); + void writeSigned (Int32 val, int n, CRC32 &crc32); + void writeString (const std::string &str, CRC32 &crc32, bool finalZero=false); + + private: + std::ostream &_os; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.cpp new file mode 100644 index 00000000000..1ac23a66139 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.cpp @@ -0,0 +1,267 @@ +/************************************************************************* +** Subfont.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cstdlib> +#include <cstring> +#include <fstream> +#include <limits> +#include "FileFinder.h" +#include "Subfont.h" +#include "Message.h" + +using namespace std; + +// helper functions + +static int skip_mapping_data (istream &is); +static bool scan_line (const char *line, int lineno, UInt16 *mapping, const string &fname, int &pos); + + +/** Constructs a new SubfontDefinition object. + * @param[in] name name of subfont definition + * @param[in] fpath path to corresponding .sfd file*/ +SubfontDefinition::SubfontDefinition (const string &name, const char *fpath) : _sfname(name) { + // read all subfont IDs from the .sfd file but skip the mapping data + ifstream is(fpath); + while (is) { + if (is.peek() == '#') // comment line? + is.ignore(numeric_limits<int>::max(), '\n'); // => skip it + else if (isspace(is.peek())) + is.get(); + else { + string id; + while (is && !isspace(is.peek())) + id += is.get(); + if (!id.empty()) { + pair<Iterator, bool> state = _subfonts.insert(pair<string,Subfont*>(id, (Subfont*)0)); + if (state.second) // id was not present in map already + state.first->second = new Subfont(*this, state.first->first); + skip_mapping_data(is); + } + } + } +} + + +SubfontDefinition::~SubfontDefinition () { + for (Iterator it=_subfonts.begin(); it != _subfonts.end(); ++it) + delete it->second; +} + + +/** Looks for a subfont definition of the given name and returns the corresponding object. + * All objects are only created once for a given name and stored in an internal cache. + * @param[in] name name of subfont definition to lookup + * @return pointer to subfont definition object or 0 if it doesn't exist */ +SubfontDefinition* SubfontDefinition::lookup (const std::string &name) { + typedef map<string,SubfontDefinition*> SFDMap; + static SFDMap sfdMap; + SFDMap::iterator it = sfdMap.find(name); + if (it != sfdMap.end()) + return it->second; + SubfontDefinition *sfd=0; + if (const char *path = FileFinder::lookup(name+".sfd", false)) { + sfd = new SubfontDefinition(name, path); + sfdMap[name] = sfd; + } + return sfd; +} + + +/** Returns the full path to the corresponding .sfd file or 0 if it can't be found. */ +const char* SubfontDefinition::path () const { + return FileFinder::lookup(filename(), false); +} + + +/** Returns the subfont with the given ID, or 0 if it doesn't exist. */ +Subfont* SubfontDefinition::subfont (const string &id) const { + ConstIterator it = _subfonts.find(id); + if (it != _subfonts.end()) + return it->second; + return 0; +} + + +/** Returns all subfonts defined in this SFD. */ +int SubfontDefinition::subfonts (vector<Subfont*> &sfs) const { + for (ConstIterator it=_subfonts.begin(); it != _subfonts.end(); ++it) + sfs.push_back(it->second); + return sfs.size(); +} + +////////////////////////////////////////////////////////////////////// + +Subfont::~Subfont () { + delete [] _mapping; +} + + +/** Reads the character mappings for a given subfont ID. + * Format of subfont definition (sfd) files: + * sfd ::= (ID entries | '#' <string> '\n')* + * ID ::= <string without whitespace> + * entries ::= (integer | integer ':' | integer '_' integer)* + * The mapping data for a subfont is given as a sequence of 256 16-bit values where + * value v at position c defines the (global) character code that is assigned to the + * local subfont character c. The sequence v,v+1,v+2,...,v+n can be abbreviated with + * v '_' v+n, e.g. 10_55. In order to continue the sequence at a different position, + * the syntax number ':' can be used. Example: 10: 5 6 7 assigns the values v=5, 6, 7 + * to c=10, 11 and 12, respectively. + * @return true if the data has been read successfully */ +bool Subfont::read () { + if (_mapping) // if there's already a mapping assigned, we're finished here + return true; + if (const char *p = _sfd.path()) { + ifstream is(p); + if (!is) + return false; + + int lineno=1; + while (is) { + if (is.peek() == '#' || is.peek() == '\n') { + is.ignore(numeric_limits<int>::max(), '\n'); // skip comment and empty line + lineno++; + } + else if (isspace(is.peek())) + is.get(); + else { + string id; + while (is && !isspace(is.peek())) + id += is.get(); + if (id != _id) + lineno += skip_mapping_data(is); + else { + // build mapping array + _mapping = new UInt16[256]; + memset(_mapping, 0, 256*sizeof(UInt16)); + int pos=0; + char buf[1024]; + bool complete=false; + while (!complete) { + is.getline(buf, 1024); + complete = scan_line(buf, lineno, _mapping, _sfd.filename() ,pos); + } + return true; + } + } + } + } + return false; +} + + +/** Returns the global character code of the target font for a + * (local) character code of the subfont. + * @param[in] c local character code relative to the subfont + * @return character code of the target font */ +UInt16 Subfont::decode (unsigned char c) { + if (!_mapping && !read()) + return 0; + return _mapping[c]; +} + + +////////////////////////////////////////////////////////////////////// + + +/** Skips the mapping data of a subfont entry. + * @param[in] is stream to read from + * @return number of lines skipped */ +static int skip_mapping_data (istream &is) { + char buf[1024]; + bool complete=false; + int lines=0; + while (is && !complete) { + is.getline(buf, 1024); + if (is.gcount() > 1) + lines++; + const char *p = buf+is.gcount()-2; + while (p >= buf && isspace(*p)) + p--; + complete = (p < buf || *p != '\\'); // line doesn't end with backslash + } + return lines; +} + + +/** Scans a single line of mapping data and stores the values in the given array. + * @param[in] line the line of text to be scanned + * @param[in] lineno line number used in exception messages + * @param[in,out] mapping the mapping data + * @param[in] fname name of the mapfile being scanned + * @param[in,out] offset position/index of next mapping value + * @return true if the line is the last one the current mapping sequence, i.e. the line doesn't end with a backslash */ +static bool scan_line (const char *line, int lineno, UInt16 *mapping, const string &fname, int &offset) { + const char *p=line; + char *q; + for (; *p && isspace(*p); p++); + while (*p) { + if (*p == '\\') { + while (*++p) + if (!isspace(*p)) + throw SubfontException("unexpected backslash in mapping table", fname, lineno); + } + else { + long val1 = strtol(p, &q, 0); // first value of range + long val2; // last value of range + ostringstream oss; // output stream for exception messages + switch (*q) { + case ':': + if (val1 < 0 || val1 > 255) + throw SubfontException(oss << "offset value " << val1 << " out of range (0-255)", fname, lineno); + offset = val1; + val1 = -1; + q++; + break; + case '_': + p = q+1; + val2 = strtol(p, &q, 0); + if (val1 < 0 || val1 > 0xffffL) + throw SubfontException(oss << "table value " << val1 << " out of range", fname, lineno); + if (val2 < 0 || val2 > 0xffffL) + throw SubfontException(oss << "table value " << val2 << " out of range", fname, lineno); + if (p == q || (!isspace(*q) && *q != '\\' && *q)) + throw SubfontException(oss << "unexpected character '" << *q << "'", fname, lineno); + break; + default: + if (p == q || (!isspace(*q) && *q != '\\' && *q)) + throw SubfontException(oss << "unexpected character '" << *q << "'", fname, lineno); + if (val1 < 0 || val1 > 0xffffL) + throw SubfontException("invalid character code", fname, lineno); + val2 = val1; + } + if (val1 >= 0) { + if (val1 > val2 || offset+val2-val1 > 255) + throw SubfontException(oss << "invalid range in mapping table: " << hex << val1 << '_' << val2, fname, lineno); + for (long v=val1; v <= val2; v++) { + if (mapping[offset]) + throw SubfontException(oss << "mapping of character " << offset << " already defined", fname, lineno); + mapping[offset++] = static_cast<UInt16>(v); + } + } + for (p=q; *p && isspace(*p); p++); + } + } + for (p--; p >= line && isspace(*p); p--); + return p < line || *p != '\\'; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.h new file mode 100644 index 00000000000..03ce75c3e99 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Subfont.h @@ -0,0 +1,102 @@ +/************************************************************************* +** Subfont.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SUBFONT_H +#define DVISVGM_SUBFONT_H + +#include <istream> +#include <map> +#include <sstream> +#include <string> +#include <vector> +#include "MessageException.h" +#include "types.h" + + +class Subfont; + + +/** Represents a collection of subfont mappings as defined in a .sfd file, and + * encapsulates the evaluation of these files. */ +class SubfontDefinition +{ + typedef std::map<std::string, Subfont*> Subfonts; + typedef Subfonts::iterator Iterator; + typedef Subfonts::const_iterator ConstIterator; + public: + ~SubfontDefinition (); + static SubfontDefinition* lookup (const std::string &name); +// int getIDs (std::vector<std::string> &ids) const; + const std::string& name() const {return _sfname;} + std::string filename() const {return _sfname+".sfd";} + Subfont* subfont (const std::string &id) const; + int subfonts (std::vector<Subfont*> &sfs) const; + const char* path () const; + + protected: + SubfontDefinition (const std::string &name, const char *fpath); + SubfontDefinition (const SubfontDefinition &sfd) {} + + private: + std::string _sfname; ///< name of subfont + Subfonts _subfonts; ///< all subfonts defined in the corresponding .sfd file +}; + + +/** Represents a single subfont mapping defined in a SubfontDefinition (.sfd file). */ +class Subfont +{ + friend class SubfontDefinition; + public: + ~Subfont(); + const std::string& id () const {return _id;} + UInt16 decode (unsigned char c); + + protected: + Subfont (SubfontDefinition &sfd, const std::string &id) : _sfd(sfd), _id(id), _mapping(0) {} + bool read (); + + private: + SubfontDefinition &_sfd; ///< SubfontDefinition where this Subfont belongs to + const std::string &_id; ///< id of this subfont as specified in the .sfd file + UInt16 *_mapping; ///< the character mapping table with 256 entries +}; + + +class SubfontException : public MessageException +{ + public: + SubfontException (const std::string &msg, const std::string &fname, int lineno=0) + : MessageException(msg), _fname(fname), _lineno(lineno) {} + + SubfontException (const std::ostream &oss, const std::string &fname, int lineno=0) + : MessageException(dynamic_cast<const std::ostringstream&>(oss).str()), _fname(fname), _lineno(lineno) {} + + virtual ~SubfontException () throw() {} + + const char* filename () const {return _fname.c_str();} + int lineno () const {return _lineno;} + + private: + std::string _fname; + int _lineno; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.cpp new file mode 100644 index 00000000000..6769f843cae --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.cpp @@ -0,0 +1,50 @@ +/************************************************************************* +** System.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <ctime> +#include "System.h" + +#if defined (HAVE_SYS_TIME_H) +#include <sys/time.h> +#elif defined (HAVE_SYS_TIMEB_H) +#include <sys/timeb.h> +#endif + + +using namespace std; + + +/** Returns timestamp (wall time) in seconds. */ +double System::time () { +#if defined (HAVE_SYS_TIME_H) + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec/1000000.0; +#elif defined (HAVE_SYS_TIMEB_H) + struct timeb tb; + ftime(&tb); + return tb.time + tb.millitm/1000.0; +#else + clock_t myclock = clock(); + return double(myclock)/CLOCKS_PER_SEC; +#endif +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.h new file mode 100644 index 00000000000..7200c93f291 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/System.h @@ -0,0 +1,29 @@ +/************************************************************************* +** System.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_SYSTEM_H +#define DVISVGM_SYSTEM_H + +namespace System +{ + double time (); +} + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.cpp new file mode 100644 index 00000000000..db36b7f50b6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.cpp @@ -0,0 +1,156 @@ +/************************************************************************* +** TFM.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <iostream> +#include <fstream> +#include <vector> +#include "FileFinder.h" +#include "Message.h" +#include "StreamReader.h" +#include "TFM.h" + +using namespace std; + + +/** Reads a sequence of n TFM words (4 Bytes each). + * @param[in] sr the TFM data is read from this object + * @param[out] v the read words + * @param[in] n number of words to be read */ +template <typename T> +static void read_words (StreamReader &sr, vector<T> &v, unsigned n) { + v.clear(); + v.resize(n); + for (unsigned i=0; i < n; i++) + v[i] = sr.readUnsigned(4); +} + + +/** Converts a TFM fix point value to double (PS point units). */ +static double fix2double (FixWord fix) { + const double pt2bp = 72/72.27; + return double(fix)/(1 << 20)*pt2bp; +} + + +TFM::TFM (istream &is) { + is.seekg(0); + StreamReader sr(is); + UInt16 lf = UInt16(sr.readUnsigned(2)); // length of entire file in 4 byte words + UInt16 lh = UInt16(sr.readUnsigned(2)); // length of header in 4 byte words + _firstChar= UInt16(sr.readUnsigned(2)); // smallest character code in font + _lastChar = UInt16(sr.readUnsigned(2)); // largest character code in font + UInt16 nw = UInt16(sr.readUnsigned(2)); // number of words in width table + UInt16 nh = UInt16(sr.readUnsigned(2)); // number of words in height table + UInt16 nd = UInt16(sr.readUnsigned(2)); // number of words in depth table + UInt16 ni = UInt16(sr.readUnsigned(2)); // number of words in italic corr. table + UInt16 nl = UInt16(sr.readUnsigned(2)); // number of words in lig/kern table + UInt16 nk = UInt16(sr.readUnsigned(2)); // number of words in kern table + UInt16 ne = UInt16(sr.readUnsigned(2)); // number of words in ext. char table + UInt16 np = UInt16(sr.readUnsigned(2)); // number of font parameter words + + if (6+lh+(_lastChar-_firstChar+1)+nw+nh+nd+ni+nl+nk+ne+np != lf) + throw FontMetricException("inconsistent length values"); + if (_firstChar >= _lastChar || _lastChar > 255 || ne > 256) + throw FontMetricException("character codes out of range"); + + readHeader(sr); + is.seekg(24+lh*4); // move to char info table + readTables(sr, nw, nh, nd, ni); +} + + +void TFM::readHeader (StreamReader &sr) { + _checksum = sr.readUnsigned(4); + _designSize = sr.readUnsigned(4); +} + + +void TFM::readTables (StreamReader &sr, int nw, int nh, int nd, int ni) { + read_words(sr, _charInfoTable, _lastChar-_firstChar+1); + read_words(sr, _widthTable, nw); + read_words(sr, _heightTable, nh); + read_words(sr, _depthTable, nd); + read_words(sr, _italicTable, ni); +} + + +/** Returns the design size of this font in PS point units. */ +double TFM::getDesignSize () const { + return fix2double(_designSize); +} + + +/** Returns the index to the entry of the character info table that describes the metric of a given character. + * @param[in] c character whose index is retrieved + * @return table index for character c, or -1 if there's no entry */ +int TFM::charIndex (int c) const { + if (c < _firstChar || c > _lastChar || size_t(c-_firstChar) >= _charInfoTable.size()) + return -1; + return c-_firstChar; +} + + +// the char info word for each character consists of 4 bytes holding the following information: +// width index w, height index (h), depth index (d), italic correction index (it), +// tag (tg) and a remainder: +// +// byte 1 | byte 2 | byte 3 | byte 4 +// xxxxxxxx | xxxx xxxx | xxxxxx xx | xxxxxxxx +// w | h d | it tg | remainder + +/** Returns the width of char c in PS point units. */ +double TFM::getCharWidth (int c) const { + int index = charIndex(c); + if (index < 0) + return 0; + index = (_charInfoTable[index] >> 24) & 0xFF; + return fix2double(_widthTable[index]) * fix2double(_designSize); +} + + +/** Returns the height of char c in PS point units. */ +double TFM::getCharHeight (int c) const { + int index = charIndex(c); + if (index < 0) + return 0; + index = (_charInfoTable[index] >> 20) & 0x0F; + return fix2double(_heightTable[index]) * fix2double(_designSize); +} + + +/** Returns the depth of char c in PS point units. */ +double TFM::getCharDepth (int c) const { + int index = charIndex(c); + if (index < 0) + return 0; + index = (_charInfoTable[index] >> 16) & 0x0F; + return fix2double(_depthTable[index]) * fix2double(_designSize); +} + + +/** Returns the italic correction of char c in PS point units. */ +double TFM::getItalicCorr (int c) const { + int index = charIndex(c); + if (index < 0) + return 0; + index = (_charInfoTable[index] >> 10) & 0x3F; + return fix2double(_italicTable[index]) * fix2double(_designSize); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.h new file mode 100644 index 00000000000..1f75d76cb50 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TFM.h @@ -0,0 +1,66 @@ +/************************************************************************* +** TFM.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_TFM_H +#define DVISVGM_TFM_H + +#include <istream> +#include <string> +#include <vector> +#include "FontMetrics.h" +#include "types.h" +#include "StreamReader.h" + +class StreamReader; + +class TFM : public FontMetrics +{ + public: +// TFM (const char *fname); + TFM (std::istream &is); + double getDesignSize () const; + double getCharWidth (int c) const; + double getCharHeight (int c) const; + double getCharDepth (int c) const; + double getItalicCorr (int c) const; + bool verticalLayout () const {return false;} + UInt32 getChecksum () const {return _checksum;} + UInt16 firstChar () const {return _firstChar;} + UInt16 lastChar () const {return _lastChar;} + + protected: + TFM () : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0) {} + void readHeader (StreamReader &sr); + void readTables (StreamReader &sr, int nw, int nh, int nd, int ni); + virtual int charIndex (int c) const; + void setCharRange (int firstchar, int lastchar) {_firstChar=firstchar; _lastChar=lastchar;} + + private: + UInt32 _checksum; + UInt16 _firstChar, _lastChar; + FixWord _designSize; ///< design size of the font in TeX points (7227 pt = 254 cm) + std::vector<UInt32> _charInfoTable; + std::vector<FixWord> _widthTable; ///< character widths in design size units + std::vector<FixWord> _heightTable; ///< character height in design size units + std::vector<FixWord> _depthTable; ///< character depth in design size units + std::vector<FixWord> _italicTable; ///< italic corrections in design size units +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.cpp new file mode 100644 index 00000000000..e95111d196b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.cpp @@ -0,0 +1,208 @@ +/************************************************************************* +** Terminal.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "Terminal.h" + +#ifdef HAVE_TERMIOS_H +#include <termios.h> +#endif + +#ifdef GWINSZ_IN_SYS_IOCTL +#include <sys/ioctl.h> +#endif + +#ifdef __WIN32__ +#include <windows.h> +#endif + +#include <cstdio> + + +using namespace std; + + +const int Terminal::RED = 1; +const int Terminal::GREEN = 2; +const int Terminal::BLUE = 4; + +const int Terminal::CYAN = GREEN|BLUE; +const int Terminal::YELLOW = RED|GREEN; +const int Terminal::MAGENTA = RED|BLUE; +const int Terminal::WHITE = RED|GREEN|BLUE; +const int Terminal::DEFAULT = -1; +const int Terminal::BLACK = 0; + +#ifdef __WIN32__ +int Terminal::_defaultColor; +int Terminal::_cursorHeight; +#endif + +int Terminal::_fgcolor = Terminal::DEFAULT; +int Terminal::_bgcolor = Terminal::DEFAULT; + + +/** Initializes the terminal. This method should be called before any of the others. + * @param[in,out] os terminal output stream (currently unused) */ +void Terminal::init (ostream &os) { +#ifdef __WIN32__ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(h, &buffer_info); + _defaultColor = (buffer_info.wAttributes & 0xff); + CONSOLE_CURSOR_INFO cursor_info; + GetConsoleCursorInfo(h, &cursor_info); + _cursorHeight = cursor_info.dwSize; + } +#endif +} + + +/** Finishes the terminal output. Should be called after last terminal action. + * @param[in,out] os terminal output stream */ +void Terminal::finish (ostream &os) { + fgcolor(DEFAULT, os); + bgcolor(DEFAULT, os); + cursor(true); +} + + +/** Returns the number of terminal columns (number of characters per row). + * If it's not possible to retrieve information about the terminal size, 0 is returned. */ +int Terminal::columns () { +#if defined(TIOCGWINSZ) + struct winsize ws; + if (ioctl(fileno(stderr), TIOCGWINSZ, &ws) < 0) + return 0; + return ws.ws_col; +#elif defined(__WIN32__) + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &info)) + return 0; + return info.dwSize.X; +#else + return 0; +#endif +} + + +/** Returns the number of terminal rows. + * If it's not possible to retrieve information about the terminal size, 0 is returned. */ +int Terminal::rows () { +#if defined(TIOCGWINSZ) + struct winsize ws; + if (ioctl(fileno(stderr), TIOCGWINSZ, &ws) < 0) + return 0; + return ws.ws_row; +#elif defined(__WIN32__) + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &info)) + return 0; + return info.dwSize.Y; +#else + return 0; +#endif +} + + +/** Sets the foreground color. + * @param[in] color color code + * @param[in] os terminal output stream */ +void Terminal::fgcolor (int color, ostream &os) { + _fgcolor = color; + +#ifdef __WIN32__ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(h, &info); + if (_fgcolor == DEFAULT) + color = _defaultColor & 0x0f; + else { + // swap red and blue bits + color = (color & 0x0a) | ((color & 1) << 2) | ((color & 4) >> 2); + } + color = (info.wAttributes & 0xf0) | (color & 0x0f); + SetConsoleTextAttribute(h, (DWORD)color); + } +#else + bool light = false; + if (color != DEFAULT && color > 7) { + light = true; + color %= 8; + } + if (color == DEFAULT) { + os << "\x1B[0m"; + if (_bgcolor != DEFAULT) + bgcolor(_bgcolor, os); + } + else + os << "\x1B[" << (light ? '1': '0') << ';' << (30+(color & 0x07)) << 'm'; +#endif +} + + +/** Sets the background color. + * @param[in] color color code + * @param[in] os terminal output stream */ +void Terminal::bgcolor (int color, ostream &os) { + _bgcolor = color; +#ifdef __WIN32__ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(h, &info); + if (_bgcolor == DEFAULT) + color = (_defaultColor & 0xf0) >> 4; + else { + // swap red and blue bits + color = (color & 0x0a) | ((color & 1) << 2) | ((color & 4) >> 2); + } + color = (info.wAttributes & 0x0f) | ((color & 0x0f) << 4); + SetConsoleTextAttribute(h, (DWORD)color); + } +#else + if (color != DEFAULT && color > 7) + color %= 8; + if (color == DEFAULT) { + os << "\x1B[0m"; + if (_fgcolor != DEFAULT) + fgcolor(_fgcolor, os); + } + else + os << "\x1B[" << (40+(color & 0x07)) << 'm'; +#endif +} + + +/** Disables or enables the console cursor + * @param[in] visible if false, the cursor is disabled, and enabled otherwise */ +void Terminal::cursor (bool visible) { +#ifdef __WIN32__ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + CONSOLE_CURSOR_INFO cursor_info; + cursor_info.bVisible = visible; + cursor_info.dwSize = _cursorHeight; + SetConsoleCursorInfo(h, &cursor_info); + } +#endif +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.h new file mode 100644 index 00000000000..08ac7e6300a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/Terminal.h @@ -0,0 +1,58 @@ +/************************************************************************* +** Terminal.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_TERMINAL_H +#define DVISVGM_TERMINAL_H + +#include <ostream> + +class Terminal +{ + public: + static const int DEFAULT; + static const int BLACK; + static const int RED; + static const int GREEN; + static const int BLUE; + static const int CYAN; + static const int YELLOW; + static const int MAGENTA; + static const int WHITE; + + public: + static void init (std::ostream &os); + static void finish (std::ostream &os); + static int columns (); + static int rows (); + static void fgcolor (int color, std::ostream &os); + static void bgcolor (int color, std::ostream &os); + static void cursor (bool visible); + + private: + static int _fgcolor; ///< current foreground color + static int _bgcolor; ///< current background color + +#ifdef __WIN32__ + static int _defaultColor; + static int _cursorHeight; ///< current height of the cursor in percent +#endif +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.cpp new file mode 100644 index 00000000000..b9412f3a74d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.cpp @@ -0,0 +1,327 @@ +/************************************************************************* +** TpicSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <cstring> +#include <sstream> +#include "Color.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "TpicSpecialHandler.h" +#include "XMLNode.h" +#include "XMLString.h" +#include "types.h" + +using namespace std; + + +TpicSpecialHandler::TpicSpecialHandler () { + reset(); +} + + +void TpicSpecialHandler::dviEndPage (unsigned pageno) { + reset(); +} + + +void TpicSpecialHandler::reset () { + _points.clear(); + _penwidth = 1.0; + _fill = -1.0; // no fill +} + + +/** Creates SVG elements that draw lines through the recorded points. + * @param[in] stroke if true, the (out)line is drawn (in black) + * @param[in] fill if true, enclosed area is filled with current color + * @param[in] ddist dash/dot distance of line in PS point units + * (0:solid line, >0:dashed line, <0:dotted line) + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, SpecialActions *actions) { + if (actions && !_points.empty()) { + XMLElementNode *elem=0; + if (_points.size() == 1) { + const DPair &p = _points.back(); + elem = new XMLElementNode("circle"); + elem->addAttribute("cx", p.x()+actions->getX()); + elem->addAttribute("cy", p.y()+actions->getY()); + elem->addAttribute("r", _penwidth/2.0); + actions->embed(p, _penwidth/2.0); + } + else { + if (_points.size() == 2 || (!fill && _points.front() != _points.back())) { + elem = new XMLElementNode("polyline"); + elem->addAttribute("fill", "none"); + elem->addAttribute("stroke-linecap", "round"); + } + else { + if (_points.front() == _points.back()) + _points.pop_back(); + if (_fill < 0) + _fill = 1; + Color color = actions->getColor(); + color *= _fill; + elem = new XMLElementNode("polygon"); + elem->addAttribute("fill", fill ? color.rgbString() : "none"); + } + ostringstream oss; + FORALL(_points, vector<DPair>::iterator, it) { + if (it != _points.begin()) + oss << ' '; + double x = it->x()+actions->getX(); + double y = it->y()+actions->getY(); + oss << XMLString(x) << ',' << XMLString(y); + actions->embed(DPair(x, y)); + } + elem->addAttribute("points", oss.str()); + if (stroke) { // draw outline? + elem->addAttribute("stroke", "black"); + elem->addAttribute("stroke-width", XMLString(_penwidth)); + } + } + if (ddist > 0) + elem->addAttribute("stroke-dasharray", XMLString(ddist)); + else if (ddist < 0) + elem->addAttribute("stroke-dasharray", XMLString(_penwidth) + ' ' + XMLString(-ddist)); + actions->appendToPage(elem); + } + reset(); +} + + +/** Stroke a quadratic spline through the midpoints of the lines defined by + * the previously recorded points. The spline starts with a straight line + * from the first point to the mid-point of the first line. The spline ends + * with a straight line from the mid-point of the last line to the last point. + * If ddist=0, the spline is stroked solid. Otherwise ddist denotes the length + * of the dashes and the gaps inbetween. + * @param[in] ddist length of dashes and gaps + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { + if (actions && !_points.empty()) { + const size_t size = _points.size(); + if (size < 3) + drawLines(true, false, ddist, actions); + else { + double x = actions->getX(); + double y = actions->getY(); + DPair p(x,y); + ostringstream oss; + oss << 'M' << XMLString(x+_points[0].x()) << ',' << XMLString(y+_points[0].y()); + DPair mid = p+_points[0]+(_points[1]-_points[0])/2.0; + oss << 'L' << XMLString(mid.x()) << ',' << XMLString(mid.y()); + actions->embed(p+_points[0]); + for (size_t i=1; i < size-1; i++) { + const DPair p0 = p+_points[i-1]; + const DPair p1 = p+_points[i]; + const DPair p2 = p+_points[i+1]; + mid = p1+(p2-p1)/2.0; + oss << 'Q' << XMLString(p1.x()) << ',' << XMLString(p1.y()) + << ' ' << XMLString(mid.x()) << ',' << XMLString(mid.y()); + actions->embed(mid); + actions->embed((p0+p1*6.0+p2)/8.0, _penwidth); + } + if (_points[0] == _points[size-1]) // closed path? + oss << 'Z'; + else { + oss << 'L' << XMLString(x+_points[size-1].x()) << ',' << XMLString(y+_points[size-1].y()); + actions->embed(p+_points[size-1]); + } + + Color color = actions->getColor(); + color *= _fill; + XMLElementNode *path = new XMLElementNode("path"); + if (_fill >= 0) { + if (_points[0] != _points[size-1]) + oss << 'Z'; + path->addAttribute("fill", color.rgbString()); + } + else + path->addAttribute("fill", "none"); + + path->addAttribute("d", oss.str()); + path->addAttribute("stroke", actions->getColor().rgbString()); + path->addAttribute("stroke-width", XMLString(_penwidth)); + if (ddist > 0) + path->addAttribute("stroke-dasharray", XMLString(ddist)); + else if (ddist < 0) + path->addAttribute("stroke-dasharray", XMLString(_penwidth) + ' ' + XMLString(-ddist)); + actions->appendToPage(path); + } + } + reset(); +} + + +/** Draws an elliptical arc. + * @param[in] cx x-coordinate of arc center + * @param[in] cy y-coordinate of arc center + * @param[in] rx length of horizonal semi-axis + * @param[in] ry length of vertical semi-axis + * @param[in] angle1 starting angle (clockwise) relative to x-axis + * @param[in] angle2 ending angle (clockwise) relative to x-axis + * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ +void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions) { + if (actions) { + const double PI2 = 4*asin(1.0); + angle1 *= -1; + angle2 *= -1; + if (fabs(angle1) > PI2) { + int n = (int)(angle1/PI2); + angle1 = angle1 - n*PI2; + angle2 = angle2 - n*PI2; + } + + double x = cx + actions->getX(); + double y = cy + actions->getY(); + XMLElementNode *elem=0; + if (fabs(angle1-angle2) >= PI2) { // closed ellipse? + elem = new XMLElementNode("ellipse"); + elem->addAttribute("cx", XMLString(x)); + elem->addAttribute("cy", XMLString(y)); + elem->addAttribute("rx", XMLString(rx)); + elem->addAttribute("ry", XMLString(ry)); + } + else { + if (angle1 < 0) + angle1 = PI2+angle1; + if (angle2 < 0) + angle2 = PI2+angle2; + elem = new XMLElementNode("path"); + int large_arg = fabs(angle1-angle2) > PI2/2 ? 0 : 1; + int sweep_flag = angle1 > angle2 ? 0 : 1; + if (angle1 > angle2) { + large_arg = 1-large_arg; + sweep_flag = 1-sweep_flag; + } + ostringstream oss; + oss << 'M' << XMLString(x+rx*cos(angle1)) << ',' << XMLString(y+ry*sin(-angle1)) + << 'A' << XMLString(rx) << ',' << XMLString(ry) + << " 0 " + << large_arg << ' ' << sweep_flag << ' ' + << XMLString(x+rx*cos(angle2)) << ',' << XMLString(y-ry*sin(angle2)); + if (_fill >= 0) + oss << 'Z'; + elem->addAttribute("d", oss.str()); + } + elem->addAttribute("stroke-width", _penwidth); + elem->addAttribute("stroke", actions->getColor().rgbString()); + elem->addAttribute("stroke-linecap", "round"); + elem->addAttribute("fill", "none"); + if (_fill >= 0) { + Color color=actions->getColor(); + color *= _fill; + elem->addAttribute("fill", color.rgbString()); + } + else + elem->addAttribute("fill", "none"); + actions->appendToPage(elem); + actions->embed(BoundingBox(cx-rx, cy-ry, cx+rx, cy+ry)); + } + reset(); +} + + +#define cmd_id(c1,c2) ((c1 << 8) | c2) + +bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (!prefix || strlen(prefix) != 2) + return false; + + const double mi2bp=0.072; // factor for milli-inch to PS points + StreamInputBuffer ib(is); + BufferInputReader in(ib); + switch (cmd_id(prefix[0], prefix[1])) { + case cmd_id('p','n'): // set pen width in milli-inches + _penwidth = in.getDouble()*mi2bp; + break; + case cmd_id('b','k'): // set fill color to black + _fill = 0; + break; + case cmd_id('w','h'): // set fill color to white + _fill = 1; + break; + case cmd_id('s','h'): // set fill color to given gray level + in.skipSpace(); + _fill = in.eof() ? 0.5 : max(0.0, min(1.0, in.getDouble())); + break; + case cmd_id('t','x'): // set fill pattern + break; + case cmd_id('p','a'): { // add point to path + double x = in.getDouble()*mi2bp; + double y = in.getDouble()*mi2bp; + _points.push_back(DPair(x,y)); + break; + } + case cmd_id('f','p'): // draw solid lines through recorded points; close and fill path if fill color was defined + drawLines(true, _fill >= 0, 0, actions); + break; + case cmd_id('i','p'): // don't draw outlines but close the recorded path and fill the resulting polygon + drawLines(false, true, 0, actions); + break; + case cmd_id('d','a'): // as fp but draw dashed lines + drawLines(true, _fill >= 0, in.getDouble()*72, actions); + break; + case cmd_id('d','t'): // as fp but draw dotted lines + drawLines(true, _fill >= 0, -in.getDouble()*72, actions); + break; + case cmd_id('s','p'): { // draw quadratic splines through recorded points + double ddist = in.getDouble(); + drawSplines(ddist, actions); + break; + } + case cmd_id('a','r'): { // draw elliptical arc + double cx = in.getDouble()*mi2bp; + double cy = in.getDouble()*mi2bp; + double rx = in.getDouble()*mi2bp; + double ry = in.getDouble()*mi2bp; + double a1 = in.getDouble(); + double a2 = in.getDouble(); + drawArc(cx, cy, rx, ry, a1, a2, actions); + break; + } + case cmd_id('i','a'): { // fill elliptical arc + double cx = in.getDouble()*mi2bp; + double cy = in.getDouble()*mi2bp; + double rx = in.getDouble()*mi2bp; + double ry = in.getDouble()*mi2bp; + double a1 = in.getDouble(); + double a2 = in.getDouble(); + if (_fill < 0) + _fill = 1; + drawArc(cx, cy, rx, ry, a1, a2, actions); + if (_fill < 0) + _fill = -1; + break; + } + default: + return false; + } + return true; +} + + +const char** TpicSpecialHandler::prefixes () const { + static const char *pfx[] = {"ar", "bk", "da", "dt", "fp", "ia", "ip", "pa", "pn", "sh", "sp", "tx", "wh", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.h new file mode 100644 index 00000000000..9afdf9a31fc --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/TpicSpecialHandler.h @@ -0,0 +1,50 @@ +/************************************************************************* +** TpicSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_TPICSPECIALHANDLER_H +#define DVISVGM_TPICSPECIALHANDLER_H + +#include <list> +#include "Pair.h" +#include "SpecialHandler.h" + +class TpicSpecialHandler : public SpecialHandler, public DVIEndPageListener +{ + public: + TpicSpecialHandler (); + const char* info () const {return "TPIC specials";} + const char* name () const {return "tpic";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + + protected: + void dviEndPage (unsigned pageno); + void reset (); + void drawLines (bool stroke, bool fill, double ddist, SpecialActions *actions); + void drawSplines (double ddist, SpecialActions *actions); + void drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions); + + private: + double _penwidth; ///< pen width in PS point units + double _fill; ///< fill intensity [0,1]; if < 0, we don't fill anything + std::vector<DPair> _points; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFActions.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFActions.h new file mode 100644 index 00000000000..a8e86831fe9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFActions.h @@ -0,0 +1,38 @@ +/************************************************************************* +** VFActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_VFACTIONS_H +#define DVISVGM_VFACTIONS_H + +#include <string> +#include <vector> +#include "types.h" + + +struct VFActions +{ + virtual ~VFActions () {} + virtual void preamble (std::string comment, UInt32 checksum, double dsize) {} + virtual void postamble () {} + virtual void defineVFFont (UInt32 fontnum, std::string path, std::string name, UInt32 checksum, double dsize, double ssize) {} + virtual void defineVFChar (UInt32 c, std::vector<UInt8> *dvi) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.cpp new file mode 100644 index 00000000000..eb9ed4d22ee --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.cpp @@ -0,0 +1,192 @@ +/************************************************************************* +** VFReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <sstream> +#include "Font.h" +#include "VFActions.h" +#include "VFReader.h" +#include "macros.h" + +using namespace std; + + +/** Converts a TFM fix point value to double (PS point units). */ +inline static double fix2double (FixWord fix) { + const double pt2bp = 72/72.27; + return double(fix)/(1 << 20)*pt2bp; +} + + +VFReader::VFReader (istream &is) + : StreamReader(is), _actions(0), _designSize(0) { +} + + +VFReader::~VFReader () { +} + + +VFActions* VFReader::replaceActions (VFActions *a) { + VFActions *ret = _actions; + _actions = a; + return ret; +} + + +/** Reads a single VF command from the current position of the input stream and calls the + * corresponding cmdFOO method. The execution can be influenced by a function of type ApproveOpcode. + * It takes an opcode and returns true if the command is supposed to be executed. + * @param[in] approve function to approve invocation of the action assigned to command + * @return opcode of the executed command */ +int VFReader::executeCommand (ApproveAction approve) { + int opcode = in().get(); + if (!in() || opcode < 0) // at end of file + throw VFException("invalid file"); + + bool approved = !approve || approve(opcode); + VFActions *actions = _actions; + if (!approved) + replaceActions(0); // disable actions + + if (opcode <= 241) // short character definition? + cmdShortChar(opcode); + else if (opcode >= 243 && opcode <= 246) // font definition? + cmdFontDef(opcode-243+1); + else { + switch (opcode) { + case 242: cmdLongChar(); break; // long character definition + case 247: cmdPre(); break; // preamble + case 248: cmdPost(); break; // postamble + default : { // invalid opcode + replaceActions(actions); // reenable actions + ostringstream oss; + oss << "undefined VF command (opcode " << opcode << ')'; + throw VFException(oss.str()); + } + } + } + replaceActions(actions); // reenable actions + return opcode; +} + + +bool VFReader::executeAll () { + in().clear(); // reset all status bits + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand() != 248); // stop reading after post (248) + return true; +} + + +/// Returns true if op indicates the preamble or a font definition +static bool is_pre_or_fontdef (int op) {return op > 242;} +static bool is_chardef (int op) {return op < 243;} + + +bool VFReader::executePreambleAndFontDefs () { + in().clear(); + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand(is_pre_or_fontdef) > 242); // stop reading after last font definition + return true; +} + + +bool VFReader::executeCharDefs () { + in().clear(); + if (!in()) + return false; + in().seekg(0); + while (!in().eof() && executeCommand(is_chardef) < 243); // stop reading after last char definition + return true; +} + +////////////////////////////////////////////////////////////////////////////// + +/** Reads and executes DVI preamble command. */ +void VFReader::cmdPre () { + UInt32 i = readUnsigned(1); // identification number (should be 2) + UInt32 k = readUnsigned(1); // length of following comment + string cmt = readString(k); // comment + UInt32 cs = readUnsigned(4); // check sum to be compared with TFM cecksum + UInt32 ds = readUnsigned(4); // design size (same as TFM design size) (fix_word) + _designSize = fix2double(ds); + if (i != 202) + throw VFException("invalid identification value in preamble"); + if (_actions) + _actions->preamble(cmt, cs, ds); +} + + +void VFReader::cmdPost () { + while ((readUnsigned(1)) == 248); // skip fill bytes + if (_actions) + _actions->postamble(); +} + + +void VFReader::cmdLongChar () { + UInt32 pl = readUnsigned(4); // packet length (length of DVI subroutine) + if (_actions) { + UInt32 cc = readUnsigned(4); // character code + readUnsigned(4); // character width from corresponding TFM file + vector<UInt8> *dvi = new vector<UInt8>(pl); // DVI subroutine + readBytes(pl, *dvi); + _actions->defineVFChar(cc, dvi); // call template method for user actions + } + else + in().seekg(8+pl, ios::cur); // skip remaining char definition bytes +} + + +/** Reads and executes short_char_x command. + * @param[in] pl packet length (length of DVI subroutine) */ +void VFReader::cmdShortChar (int pl) { + if (_actions) { + UInt32 cc = readUnsigned(1); // character code + readUnsigned(3); // character width from corresponding TFM file + vector<UInt8> *dvi = new vector<UInt8>(pl); // DVI subroutine + readBytes(pl, *dvi); + _actions->defineVFChar(cc, dvi); // call template method for user actions + } + else + in().seekg(4+pl, ios::cur); // skip char definition bytes +} + + +void VFReader::cmdFontDef (int len) { + UInt32 fontnum = readUnsigned(len); // font number + UInt32 checksum = readUnsigned(4); // font checksum (to be compared with corresponding TFM checksum) + UInt32 ssize = readUnsigned(4); // scaled size of font relative to design size (fix_word) + UInt32 dsize = readUnsigned(4); // design size of font (same as TFM design size) (fix_word) + UInt32 pathlen = readUnsigned(1); // length of font path + UInt32 namelen = readUnsigned(1); // length of font name + string fontpath = readString(pathlen); + string fontname = readString(namelen); + if (_actions) { + double ss = fix2double(ssize); + double ds = fix2double(dsize); + _actions->defineVFFont(fontnum, fontpath, fontname, checksum, ds, ss*_designSize); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.h new file mode 100644 index 00000000000..f6d9474ccbe --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VFReader.h @@ -0,0 +1,65 @@ +/************************************************************************* +** VFReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_VFREADER_H +#define DVISVGM_VFREADER_H + +#include "MessageException.h" +#include "StreamReader.h" +#include "types.h" + + +struct VFException : public MessageException +{ + VFException (const std::string &msg) : MessageException(msg) {} +}; + + +struct VFActions; + + +class VFReader : public StreamReader +{ + typedef bool (*ApproveAction)(int); + public: + VFReader (std::istream &is); + virtual ~VFReader (); + VFActions* replaceActions (VFActions *a); + bool executeAll (); + bool executePreambleAndFontDefs (); + bool executeCharDefs (); + + protected: + int executeCommand (ApproveAction approve=0); + + // the following methods represent the VF commands + // they are called by executeCommand and should not be used directly + void cmdPre (); + void cmdPost (); + void cmdShortChar (int pl); + void cmdLongChar (); + void cmdFontDef (int len); + + private: + VFActions *_actions; ///< actions to execute when reading a VF command + double _designSize; ///< design size of currently read VF +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VectorStream.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VectorStream.h new file mode 100644 index 00000000000..345b319c7b3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/VectorStream.h @@ -0,0 +1,46 @@ +/************************************************************************* +** VectorStream.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_VECTORSTREAM_H +#define DVISVGM_VECTORSTREAM_H + +#include <istream> +#include <vector> + + +template <typename T> +struct VectorStreamBuffer : public std::streambuf +{ + VectorStreamBuffer (std::vector<T> &source) { + setg((char*)&source[0], (char*)&source[0], (char*)&source[0]+source.size()); + } +}; + + +template <typename T> +class VectorInputStream : public std::istream +{ + public: + VectorInputStream (std::vector<T> &source) : std::istream(&_buf), _buf(source) {} + private: + VectorStreamBuffer<T> _buf; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.cpp new file mode 100644 index 00000000000..caee2ec7439 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.cpp @@ -0,0 +1,101 @@ +/************************************************************************* +** XMLDocument.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "macros.h" +#include "XMLDocument.h" + +using namespace std; + +XMLDocument::XMLDocument (XMLElementNode *root) + : _rootElement(root), _emitted(false) +{ +} + + +XMLDocument::~XMLDocument () { + clear(); +} + + +void XMLDocument::clear () { + delete _rootElement; + _rootElement = 0; + FORALL(_nodes, list<XMLNode*>::iterator, i) + delete *i; + _nodes.clear(); +} + + +void XMLDocument::append (XMLNode *node) { + if (!node) + return; + XMLElementNode *newRoot = dynamic_cast<XMLElementNode*>(node); + if (newRoot) { // there can only be one root element node in the document + delete _rootElement; // so if there is already one... + _rootElement = newRoot; // ...we replace it + } + else + _nodes.push_back(node); +} + + +void XMLDocument::setRootNode (XMLElementNode *root) { + delete _rootElement; + _rootElement = root; +} + + +ostream& XMLDocument::write (ostream &os) const { + if (_rootElement) { // no root element => no output + os << "<?xml version='1.0'?>\n"; + FORALL(_nodes, list<XMLNode*>::const_iterator, i) + (*i)->write(os); + _rootElement->write(os); + } + return os; +} + +/** Writes a part of the XML document to the given output stream and removes + * the completely written nodes. The output stops when a stop node is reached + * (this node won't be printed at all). If a node was only partly emitted, i.e. + * its child was the stop node, a further call of emit will continue the output. + * @param[in] os stream to which the output is written + * @param[in] stopNode node where emitting stops (if 0 the whole tree will be emitted) + * @return true if node was completely emitted */ +bool XMLDocument::emit (ostream& os, XMLNode *stopNode) { + if (_rootElement) { // no root element => no output + if (!_emitted) { + os << "<?xml version='1.0' encoding='ISO-8859-1'?>\n"; + _emitted = true; + } + FORALL(_nodes, list<XMLNode*>::iterator, i) { + if ((*i)->emit(os, stopNode)) { + list<XMLNode*>::iterator it = i++; // prevent i from being invalidated... + _nodes.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + return _rootElement->emit(os, stopNode); + } + return true; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.h new file mode 100644 index 00000000000..c3d6b928ee7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLDocument.h @@ -0,0 +1,44 @@ +/************************************************************************* +** XMLDocument.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_XMLDOCUMENT_H +#define DVISVGM_XMLDOCUMENT_H + +#include "XMLNode.h" + +class XMLDocument +{ + public: + XMLDocument (XMLElementNode *root=0); + ~XMLDocument (); + void clear (); + void append (XMLNode *node); + void setRootNode (XMLElementNode *root); + const XMLElementNode* getRootElement () const {return _rootElement;} + std::ostream& write (std::ostream &os) const; + bool emit (std::ostream& os, XMLNode *stopNode); + + private: + std::list<XMLNode*> _nodes; + XMLElementNode *_rootElement; + bool _emitted; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.cpp new file mode 100644 index 00000000000..82b85b52ffd --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.cpp @@ -0,0 +1,344 @@ +/************************************************************************* +** XMLNode.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include "macros.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + +bool XMLNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + write(os); + return true; +} + + +XMLElementNode::XMLElementNode (const string &n) : _name(n), _emitted(false) { +} + + +XMLElementNode::XMLElementNode (const XMLElementNode &node) + : _name(node._name), _attributes(node._attributes), _emitted(false) +{ + FORALL(node._children, ChildList::const_iterator, it) + _children.push_back((*it)->clone()); +} + + +XMLElementNode::~XMLElementNode () { + FORALL(_children, ChildList::iterator, i) + delete *i; +} + + +void XMLElementNode::addAttribute (const string &name, const string &value) { + _attributes[name] = value; +} + + +void XMLElementNode::addAttribute (const string &name, double value) { + _attributes[name] = XMLString(value); +} + + +void XMLElementNode::append (XMLNode *child) { + if (!child) + return; + XMLTextNode *textNode1 = dynamic_cast<XMLTextNode*>(child); + if (!textNode1 || _children.empty()) + _children.push_back(child); + else { + if (XMLTextNode *textNode2 = dynamic_cast<XMLTextNode*>(_children.back())) + textNode2->append(textNode1); // merge two consecutive text nodes + else + _children.push_back(child); + } +} + + +void XMLElementNode::append (const string &str) { + if (_children.empty() || !dynamic_cast<XMLTextNode*>(_children.back())) + _children.push_back(new XMLTextNode(str)); + else + static_cast<XMLTextNode*>(_children.back())->append(str); +} + + +void XMLElementNode::prepend (XMLNode *child) { + if (!child) + return; + XMLTextNode *textNode1 = dynamic_cast<XMLTextNode*>(child); + if (!textNode1 || _children.empty()) + _children.push_front(child); + else { + if (XMLTextNode *textNode2 = dynamic_cast<XMLTextNode*>(_children.back())) + textNode2->prepend(textNode1); // merge two consecutive text nodes + else + _children.push_front(child); + } +} + + +/** Inserts a new child node before a given child node already present. The latter + * will be the following sibling of the node to be inserted. If there's no such + * node present, nothing is inserted. + * @param[in] child node to be inserted + * @param[in] sibling following sibling of 'child' + * @return true on success */ +bool XMLElementNode::insertBefore (XMLNode *child, XMLNode *sibling) { + ChildList::iterator it = _children.begin(); + while (it != _children.end() && *it != sibling) + ++it; + if (it != _children.end()) { + _children.insert(it, child); + return true; + } + return false; +} + + +/** Inserts a new child node after a given child node already present. The latter + * will be the preceding sibling of the node to be inserted. If there's no such + * node present, nothing is inserted. + * @param[in] child node to be inserted + * @param[in] sibling preceding sibling of 'child' + * @return true on success */ +bool XMLElementNode::insertAfter (XMLNode *child, XMLNode *sibling) { + ChildList::iterator it = _children.begin(); + while (it != _children.end() && *it != sibling) + ++it; + if (it != _children.end()) { + _children.insert(++it, child); + return true; + } + return false; +} + + +/** Finds all descendant elements of a given name and given attribute. + * @param[in] name name of elements to find + * @param[in] attr_name name of attribute to find + * @param[out] descendants all elements found + * @return true if at least one element was found */ +bool XMLElementNode::findDescendants (const char *name, const char *attr_name, vector<XMLElementNode*> &descendants) { + FORALL(_children, ChildList::iterator, it) { + if (XMLElementNode *elem = dynamic_cast<XMLElementNode*>(*it)) { + if ((!name || elem->getName() == name) && (!attr_name || elem->hasAttribute(attr_name))) + descendants.push_back(elem); + elem->findDescendants(name, attr_name, descendants); + } + } + return !descendants.empty(); +} + + +ostream& XMLElementNode::write (ostream &os) const { + os << '<' << _name; + FORALL(_attributes, AttribMap::const_iterator, i) + os << ' ' << i->first << "='" << i->second << '\''; + if (_children.empty()) + os << "/>\n"; + else { + os << '>'; + if (dynamic_cast<XMLElementNode*>(_children.front())) + os << '\n'; + FORALL(_children, ChildList::const_iterator, i) + (*i)->write(os); + os << "</" << _name << ">\n"; + } + return os; +} + + +/** Writes a part of the XML tree to the given output stream and removes + * the completely written nodes. The output stops when a stop node is reached + * (this node won't be printed at all). If a node was only partly emitted, i.e. + * its child was the stop node, a further call of emit will continue the output. + * @param[in] os stream to which the output is sent to + * @param[in] stopNode node where emitting stops (if 0 the whole tree will be emitted) + * @return true if node was emitted completely */ +bool XMLElementNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + + if (!_emitted) { + os << '<' << _name; + FORALL(_attributes, AttribMap::iterator, i) + os << ' ' << i->first << "='" << i->second << '\''; + if (_children.empty()) + os << "/>\n"; + else { + os << '>'; + if (dynamic_cast<XMLElementNode*>(_children.front())) + os << '\n'; + } + + _emitted = true; + } + if (!_children.empty()) { + FORALL(_children, ChildList::iterator, i) { + if ((*i)->emit(os, stopNode)) { + ChildList::iterator it = i++; // prevent i from being invalidated... + _children.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + os << "</" << _name << ">\n"; + } + return true; +} + + +/** Returns true if this element has an attribute of given name. */ +bool XMLElementNode::hasAttribute (const string &name) const { + return _attributes.find(name) != _attributes.end(); +} + + +/** Returns the value of an attribute. + * @param[in] name name of attribute + * @return attribute value or 0 if attribute doesn't exist */ +const char* XMLElementNode::getAttributeValue(const std::string& name) const { + AttribMap::const_iterator it = _attributes.find(name); + if (it != _attributes.end()) + return it->second.c_str(); + return 0; +} + + +////////////////////// + +void XMLTextNode::append (XMLNode *node) { + if (XMLTextNode *tn = dynamic_cast<XMLTextNode*>(node)) + append(tn); + else + delete node; +} + + +void XMLTextNode::append (XMLTextNode *node) { + if (node) + _text += node->_text; + delete node; +} + + +void XMLTextNode::append (const string &str) { + _text += str; +} + + +void XMLTextNode::prepend (XMLNode *node) { + if (XMLTextNode *tn = dynamic_cast<XMLTextNode*>(node)) + prepend(tn); + else + delete node; +} + + +////////////////////// + +XMLDeclarationNode::XMLDeclarationNode (const string &n, const string &p) + : _name(n), _params(p), _emitted(false) +{ +} + + +XMLDeclarationNode::XMLDeclarationNode (const XMLDeclarationNode &node) + : _name(node._name), _params(node._params), _emitted(false) +{ + FORALL(node._children, list<XMLDeclarationNode*>::const_iterator, it) + _children.push_back(new XMLDeclarationNode(**it)); +} + + +XMLDeclarationNode::~XMLDeclarationNode () { + FORALL(_children, list<XMLDeclarationNode*>::iterator, i) + delete *i; +} + + +/** Appends another declaration node to this one. + * @param[in] child child to append, must be of type XMLDeclarationNode */ +void XMLDeclarationNode::append (XMLNode *child) { + if (XMLDeclarationNode *decl_node = dynamic_cast<XMLDeclarationNode*>(child)) + _children.push_back(decl_node); + else + delete child; +} + + +ostream& XMLDeclarationNode::write (ostream &os) const { + os << "<!" << _name << ' ' << _params; + if (_children.empty()) + os << ">\n"; + else { + os << "[\n"; + FORALL(_children, list<XMLDeclarationNode*>::const_iterator, i) + (*i)->write(os); + os << "]>\n"; + } + return os; +} + + +bool XMLDeclarationNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + + if (!_emitted) { + os << "<!" << _name << ' ' << _params; + if (_children.empty()) + os << ">\n"; + else + os << "[\n"; + _emitted = true; + } + if (!_children.empty()) { + FORALL(_children, list<XMLDeclarationNode*>::iterator, i) { + if ((*i)->emit(os, stopNode)) { + list<XMLDeclarationNode*>::iterator it = i++; // prevent i from being invalidated... + _children.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + os << "]>\n"; + } + return true; + +} + +////////////////////// + +ostream& XMLCDataNode::write (ostream &os) const { + os << "<![CDATA[\n" + << _data + << "]]>\n"; + return os; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.h new file mode 100644 index 00000000000..cd878701db9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLNode.h @@ -0,0 +1,134 @@ +/************************************************************************* +** XMLNode.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_XMLNODE_H +#define DVISVGM_XMLNODE_H + +#include <list> +#include <map> +#include <ostream> +#include <string> + +#include "SpecialActions.h" + + +struct XMLNode +{ + virtual ~XMLNode () {} + virtual XMLNode* clone () const =0; + virtual std::ostream& write (std::ostream &os) const =0; + virtual bool emit (std::ostream &os, XMLNode *stopElement); + virtual void append (XMLNode *child) {} + virtual void prepend (XMLNode *child) {} +}; + + +class XMLElementNode : public XMLNode +{ + typedef std::map<std::string,std::string> AttribMap; + typedef std::list<XMLNode*> ChildList; + public: + XMLElementNode (const std::string &name); + XMLElementNode (const XMLElementNode &node); + ~XMLElementNode (); + XMLNode* clone () const {return new XMLElementNode(*this);} + void addAttribute (const std::string &name, const std::string &value); + void addAttribute (const std::string &name, double value); + void append (XMLNode *child); + void append (const std::string &str); + void prepend (XMLNode *child); + bool insertAfter (XMLNode *child, XMLNode *sibling); + bool insertBefore (XMLNode *child, XMLNode *sibling); + bool hasAttribute (const std::string &name) const; + const char* getAttributeValue (const std::string &name) const; + bool findDescendants (const char *name, const char *attr_name, std::vector<XMLElementNode*> &descendants); + std::ostream& write (std::ostream &os) const; + bool emit (std::ostream &os, XMLNode *stopElement); + bool empty () const {return _children.empty();} + const std::list<XMLNode*>& children () const {return _children;} + const std::string& getName () const {return _name;} + + private: + std::string _name; // element name (<name a1="v1" .. an="vn">...</name>) + AttribMap _attributes; + ChildList _children; // child nodes + bool _emitted; // true if node has been (partly) emitted +}; + + +class XMLTextNode : public XMLNode +{ + public: + XMLTextNode (const std::string &str) : _text(str) {} + XMLNode* clone () const {return new XMLTextNode(*this);} + void append (XMLNode *node); + void append (XMLTextNode *node); + void append (const std::string &str); + void prepend (XMLNode *child); + std::ostream& write (std::ostream &os) const {return os << _text;} + + private: + std::string _text; +}; + + +class XMLCommentNode : public XMLNode +{ + public: + XMLCommentNode (const std::string &str) : _text(str) {} + XMLNode* clone () const {return new XMLCommentNode(*this);} + std::ostream& write (std::ostream &os) const {return os << "<!--" << _text << "-->\n";} + + private: + std::string _text; +}; + + +class XMLDeclarationNode : public XMLNode +{ + public: + XMLDeclarationNode (const std::string &n, const std::string &p); + XMLDeclarationNode (const XMLDeclarationNode &node); + ~XMLDeclarationNode (); + XMLNode* clone () const {return new XMLDeclarationNode(*this);} + void append (XMLNode *child); + std::ostream& write (std::ostream &os) const; + bool emit (std::ostream &os, XMLNode *stopElement); + + private: + std::string _name; + std::string _params; + std::list<XMLDeclarationNode*> _children; + bool _emitted; +}; + + +class XMLCDataNode : public XMLNode +{ + public: + XMLCDataNode (const std::string &d) : _data(d) {} + XMLNode* clone () const {return new XMLCDataNode(*this);} + std::ostream& write (std::ostream &os) const; + + private: + std::string _data; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.cpp new file mode 100644 index 00000000000..ea4487f45bc --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.cpp @@ -0,0 +1,150 @@ +/************************************************************************* +** XMLString.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <cstdlib> +#include <iomanip> +#include <sstream> +#include "macros.h" +#include "types.h" +#include "XMLString.h" + +using namespace std; + +int XMLString::DECIMAL_PLACES = 0; + + +/** Converts a unicode value to a UTF-8 byte sequence. + * @param[in] c character code + * @return utf8 seqence consisting of 1-4 bytes */ +static string to_utf8 (Int32 c) { + string utf8; + if (c >= 0) { + if (c < 0x80) + utf8 += c; + else if (c < 0x800) { + utf8 += 0xC0 + (c >> 6); + utf8 += 0x80 + (c & 0x3F); + } + else if (c == 0xFFFE || c == 0xFFFF) + utf8 += (c & 0xFF); + else if (c < 0x10000) { + utf8 += 0xE0 + (c >> 12); + utf8 += 0x80 + ((c >> 6) & 0x3F); + utf8 += 0x80 + (c & 0x3F); + } + else if (c < 0x110000) { + utf8 += 0xF0 + (c >> 18); + utf8 += 0x80 + ((c >> 12) & 0x3F); + utf8 += 0x80 + ((c >> 6) & 0x3F); + utf8 += 0x80 + (c & 0x3F); + } + } + return utf8; +} + + +static string translate (UInt32 c) { + switch (c) { + case '<' : return "<"; + case '&' : return "&"; + case '"' : return """; + case '\'': return "'"; + } + return to_utf8(c); +} + + +/** Rounds a floating point value to a given number of decimal places. + * @param[in] x number to round + * @param[in] n number of decimal places (must be between 1 and 6) + * @return rounded value */ +static inline double round (double x, long n) { + const long pow10[] = {10L, 100L, 1000L, 10000L, 100000L, 1000000L}; + n--; + return floor(x*pow10[n]+0.5)/pow10[n]; +} + + +XMLString::XMLString (const string &str, bool plain) { + if (plain) + *this = str; + else { + FORALL(str, string::const_iterator, i) + *this += translate(*i); + } +} + + +XMLString::XMLString (const char *str, bool plain) { + if (str) { + if (plain) + *this = str; + else { + while (*str) + *this += translate(*str++); + } + } +} + + +XMLString::XMLString (int n, bool cast) { + if (cast) { + stringstream ss; + ss << n; + ss >> *this; + } + else + *this += translate(n); +} + + +XMLString::XMLString (double x) { + stringstream ss; + if (DECIMAL_PLACES > 0) + x = round(x, DECIMAL_PLACES); + else if (fabs(x) < 1e-8) + x = 0; + ss << x; + ss >> *this; +} + + +/* +ostream& XMLString::write (ostream &os) const { + const string *self = static_cast<const string*>(this); + FORALL(*self, string::const_iterator, i) { + unsigned char c = *i; + switch (c) { + case '<' : os << "<"; break; + case '&' : os << "&"; break; + case '"' : os << """; break; + case '\'': os << "'"; break; + default : + if (c >= 32 && c <= 126) + os << c; + else + os << "&#" << int(c) << ';'; + } + } + return os; +} +*/ diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.h new file mode 100644 index 00000000000..ae27053a856 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/XMLString.h @@ -0,0 +1,40 @@ +/************************************************************************* +** XMLString.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_XMLSTRING_H +#define DVISVGM_XMLSTRING_H + +#include <string> + + +class XMLString : public std::string +{ + public: + XMLString () : std::string() {} + XMLString (const char *str, bool plain=false); + XMLString (const std::string &str, bool plain=false); + XMLString (int n, bool cast=true); + XMLString (double x); + + static int DECIMAL_PLACES; ///< number of decimal places applied to floating point values (0-6) +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/dvisvgm.cpp new file mode 100644 index 00000000000..aafd843ecd1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/dvisvgm.cpp @@ -0,0 +1,436 @@ +/************************************************************************* +** dvisvgm.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <cmath> +#include <fstream> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <string> +#include "gzstream.h" +#include "CommandLine.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "EPSToSVG.h" +#include "FileFinder.h" +#include "FilePath.h" +#include "FileSystem.h" +#include "Font.h" +#include "FontCache.h" +#include "FontEngine.h" +#include "FontMap.h" +#include "Ghostscript.h" +#include "HtmlSpecialHandler.h" +#include "InputReader.h" +#include "Message.h" +#include "PageSize.h" +#include "PSInterpreter.h" +#include "SignalHandler.h" +#include "SpecialManager.h" +#include "SVGOutputBase.h" +#include "System.h" + +#ifdef __MSVC__ +#include <potracelib.h> +#else +extern "C" { +#include <potracelib.h> +} +#endif + +using namespace std; + +class SVGOutput : public SVGOutputBase +{ + public: + SVGOutput (const char *base=0, string pattern="", int zip_level=0) + : _path(base ? base : ""), + _pattern(pattern), + _stdout(base == 0), + _zipLevel(zip_level), + _page(-1), + _os(0) {} + + + ~SVGOutput () { + delete _os; + } + + + /** Returns an output stream for the given page. + * @param[in] page number of current page + * @param[in] numPages total number of pages in the DVI file + * @return output stream for the given page */ + ostream& getPageStream (int page, int numPages) const { + string fname = filename(page, numPages); + if (fname.empty()) { + delete _os; + _os = 0; + return cout; + } + if (page == _page) + return *_os; + + _page = page; + delete _os; + + if (_zipLevel > 0) + _os = new ogzstream(fname.c_str(), _zipLevel); + else + _os = new ofstream(fname.c_str()); + if (!_os || !*_os) { + delete _os; + _os = 0; + throw MessageException("can't open file "+fname+" for writing"); + } + return *_os; + } + + + /** Returns the name of the SVG file containing the given page. + * @param[in] page number of current page + * @param[in] numPages total number of pages */ + string filename (int page, int numPages) const { + if (_stdout) + return ""; + string fname = _pattern; + if (fname.empty()) + fname = numPages > 1 ? "%f-%p" : "%f"; + else if (numPages > 1 && fname.find("%p") == string::npos) + fname += FileSystem::isDirectory(fname.c_str()) ? "/%f-%p" : "-%p"; + + // replace pattern variables by their actual values + // %f: basename of the DVI file + // %p: current page number + ostringstream oss; + oss << setfill('0') << setw(max(2, int(1+log10((double)numPages)))) << page; + size_t pos=0; + while ((pos = fname.find('%', pos)) != string::npos && pos < fname.length()-1) { + switch (fname[pos+1]) { + case 'f': fname.replace(pos, 2, _path.basename()); pos += _path.basename().length(); break; + case 'p': fname.replace(pos, 2, oss.str()); pos += oss.str().length(); break; + default : ++pos; + } + } + FilePath outpath(fname, true); + if (outpath.suffix().empty()) + outpath.suffix(_zipLevel > 0 ? "svgz" : "svg"); + string apath = outpath.absolute(); + string rpath = outpath.relative(); + return apath.length() < rpath.length() ? apath : rpath; + } + + private: + FilePath _path; + string _pattern; + bool _stdout; + int _zipLevel; + mutable int _page; // number of current page being written + mutable ostream *_os; +}; + +//////////////////////////////////////////////////////////////////////////////// + +static void show_help (const CommandLine &cmd) { + cout << PACKAGE_STRING "\n\n"; + cmd.help(cmd.help_arg()); + cout << "\nCopyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> \n\n"; +} + + +static string remove_path (string fname) { + fname = FileSystem::adaptPathSeperators(fname); + size_t slashpos = fname.rfind('/'); + if (slashpos == string::npos) + return fname; + return fname.substr(slashpos+1); +} + + +static string ensure_suffix (string fname, bool eps) { + size_t dotpos = remove_path(fname).rfind('.'); + if (dotpos == string::npos) + fname += (eps ? ".eps" : ".dvi"); + return fname; +} + + +static string get_transformation_string (const CommandLine &args) { + ostringstream oss; + if (args.rotate_given()) + oss << 'R' << args.rotate_arg() << ",w/2,h/2"; + if (args.translate_given()) + oss << 'T' << args.translate_arg(); + if (args.scale_given()) + oss << 'S' << args.scale_arg(); + if (args.transform_given()) + oss << args.transform_arg(); + return oss.str(); +} + + +static void set_libgs (CommandLine &args) { +#if !defined(DISABLE_GS) && !defined(HAVE_LIBGS) + if (args.libgs_given()) + Ghostscript::LIBGS_NAME = args.libgs_arg(); + else if (getenv("LIBGS")) + Ghostscript::LIBGS_NAME = getenv("LIBGS"); +#endif +} + + +static bool set_cache_dir (const CommandLine &args) { + if (args.cache_given() && !args.cache_arg().empty()) { + if (args.cache_arg() == "none") + PhysicalFont::CACHE_PATH = 0; + else if (FileSystem::exists(args.cache_arg().c_str())) + PhysicalFont::CACHE_PATH = args.cache_arg().c_str(); + else + Message::wstream(true) << "cache directory '" << args.cache_arg() << "' does not exist (caching disabled)\n"; + } + else { + if (const char *userdir = FileSystem::userdir()) { + static string path = userdir; + path += "/.dvisvgm"; + path = FileSystem::adaptPathSeperators(path); + const string cachepath = path+"/cache"; + if (!FileSystem::exists(cachepath.c_str())) { + if (!FileSystem::exists(path.c_str())) + FileSystem::mkdir(cachepath.c_str()); + else { + FileSystem::mkdir(cachepath.c_str()); + // move existing cache files from former location to new one + vector<string> files; + FileSystem::collect(path.c_str(), files); + FORALL(files, vector<string>::iterator, it) { + if (it->at(0) == 'f' && it->length() > 4 && it->substr(it->length()-4, 4) == ".fgd") { + const char *fname = it->c_str()+1; + FileSystem::copy(path+"/"+fname, cachepath+"/"+fname, true); + } + } + } + } + path = cachepath; + PhysicalFont::CACHE_PATH = path.c_str(); + } + if (args.cache_given() && args.cache_arg().empty()) { + cout << "cache directory: " << (PhysicalFont::CACHE_PATH ? PhysicalFont::CACHE_PATH : "(none)") << '\n'; + FontCache::fontinfo(PhysicalFont::CACHE_PATH, cout, true); + return false; + } + } + return true; +} + + +static bool check_bbox (const string &bboxstr) { + const char *formats[] = {"none", "min", "dvi", 0}; + for (const char **p=formats; *p; ++p) + if (bboxstr == *p) + return true; + if (isalpha(bboxstr[0])) { + try { + PageSize size(bboxstr); + return true; + } + catch (const PageSizeException &e) { + Message::estream(true) << "invalid bounding box format '" << bboxstr << "'\n"; + return false; + } + } + try { + BoundingBox bbox; + bbox.set(bboxstr); + return true; + } + catch (const MessageException &e) { + Message::estream(true) << e.what() << '\n'; + return false; + } +} + + +static void print_version (bool extended) { + ostringstream oss; + oss << PACKAGE_STRING; + if (extended) { + if (strlen(TARGET_SYSTEM) > 0) + oss << " (" TARGET_SYSTEM ")"; + int len = oss.str().length(); + oss << "\n" << string(len, '-') << "\n" + "freetype: " << FontEngine::version() << "\n"; + + Ghostscript gs; + string gsver = gs.revision(true); + if (!gsver.empty()) + oss << "Ghostscript: " << gsver + "\n"; + oss << +#ifdef MIKTEX + "MiKTeX: " << FileFinder::version() << "\n" +#else + "kpathsea: " << FileFinder::version() << "\n" +#endif + "potrace: " << (strchr(potrace_version(), ' ') ? strchr(potrace_version(), ' ')+1 : "unknown") << "\n" + "zlib: " << zlibVersion(); + } + cout << oss.str() << endl; +} + + +static void init_fontmap (const CommandLine &args) { + const char *mapseq = args.fontmap_given() ? args.fontmap_arg().c_str() : 0; + bool additional = mapseq && strchr("+-=", *mapseq); + if (!mapseq || additional) { + const char *mapfiles[] = {"ps2pk.map", "dvipdfm.map", "psfonts.map", 0}; + bool found = false; + for (const char **p=mapfiles; *p && !found; p++) + found = FontMap::instance().read(*p); + if (!found) + Message::wstream(true) << "none of the default map files could be found"; + } + if (mapseq) + FontMap::instance().read(mapseq); +} + + +int main (int argc, char *argv[]) { + CommandLine args; + args.parse(argc, argv); + if (args.error()) + return 1; + + Message::COLORIZE = args.color_given(); + + try { + FileFinder::init(argv[0], "dvisvgm", !args.no_mktexmf_given()); + } + catch (MessageException &e) { + Message::estream(true) << e.what() << '\n'; + return 0; + } + + set_libgs(args); + if (args.version_given()) { + print_version(args.version_arg()); + return 0; + } + if (args.list_specials_given()) { + SVGOutput out; + DVIToSVG dvisvg(cin, out); + if (const SpecialManager *sm = dvisvg.setProcessSpecials()) + sm->writeHandlerInfo(cout); + return 0; + } + + if (!set_cache_dir(args)) + return 0; + + if (argc == 1 || args.help_given()) { + show_help(args); + return 0; + } + + if (argc > 1 && args.numFiles() < 1) { + Message::estream(true) << "no input file given\n"; + return 1; + } + + if (args.stdout_given() && args.zip_given()) { + Message::estream(true) << "writing SVGZ files to stdout is not supported\n"; + return 1; + } + + if (!check_bbox(args.bbox_arg())) + return 1; + + if (args.progress_given()) { + DVIReader::COMPUTE_PAGE_LENGTH = args.progress_given(); + DVIToSVGActions::PROGRESSBAR_DELAY = args.progress_arg(); + } + SVGTree::CREATE_STYLE = !args.no_styles_given(); + SVGTree::USE_FONTS = !args.no_fonts_given(); + SVGTree::CREATE_USE_ELEMENTS = args.no_fonts_arg() < 1; + SVGTree::ZOOM_FACTOR = args.zoom_arg(); + DVIToSVG::TRACE_MODE = args.trace_all_given() ? (args.trace_all_arg() ? 'a' : 'm') : 0; + Message::LEVEL = args.verbosity_arg(); + PhysicalFont::EXACT_BBOX = args.exact_given(); + PhysicalFont::KEEP_TEMP_FILES = args.keep_given(); + PhysicalFont::METAFONT_MAG = args.mag_arg(); + XMLString::DECIMAL_PLACES = max(0, min(6, args.precision_arg())); + if (!HtmlSpecialHandler::setLinkMarker(args.linkmark_arg())) + Message::wstream(true) << "invalid argument '"+args.linkmark_arg()+"' supplied for option --linkmark\n"; + double start_time = System::time(); + bool eps_given=false; +#if defined(HAVE_LIBGS) || !defined(DISABLE_GS) + eps_given = args.eps_given(); +#endif + string inputfile = ensure_suffix(args.file(0), eps_given); + ifstream ifs(inputfile.c_str(), ios_base::binary|ios_base::in); + if (!ifs) { + Message::estream(true) << "can't open file '" << inputfile << "' for reading\n"; + return 0; + } + try { + SVGOutput out(args.stdout_given() ? 0 : inputfile.c_str(), args.output_arg(), args.zip_given() ? args.zip_arg() : 0); + SignalHandler::instance().start(); +#if defined(HAVE_LIBGS) || !defined(DISABLE_GS) + if (args.eps_given()) { + EPSToSVG eps2svg(inputfile, out); + eps2svg.convert(); + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) + << "file converted in " << (System::time()-start_time) << " seconds\n"; + } + else +#endif + { + DVIToSVG dvi2svg(ifs, out); + const char *ignore_specials = args.no_specials_given() ? (args.no_specials_arg().empty() ? "*" : args.no_specials_arg().c_str()) : 0; + dvi2svg.setProcessSpecials(ignore_specials, true); + dvi2svg.setPageTransformation(get_transformation_string(args)); + dvi2svg.setPageSize(args.bbox_arg()); + + init_fontmap(args); + pair<int,int> pageinfo; + dvi2svg.convert(args.page_arg(), &pageinfo); + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) << "\n" << pageinfo.first << " of " << pageinfo.second << " page"; + if (pageinfo.second > 1) + Message::mstream(false, Message::MC_PAGE_NUMBER) << 's'; + Message::mstream(false, Message::MC_PAGE_NUMBER) << " converted in " << (System::time()-start_time) << " seconds\n"; + } + } + catch (DVIException &e) { + Message::estream() << "\nDVI error: " << e.what() << '\n'; + } + catch (PSException &e) { + Message::estream() << "\nPostScript error: " << e.what() << '\n'; + } + catch (SignalException &e) { + Message::wstream(true) << "execution interrupted by user\n"; + } + catch (MessageException &e) { + Message::estream(true) << e.what() << '\n'; + } + FileFinder::finish(); + return 0; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.cpp new file mode 100644 index 00000000000..2893c299891 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.cpp @@ -0,0 +1,172 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.C +// Revision : $Revision: 1.3 $ +// Revision_date : $Date: 2006/01/05 16:22:35 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#include "gzstream.h" +#include <iostream> +#include <string.h> // for memcpy + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +const int gzstreambuf::bufferSize = 47+256; // size of data buff + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See header file for user classes. +// ---------------------------------------------------------------------------- + +// -------------------------------------- +// class gzstreambuf: +// -------------------------------------- + +gzstreambuf* gzstreambuf::open(const char* name, int compression_level, int open_mode) { + if ( is_open()) + return (gzstreambuf*)0; + mode = open_mode; + // no append nor read/write mode + if ((mode & std::ios::ate) || (mode & std::ios::app) + || ((mode & std::ios::in) && (mode & std::ios::out))) + return (gzstreambuf*)0; + if (compression_level < 1) + compression_level = 1; + else if (compression_level > 9) + compression_level = 9; + char fmode[10]; + char* fmodeptr = fmode; + if ( mode & std::ios::in) + *fmodeptr++ = 'r'; + else if ( mode & std::ios::out) + *fmodeptr++ = 'w'; + *fmodeptr++ = 'b'; + *fmodeptr++ = '0'+compression_level; + *fmodeptr = '\0'; + file = gzopen( name, fmode); + if (file == 0) + return (gzstreambuf*)0; + opened = 1; + return this; +} + +gzstreambuf * gzstreambuf::close() { + if ( is_open()) { + sync(); + opened = 0; + if ( gzclose( file) == Z_OK) + return this; + } + return (gzstreambuf*)0; +} + +int gzstreambuf::underflow() { // used for input buffer only + if ( gptr() && ( gptr() < egptr())) + return * reinterpret_cast<unsigned char *>( gptr()); + + if ( ! (mode & std::ios::in) || ! opened) + return EOF; + // Josuttis' implementation of inbuf + int n_putback = gptr() - eback(); + if ( n_putback > 4) + n_putback = 4; + memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback); + + int num = gzread( file, buffer+4, bufferSize-4); + if (num <= 0) // ERROR or EOF + return EOF; + + // reset buffer pointers + setg( buffer + (4 - n_putback), // beginning of putback area + buffer + 4, // read position + buffer + 4 + num); // end of buffer + + // return next character + return * reinterpret_cast<unsigned char *>( gptr()); +} + +int gzstreambuf::flush_buffer() { + // Separate the writing of the buffer from overflow() and + // sync() operation. + int w = pptr() - pbase(); + if ( gzwrite( file, pbase(), w) != w) + return EOF; + pbump( -w); + return w; +} + +int gzstreambuf::overflow( int c) { // used for output buffer only + if ( ! ( mode & std::ios::out) || ! opened) + return EOF; + if (c != EOF) { + *pptr() = c; + pbump(1); + } + if ( flush_buffer() == EOF) + return EOF; + return c; +} + +int gzstreambuf::sync() { + // Changed to use flush_buffer() instead of overflow( EOF) + // which caused improper behavior with std::endl and flush(), + // bug reported by Vincent Ricard. + if ( pptr() && pptr() > pbase()) { + if ( flush_buffer() == EOF) + return -1; + } + return 0; +} + +// -------------------------------------- +// class gzstreambase: +// -------------------------------------- + +gzstreambase::gzstreambase( const char* name, int compression_level, int mode) { + init( &buf); + open( name, compression_level, mode); +} + +gzstreambase::~gzstreambase() { + buf.close(); +} + +void gzstreambase::open( const char* name, int compression_level, int open_mode) { + if ( ! buf.open( name, compression_level, open_mode)) + clear( rdstate() | std::ios::badbit); +} + +void gzstreambase::close() { + if ( buf.is_open()) + if ( ! buf.close()) + clear( rdstate() | std::ios::badbit); +} + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +// ============================================================================ +// EOF // diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.h new file mode 100644 index 00000000000..60f38c4fac7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/gzstream.h @@ -0,0 +1,121 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.h +// Revision : $Revision: 1.3 $ +// Revision_date : $Date: 2006/01/05 16:22:35 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#ifndef GZSTREAM_H +#define GZSTREAM_H 1 + +// standard C++ with new header file names and std:: namespace +#include <iostream> +#include <fstream> +#include <zlib.h> + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See below for user classes. +// ---------------------------------------------------------------------------- + +class gzstreambuf : public std::streambuf { +private: + static const int bufferSize; // size of data buff + // totals 512 bytes under g++ for igzstream at the end. + + gzFile file; // file handle for compressed file + char buffer[47+256]; // data buffer + char opened; // open/close state of stream + int mode; // I/O mode + + int flush_buffer(); +public: + gzstreambuf() : opened(0) { + setp( buffer, buffer + (bufferSize-1)); + setg( buffer + 4, // beginning of putback area + buffer + 4, // read position + buffer + 4); // end position + // ASSERT: both input & output capabilities will not be used together + } + int is_open() { return opened; } + gzstreambuf* open(const char* name, int compression_level, int open_mode); + gzstreambuf* close(); + ~gzstreambuf() { close(); } + + virtual int overflow( int c = EOF); + virtual int underflow(); + virtual int sync(); +}; + +class gzstreambase : virtual public std::ios { +protected: + gzstreambuf buf; +public: + gzstreambase() { init(&buf); } + gzstreambase( const char* name, int compression_level, int open_mode); + ~gzstreambase(); + void open( const char* name, int compression_level, int open_mode); + void close(); + gzstreambuf* rdbuf() { return &buf; } +}; + +// ---------------------------------------------------------------------------- +// User classes. Use igzstream and ogzstream analogously to ifstream and +// ofstream respectively. They read and write files based on the gz* +// function interface of the zlib. Files are compatible with gzip compression. +// ---------------------------------------------------------------------------- + +class igzstream : public gzstreambase, public std::istream { +public: + igzstream() : std::istream( &buf) {} + igzstream( const char* name, int compression_level, int open_mode = std::ios::in) + : gzstreambase(name, compression_level, open_mode), std::istream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int compression_level, int open_mode = std::ios::in) { + gzstreambase::open( name, compression_level, open_mode); + } +}; + +class ogzstream : public gzstreambase, public std::ostream { +public: + ogzstream() : std::ostream( &buf) {} + ogzstream( const char* name, int compression_level, int mode = std::ios::out) + : gzstreambase(name, compression_level, mode), std::ostream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int compression_level, int open_mode = std::ios::out) { + gzstreambase::open(name, compression_level, open_mode); + } +}; + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +#endif // GZSTREAM_H +// ============================================================================ +// EOF // + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/iapi.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/iapi.h new file mode 100644 index 00000000000..8e29d938d03 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/iapi.h @@ -0,0 +1,300 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id: iapi.h 9043 2008-08-28 22:48:19Z giles $ */ + +/* + * Public API for Ghostscript interpreter + * for use both as DLL and for static linking. + * + * Should work for Windows, OS/2, Linux, Mac. + * + * DLL exported functions should be as similar as possible to imain.c + * You will need to include "ierrors.h". + * + * Current problems: + * 1. Ghostscript does not support multiple instances. + * 2. Global variables in gs_main_instance_default() + * and gsapi_instance_counter + */ + +/* Exported functions may need different prefix + * GSDLLEXPORT marks functions as exported + * GSDLLAPI is the calling convention used on functions exported + * by Ghostscript + * GSDLLCALL is used on callback functions called by Ghostscript + * When you include this header file in the caller, you may + * need to change the definitions by defining these + * before including this header file. + * Make sure you get the calling convention correct, otherwise your + * program will crash either during callbacks or soon after returning + * due to stack corruption. + */ + +#ifndef iapi_INCLUDED +# define iapi_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WINDOWS_) || defined(__WINDOWS__) +# ifndef _Windows +# define _Windows +# endif +#endif + +#ifdef _Windows +# ifndef GSDLLEXPORT +# define GSDLLEXPORT __declspec(dllexport) +# endif +# ifndef GSDLLAPI +# define GSDLLAPI __stdcall +# endif +# ifndef GSDLLCALL +# define GSDLLCALL __stdcall +# endif +#endif /* _Windows */ + +#if defined(OS2) && defined(__IBMC__) +# ifndef GSDLLAPI +# define GSDLLAPI _System +# endif +# ifndef GSDLLCALL +# define GSDLLCALL _System +# endif +#endif /* OS2 && __IBMC */ + +#ifdef __MACOS__ +# pragma export on +#endif + +#ifndef GSDLLEXPORT +# define GSDLLEXPORT +#endif +#ifndef GSDLLAPI +# define GSDLLAPI +#endif +#ifndef GSDLLCALL +# define GSDLLCALL +#endif + +#if defined(__IBMC__) +# define GSDLLAPIPTR * GSDLLAPI +# define GSDLLCALLPTR * GSDLLCALL +#else +# define GSDLLAPIPTR GSDLLAPI * +# define GSDLLCALLPTR GSDLLCALL * +#endif + +#ifndef display_callback_DEFINED +# define display_callback_DEFINED +typedef struct display_callback_s display_callback; +#endif + +typedef struct gsapi_revision_s { + const char *product; + const char *copyright; + long revision; + long revisiondate; +} gsapi_revision_t; + + +/* Get version numbers and strings. + * This is safe to call at any time. + * You should call this first to make sure that the correct version + * of the Ghostscript is being used. + * pr is a pointer to a revision structure. + * len is the size of this structure in bytes. + * Returns 0 if OK, or if len too small (additional parameters + * have been added to the structure) it will return the required + * size of the structure. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_revision(gsapi_revision_t *pr, int len); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * If you try to create two instances, the second attempt + * will return < 0 and set pinstance to NULL. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Create a new instance of Ghostscript. + * This instance is passed to most other API functions. + * The caller_handle will be provided to callback functions. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_new_instance(void **pinstance, void *caller_handle); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Destroy an instance of Ghostscript + * Before you call this, Ghostscript must have finished. + * If Ghostscript has been initialised, you must call gsapi_exit() + * before gsapi_delete_instance. + */ +GSDLLEXPORT void GSDLLAPI +gsapi_delete_instance(void *instance); + +/* Set the callback functions for stdio + * The stdin callback function should return the number of + * characters read, 0 for EOF, or -1 for error. + * The stdout and stderr callback functions should return + * the number of characters written. + * If a callback address is NULL, the real stdio will be used. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_set_stdio(void *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); + +/* Set the callback function for polling. + * This is used for handling window events or cooperative + * multitasking. This function will only be called if + * Ghostscript was compiled with CHECK_INTERRUPTS + * as described in gpcheck.h. + * The polling function should return 0 if all is well, + * and negative if it wants ghostscript to abort. + * The polling function must be fast. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_poll(void *instance, + int (GSDLLCALLPTR poll_fn)(void *caller_handle)); + +/* Set the display device callback structure. + * If the display device is used, this must be called + * after gsapi_new_instance() and before gsapi_init_with_args(). + * See gdevdisp.h for more details. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_display_callback( + void *instance, display_callback *callback); + + +/* Initialise the interpreter. + * This calls gs_main_init_with_args() in imainarg.c + * 1. If quit or EOF occur during gsapi_init_with_args(), + * the return value will be e_Quit. This is not an error. + * You must call gsapi_exit() and must not call any other + * gsapi_XXX functions. + * 2. If usage info should be displayed, the return value will be e_Info + * which is not an error. Do not call gsapi_exit(). + * 3. Under normal conditions this returns 0. You would then + * call one or more gsapi_run_*() functions and then finish + * with gsapi_exit(). + */ +GSDLLEXPORT int GSDLLAPI gsapi_init_with_args(void *instance, + int argc, char **argv); + +/* + * The gsapi_run_* functions are like gs_main_run_* except + * that the error_object is omitted. + * If these functions return <= -100, either quit or a fatal + * error has occured. You then call gsapi_exit() next. + * The only exception is gsapi_run_string_continue() + * which will return e_NeedInput if all is well. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_begin(void *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_continue(void *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_end(void *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_with_length(void *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string(void *instance, + const char *str, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_file(void *instance, + const char *file_name, int user_errors, int *pexit_code); + + +/* Exit the interpreter. + * This must be called on shutdown if gsapi_init_with_args() + * has been called, and just before gsapi_delete_instance(). + */ +GSDLLEXPORT int GSDLLAPI +gsapi_exit(void *instance); + +/* Visual Tracer */ +/* This function is only for debug purpose clients */ +struct vd_trace_interface_s; +GSDLLEXPORT void GSDLLAPI +gsapi_set_visual_tracer(struct vd_trace_interface_s *I); + + +/* function prototypes */ +typedef int (GSDLLAPIPTR PFN_gsapi_revision)( + gsapi_revision_t *pr, int len); +typedef int (GSDLLAPIPTR PFN_gsapi_new_instance)( + void **pinstance, void *caller_handle); +typedef void (GSDLLAPIPTR PFN_gsapi_delete_instance)( + void *instance); +typedef int (GSDLLAPIPTR PFN_gsapi_set_stdio)(void *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_poll)(void *instance, + int(GSDLLCALLPTR poll_fn)(void *caller_handle)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_display_callback)( + void *instance, display_callback *callback); +typedef int (GSDLLAPIPTR PFN_gsapi_init_with_args)( + void *instance, int argc, char **argv); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_begin)( + void *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_continue)( + void *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_end)( + void *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_with_length)( + void *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string)( + void *instance, const char *str, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_file)(void *instance, + const char *file_name, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_exit)(void *instance); +typedef void (GSDLLAPIPTR PFN_gsapi_set_visual_tracer) + (struct vd_trace_interface_s *I); + + +#ifdef __MACOS__ +#pragma export off +#endif + +#ifdef __cplusplus +} /* extern 'C' protection */ +#endif + +#endif /* iapi_INCLUDED */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ierrors.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ierrors.h new file mode 100644 index 00000000000..3184341177e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/ierrors.h @@ -0,0 +1,153 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id: ierrors.h 8022 2007-06-05 22:23:38Z giles $ */ +/* Definition of error codes */ + +#ifndef ierrors_INCLUDED +# define ierrors_INCLUDED + +/* + * DO NOT USE THIS FILE IN THE GRAPHICS LIBRARY. + * THIS FILE IS PART OF THE POSTSCRIPT INTERPRETER. + * USE gserrors.h IN THE LIBRARY. + */ + +/* + * A procedure that may return an error always returns + * a non-negative value (zero, unless otherwise noted) for success, + * or negative for failure. + * We use ints rather than an enum to avoid a lot of casting. + */ + +/* Define the error name table */ +extern const char *const gs_error_names[]; + + /* ------ PostScript Level 1 errors ------ */ + +#define e_unknownerror (-1) /* unknown error */ +#define e_dictfull (-2) +#define e_dictstackoverflow (-3) +#define e_dictstackunderflow (-4) +#define e_execstackoverflow (-5) +#define e_interrupt (-6) +#define e_invalidaccess (-7) +#define e_invalidexit (-8) +#define e_invalidfileaccess (-9) +#define e_invalidfont (-10) +#define e_invalidrestore (-11) +#define e_ioerror (-12) +#define e_limitcheck (-13) +#define e_nocurrentpoint (-14) +#define e_rangecheck (-15) +#define e_stackoverflow (-16) +#define e_stackunderflow (-17) +#define e_syntaxerror (-18) +#define e_timeout (-19) +#define e_typecheck (-20) +#define e_undefined (-21) +#define e_undefinedfilename (-22) +#define e_undefinedresult (-23) +#define e_unmatchedmark (-24) +#define e_VMerror (-25) /* must be the last Level 1 error */ + +#define LEVEL1_ERROR_NAMES\ + "unknownerror", "dictfull", "dictstackoverflow", "dictstackunderflow",\ + "execstackoverflow", "interrupt", "invalidaccess", "invalidexit",\ + "invalidfileaccess", "invalidfont", "invalidrestore", "ioerror",\ + "limitcheck", "nocurrentpoint", "rangecheck", "stackoverflow",\ + "stackunderflow", "syntaxerror", "timeout", "typecheck", "undefined",\ + "undefinedfilename", "undefinedresult", "unmatchedmark", "VMerror" + + /* ------ Additional Level 2 errors (also in DPS) ------ */ + +#define e_configurationerror (-26) +#define e_undefinedresource (-27) +#define e_unregistered (-28) + +#define LEVEL2_ERROR_NAMES\ + "configurationerror", "undefinedresource", "unregistered" + + /* ------ Additional DPS errors ------ */ + +#define e_invalidcontext (-29) +/* invalidid is for the NeXT DPS extension. */ +#define e_invalidid (-30) + +#define DPS_ERROR_NAMES\ + "invalidcontext", "invalidid" + +#define ERROR_NAMES\ + LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES + + /* ------ Pseudo-errors used internally ------ */ + +/* + * Internal code for a fatal error. + * gs_interpret also returns this for a .quit with a positive exit code. + */ +#define e_Fatal (-100) + +/* + * Internal code for the .quit operator. + * The real quit code is an integer on the operand stack. + * gs_interpret returns this only for a .quit with a zero exit code. + */ +#define e_Quit (-101) + +/* + * Internal code for a normal exit from the interpreter. + * Do not use outside of interp.c. + */ +#define e_InterpreterExit (-102) + +/* + * Internal code that indicates that a procedure has been stored in the + * remap_proc of the graphics state, and should be called before retrying + * the current token. This is used for color remapping involving a call + * back into the interpreter -- inelegant, but effective. + */ +#define e_RemapColor (-103) + +/* + * Internal code to indicate we have underflowed the top block + * of the e-stack. + */ +#define e_ExecStackUnderflow (-104) + +/* + * Internal code for the vmreclaim operator with a positive operand. + * We need to handle this as an error because otherwise the interpreter + * won't reload enough of its state when the operator returns. + */ +#define e_VMreclaim (-105) + +/* + * Internal code for requesting more input from run_string. + */ +#define e_NeedInput (-106) + +/* + * Internal code for a normal exit when usage info is displayed. + * This allows Window versions of Ghostscript to pause until + * the message can be read. + */ +#define e_Info (-110) + +/* + * Define which error codes require re-executing the current object. + */ +#define ERROR_IS_INTERRUPT(ecode)\ + ((ecode) == e_interrupt || (ecode) == e_timeout) + +#endif /* ierrors_INCLUDED */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/macros.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/macros.h new file mode 100644 index 00000000000..73217c763e0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/macros.h @@ -0,0 +1,42 @@ +/************************************************************************* +** macros.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_MACROS_H +#define DVISVGM_MACROS_H + +#define FORALL(container, itertype, itervar) \ + for (itertype itervar=(container).begin(); itervar != (container).end(); ++itervar) + +#define IMPLEMENT_ARITHMETIC_OPERATOR(class, op) \ + inline class operator op (class a, const class &b) { \ + return a op##= b; \ + } + +#define IMPLEMENT_ARITHMETIC_OPERATOR2(class, scalar, op) \ + inline class operator op (class a, scalar b) { \ + return a op##= b; \ + } + +#define IMPLEMENT_OUTPUT_OPERATOR(class) \ + inline std::ostream& operator << (std::ostream &os, class obj) { \ + return obj.write(os); \ + } + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/options.xml b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/options.xml new file mode 100644 index 00000000000..33ce8bd44f9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/options.xml @@ -0,0 +1,155 @@ +<?xml version="1.0"?> +<!-- ********************************************************************* +** options.xml ** +** ** +** This file is part of dvisvgm - the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +***********************************************************************--> +<!DOCTYPE cmdline SYSTEM "options.dtd"> + +<cmdline class="CommandLine"> + <program> + <name>dvisvgm</name> + <usage>[options] dvifile</usage> + <usage>-E [options] epsfile</usage> + <description>This program converts DVI files, as created by TeX/LaTeX, to\nthe XML-based scalable vector graphics format SVG.</description> + </program> + <options> + <section title="Input options"> + <option long="page" short="p"> + <arg type="string" name="ranges" default="1"/> + <description>choose pages to convert</description> + </option> + <option long="fontmap" short="m"> + <arg type="string" name="filenames"/> + <description>evaluate (additional) font map files</description> + </option> + <option long="eps" short="E" if="!defined(DISABLE_GS)"> + <description>convert an EPS file to SVG</description> + </option> + </section> + <section title="SVG output options"> + <option long="bbox" short="b"> + <arg type="string" name="size" default="min"/> + <description>set size of bounding box</description> + </option> + <option long="linkmark" short="L"> + <arg type="string" name="type" default="box"/> + <description>select how to mark hyperlinked areas</description> + </option> + <option long="output" short="o"> + <arg type="string" name="pattern"/> + <description>set name pattern of output files</description> + </option> + <option long="precision" short="d"> + <arg type="int" name="number" default="0"/> + <description>set number of decimal points (0-6)</description> + </option> + <option long="stdout" short="s"> + <description>write SVG output to stdout</description> + </option> + <option long="no-fonts" short="n"> + <arg type="int" name="variant" default="0" optional="yes"/> + <description>draw glyphs by using path elements</description> + </option> + <option long="no-styles"> + <description>don't use styles to reference fonts</description> + </option> + <option long="zip" short="z"> + <arg type="int" name="level" default="9" optional="yes"/> + <description>create compressed .svgz file</description> + </option> + </section> + <section title="SVG transformations"> + <option long="rotate" short="r"> + <arg type="double" name="angle"/> + <description>rotate page content clockwise</description> + </option> + <option long="scale" short="c"> + <arg type="string" name="sx[,sy]"/> + <description>scale page content</description> + </option> + <option long="translate" short="t"> + <arg type="string" name="tx[,ty]"/> + <description>shift page content</description> + </option> + <option long="transform" short="T"> + <arg type="string" name="commands"/> + <description>transform page content</description> + </option> + <option long="zoom" short="Z"> + <arg type="double" name="factor" default="1.0"/> + <description>zoom page content</description> + </option> + </section> + <section title="Processing options"> + <option long="cache" short="C"> + <arg type="string" name="dir" optional="yes"/> + <description>set/print path of cache directory</description> + </option> + <option long="exact" short="e"> + <description>compute exact glyph boxes</description> + </option> + <option long="keep"> + <description>keep temporary files</description> + </option> + <option long="libgs" if="!defined(HAVE_LIBGS) && !defined(DISABLE_GS)"> + <arg name="filename" type="string"/> + <description>set name of Ghostscript shared library</description> + </option> + <option long="mag" short="M"> + <arg type="double" name="factor" default="4"/> + <description>magnification of Metafont output</description> + </option> + <option long="no-mktexmf"> + <description>don't try to create missing fonts</description> + </option> + <option long="no-specials" short="S"> + <arg type="string" name="prefixes" optional="yes"/> + <description>don't process [selected] specials</description> + </option> + <option long="trace-all" short="a"> + <arg name="retrace" type="bool" optional="yes" default="no"/> + <description>trace all glyphs of bitmap fonts</description> + </option> + </section> + <section title="Message options"> + <option long="color"> + <description>colorize messages</description> + </option> + <option long="help" short="h"> + <arg name="mode" type="int" optional="yes" default="0"/> + <description>print this summary of options and exit</description> + </option> + <option long="list-specials" short="l"> + <description>print supported special sets and exit</description> + </option> + <option long="progress" short="P"> + <arg name="delay" type="double" optional="yes" default="0.5"/> + <description>enable progess indicator</description> + </option> + <option long="verbosity" short="v"> + <arg type="unsigned" name="level" default="7"/> + <description>set verbosity level (0-7)</description> + </option> + <option long="version" short="V"> + <arg type="bool" name="extended" optional="yes" default="no"/> + <description>print version and exit</description> + </option> + </section> + </options> +</cmdline> + diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/psdefs.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/psdefs.cpp new file mode 100644 index 00000000000..4edce3af1d8 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/psdefs.cpp @@ -0,0 +1,83 @@ +/************************************************************************* +** psdefs.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include "PSInterpreter.h" + +const char *PSInterpreter::PSDEFS = +"3 dict dup begin/Install{matrix setmatrix}def/HWResolution[72 72]def/PageSize[10" +"000 10000]def end setpagedevice/@dodraw true store/@patcnt 0 store/@SD systemdic" +"t def/@UD userdict def true setglobal @SD/:save @SD/save get put @SD/:restore @S" +"D/restore get put @SD/:gsave @SD/gsave get put @SD/:grestore @SD/grestore get pu" +"t @SD/:grestoreall @SD/grestoreall get put @SD/:stroke @SD/stroke get put @SD/:f" +"ill @SD/fill get put @SD/:eofill @SD/eofill get put @SD/:clip @SD/clip get put @" +"SD/:eoclip @SD/eoclip get put @SD/:charpath @SD/charpath get put @SD/:show @SD/s" +"how get put @SD/.setopacityalpha known not{@SD/.setopacityalpha{pop}put}if @SD/p" +"rseq{-1 1{-1 roll =only( )print}for(\\n)print}put @SD/prcmd{( )exch(\\ndvi.)3{pr" +"int}repeat prseq}put @SD/cvxall{{cvx}forall}put @SD/defpr{[exch[/copy @SD]cvxall" +" 5 -1 roll dup 6 1 roll[/get/exec]cvxall 6 -1 roll dup 7 1 roll 4 -1 roll dup 5 " +"1 roll dup length string cvs/prcmd cvx]cvx def}put @SD/querypos{{currentpoint}st" +"opped{$error/newerror false put}{2(querypos)prcmd}ifelse}put @SD/applyscalevals{" +"1 0 transform 0 0 transform 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt " +"0 1 transform 0 0 transform 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt " +"1 0 transform dup mul exch dup dup mul 3 -1 roll add sqrt div 3(applyscalevals)p" +"rcmd}put @SD/prpath{{2(moveto)prcmd}{2(lineto)prcmd}{6(curveto)prcmd}{0(closepat" +"h)prcmd}pathforall}put @SD/charpath{/@dodraw false store :charpath/@dodraw true " +"store}put @SD/show{@dodraw{dup :gsave currentpoint newpath moveto true charpath " +"eofill :grestore :show}if}put @SD/stroke{@dodraw{0(newpath)prcmd prpath 0(stroke" +")prcmd newpath}{:stroke}ifelse}put @SD/fill{@dodraw{0(newpath)prcmd prpath 0(fil" +"l)prcmd newpath}{:fill}ifelse}put @SD/eofill{@dodraw{0(newpath)prcmd prpath 0(eo" +"fill)prcmd newpath}{:eofill}ifelse}put @SD/clip{:clip 0(newpath)prcmd prpath 0(c" +"lip)prcmd}put @SD/eoclip{:eoclip 0(newpath)prcmd prpath 0(eoclip)prcmd}put @SD/b" +"op{pop pop}put/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch rlineto neg" +" 0 rlineto closepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt exch 0 lt xor" +"{dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup 0 rlineto exch 0" +" exch rlineto neg 0 rlineto}ifelse closepath}bind def @SD/rectclip{newpath dup t" +"ype/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifelse clip newpath" +"}put @SD/rectfill{gsave newpath dup type/arraytype eq{aload length 4 idiv{@rectc" +"c}repeat}{@rectcc}ifelse fill grestore}put @SD/rectstroke{gsave newpath dup type" +"/arraytype eq{aload length 4 idiv{@rect}repeat}{@rect}ifelse stroke grestore}put" +" false setglobal @SD readonly pop/initclip 0 defpr/sysexec{@SD exch get exec}def" +"/adddot{dup length 1 add string dup 0 46 put dup 3 -1 roll 1 exch putinterval}de" +"f/setlinewidth{dup/setlinewidth sysexec applyscalevals 1(setlinewidth)prcmd}def/" +"setlinecap 1 defpr/setlinejoin 1 defpr/setmiterlimit 1 defpr/setdash{mark 3 1 ro" +"ll 2 copy/setdash sysexec applyscalevals exch aload length 1 add -1 roll countto" +"mark(setdash)prcmd pop}def/setgstate{currentlinewidth 1(setlinewidth)prcmd curre" +"ntlinecap 1(setlinecap)prcmd currentlinejoin 1(setlinejoin)prcmd currentmiterlim" +"it 1(setmiterlimit)prcmd currentrgbcolor 3(setrgbcolor)prcmd 6 array currentmatr" +"ix aload pop 6(setmatrix)prcmd currentdash mark 3 1 roll exch aload length 1 add" +" -1 roll counttomark(setdash)prcmd pop}def/save{@UD begin/@saveID vmstatus pop p" +"op def end :save @saveID 1(save)prcmd}def/restore{:restore setgstate @UD/@saveID" +" known{@UD begin @saveID end}{0}ifelse 1(restore)prcmd}def/gsave 0 defpr/grestor" +"e{:grestore setgstate 0(grestore)prcmd}def/grestoreall{:grestoreall setstate 0(g" +"restoreall)prcmd}def/rotate{dup type/arraytype ne{dup 1(rotate)prcmd}if/rotate s" +"ysexec}def/scale{dup type/arraytype ne{2 copy 2(scale)prcmd}if/scale sysexec}def" +"/translate{dup type/arraytype ne{2 copy 2(translate)prcmd}if/translate sysexec}d" +"ef/setmatrix{dup/setmatrix sysexec aload pop 6(setmatrix)prcmd}def/initmatrix{ma" +"trix setmatrix}def/concat{matrix currentmatrix matrix concatmatrix setmatrix}def" +"/makepattern{gsave <</mx 3 -1 roll >> begin dup/XUID[1000000 @patcnt]put mx/make" +"pattern sysexec dup dup begin PatternType @patcnt BBox aload pop XStep YStep Pai" +"ntType mx aload pop 15(makepattern)prcmd newpath matrix setmatrix PaintProc 0 1(" +"makepattern)prcmd end/@patcnt @patcnt 1 add store end grestore}def/setpattern{be" +"gin PatternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[currentcol" +"orspace aload length -1 roll pop]setcolorspace/setcolor sysexec XUID aload pop e" +"xch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd}{/setpattern sysexec" +"}ifelse end}def/setcolor{dup type/dicttype eq{setpattern}{/setcolor sysexec}ifel" +"se}def/setgray 1 defpr/setcmykcolor 4 defpr/sethsbcolor 3 defpr/setrgbcolor 3 de" +"fpr/.setopacityalpha{dup/.setopacityalpha sysexec 1(setopacityalpha)prcmd}def "; diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.6/src/types.h b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/types.h new file mode 100644 index 00000000000..306a0ab4e26 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.6/src/types.h @@ -0,0 +1,84 @@ +/************************************************************************* +** types.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2014 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** 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 3 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, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef DVISVGM_TYPES_H +#define DVISVGM_TYPES_H + +namespace internal { + template<unsigned BYTES> + class ERROR_inttype_not_available + { + ERROR_inttype_not_available(); + }; + + template<bool FIRST, typename A, typename B> + struct select + { + typedef A T; + }; + + template<typename A, typename B> + struct select<false, A, B> + { + typedef B T; + }; +} + + +// Retrieves a signed integer type with sizeof(T) == BYTES +template<unsigned BYTES, bool SIGNED> +struct int_t +{ + typedef typename internal::select<sizeof(signed char) == BYTES, signed char, + typename internal::select<sizeof(signed short) == BYTES, signed short, + typename internal::select<sizeof(signed int) == BYTES, signed int, + typename internal::select<sizeof(signed long) == BYTES, signed long, + typename internal::select<sizeof(signed long long) == BYTES, signed long long, + internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T; +}; + + +// Retrieves an unsigned integer type with sizeof(T) == BYTES +template<unsigned BYTES> +struct int_t<BYTES, false> +{ + typedef typename internal::select<sizeof(unsigned char) == BYTES, unsigned char, + typename internal::select<sizeof(unsigned short) == BYTES, unsigned short, + typename internal::select<sizeof(unsigned int) == BYTES, unsigned int, + typename internal::select<sizeof(unsigned long) == BYTES, unsigned long, + typename internal::select<sizeof(unsigned long long) == BYTES, unsigned long long, + internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T; +}; + + +// Machine independent definition of sized integer types +typedef int_t<1, true>::T Int8; +typedef int_t<2, true>::T Int16; +typedef int_t<4, true>::T Int32; +typedef int_t<8, true>::T Int64; +typedef int_t<1, false>::T UInt8; +typedef int_t<2, false>::T UInt16; +typedef int_t<4, false>::T UInt32; +typedef int_t<8, false>::T UInt64; + +typedef Int32 FixWord; +typedef UInt32 ScaledInt; + +#endif |